diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go index 783d917b68..d412ca82c4 100644 --- a/pkg/machine/qemu/machine.go +++ b/pkg/machine/qemu/machine.go @@ -599,27 +599,47 @@ func (v *MachineVM) Start(name string, opts machine.StartOptions) error { _ = v.writeConfig() } } - if len(v.Mounts) > 0 { - connected := false - backoff = 500 * time.Millisecond - for i := 0; i < maxBackoffs; i++ { - if i > 0 { - time.Sleep(backoff) - backoff *= 2 - } - state, err := v.State(true) - if err != nil { - return err - } - if state == machine.Running && v.isListening() { - connected = true - break - } + if len(v.Mounts) == 0 { + v.waitAPIAndPrintInfo(forwardState, forwardSock, opts.NoInfo) + return nil + } + + connected := false + backoff = defaultBackoff + var sshError error + for i := 0; i < maxBackoffs; i++ { + if i > 0 { + time.Sleep(backoff) + backoff *= 2 } - if !connected { - return fmt.Errorf("machine did not transition into running state") + state, err := v.State(true) + if err != nil { + return err + } + if state == machine.Running && v.isListening() { + // Also make sure that SSH is up and running. The + // ready service's dependencies don't fully make sure + // that clients can SSH into the machine immediately + // after boot. + // + // CoreOS users have reported the same observation but + // the underlying source of the issue remains unknown. + if sshError = v.SSH(name, machine.SSHOptions{Args: []string{"true"}}); sshError != nil { + logrus.Debugf("SSH readiness check for machine failed: %v", sshError) + continue + } + connected = true + break } } + if !connected { + msg := "machine did not transition into running state" + if sshError != nil { + return fmt.Errorf("%s: ssh error: %v", msg, sshError) + } + return errors.New(msg) + } + for _, mount := range v.Mounts { if !opts.Quiet { fmt.Printf("Mounting volume... %s:%s\n", mount.Source, mount.Target)