diff --git a/cmd/minikube/cmd/stop.go b/cmd/minikube/cmd/stop.go index 8dcd5f58ee36..a93cc79cdf42 100644 --- a/cmd/minikube/cmd/stop.go +++ b/cmd/minikube/cmd/stop.go @@ -52,7 +52,6 @@ func runStop(cmd *cobra.Command, args []string) { defer api.Close() nonexistent := false - stop := func() (err error) { err = cluster.StopHost(api) switch err := errors.Cause(err).(type) { @@ -64,9 +63,10 @@ func runStop(cmd *cobra.Command, args []string) { return err } } - if err := pkgutil.RetryAfter(5, stop, 2*time.Second); err != nil { + if err := pkgutil.RetryAfter(3, stop, 2*time.Second); err != nil { exit.WithError("Unable to stop VM", err) } + if !nonexistent { out.T(out.Stopped, `"{{.profile_name}}" stopped.`, out.V{"profile_name": profile}) } diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index e27c496041e7..65cd0b877c88 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -228,21 +228,22 @@ func adjustGuestClock(h hostRunner, t time.Time) error { } // trySSHPowerOff runs the poweroff command on the guest VM to speed up deletion -func trySSHPowerOff(h *host.Host) { +func trySSHPowerOff(h *host.Host) error { s, err := h.Driver.GetState() if err != nil { glog.Warningf("unable to get state: %v", err) - return + return err } if s != state.Running { glog.Infof("host is in state %s", s) - return + return nil } out.T(out.Shutdown, `Powering off "{{.profile_name}}" via SSH ...`, out.V{"profile_name": 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) + return nil } // StopHost stops the host VM, saving state to disk. @@ -251,7 +252,15 @@ func StopHost(api libmachine.API) error { if err != nil { return errors.Wrapf(err, "load") } + out.T(out.Stopping, `Stopping "{{.profile_name}}" in {{.driver_name}} ...`, out.V{"profile_name": cfg.GetMachineName(), "driver_name": host.DriverName}) + if host.DriverName == constants.DriverHyperv { + glog.Infof("As there are issues with stopping Hyper-V VMs using API, trying to shut down using SSH") + if err := trySSHPowerOff(host); err != nil { + return errors.Wrap(err, "ssh power off") + } + } + if err := host.Stop(); err != nil { alreadyInStateError, ok := err.(mcnerror.ErrHostAlreadyInState) if ok && alreadyInStateError.State == state.Stopped { @@ -270,7 +279,9 @@ func DeleteHost(api libmachine.API) error { } // This is slow if SSH is not responding, but HyperV hangs otherwise, See issue #2914 if host.Driver.DriverName() == constants.DriverHyperv { - trySSHPowerOff(host) + if err := trySSHPowerOff(host); err != nil { + glog.Infof("Unable to power off minikube because the host was not found.") + } } out.T(out.DeletingHost, `Deleting "{{.profile_name}}" in {{.driver_name}} ...`, out.V{"profile_name": cfg.GetMachineName(), "driver_name": host.DriverName})