Skip to content
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

hyperv: Run "sudo poweroff" before stopping VM #4758

Merged
merged 2 commits into from
Jul 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/minikube/cmd/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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})
}
Expand Down
19 changes: 15 additions & 4 deletions pkg/minikube/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,21 +226,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.
Expand All @@ -249,7 +250,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 {
Expand All @@ -268,7 +277,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})
Expand Down