From 8809ab113afe8bf19903540a8b38ea177f7fb44c Mon Sep 17 00:00:00 2001 From: tstromberg Date: Tue, 5 Nov 2019 14:59:12 -0800 Subject: [PATCH 1/5] Validate existing drivers too --- cmd/minikube/cmd/start.go | 103 ++++++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 3e67510e17..18a106632c 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -284,13 +284,13 @@ func runStart(cmd *cobra.Command, args []string) { registryMirror = viper.GetStringSlice("registry_mirror") } - oldConfig, err := cfg.Load() + existing, err := cfg.Load() if err != nil && !os.IsNotExist(err) { exit.WithCodeT(exit.Data, "Unable to load config: {{.error}}", out.V{"error": err}) } - driverName := selectDriver(oldConfig) - glog.Infof("selected: %v", driverName) + driverName := selectDriver(existing) + validateDriver(driverName, existing) err = autoSetDriverOptions(cmd, driverName) if err != nil { glog.Errorf("Error autoSetOptions : %v", err) @@ -309,7 +309,7 @@ func runStart(cmd *cobra.Command, args []string) { } } - k8sVersion, isUpgrade := getKubernetesVersion(oldConfig) + k8sVersion, isUpgrade := getKubernetesVersion(existing) config, err := generateCfgFromFlags(cmd, k8sVersion, driverName) if err != nil { exit.WithError("Failed to generate config", err) @@ -542,67 +542,85 @@ func showKubectlInfo(kcs *kubeconfig.Settings, k8sVersion string) error { return nil } -func selectDriver(oldConfig *cfg.Config) string { +// selectDriver returns which driver to choose based on flags, existing configs, and hypervisor detection +func selectDriver(existing *cfg.Config) string { name := viper.GetString("vm-driver") - glog.Infof("selectDriver: flag=%q, old=%v", name, oldConfig) - if name == "" { - // By default, the driver is whatever we used last time - if oldConfig != nil { - return oldConfig.MachineConfig.VMDriver - } - options := driver.Choices() - pick, alts := driver.Choose(options) - if len(options) > 1 { - out.T(out.Sparkle, `Automatically selected the '{{.driver}}' driver (alternates: {{.alternates}})`, out.V{"driver": pick.Name, "alternates": alts}) - } else { - out.T(out.Sparkle, `Automatically selected the '{{.driver}}' driver`, out.V{"driver": pick.Name}) - } - - if pick.Name == "" { - exit.WithCodeT(exit.Config, "Unable to determine a default driver to use. Try specifying --vm-driver, or see https://minikube.sigs.k8s.io/docs/start/") - } - - name = pick.Name + glog.Infof("selectDriver: flag=%q, old=%v", name, existing) + if name != "" { + return name } + + options := driver.Choices() + pick, alts := driver.Choose(options) + + // By default, the driver is whatever we used last time + if existing != nil { + // alts by any other name + others := []string{} + if pick.Name != existing.MachineConfig.VMDriver { + others = append(others, pick.Name) + } + for _, d := range alts { + if d.Name != existing.MachineConfig.VMDriver { + others = append(others, d.Name) + } + } + out.T(out.Sparkle, `Using '{{.driver}}' driver as per existing configuration (alternates: {{.alternates}})`, out.V{"driver": existing.MachineConfig.VMDriver, "alternates": others}) + return existing.MachineConfig.VMDriver + } + + if len(options) > 1 { + out.T(out.Sparkle, `Automatically selected the '{{.driver}}' driver (alternates: {{.alternates}})`, out.V{"driver": pick.Name, "alternates": alts}) + } else { + out.T(out.Sparkle, `Automatically selected the '{{.driver}}' driver`, out.V{"driver": pick.Name}) + } + + if pick.Name == "" { + exit.WithCodeT(exit.Config, "Unable to determine a default driver to use. Try specifying --vm-driver, or see https://minikube.sigs.k8s.io/docs/start/") + } + return pick.Name +} + +// validateDriver validates that the selected driver appears sane, exits if not +func validateDriver(name string, existing *cfg.Config) { if !driver.Supported(name) { - exit.WithCodeT(exit.Failure, "The driver '{{.driver}}' is not supported on {{.os}}", out.V{"driver": name, "os": runtime.GOOS}) + exit.WithCodeT(exit.Unavailable, "The driver '{{.driver}}' is not supported on {{.os}}", out.V{"driver": name, "os": runtime.GOOS}) } st := driver.Status(name) if st.Error != nil { out.ErrLn("") - out.WarningT("'{{.driver}}' driver reported a possible issue: {{.error}}", out.V{"driver": name, "error": st.Error, "fix": st.Fix}) + + out.WarningT("'{{.driver}}' driver reported an issue: {{.error}}", out.V{"driver": name, "error": st.Error}) out.ErrT(out.Tip, "Suggestion: {{.fix}}", out.V{"fix": translate.T(st.Fix)}) if st.Doc != "" { out.ErrT(out.Documentation, "Documentation: {{.url}}", out.V{"url": st.Doc}) } out.ErrLn("") + + if !st.Installed && !viper.GetBool(force) { + exit.WithCodeT(exit.Unavailable, "{{.driver}} does not appear to be installed", out.V{"driver": name}) + } + } + + if existing == nil { + return } - // Detect if our driver conflicts with a previously created VM. If we run into any errors, just move on. api, err := machine.NewAPIClient() if err != nil { - glog.Infof("selectDriver NewAPIClient: %v", err) - return name - } - - exists, err := api.Exists(cfg.GetMachineName()) - if err != nil { - glog.Infof("selectDriver api.Exists: %v", err) - return name - } - if !exists { - return name + glog.Warningf("selectDriver NewAPIClient: %v", err) + return } h, err := api.Load(cfg.GetMachineName()) if err != nil { - glog.Infof("selectDriver api.Load: %v", err) - return name + glog.Warningf("selectDriver api.Load: %v", err) + return } - if h.Driver.DriverName() == name || h.Driver.DriverName() == "not-found" { - return name + if h.Driver.DriverName() == name { + return } out.ErrT(out.Conflict, `The existing "{{.profile_name}}" VM that was created using the "{{.old_driver}}" driver, and is incompatible with the "{{.driver}}" driver.`, @@ -613,7 +631,6 @@ func selectDriver(oldConfig *cfg.Config) string { or 2) Restart with the existing driver: '{{.command}} start --vm-driver={{.old_driver}}'`, out.V{"command": minikubeCmd(), "old_driver": h.Driver.DriverName()}) exit.WithCodeT(exit.Config, "Exiting due to driver incompatibility") - return "" } func selectImageRepository(mirrorCountry string, k8sVersion string) (bool, string, error) { From fb3360da061a46758bdef3a9f923ce09ac510db4 Mon Sep 17 00:00:00 2001 From: tstromberg Date: Tue, 5 Nov 2019 17:16:23 -0800 Subject: [PATCH 2/5] Check health of drivers from existing configs --- cmd/minikube/cmd/start.go | 29 +++++++++++++------------- go.mod | 3 --- go.sum | 21 ++----------------- pkg/minikube/driver/driver.go | 30 +++++++++++++++++++-------- pkg/minikube/driver/driver_test.go | 31 ++++++++++++++++++---------- pkg/minikube/registry/global.go | 9 ++------ pkg/minikube/registry/global_test.go | 12 +++++------ 7 files changed, 64 insertions(+), 71 deletions(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 42c3612666..287f21ab7e 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -290,6 +290,7 @@ func runStart(cmd *cobra.Command, args []string) { } driverName := selectDriver(existing) + glog.Infof("selected driver: %s", driverName) validateDriver(driverName, existing) err = autoSetDriverOptions(cmd, driverName) if err != nil { @@ -557,27 +558,19 @@ func showKubectlInfo(kcs *kubeconfig.Settings, k8sVersion string) error { func selectDriver(existing *cfg.Config) string { name := viper.GetString("vm-driver") glog.Infof("selectDriver: flag=%q, old=%v", name, existing) + options := driver.Choices() + pick, alts := driver.Choose(name, options) + if name != "" { + out.T(out.Sparkle, `Selecting '{{.driver}}' driver from user configuration (alternates: {{.alternates}})`, out.V{"driver": existing.MachineConfig.VMDriver, "alternates": alts}) return name } - options := driver.Choices() - pick, alts := driver.Choose(options) - // By default, the driver is whatever we used last time if existing != nil { - // alts by any other name - others := []string{} - if pick.Name != existing.MachineConfig.VMDriver { - others = append(others, pick.Name) - } - for _, d := range alts { - if d.Name != existing.MachineConfig.VMDriver { - others = append(others, d.Name) - } - } - out.T(out.Sparkle, `Using '{{.driver}}' driver as per existing configuration (alternates: {{.alternates}})`, out.V{"driver": existing.MachineConfig.VMDriver, "alternates": others}) - return existing.MachineConfig.VMDriver + pick, alts := driver.Choose(existing.MachineConfig.VMDriver, options) + out.T(out.Sparkle, `Selecting '{{.driver}}' driver from existing profile (alternates: {{.alternates}})`, out.V{"driver": existing.MachineConfig.VMDriver, "alternates": alts}) + return pick.Name } if len(options) > 1 { @@ -594,11 +587,14 @@ func selectDriver(existing *cfg.Config) string { // validateDriver validates that the selected driver appears sane, exits if not func validateDriver(name string, existing *cfg.Config) { + glog.Infof("validating driver %q against %+v", name, existing) if !driver.Supported(name) { exit.WithCodeT(exit.Unavailable, "The driver '{{.driver}}' is not supported on {{.os}}", out.V{"driver": name, "os": runtime.GOOS}) } st := driver.Status(name) + glog.Infof("status for %s: %+v", name, st) + if st.Error != nil { out.ErrLn("") @@ -610,6 +606,9 @@ func validateDriver(name string, existing *cfg.Config) { out.ErrLn("") if !st.Installed && !viper.GetBool(force) { + if existing != nil && name == existing.MachineConfig.VMDriver { + exit.WithCodeT(exit.Unavailable, "{{.driver}} does not appear to be installed, but is specified by an existing profile. Please run 'minikube delete' or install {{.driver}}", out.V{"driver": name}) + } exit.WithCodeT(exit.Unavailable, "{{.driver}} does not appear to be installed", out.V{"driver": name}) } } diff --git a/go.mod b/go.mod index bee76d17ed..ad306de70f 100644 --- a/go.mod +++ b/go.mod @@ -21,14 +21,11 @@ require ( github.com/docker/machine v0.7.1-0.20190718054102-a555e4f7a8f5 // version is 0.7.1 to pin to a555e4f7a8f5 github.com/elazarl/goproxy v0.0.0-20190421051319-9d40249d3c2f github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f // indirect - github.com/ghodss/yaml v1.0.0 // indirect github.com/go-ole/go-ole v1.2.4 // indirect github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b - github.com/google/btree v1.0.0 // indirect github.com/google/go-cmp v0.3.0 github.com/gorilla/mux v1.7.1 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.5.0 // indirect github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce // indirect github.com/hashicorp/go-getter v1.4.0 github.com/hashicorp/go-multierror v0.0.0-20160811015721-8c5f0ad93604 // indirect diff --git a/go.sum b/go.sum index cef3a35ca6..be67b2409d 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,6 @@ bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1: cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.36.0 h1:+aCSj7tOo2LODWVEuZDZeGCckdt6MlSF+X/rB3wUiS8= -cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= @@ -188,6 +186,7 @@ github.com/golang/mock v0.0.0-20160127222235-bd3c8e81be01/go.mod h1:oTYuIxOrZwtP github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -223,8 +222,6 @@ github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU= github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3 h1:siORttZ36U2R/WjiJuDz8znElWBiAlO9rVt+mqJt0Cc= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -247,9 +244,6 @@ github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce h1:prjrVgOk2Yg6w github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-getter v1.3.0 h1:pFMSFlI9l5NaeuzkpE3L7BYk9qQ9juTAgXW/H0cqxcU= -github.com/hashicorp/go-getter v1.3.0/go.mod h1:/O1k/AizTN0QmfEKknCYGvICeyKUDqCYA8vvWtGWDeQ= -github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY= github.com/hashicorp/go-multierror v0.0.0-20160811015721-8c5f0ad93604 h1:VIq8E7fMiC4h3agg0ya56L0jHn7QisZZcWZXVKJb9jQ= github.com/hashicorp/go-multierror v0.0.0-20160811015721-8c5f0ad93604/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-retryablehttp v0.5.4 h1:1BZvpawXoJCWX6pNtow9+rpEj+3itIlutiqnntI6jOE= @@ -576,8 +570,6 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -593,7 +585,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -612,7 +603,6 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181004145325-8469e314837c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181213200352-4d1cda033e06/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -656,8 +646,6 @@ gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmK google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0 h1:K6z2u68e86TPdSdefXdzvXgR1zEMa+459vBSfWYAZkI= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -665,18 +653,15 @@ google.golang.org/api v0.9.0 h1:jbyannxz0XFD3zdjgrSUsaJbgpH4eTrkdhRChkHPfO8= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/genproto v0.0.0-20170731182057-09f6ed296fc6/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922 h1:mBVYJnbrXLA/ZCBTCe7PtEgAUP+1bg92qTaFoPHdz+8= -google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -687,8 +672,6 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/grpc v1.13.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= -google.golang.org/grpc v1.17.0 h1:TRJYBgMclJvGYn2rIMjj+h9KtMt5r1Ij7ODVRIZkwhk= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1 h1:j6XxA85m/6txkUCHvzlV5f+HBNl/1r5cZ2A/3IEFOO8= diff --git a/pkg/minikube/driver/driver.go b/pkg/minikube/driver/driver.go index 44c2a54fae..05597af7f8 100644 --- a/pkg/minikube/driver/driver.go +++ b/pkg/minikube/driver/driver.go @@ -95,14 +95,7 @@ func FlagDefaults(name string) FlagHints { // Choices returns a list of drivers which are possible on this system func Choices() []registry.DriverState { - options := []registry.DriverState{} - for _, ds := range registry.Installed() { - if !ds.State.Healthy { - glog.Warningf("%q is installed, but unhealthy: %v", ds.Name, ds.State.Error) - continue - } - options = append(options, ds) - } + options := registry.Available() // Descending priority for predictability and appearance sort.Slice(options, func(i, j int) bool { @@ -112,9 +105,25 @@ func Choices() []registry.DriverState { } // Choose returns a suggested driver from a set of options -func Choose(options []registry.DriverState) (registry.DriverState, []registry.DriverState) { +func Choose(requested string, options []registry.DriverState) (registry.DriverState, []registry.DriverState) { + glog.Infof("requested: %q", requested) pick := registry.DriverState{} for _, ds := range options { + if ds.Name == requested { + glog.Infof("choosing %q because it was requested", ds.Name) + pick = ds + continue + } + + if !ds.State.Installed { + continue + } + + if !ds.State.Healthy { + glog.Infof("not recommending %q due to health: %v", ds.Name, ds.State.Error) + continue + } + if ds.Priority <= registry.Discouraged { glog.Infof("not recommending %q due to priority: %d", ds.Name, ds.Priority) continue @@ -128,6 +137,9 @@ func Choose(options []registry.DriverState) (registry.DriverState, []registry.Dr alternates := []registry.DriverState{} for _, ds := range options { if ds != pick { + if !ds.State.Healthy || !ds.State.Installed { + continue + } alternates = append(alternates, ds) } } diff --git a/pkg/minikube/driver/driver_test.go b/pkg/minikube/driver/driver_test.go index cd35e8d775..8c2d81ad1e 100644 --- a/pkg/minikube/driver/driver_test.go +++ b/pkg/minikube/driver/driver_test.go @@ -83,10 +83,11 @@ func TestFlagDefaults(t *testing.T) { func TestChoices(t *testing.T) { tests := []struct { - def registry.DriverDef - choices []string - pick string - alts []string + def registry.DriverDef + choices []string + pick string + alts []string + requested string }{ { def: registry.DriverDef{ @@ -94,7 +95,7 @@ func TestChoices(t *testing.T) { Priority: registry.Default, Status: func() registry.State { return registry.State{Installed: true, Healthy: false} }, }, - choices: []string{}, + choices: []string{"unhealthy"}, pick: "", alts: []string{}, }, @@ -104,7 +105,7 @@ func TestChoices(t *testing.T) { Priority: registry.Discouraged, Status: func() registry.State { return registry.State{Installed: true, Healthy: true} }, }, - choices: []string{"discouraged"}, + choices: []string{"unhealthy", "discouraged"}, pick: "", alts: []string{"discouraged"}, }, @@ -114,7 +115,7 @@ func TestChoices(t *testing.T) { Priority: registry.Default, Status: func() registry.State { return registry.State{Installed: true, Healthy: true} }, }, - choices: []string{"default", "discouraged"}, + choices: []string{"unhealthy", "default", "discouraged"}, pick: "default", alts: []string{"discouraged"}, }, @@ -124,15 +125,23 @@ func TestChoices(t *testing.T) { Priority: registry.Preferred, Status: func() registry.State { return registry.State{Installed: true, Healthy: true} }, }, - choices: []string{"preferred", "default", "discouraged"}, + choices: []string{"preferred", "default", "unhealthy", "discouraged"}, pick: "preferred", alts: []string{"default", "discouraged"}, }, + { + requested: "unhealthy", + choices: []string{"preferred", "unhealthy", "default", "discouraged"}, + pick: "unhealthy", + alts: []string{"preferred", "default", "discouraged"}, + }, } for _, tc := range tests { t.Run(tc.def.Name, func(t *testing.T) { - if err := registry.Register(tc.def); err != nil { - t.Errorf("register returned error: %v", err) + if tc.def.Name != "" { + if err := registry.Register(tc.def); err != nil { + t.Errorf("register returned error: %v", err) + } } got := Choices() @@ -145,7 +154,7 @@ func TestChoices(t *testing.T) { t.Errorf("choices mismatch (-want +got):\n%s", diff) } - pick, alts := Choose(got) + pick, alts := Choose(tc.requested, got) if pick.Name != tc.pick { t.Errorf("pick = %q, expected %q", pick.Name, tc.pick) } diff --git a/pkg/minikube/registry/global.go b/pkg/minikube/registry/global.go index 97882296a5..e7616d731a 100644 --- a/pkg/minikube/registry/global.go +++ b/pkg/minikube/registry/global.go @@ -53,8 +53,8 @@ func Driver(name string) DriverDef { return globalRegistry.Driver(name) } -// Installed returns a list of installed drivers in the global registry -func Installed() []DriverState { +// Available returns a list of available drivers in the global registry +func Available() []DriverState { sts := []DriverState{} glog.Infof("Querying for installed drivers using PATH=%s", os.Getenv("PATH")) @@ -65,11 +65,6 @@ func Installed() []DriverState { } s := d.Status() glog.Infof("%s priority: %d, state: %+v", d.Name, d.Priority, s) - - if !s.Installed { - glog.Infof("%q not installed: %v", d.Name, s.Error) - continue - } sts = append(sts, DriverState{Name: d.Name, Priority: d.Priority, State: s}) } return sts diff --git a/pkg/minikube/registry/global_test.go b/pkg/minikube/registry/global_test.go index c6b23552c5..19a502403e 100644 --- a/pkg/minikube/registry/global_test.go +++ b/pkg/minikube/registry/global_test.go @@ -64,7 +64,7 @@ func TestGlobalList(t *testing.T) { } } -func TestGlobalInstalled(t *testing.T) { +func TestGlobalAvailable(t *testing.T) { globalRegistry = newRegistry() if err := Register(DriverDef{Name: "foo"}); err != nil { @@ -74,7 +74,7 @@ func TestGlobalInstalled(t *testing.T) { bar := DriverDef{ Name: "bar", Priority: Default, - Status: func() State { return State{Installed: true} }, + Status: func() State { return State{} }, } if err := Register(bar); err != nil { t.Errorf("register returned error: %v", err) @@ -84,14 +84,12 @@ func TestGlobalInstalled(t *testing.T) { { Name: "bar", Priority: Default, - State: State{ - Installed: true, - }, + State: State{}, }, } - if diff := cmp.Diff(Installed(), expected); diff != "" { - t.Errorf("installed mismatch (-want +got):\n%s", diff) + if diff := cmp.Diff(Available(), expected); diff != "" { + t.Errorf("available mismatch (-want +got):\n%s", diff) } } From 992d4fd04ab2319df016a41fa309a9c6478b4f82 Mon Sep 17 00:00:00 2001 From: tstromberg Date: Wed, 6 Nov 2019 10:05:50 -0800 Subject: [PATCH 3/5] Add an explicit Unhealthy driver priority (lowest) --- pkg/minikube/driver/driver_test.go | 8 ++++---- pkg/minikube/registry/global.go | 14 +++++++++++++- pkg/minikube/registry/global_test.go | 22 ++++++++++++++++++---- pkg/minikube/registry/registry.go | 16 ++++++++-------- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/pkg/minikube/driver/driver_test.go b/pkg/minikube/driver/driver_test.go index 8c2d81ad1e..7f07f9d62e 100644 --- a/pkg/minikube/driver/driver_test.go +++ b/pkg/minikube/driver/driver_test.go @@ -105,7 +105,7 @@ func TestChoices(t *testing.T) { Priority: registry.Discouraged, Status: func() registry.State { return registry.State{Installed: true, Healthy: true} }, }, - choices: []string{"unhealthy", "discouraged"}, + choices: []string{"discouraged", "unhealthy"}, pick: "", alts: []string{"discouraged"}, }, @@ -115,7 +115,7 @@ func TestChoices(t *testing.T) { Priority: registry.Default, Status: func() registry.State { return registry.State{Installed: true, Healthy: true} }, }, - choices: []string{"unhealthy", "default", "discouraged"}, + choices: []string{"default", "discouraged", "unhealthy"}, pick: "default", alts: []string{"discouraged"}, }, @@ -125,13 +125,13 @@ func TestChoices(t *testing.T) { Priority: registry.Preferred, Status: func() registry.State { return registry.State{Installed: true, Healthy: true} }, }, - choices: []string{"preferred", "default", "unhealthy", "discouraged"}, + choices: []string{"preferred", "default", "discouraged", "unhealthy"}, pick: "preferred", alts: []string{"default", "discouraged"}, }, { requested: "unhealthy", - choices: []string{"preferred", "unhealthy", "default", "discouraged"}, + choices: []string{"preferred", "default", "discouraged", "unhealthy"}, pick: "unhealthy", alts: []string{"preferred", "default", "discouraged"}, }, diff --git a/pkg/minikube/registry/global.go b/pkg/minikube/registry/global.go index e7616d731a..6bd81ff0c2 100644 --- a/pkg/minikube/registry/global.go +++ b/pkg/minikube/registry/global.go @@ -18,6 +18,7 @@ package registry import ( "os" + "sort" "github.com/golang/glog" ) @@ -65,8 +66,19 @@ func Available() []DriverState { } s := d.Status() glog.Infof("%s priority: %d, state: %+v", d.Name, d.Priority, s) - sts = append(sts, DriverState{Name: d.Name, Priority: d.Priority, State: s}) + + priority := d.Priority + if !s.Healthy { + priority = Unhealthy + } + + sts = append(sts, DriverState{Name: d.Name, Priority: priority, State: s}) } + + // Descending priority for predictability + sort.Slice(sts, func(i, j int) bool { + return sts[i].Priority > sts[j].Priority + }) return sts } diff --git a/pkg/minikube/registry/global_test.go b/pkg/minikube/registry/global_test.go index 19a502403e..dbc76b6d51 100644 --- a/pkg/minikube/registry/global_test.go +++ b/pkg/minikube/registry/global_test.go @@ -72,19 +72,33 @@ func TestGlobalAvailable(t *testing.T) { } bar := DriverDef{ - Name: "bar", + Name: "healthy-bar", Priority: Default, - Status: func() State { return State{} }, + Status: func() State { return State{Healthy: true} }, } if err := Register(bar); err != nil { t.Errorf("register returned error: %v", err) } + foo := DriverDef{ + Name: "unhealthy-foo", + Priority: Default, + Status: func() State { return State{Healthy: false} }, + } + if err := Register(foo); err != nil { + t.Errorf("register returned error: %v", err) + } + expected := []DriverState{ { - Name: "bar", + Name: "healthy-bar", Priority: Default, - State: State{}, + State: State{Healthy: true}, + }, + { + Name: "unhealthy-foo", + Priority: Unhealthy, + State: State{Healthy: false}, }, } diff --git a/pkg/minikube/registry/registry.go b/pkg/minikube/registry/registry.go index 2c1676fed2..60b53de5a4 100644 --- a/pkg/minikube/registry/registry.go +++ b/pkg/minikube/registry/registry.go @@ -29,20 +29,20 @@ import ( type Priority int const ( - // Unknown priority + // Unknown is when there is no status check available Unknown Priority = iota - // Discouraged priority + // Unhealthy is when a driver does not pass health checks + Unhealthy + // Discouraged is when a driver has caveats that preclude it's recommendation Discouraged - // Deprecated priority + // Deprecated is when a driver has been formally deprecated Deprecated - // Fallback priority + // Fallback is when a driver works well, but may not be high performance Fallback - // Default priority + // Default is what what most 3rd party drivers are Default - // Preferred priority + // Preferred is for drivers that use a native hypervisor interface Preferred - // StronglyPreferred priority - StronglyPreferred ) // Registry contains all the supported driver definitions on the host From b02b4e158ad75e9e843a294e271da851b917cd63 Mon Sep 17 00:00:00 2001 From: tstromberg Date: Wed, 6 Nov 2019 14:18:28 -0800 Subject: [PATCH 4/5] Avoid panic and output correct driver name --- cmd/minikube/cmd/start.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 287f21ab7e..89c18c782a 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -562,7 +562,7 @@ func selectDriver(existing *cfg.Config) string { pick, alts := driver.Choose(name, options) if name != "" { - out.T(out.Sparkle, `Selecting '{{.driver}}' driver from user configuration (alternates: {{.alternates}})`, out.V{"driver": existing.MachineConfig.VMDriver, "alternates": alts}) + out.T(out.Sparkle, `Selecting '{{.driver}}' driver from user configuration (alternates: {{.alternates}})`, out.V{"driver": name, "alternates": alts}) return name } From 3f98e12fa98cdd6a36708293d11a9f496038b5ba Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Mon, 11 Nov 2019 12:16:13 -0800 Subject: [PATCH 5/5] Remove redundant return --- cmd/minikube/cmd/start.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index b6ae668217..6dc7e4a35f 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -645,7 +645,6 @@ func validateDriver(name string, existing *cfg.Config) { `, out.V{"command": minikubeCmd(), "old_driver": h.Driver.DriverName(), "profile_name": cfg.GetMachineName()}) exit.WithCodeT(exit.Config, "Exiting.") - return } func selectImageRepository(mirrorCountry string, k8sVersion string) (bool, string, error) {