diff --git a/pkg/drivers/kic/kic.go b/pkg/drivers/kic/kic.go index 78f9733d84..14873fe0e7 100644 --- a/pkg/drivers/kic/kic.go +++ b/pkg/drivers/kic/kic.go @@ -38,6 +38,7 @@ import ( "k8s.io/minikube/pkg/minikube/cruntime" "k8s.io/minikube/pkg/minikube/download" "k8s.io/minikube/pkg/minikube/sysinit" + "k8s.io/minikube/pkg/util/retry" ) // Driver represents a kic driver https://minikube.sigs.k8s.io/docs/reference/drivers/docker @@ -258,9 +259,14 @@ func (d *Driver) Kill() error { if err := sysinit.New(d.exec).ForceStop("kubelet"); err != nil { glog.Warningf("couldn't force stop kubelet. will continue with kill anyways: %v", err) } - cmd := exec.Command(d.NodeConfig.OCIBinary, "kill", d.MachineName) - if err := cmd.Run(); err != nil { - return errors.Wrapf(err, "killing kic node %s", d.MachineName) + + if err := oci.ShutDown(d.OCIBinary, d.MachineName); err != nil { + glog.Warningf("couldn't shutdown the container, will contineu with kill anyways: %v", err) + } + + cr := command.NewExecRunner() // using exec runner for interacting with dameon. + if _, err := cr.RunCmd(exec.Command(d.NodeConfig.OCIBinary, "kill", d.MachineName)); err != nil { + return errors.Wrapf(err, "killing %q", d.MachineName) } return nil } @@ -292,40 +298,43 @@ func (d *Driver) Remove() error { func (d *Driver) Restart() error { s, err := d.GetState() if err != nil { - return errors.Wrap(err, "get kic state") + glog.Warningf("get state during restart: %v", err) } - switch s { - case state.Stopped: + if s == state.Stopped { // don't stop if already stopped return d.Start() - case state.Running, state.Error: - if err = d.Stop(); err != nil { - return fmt.Errorf("restarting a kic stop phase %v", err) - } - if err = d.Start(); err != nil { - return fmt.Errorf("restarting a kic start phase %v", err) - } - return nil } + if err = d.Stop(); err != nil { + return fmt.Errorf("stop during restart %v", err) + } + if err = d.Start(); err != nil { + return fmt.Errorf("start during restart %v", err) + } + return nil - return fmt.Errorf("restarted not implemented for kic state %s yet", s) } -// Start a _stopped_ kic container -// not meant to be used for Create(). +// Start an already created kic container func (d *Driver) Start() error { - s, err := d.GetState() - if err != nil { - return errors.Wrap(err, "get kic state") + cr := command.NewExecRunner() // using exec runner for interacting with + if _, err := cr.RunCmd(exec.Command(d.NodeConfig.OCIBinary, "start", d.MachineName)); err != nil { + return err } - if s == state.Stopped { - cmd := exec.Command(d.NodeConfig.OCIBinary, "start", d.MachineName) - if err := cmd.Run(); err != nil { - return errors.Wrapf(err, "starting a stopped kic node %s", d.MachineName) + checkRunning := func() error { + s, err := oci.ContainerStatus(d.NodeConfig.OCIBinary, d.MachineName) + if err != nil { + return err } + if s != state.Running { + return fmt.Errorf("expected container state be running but got %q", s) + } + glog.Infof("container %q state is running.", d.MachineName) return nil } - // TODO:medyagh maybe make it idempotent - return fmt.Errorf("cant start a not-stopped (%s) kic node", s) + + if err := retry.Expo(checkRunning, 500*time.Microsecond, time.Second*30); err != nil { + return err + } + return nil } // Stop a host gracefully, including any containers that we are managing. diff --git a/pkg/drivers/kic/oci/oci.go b/pkg/drivers/kic/oci/oci.go index ea739fff90..44da3a0955 100644 --- a/pkg/drivers/kic/oci/oci.go +++ b/pkg/drivers/kic/oci/oci.go @@ -25,6 +25,7 @@ import ( "bufio" "bytes" + "github.com/docker/machine/libmachine/state" "github.com/golang/glog" "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/constants" @@ -171,7 +172,7 @@ func CreateContainerNode(p CreateParams) error { if err != nil { return fmt.Errorf("temporary error checking status for %q : %v", p.Name, err) } - if s != "running" { + if s != state.Running { return fmt.Errorf("temporary error created container %q is not running yet", p.Name) } glog.Infof("the created container %q has a running status.", p.Name) @@ -488,9 +489,23 @@ func PointToHostDockerDaemon() error { } // ContainerStatus returns status of a container running,exited,... -func ContainerStatus(ociBin string, name string) (string, error) { +func ContainerStatus(ociBin string, name string) (state.State, error) { out, err := WarnIfSlow(ociBin, "inspect", name, "--format={{.State.Status}}") - return strings.TrimSpace(string(out)), err + o := strings.TrimSpace(string(out)) + switch o { + case "running": + return state.Running, nil + case "exited": + return state.Stopped, nil + case "paused": + return state.Paused, nil + case "restarting": + return state.Starting, nil + case "dead": + return state.Error, nil + default: + return state.None, errors.Wrapf(err, "unknown state %q", name) + } } // Shutdown will run command to shut down the container