-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fallback to alternate drivers on failure #7389
Changes from 7 commits
ac1b3b0
357b5bb
26c7471
af8d01d
dd957ff
b66447e
31f225d
3d037a8
66f9e13
f290aa9
78595b1
eb42d16
81ac4d2
5df9ead
45bf65c
c40a942
aee3c1d
d2dbf53
198247d
e4b4a5a
9853274
322b5d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -304,11 +304,43 @@ func runStart(cmd *cobra.Command, args []string) { | |
} | ||
|
||
validateSpecifiedDriver(existing) | ||
ds := selectDriver(existing) | ||
ds, alts, specified := selectDriver(existing) | ||
err = startWithDriver(cmd, ds, existing) | ||
if err != nil && !specified { | ||
// Walk down the rest of the options | ||
for _, alt := range alts { | ||
out.WarningT("Startup with {{.old_driver}} driver failed, trying with {{.new_driver}}.", out.V{"old_driver": ds.Name, "new_driver": alt.Name}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change 'trying with' |
||
ds = alt | ||
// Delete the existing cluster and try again with the next driver on the list | ||
profile, err := config.LoadProfile(ClusterFlagValue()) | ||
if err != nil { | ||
out.ErrT(out.Meh, `"{{.name}}" profile does not exist, trying anyways.`, out.V{"name": ClusterFlagValue()}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this can be hidden in a log message. |
||
} | ||
|
||
err = deleteProfile(profile) | ||
if err != nil { | ||
out.WarningT("Failed to delete cluster {{.name}}, proceeding with retry anyway.", out.V{"name": ClusterFlagValue()}) | ||
} | ||
err = startWithDriver(cmd, ds, existing) | ||
if err != nil { | ||
continue | ||
} else { | ||
// Success! | ||
os.Exit(0) | ||
} | ||
} | ||
} | ||
|
||
// Use the most recent error | ||
exit.WithError("startup failed", err) | ||
|
||
} | ||
|
||
func startWithDriver(cmd *cobra.Command, ds registry.DriverState, existing *config.ClusterConfig) error { | ||
driverName := ds.Name | ||
glog.Infof("selected driver: %s", driverName) | ||
validateDriver(ds, existing) | ||
err = autoSetDriverOptions(cmd, driverName) | ||
err := autoSetDriverOptions(cmd, driverName) | ||
if err != nil { | ||
glog.Errorf("Error autoSetOptions : %v", err) | ||
} | ||
|
@@ -324,19 +356,19 @@ func runStart(cmd *cobra.Command, args []string) { | |
k8sVersion := getKubernetesVersion(existing) | ||
cc, n, err := generateCfgFromFlags(cmd, k8sVersion, driverName) | ||
if err != nil { | ||
exit.WithError("Failed to generate config", err) | ||
return errors.Wrap(err, "Failed to generate config") | ||
} | ||
|
||
// This is about as far as we can go without overwriting config files | ||
if viper.GetBool(dryRun) { | ||
out.T(out.DryRun, `dry-run validation complete!`) | ||
return | ||
return nil | ||
} | ||
|
||
if driver.IsVM(driverName) { | ||
url, err := download.ISO(viper.GetStringSlice(isoURL), cmd.Flags().Changed(isoURL)) | ||
if err != nil { | ||
exit.WithError("Failed to cache ISO", err) | ||
return errors.Wrap(err, "Failed to cache ISO") | ||
} | ||
cc.MinikubeISO = url | ||
} | ||
|
@@ -357,7 +389,10 @@ func runStart(cmd *cobra.Command, args []string) { | |
|
||
kubeconfig, err := node.Start(cc, n, existingAddons, true) | ||
if err != nil { | ||
kubeconfig = maybeDeleteAndRetry(cc, n, existingAddons, err) | ||
kubeconfig, err = maybeDeleteAndRetry(cc, n, existingAddons, err) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
numNodes := viper.GetInt(nodes) | ||
|
@@ -379,7 +414,7 @@ func runStart(cmd *cobra.Command, args []string) { | |
out.Ln("") // extra newline for clarity on the command line | ||
err := node.Add(&cc, n) | ||
if err != nil { | ||
exit.WithError("adding node", err) | ||
return errors.Wrap(err, "adding node") | ||
} | ||
} | ||
} | ||
|
@@ -388,6 +423,8 @@ func runStart(cmd *cobra.Command, args []string) { | |
if err := showKubectlInfo(kubeconfig, k8sVersion, cc.Name); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this can be moved out of |
||
glog.Errorf("kubectl info: %v", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func updateDriver(driverName string) { | ||
|
@@ -462,7 +499,7 @@ func showKubectlInfo(kcs *kubeconfig.Settings, k8sVersion string, machineName st | |
return nil | ||
} | ||
|
||
func maybeDeleteAndRetry(cc config.ClusterConfig, n config.Node, existingAddons map[string]bool, originalErr error) *kubeconfig.Settings { | ||
func maybeDeleteAndRetry(cc config.ClusterConfig, n config.Node, existingAddons map[string]bool, originalErr error) (*kubeconfig.Settings, error) { | ||
if viper.GetBool(deleteOnFailure) { | ||
out.WarningT("Node {{.name}} failed to start, deleting and trying again.", out.V{"name": n.Name}) | ||
// Start failed, delete the cluster and try again | ||
|
@@ -484,14 +521,13 @@ func maybeDeleteAndRetry(cc config.ClusterConfig, n config.Node, existingAddons | |
} | ||
if err != nil { | ||
// Ok we failed again, let's bail | ||
exit.WithError("Start failed after cluster deletion", err) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. glog.Info the error saying..ok we are giving up here is the error btw: |
||
return nil, err | ||
} | ||
} | ||
return kubeconfig | ||
return kubeconfig, nil | ||
} | ||
// Don't delete the cluster unless they ask | ||
exit.WithError("startup failed", originalErr) | ||
return nil | ||
return nil, errors.Wrap(originalErr, "startup failed") | ||
} | ||
|
||
func kubectlVersion(path string) (string, error) { | ||
|
@@ -519,7 +555,7 @@ func kubectlVersion(path string) (string, error) { | |
return cv.ClientVersion.GitVersion, nil | ||
} | ||
|
||
func selectDriver(existing *config.ClusterConfig) registry.DriverState { | ||
func selectDriver(existing *config.ClusterConfig) (registry.DriverState, []registry.DriverState, bool) { | ||
// Technically unrelated, but important to perform before detection | ||
driver.SetLibvirtURI(viper.GetString(kvmQemuURI)) | ||
|
||
|
@@ -528,7 +564,7 @@ func selectDriver(existing *config.ClusterConfig) registry.DriverState { | |
old := hostDriver(existing) | ||
ds := driver.Status(old) | ||
out.T(out.Sparkle, `Using the {{.driver}} driver based on existing profile`, out.V{"driver": ds.String()}) | ||
return ds | ||
return ds, nil, true | ||
} | ||
|
||
// Default to looking at the new driver parameter | ||
|
@@ -548,7 +584,7 @@ func selectDriver(existing *config.ClusterConfig) registry.DriverState { | |
exit.WithCodeT(exit.Unavailable, "The driver '{{.driver}}' is not supported on {{.os}}", out.V{"driver": d, "os": runtime.GOOS}) | ||
} | ||
out.T(out.Sparkle, `Using the {{.driver}} driver based on user configuration`, out.V{"driver": ds.String()}) | ||
return ds | ||
return ds, nil, true | ||
} | ||
|
||
// Fallback to old driver parameter | ||
|
@@ -558,7 +594,7 @@ func selectDriver(existing *config.ClusterConfig) registry.DriverState { | |
exit.WithCodeT(exit.Unavailable, "The driver '{{.driver}}' is not supported on {{.os}}", out.V{"driver": d, "os": runtime.GOOS}) | ||
} | ||
out.T(out.Sparkle, `Using the {{.driver}} driver based on user configuration`, out.V{"driver": ds.String()}) | ||
return ds | ||
return ds, nil, true | ||
} | ||
|
||
choices := driver.Choices(viper.GetBool("vm")) | ||
|
@@ -581,7 +617,7 @@ func selectDriver(existing *config.ClusterConfig) registry.DriverState { | |
} else { | ||
out.T(out.Sparkle, `Automatically selected the {{.driver}} driver`, out.V{"driver": pick.String()}) | ||
} | ||
return pick | ||
return pick, alts, false | ||
} | ||
|
||
// hostDriver returns the actual driver used by a libmachine host, which can differ from our config | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's start by outputting the error message. It's unlikely to be terribly long, and it should be very informative.