From e74db397833fbad8dd1738933c0e9f4587b7a59c Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Wed, 13 Feb 2019 09:21:58 -0800 Subject: [PATCH 1/4] Issue a poweroff request before deleting a VM. Avoids HyperV hang --- cmd/minikube/cmd/delete.go | 10 ++++++---- cmd/minikube/cmd/stop.go | 2 -- pkg/minikube/cluster/cluster.go | 26 +++++++++++++++++++++++++- pkg/minikube/console/style.go | 1 + 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/cmd/minikube/cmd/delete.go b/cmd/minikube/cmd/delete.go index eeba8e3e703a..cba64523101f 100644 --- a/cmd/minikube/cmd/delete.go +++ b/cmd/minikube/cmd/delete.go @@ -54,10 +54,13 @@ associated files.`, cc, err := pkg_config.Load() if err != nil && !os.IsNotExist(err) { console.ErrLn("Error loading profile config: %v", err) - } else if err == nil { + } + + // In the case of "none", we want to uninstall Kubernetes as there is no VM to delete + if err == nil && cc.MachineConfig.VMDriver == "none" { kc := cc.KubernetesConfig - bsName := viper.GetString(cmdcfg.Bootstrapper) // Name ? - console.OutStyle("resetting", "Reverting Kubernetes %s using %s ...", kc.KubernetesVersion, bsName) + bsName := viper.GetString(cmdcfg.Bootstrapper) + console.OutStyle("resetting", "Uninstalling Kubernetes %s using %s ...", kc.KubernetesVersion, bsName) clusterBootstrapper, err := GetClusterBootstrapper(api, viper.GetString(cmdcfg.Bootstrapper)) if err == nil { if err = clusterBootstrapper.DeleteCluster(kc); err != nil { @@ -66,7 +69,6 @@ associated files.`, } } - console.OutStyle("deleting-vm", "Deleting %q Kubernetes VM ...", profile) if err = cluster.DeleteHost(api); err != nil { switch err := errors.Cause(err).(type) { case mcnerror.ErrHostDoesNotExist: diff --git a/cmd/minikube/cmd/stop.go b/cmd/minikube/cmd/stop.go index b4eeadebfee3..43868ce6bd22 100644 --- a/cmd/minikube/cmd/stop.go +++ b/cmd/minikube/cmd/stop.go @@ -40,8 +40,6 @@ var stopCmd = &cobra.Command{ itself, leaving all files intact. The cluster can be started again with the "start" command.`, Run: func(cmd *cobra.Command, args []string) { profile := viper.GetString(pkg_config.MachineProfile) - console.OutStyle("stopping", "Stopping %q Kubernetes cluster...", profile) - api, err := machine.NewAPIClient() if err != nil { console.Fatal("Error getting client: %v", err) diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index 23d7a90c1dc9..3e522a9ac963 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -125,12 +125,34 @@ func StartHost(api libmachine.API, config cfg.MachineConfig) (*host.Host, error) return h, nil } -// StopHost stops the host VM. +// tryPowerOff runs the poweroff command on the guest VM to speed up deletion +func tryPowerOff(h *host.Host) { + if h.Driver.DriverName() == "none" { + return + } + s, err := h.Driver.GetState() + if err != nil { + glog.Warningf("unable to get state: %v", err) + return + } + if s != state.Running { + glog.Infof("host is in state %s", s) + return + } + + console.OutStyle("shutdown", "Powering off %q via SSH ...", cfg.GetMachineName()) + out, err := h.RunSSHCommand("sudo poweroff") + // poweroff always results in an error, since the host disconnects. + glog.Infof("poweroff result: out=%s, err=%v", out, err) +} + +// StopHost stops the host VM, saving state to disk. func StopHost(api libmachine.API) error { host, err := api.Load(cfg.GetMachineName()) if err != nil { return errors.Wrapf(err, "load") } + console.OutStyle("stopping", "Stopping %q in %s ...", cfg.GetMachineName(), host.DriverName) if err := host.Stop(); err != nil { alreadyInStateError, ok := err.(mcnerror.ErrHostAlreadyInState) if ok && alreadyInStateError.State == state.Stopped { @@ -147,6 +169,8 @@ func DeleteHost(api libmachine.API) error { if err != nil { return errors.Wrap(err, "load") } + tryPowerOff(host) + console.OutStyle("deleting-vm", "Deleting %q from %s...", cfg.GetMachineName(), host.DriverName) if err := host.Driver.Remove(); err != nil { return errors.Wrap(err, "host remove") } diff --git a/pkg/minikube/console/style.go b/pkg/minikube/console/style.go index 1380769995b5..531e5c820d13 100644 --- a/pkg/minikube/console/style.go +++ b/pkg/minikube/console/style.go @@ -70,6 +70,7 @@ var styles = map[string]style{ "containerd": {Prefix: "๐Ÿ“ฆ "}, "permissions": {Prefix: "๐Ÿ”‘ "}, "enabling": {Prefix: "๐Ÿ”Œ "}, + "shutdown": {Prefix: "๐Ÿ™… "}, "pulling": {Prefix: "๐Ÿšœ "}, "verifying": {Prefix: "๐Ÿค” "}, "verifying-noline": {Prefix: "๐Ÿค” ", OmitNewline: true}, From 277100d371945812995df31f19c8d07864a4369a Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Wed, 13 Feb 2019 09:23:56 -0800 Subject: [PATCH 2/4] add an extra space for consistency --- pkg/minikube/cluster/cluster.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index 3e522a9ac963..331d43421733 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -170,7 +170,7 @@ func DeleteHost(api libmachine.API) error { return errors.Wrap(err, "load") } tryPowerOff(host) - console.OutStyle("deleting-vm", "Deleting %q from %s...", cfg.GetMachineName(), host.DriverName) + console.OutStyle("deleting-vm", "Deleting %q from %s ...", cfg.GetMachineName(), host.DriverName) if err := host.Driver.Remove(); err != nil { return errors.Wrap(err, "host remove") } From 1c09ba2a4841ee554209b17e06244464d85ef473 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Wed, 13 Feb 2019 09:41:53 -0800 Subject: [PATCH 3/4] Make the output clearer and less cluttered --- cmd/minikube/cmd/delete.go | 4 +--- pkg/minikube/cluster/cluster.go | 4 ++-- pkg/minikube/console/style.go | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cmd/minikube/cmd/delete.go b/cmd/minikube/cmd/delete.go index cba64523101f..99e11bb5c16b 100644 --- a/cmd/minikube/cmd/delete.go +++ b/cmd/minikube/cmd/delete.go @@ -77,8 +77,6 @@ associated files.`, console.Fatal("Failed to delete VM: %v", err) os.Exit(1) } - } else { - console.OutStyle("crushed", "VM deleted.") } if err := cmdUtil.KillMountProcess(); err != nil { @@ -93,7 +91,7 @@ associated files.`, console.Fatal("Failed to remove profile: %v", err) os.Exit(1) } - console.Success("Removed %q profile!", profile) + console.OutStyle("crushed", "The %q cluster is now deleted. I hope you are happy.", profile) }, } diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index 331d43421733..253dbcd6c596 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -140,7 +140,7 @@ func tryPowerOff(h *host.Host) { return } - console.OutStyle("shutdown", "Powering off %q via SSH ...", cfg.GetMachineName()) + console.OutStyle("shutdown", "Powering off %q VM via SSH ...", cfg.GetMachineName()) out, err := h.RunSSHCommand("sudo poweroff") // poweroff always results in an error, since the host disconnects. glog.Infof("poweroff result: out=%s, err=%v", out, err) @@ -170,7 +170,7 @@ func DeleteHost(api libmachine.API) error { return errors.Wrap(err, "load") } tryPowerOff(host) - console.OutStyle("deleting-vm", "Deleting %q from %s ...", cfg.GetMachineName(), host.DriverName) + console.OutStyle("deleting-host", "Deleting %q host from %s ...", cfg.GetMachineName(), host.DriverName) if err := host.Driver.Remove(); err != nil { return errors.Wrap(err, "host remove") } diff --git a/pkg/minikube/console/style.go b/pkg/minikube/console/style.go index 531e5c820d13..0dbc5a6f4cd9 100644 --- a/pkg/minikube/console/style.go +++ b/pkg/minikube/console/style.go @@ -58,7 +58,7 @@ var styles = map[string]style{ "starting-vm": {Prefix: "๐Ÿ”ฅ "}, "starting-none": {Prefix: "๐Ÿคน "}, "resetting": {Prefix: "๐Ÿ”„ "}, - "deleting-vm": {Prefix: "๐Ÿ”ฅ "}, + "deleting-host": {Prefix: "๐Ÿ”ฅ "}, "copying": {Prefix: "โœจ "}, "connectivity": {Prefix: "๐Ÿ“ถ "}, "internet": {Prefix: "๐ŸŒ "}, @@ -70,7 +70,7 @@ var styles = map[string]style{ "containerd": {Prefix: "๐Ÿ“ฆ "}, "permissions": {Prefix: "๐Ÿ”‘ "}, "enabling": {Prefix: "๐Ÿ”Œ "}, - "shutdown": {Prefix: "๐Ÿ™… "}, + "shutdown": {Prefix: "๐Ÿ›‘ "}, "pulling": {Prefix: "๐Ÿšœ "}, "verifying": {Prefix: "๐Ÿค” "}, "verifying-noline": {Prefix: "๐Ÿค” ", OmitNewline: true}, From eb00fdb3d76717fbb2b4e11ab4b78d2e20025395 Mon Sep 17 00:00:00 2001 From: Thomas Stromberg Date: Wed, 13 Feb 2019 09:42:49 -0800 Subject: [PATCH 4/4] Remove VM/host --- pkg/minikube/cluster/cluster.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index 253dbcd6c596..08a34b0defac 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -140,7 +140,7 @@ func tryPowerOff(h *host.Host) { return } - console.OutStyle("shutdown", "Powering off %q VM via SSH ...", cfg.GetMachineName()) + console.OutStyle("shutdown", "Powering off %q via SSH ...", cfg.GetMachineName()) out, err := h.RunSSHCommand("sudo poweroff") // poweroff always results in an error, since the host disconnects. glog.Infof("poweroff result: out=%s, err=%v", out, err) @@ -170,7 +170,7 @@ func DeleteHost(api libmachine.API) error { return errors.Wrap(err, "load") } tryPowerOff(host) - console.OutStyle("deleting-host", "Deleting %q host from %s ...", cfg.GetMachineName(), host.DriverName) + console.OutStyle("deleting-host", "Deleting %q from %s ...", cfg.GetMachineName(), host.DriverName) if err := host.Driver.Remove(); err != nil { return errors.Wrap(err, "host remove") }