diff --git a/cmd/minikube/cmd/stop.go b/cmd/minikube/cmd/stop.go index 6d80a998d903..e6cddf3253e9 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 { console.OutStyle(console.Stopped, "%q stopped.", profile) } diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index 39d6e06c8b14..850596d20c6b 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -212,22 +212,23 @@ func adjustGuestClock(h hostRunner, t time.Time) error { return err } -// trySSHPowerOff runs the poweroff command on the guest VM to speed up deletion -func trySSHPowerOff(h *host.Host) { +// TrySSHPowerOff runs the poweroff command on the guest VM to speed up deletion +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 } console.OutStyle(console.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) + return nil } // StopHost stops the host VM, saving state to disk. @@ -237,6 +238,12 @@ func StopHost(api libmachine.API) error { return errors.Wrapf(err, "load") } console.OutStyle(console.Stopping, "Stopping %q in %s ...", cfg.GetMachineName(), 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.Wrapf(err, "Unable to Power off cluster on %q using SSH", host.DriverName) + } + } if err := host.Stop(); err != nil { alreadyInStateError, ok := err.(mcnerror.ErrHostAlreadyInState) if ok && alreadyInStateError.State == state.Stopped { @@ -255,7 +262,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 { + return errors.Wrap(err, "Unable to power off minikube because the host was not found.") + } } console.OutStyle(console.DeletingHost, "Deleting %q from %s ...", cfg.GetMachineName(), host.DriverName)