From 31049f972aacd5aaac3d7e555e08b1da1fdcc065 Mon Sep 17 00:00:00 2001 From: "Lubomir I. Ivanov" Date: Wed, 31 Oct 2018 19:57:53 +0200 Subject: [PATCH] kubeadm: graduate the etcd phase --- cmd/kubeadm/app/cmd/alpha/alpha.go | 1 - cmd/kubeadm/app/cmd/init.go | 10 +- cmd/kubeadm/app/cmd/phases/BUILD | 2 - cmd/kubeadm/app/cmd/phases/etcd.go | 117 +++++++++++------------- cmd/kubeadm/app/cmd/phases/etcd_test.go | 85 ----------------- cmd/kubeadm/app/phases/etcd/local.go | 3 +- 6 files changed, 54 insertions(+), 164 deletions(-) delete mode 100644 cmd/kubeadm/app/cmd/phases/etcd_test.go diff --git a/cmd/kubeadm/app/cmd/alpha/alpha.go b/cmd/kubeadm/app/cmd/alpha/alpha.go index 06cf9b42794..dbcc722ed21 100644 --- a/cmd/kubeadm/app/cmd/alpha/alpha.go +++ b/cmd/kubeadm/app/cmd/alpha/alpha.go @@ -53,7 +53,6 @@ func newCmdPhase(out io.Writer) *cobra.Command { cmd.AddCommand(phases.NewCmdAddon()) cmd.AddCommand(phases.NewCmdBootstrapToken()) - cmd.AddCommand(phases.NewCmdEtcd()) cmd.AddCommand(phases.NewCmdMarkMaster()) cmd.AddCommand(phases.NewCmdSelfhosting()) cmd.AddCommand(phases.NewCmdUploadConfig()) diff --git a/cmd/kubeadm/app/cmd/init.go b/cmd/kubeadm/app/cmd/init.go index 48bc6c9d688..5e62d27112b 100644 --- a/cmd/kubeadm/app/cmd/init.go +++ b/cmd/kubeadm/app/cmd/init.go @@ -48,7 +48,6 @@ import ( clusterinfophase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo" nodebootstraptokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" - etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" markmasterphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/markmaster" patchnodephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/patchnode" @@ -168,6 +167,7 @@ func NewCmdInit(out io.Writer) *cobra.Command { initRunner.AppendPhase(phases.NewCertsPhase()) initRunner.AppendPhase(phases.NewKubeConfigPhase()) initRunner.AppendPhase(phases.NewControlPlanePhase()) + initRunner.AppendPhase(phases.NewEtcdPhase()) // TODO: add other phases to the runner. // sets the data builder function, that will be used by the runner @@ -434,14 +434,6 @@ func runInit(i *initData, out io.Writer) error { adminKubeConfigPath := filepath.Join(kubeConfigDir, kubeadmconstants.AdminKubeConfigFileName) - // Add etcd static pod spec only if external etcd is not configured - if i.cfg.Etcd.External == nil { - glog.V(1).Infof("[init] no external etcd found. Creating manifest for local etcd static pod") - if err := etcdphase.CreateLocalEtcdStaticPodManifestFile(manifestDir, i.cfg); err != nil { - return errors.Wrap(err, "error creating local etcd static pod manifest file") - } - } - // If we're dry-running, print the generated manifests if err := printFilesIfDryRunning(i.dryRun, manifestDir); err != nil { return errors.Wrap(err, "error printing files on dryrun") diff --git a/cmd/kubeadm/app/cmd/phases/BUILD b/cmd/kubeadm/app/cmd/phases/BUILD index 3c73b3ead13..7226e9a6524 100644 --- a/cmd/kubeadm/app/cmd/phases/BUILD +++ b/cmd/kubeadm/app/cmd/phases/BUILD @@ -65,13 +65,11 @@ go_test( name = "go_default_test", srcs = [ "addons_test.go", - "etcd_test.go", "util_test.go", ], embed = [":go_default_library"], deps = [ "//cmd/kubeadm/app/apis/kubeadm/v1beta1:go_default_library", - "//cmd/kubeadm/test:go_default_library", "//cmd/kubeadm/test/cmd:go_default_library", "//pkg/version:go_default_library", ], diff --git a/cmd/kubeadm/app/cmd/phases/etcd.go b/cmd/kubeadm/app/cmd/phases/etcd.go index 911cafbfb03..bd6a2f33c36 100644 --- a/cmd/kubeadm/app/cmd/phases/etcd.go +++ b/cmd/kubeadm/app/cmd/phases/etcd.go @@ -19,84 +19,71 @@ package phases import ( "fmt" - "github.com/spf13/cobra" - + "github.com/golang/glog" + "github.com/pkg/errors" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" - kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" - kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" - cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" - kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" + "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow" etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd" "k8s.io/kubernetes/pkg/util/normalizer" ) var ( - etcdLocalLongDesc = fmt.Sprintf(normalizer.LongDesc(` - Generates the static Pod manifest file for a local, single-node etcd instance and saves it to %s file. - `+cmdutil.AlphaDisclaimer), kubeadmconstants.GetStaticPodFilepath(kubeadmconstants.Etcd, kubeadmconstants.GetStaticPodDirectory())) - etcdLocalExample = normalizer.Examples(` # Generates the static Pod manifest file for etcd, functionally - # equivalent to what generated by kubeadm init. - kubeadm alpha phase etcd local + # equivalent to what is generated by kubeadm init. + kubeadm init phase etcd local - # Generates the static Pod manifest file for etcd. - kubeadm alpha phase etcd local --config masterconfiguration.yaml + # Generates the static Pod manifest file for etcd using options + # read from a configuration file. + kubeadm init phase etcd local --config config.yaml `) ) -// NewCmdEtcd returns main command for Etcd phase -func NewCmdEtcd() *cobra.Command { - cmd := &cobra.Command{ - Use: "etcd", - Short: "Generates static Pod manifest file for etcd.", - Long: cmdutil.MacroCommandLongDescription, - } - - manifestPath := kubeadmconstants.GetStaticPodDirectory() - cmd.AddCommand(getEtcdSubCommands(manifestPath, "")...) - return cmd +type etcdData interface { + Cfg() *kubeadmapi.InitConfiguration + ManifestDir() string } -// getEtcdSubCommands returns sub commands for etcd phase -func getEtcdSubCommands(outDir, defaultKubernetesVersion string) []*cobra.Command { - - cfg := &kubeadmapiv1beta1.InitConfiguration{} - - // Default values for the cobra help text - kubeadmscheme.Scheme.Default(cfg) - - var cfgPath string - var subCmds []*cobra.Command - - properties := struct { - use string - short string - long string - examples string - cmdFunc func(outDir string, cfg *kubeadmapi.InitConfiguration) error - }{ - use: "local", - short: "Generates the static Pod manifest file for a local, single-node etcd instance", - long: etcdLocalLongDesc, - examples: etcdLocalExample, - cmdFunc: etcdphase.CreateLocalEtcdStaticPodManifestFile, +// NewEtcdPhase creates a kubeadm workflow phase that implements handling of etcd. +func NewEtcdPhase() workflow.Phase { + phase := workflow.Phase{ + Name: "etcd", + Short: "Generates static Pod manifest file for local etcd.", + Example: etcdLocalExample, + Phases: []workflow.Phase{ + newEtcdLocalSubPhase(), + }, + } + return phase +} + +func newEtcdLocalSubPhase() workflow.Phase { + phase := workflow.Phase{ + Name: "local", + Short: "Generates the static Pod manifest file for a local, single-node local etcd instance.", + Example: etcdLocalExample, + Run: runEtcdPhaseLocal(), + } + return phase +} + +func runEtcdPhaseLocal() func(c workflow.RunData) error { + return func(c workflow.RunData) error { + data, ok := c.(etcdData) + if !ok { + return errors.New("etcd phase invoked with an invalid data struct") + } + cfg := data.Cfg() + + // Add etcd static pod spec only if external etcd is not configured + if cfg.Etcd.External == nil { + fmt.Printf("[etcd] Creating static Pod manifest for local etcd in %q\n", data.ManifestDir()) + if err := etcdphase.CreateLocalEtcdStaticPodManifestFile(data.ManifestDir(), cfg); err != nil { + return errors.Wrap(err, "error creating local etcd static pod manifest file") + } + } else { + glog.V(1).Infof("[etcd] External etcd mode. Skipping the creation of a manifest for local etcd") + } + return nil } - - // Creates the UX Command - cmd := &cobra.Command{ - Use: properties.use, - Short: properties.short, - Long: properties.long, - Example: properties.examples, - Run: runCmdPhase(properties.cmdFunc, &outDir, &cfgPath, cfg, defaultKubernetesVersion), - } - - // Add flags to the command - cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, `The path where certificates are stored`) - cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file. WARNING: Usage of a configuration file is experimental") - - subCmds = append(subCmds, cmd) - - return subCmds } diff --git a/cmd/kubeadm/app/cmd/phases/etcd_test.go b/cmd/kubeadm/app/cmd/phases/etcd_test.go deleted file mode 100644 index 640d9ed67bf..00000000000 --- a/cmd/kubeadm/app/cmd/phases/etcd_test.go +++ /dev/null @@ -1,85 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package phases - -import ( - "fmt" - "os" - "testing" - - testutil "k8s.io/kubernetes/cmd/kubeadm/test" - cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd" -) - -const phaseTestK8sVersion = "v1.11.0" - -func TestEtcdSubCommandsHasFlags(t *testing.T) { - - subCmds := getEtcdSubCommands("", phaseTestK8sVersion) - - commonFlags := []string{ - "cert-dir", - "config", - } - - var tests = []struct { - command string - additionalFlags []string - }{ - { - command: "local", - }, - } - - for _, test := range tests { - expectedFlags := append(commonFlags, test.additionalFlags...) - cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...) - } -} - -func TestEtcdCreateFilesWithFlags(t *testing.T) { - - var tests = []struct { - command string - additionalFlags []string - expectedFiles []string - }{ - { - command: "local", - expectedFiles: []string{"etcd.yaml"}, - additionalFlags: []string{}, - }, - } - - for _, test := range tests { - - // Create temp folder for the test case - tmpdir := testutil.SetupTempDir(t) - defer os.RemoveAll(tmpdir) - - // Get subcommands working in the temporary directory - subCmds := getEtcdSubCommands(tmpdir, phaseTestK8sVersion) - - // Execute the subcommand - certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir) - allFlags := append(test.additionalFlags, certDirFlag) - cmdtestutil.RunSubCommand(t, subCmds, test.command, allFlags...) - - // Checks that requested files are there - testutil.AssertFileExists(t, tmpdir, test.expectedFiles...) - } -} diff --git a/cmd/kubeadm/app/phases/etcd/local.go b/cmd/kubeadm/app/phases/etcd/local.go index 2e3bf6c61c1..79e66190230 100644 --- a/cmd/kubeadm/app/phases/etcd/local.go +++ b/cmd/kubeadm/app/phases/etcd/local.go @@ -46,7 +46,6 @@ func CreateLocalEtcdStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.In if cfg.ClusterConfiguration.Etcd.External != nil { return errors.New("etcd static pod manifest cannot be generated for cluster using external etcd") } - glog.V(1).Infoln("creating local etcd static pod manifest file") // gets etcd StaticPodSpec emptyInitialCluster := []etcdutil.Member{} spec := GetEtcdPodSpec(cfg, emptyInitialCluster) @@ -55,7 +54,7 @@ func CreateLocalEtcdStaticPodManifestFile(manifestDir string, cfg *kubeadmapi.In return err } - fmt.Printf("[etcd] Wrote Static Pod manifest for a local etcd instance to %q\n", kubeadmconstants.GetStaticPodFilepath(kubeadmconstants.Etcd, manifestDir)) + glog.V(1).Infof("[etcd] wrote Static Pod manifest for a local etcd instance to %q\n", kubeadmconstants.GetStaticPodFilepath(kubeadmconstants.Etcd, manifestDir)) return nil }