From 5cd7660d1e49089155bb3c2b59ae25430e7eb7b5 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Thu, 19 Mar 2020 17:44:21 -0700 Subject: [PATCH] fixHost: only reprovision if necessary, and only once --- cmd/minikube/cmd/node_add.go | 2 +- cmd/minikube/cmd/node_start.go | 2 +- cmd/minikube/cmd/start.go | 18 +++++++++++------- go.sum | 3 +++ pkg/minikube/machine/cluster_test.go | 12 ++++++------ pkg/minikube/machine/fix.go | 23 ++++++++++------------- pkg/minikube/machine/start.go | 4 ++-- pkg/minikube/node/config.go | 8 ++++++++ pkg/minikube/node/machine.go | 8 ++++---- pkg/minikube/node/node.go | 2 +- pkg/minikube/node/start.go | 4 ++-- 11 files changed, 49 insertions(+), 37 deletions(-) diff --git a/cmd/minikube/cmd/node_add.go b/cmd/minikube/cmd/node_add.go index 9ee9e39f1e7d..f450d2054090 100644 --- a/cmd/minikube/cmd/node_add.go +++ b/cmd/minikube/cmd/node_add.go @@ -53,7 +53,7 @@ var nodeAddCmd = &cobra.Command{ exit.WithError("Error adding node to cluster", err) } - _, err = node.Start(*cc, *n, false, nil) + _, err = node.Start(*cc, config.ClusterConfig{}, *n, false, nil) if err != nil { exit.WithError("Error starting node", err) } diff --git a/cmd/minikube/cmd/node_start.go b/cmd/minikube/cmd/node_start.go index c0090b628759..ede4130c879a 100644 --- a/cmd/minikube/cmd/node_start.go +++ b/cmd/minikube/cmd/node_start.go @@ -61,7 +61,7 @@ var nodeStartCmd = &cobra.Command{ } // Start it up baby - _, err = node.Start(*cc, *n, false, nil) + _, err = node.Start(*cc, *cc, *n, false, nil) if err != nil { out.FatalT("Failed to start node {{.name}}", out.V{"name": name}) } diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 6227dfa16adf..35019c76ecbc 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -313,7 +313,7 @@ func runStart(cmd *cobra.Command, args []string) { } k8sVersion := getKubernetesVersion(existing) - mc, n, err := generateCfgFromFlags(cmd, k8sVersion, driverName) + cc, n, err := generateCfgFromFlags(cmd, k8sVersion, driverName) if err != nil { exit.WithError("Failed to generate config", err) } @@ -329,7 +329,7 @@ func runStart(cmd *cobra.Command, args []string) { if err != nil { exit.WithError("Failed to cache ISO", err) } - mc.MinikubeISO = url + cc.MinikubeISO = url } if viper.GetBool(nativeSSH) { @@ -338,12 +338,12 @@ func runStart(cmd *cobra.Command, args []string) { ssh.SetDefaultClient(ssh.External) } - kubeconfig, err := startNode(existing, mc, n) + kubeconfig, err := startNode(existing, cc, n) if err != nil { exit.WithError("Starting node", err) } - if err := showKubectlInfo(kubeconfig, k8sVersion, mc.Name); err != nil { + if err := showKubectlInfo(kubeconfig, k8sVersion, cc.Name); err != nil { glog.Errorf("kubectl info: %v", err) } } @@ -383,7 +383,7 @@ func displayEnviron(env []string) { } } -func startNode(existing *config.ClusterConfig, mc config.ClusterConfig, n config.Node) (*kubeconfig.Settings, error) { +func startNode(existing *config.ClusterConfig, cc config.ClusterConfig, n config.Node) (*kubeconfig.Settings, error) { var existingAddons map[string]bool if viper.GetBool(installAddons) { existingAddons = map[string]bool{} @@ -391,7 +391,11 @@ func startNode(existing *config.ClusterConfig, mc config.ClusterConfig, n config existingAddons = existing.Addons } } - return node.Start(mc, n, true, existingAddons) + + if existing == nil { + existing = &config.ClusterConfig{} + } + return node.Start(cc, *existing, n, true, existingAddons) } func showKubectlInfo(kcs *kubeconfig.Settings, k8sVersion string, machineName string) error { @@ -814,7 +818,7 @@ func validateRegistryMirror() { } } -// generateCfgFromFlags generates config.Config based on flags and supplied arguments +// generateCfgFromFlags generates config.ClusterConfig based on flags and supplied arguments func generateCfgFromFlags(cmd *cobra.Command, k8sVersion string, drvName string) (config.ClusterConfig, config.Node, error) { r, err := cruntime.New(cruntime.Config{Type: viper.GetString(containerRuntime)}) if err != nil { diff --git a/go.sum b/go.sum index d84ef83e6eb5..8a4fe67c9853 100644 --- a/go.sum +++ b/go.sum @@ -61,7 +61,9 @@ github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmx github.com/afbjorklund/go-getter v1.4.1-0.20190910175809-eb9f6c26742c h1:18gEt7qzn7CW7qMkfPTFyyotlPbvPQo9o4IDV8jZqP4= github.com/afbjorklund/go-getter v1.4.1-0.20190910175809-eb9f6c26742c/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -972,6 +974,7 @@ google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/minikube/machine/cluster_test.go b/pkg/minikube/machine/cluster_test.go index 0c32c8642a28..fbb0066691d9 100644 --- a/pkg/minikube/machine/cluster_test.go +++ b/pkg/minikube/machine/cluster_test.go @@ -129,7 +129,7 @@ func TestStartHostExists(t *testing.T) { n := config.Node{Name: ih.Name} // This should pass without calling Create because the host exists already. - h, err := StartHost(api, mc, n) + h, err := StartHost(api, mc, mc, n) if err != nil { t.Fatalf("Error starting host: %v", err) } @@ -163,7 +163,7 @@ func TestStartHostErrMachineNotExist(t *testing.T) { n := config.Node{Name: h.Name} // This should pass with creating host, while machine does not exist. - h, err = StartHost(api, mc, n) + h, err = StartHost(api, mc, mc, n) if err != nil { if err != ErrorMachineNotExist { t.Fatalf("Error starting host: %v", err) @@ -174,7 +174,7 @@ func TestStartHostErrMachineNotExist(t *testing.T) { n.Name = h.Name // Second call. This should pass without calling Create because the host exists already. - h, err = StartHost(api, mc, n) + h, err = StartHost(api, mc, mc, n) if err != nil { t.Fatalf("Error starting host: %v", err) } @@ -207,7 +207,7 @@ func TestStartStoppedHost(t *testing.T) { mc := defaultClusterConfig mc.Name = h.Name n := config.Node{Name: h.Name} - h, err = StartHost(api, mc, n) + h, err = StartHost(api, mc, mc, n) if err != nil { t.Fatal("Error starting host.") } @@ -235,7 +235,7 @@ func TestStartHost(t *testing.T) { md := &tests.MockDetector{Provisioner: &tests.MockProvisioner{}} provision.SetDetector(md) - h, err := StartHost(api, defaultClusterConfig, config.Node{Name: "minikube"}) + h, err := StartHost(api, defaultClusterConfig, defaultClusterConfig, config.Node{Name: "minikube"}) if err != nil { t.Fatal("Error starting host.") } @@ -269,7 +269,7 @@ func TestStartHostConfig(t *testing.T) { DockerOpt: []string{"param=value"}, } - h, err := StartHost(api, cfg, config.Node{Name: "minikube"}) + h, err := StartHost(api, cfg, cfg, config.Node{Name: "minikube"}) if err != nil { t.Fatal("Error starting host.") } diff --git a/pkg/minikube/machine/fix.go b/pkg/minikube/machine/fix.go index 25f921cd5a9a..c8fcee801e82 100644 --- a/pkg/minikube/machine/fix.go +++ b/pkg/minikube/machine/fix.go @@ -20,6 +20,7 @@ import ( "fmt" "math" "os" + "reflect" "strconv" "strings" "time" @@ -28,7 +29,6 @@ import ( "github.com/docker/machine/libmachine" "github.com/docker/machine/libmachine/host" - "github.com/docker/machine/libmachine/provision" "github.com/docker/machine/libmachine/state" "github.com/golang/glog" "github.com/pkg/errors" @@ -36,7 +36,7 @@ import ( "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/pkg/minikube/driver" "k8s.io/minikube/pkg/minikube/out" - "k8s.io/minikube/pkg/util/retry" + "k8s.io/minikube/pkg/provision" ) // hostRunner is a minimal host.Host based interface for running commands @@ -56,7 +56,7 @@ var ( ) // fixHost fixes up a previously configured VM so that it is ready to run Kubernetes -func fixHost(api libmachine.API, cc config.ClusterConfig, n config.Node) (*host.Host, error) { +func fixHost(api libmachine.API, cc config.ClusterConfig, existing config.ClusterConfig, n config.Node) (*host.Host, error) { out.T(out.Waiting, "Reconfiguring existing host ...") start := time.Now() @@ -78,15 +78,16 @@ func fixHost(api libmachine.API, cc config.ClusterConfig, n config.Node) (*host. return h, err } + old := engineOptions(existing) e := engineOptions(cc) - if len(e.Env) > 0 { + if !reflect.DeepEqual(old, e) { + glog.Infof("docker config changed, updating provisioner: %+v", e) h.HostOptions.EngineOptions.Env = e.Env - glog.Infof("Detecting provisioner ...") - provisioner, err := provision.DetectProvisioner(h.Driver) - if err != nil { - return h, errors.Wrap(err, "detecting provisioner") + p := provision.NewBuildrootProvisioner(h.Driver) + if driver.IsKIC(h.Driver.DriverName()) { + p = provision.NewUbuntuProvisioner(h.Driver) } - if err := provisioner.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions); err != nil { + if err := p.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions); err != nil { return h, errors.Wrap(err, "provision") } } @@ -104,10 +105,6 @@ func fixHost(api libmachine.API, cc config.ClusterConfig, n config.Node) (*host. return h, nil } - glog.Infof("Configuring auth for driver %s ...", h.Driver.DriverName()) - if err := h.ConfigureAuth(); err != nil { - return h, &retry.RetriableError{Err: errors.Wrap(err, "Error configuring auth on host")} - } return h, ensureSyncedGuestClock(h, cc.Driver) } diff --git a/pkg/minikube/machine/start.go b/pkg/minikube/machine/start.go index 73c982fa809f..a885b0476e37 100644 --- a/pkg/minikube/machine/start.go +++ b/pkg/minikube/machine/start.go @@ -62,7 +62,7 @@ var ( ) // StartHost starts a host VM. -func StartHost(api libmachine.API, cfg config.ClusterConfig, n config.Node) (*host.Host, error) { +func StartHost(api libmachine.API, cfg config.ClusterConfig, existing config.ClusterConfig, n config.Node) (*host.Host, error) { // Prevent machine-driver boot races, as well as our own certificate race releaser, err := acquireMachinesLock(cfg.Name) if err != nil { @@ -83,7 +83,7 @@ func StartHost(api libmachine.API, cfg config.ClusterConfig, n config.Node) (*ho return createHost(api, cfg, n) } glog.Infoln("Skipping create...Using existing machine configuration") - return fixHost(api, cfg, n) + return fixHost(api, cfg, existing, n) } func engineOptions(cfg config.ClusterConfig) *engine.Options { diff --git a/pkg/minikube/node/config.go b/pkg/minikube/node/config.go index b29867f1b6ae..df7eed881a6a 100644 --- a/pkg/minikube/node/config.go +++ b/pkg/minikube/node/config.go @@ -23,6 +23,7 @@ import ( "os/exec" "path/filepath" "strconv" + "time" "github.com/blang/semver" "github.com/docker/machine/libmachine" @@ -59,6 +60,12 @@ var ( // configureRuntimes does what needs to happen to get a runtime going. func configureRuntimes(runner cruntime.CommandRunner, drvName string, k8s config.KubernetesConfig, kv semver.Version) cruntime.Manager { + start := time.Now() + glog.Infof("configureRuntimes start") + defer func() { + glog.Infof("configureRuntimes took %s", time.Since(start)) + }() + co := cruntime.Config{ Type: viper.GetString(containerRuntime), Runner: runner, ImageRepository: k8s.ImageRepository, @@ -90,6 +97,7 @@ func configureRuntimes(runner cruntime.CommandRunner, drvName string, k8s config } } + glog.Infof("enabling %s ...", cr.Name()) err = cr.Enable(disableOthers) if err != nil { exit.WithError("Failed to enable container runtime", err) diff --git a/pkg/minikube/node/machine.go b/pkg/minikube/node/machine.go index 483131515af5..ffe4a792d71c 100644 --- a/pkg/minikube/node/machine.go +++ b/pkg/minikube/node/machine.go @@ -39,12 +39,12 @@ import ( "k8s.io/minikube/pkg/util/retry" ) -func startMachine(cfg *config.ClusterConfig, node *config.Node) (runner command.Runner, preExists bool, machineAPI libmachine.API, host *host.Host) { +func startMachine(cfg *config.ClusterConfig, existing *config.ClusterConfig, node *config.Node) (runner command.Runner, preExists bool, machineAPI libmachine.API, host *host.Host) { m, err := machine.NewAPIClient() if err != nil { exit.WithError("Failed to get machine client", err) } - host, preExists = startHost(m, *cfg, *node) + host, preExists = startHost(m, *cfg, *existing, *node) runner, err = machine.CommandRunner(host) if err != nil { exit.WithError("Failed to get command runner", err) @@ -68,13 +68,13 @@ func startMachine(cfg *config.ClusterConfig, node *config.Node) (runner command. } // startHost starts a new minikube host using a VM or None -func startHost(api libmachine.API, mc config.ClusterConfig, n config.Node) (*host.Host, bool) { +func startHost(api libmachine.API, mc config.ClusterConfig, existing config.ClusterConfig, n config.Node) (*host.Host, bool) { exists, err := api.Exists(mc.Name) if err != nil { exit.WithError("Failed to check if machine exists", err) } - host, err := machine.StartHost(api, mc, n) + host, err := machine.StartHost(api, mc, existing, n) if err != nil { exit.WithError("Unable to start VM. Please investigate and run 'minikube delete' if possible", err) } diff --git a/pkg/minikube/node/node.go b/pkg/minikube/node/node.go index e92bad65b597..c25a9c95bd99 100644 --- a/pkg/minikube/node/node.go +++ b/pkg/minikube/node/node.go @@ -65,7 +65,7 @@ func Add(cc *config.ClusterConfig, name string, controlPlane bool, worker bool, return nil, err } - _, err = Start(*cc, n, false, nil) + _, err = Start(*cc, *cc, n, false, nil) return &n, err } diff --git a/pkg/minikube/node/start.go b/pkg/minikube/node/start.go index a3c5eee92bee..8b75831f583a 100644 --- a/pkg/minikube/node/start.go +++ b/pkg/minikube/node/start.go @@ -33,7 +33,7 @@ import ( ) // Start spins up a guest and starts the kubernetes node. -func Start(mc config.ClusterConfig, n config.Node, primary bool, existingAddons map[string]bool) (*kubeconfig.Settings, error) { +func Start(mc config.ClusterConfig, existing config.ClusterConfig, n config.Node, primary bool, existingAddons map[string]bool) (*kubeconfig.Settings, error) { k8sVersion := mc.KubernetesConfig.KubernetesVersion driverName := mc.Driver @@ -59,7 +59,7 @@ func Start(mc config.ClusterConfig, n config.Node, primary bool, existingAddons handleDownloadOnly(&cacheGroup, &kicGroup, k8sVersion) waitDownloadKicArtifacts(&kicGroup) - mRunner, preExists, machineAPI, host := startMachine(&mc, &n) + mRunner, preExists, machineAPI, host := startMachine(&mc, &existing, &n) defer machineAPI.Close() // wait for preloaded tarball to finish downloading before configuring runtimes