diff --git a/pkg/bootstrap/docker/down.go b/pkg/bootstrap/docker/down.go index cdab5237af77..e758c2ba2900 100644 --- a/pkg/bootstrap/docker/down.go +++ b/pkg/bootstrap/docker/down.go @@ -5,32 +5,29 @@ import ( "io" "strings" - docker "github.com/fsouza/go-dockerclient" "github.com/golang/glog" "github.com/spf13/cobra" kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubelet/dockertools" "github.com/openshift/origin/pkg/bootstrap/docker/dockerhelper" - "github.com/openshift/origin/pkg/bootstrap/docker/errors" "github.com/openshift/origin/pkg/bootstrap/docker/openshift" osclientcmd "github.com/openshift/origin/pkg/cmd/util/clientcmd" - dockerutil "github.com/openshift/origin/pkg/cmd/util/docker" ) const ( cmdDownLong = ` Stops the container running OpenShift on Docker and associated containers. -If you started your OpenShift with a specific docker-machine, you need to specify the +If you started your OpenShift with a specific docker-machine, you need to specify the same machine using the --docker-machine argument. ` cmdDownExample = ` - # Stop local Docker cluster + # Stop local OpenShift cluster %[1]s - # Stop cluster running on Docker machine 'mymachine' + # Stop OpenShift cluster running on Docker machine 'mymachine' %[1]s --docker-machine=mymachine ` @@ -60,7 +57,7 @@ func NewCmdDown(name, fullName string, f *osclientcmd.Factory, out io.Writer) *c // Stop stops the currently running origin container and any // containers started by the node. func (c *ClientStopConfig) Stop(out io.Writer) error { - client, err := c.getDockerClient(out) + client, _, err := getDockerClient(out, c.DockerMachine, false) if err != nil { return err } @@ -94,16 +91,3 @@ func (c *ClientStopConfig) Stop(out io.Writer) error { } return nil } - -func (c *ClientStopConfig) getDockerClient(out io.Writer) (*docker.Client, error) { - // Get Docker client - if len(c.DockerMachine) > 0 { - client, _, err := getDockerMachineClient(c.DockerMachine, out) - return client, err - } - client, _, err := dockerutil.NewHelper().GetClient() - if err != nil { - return nil, errors.ErrNoDockerClient(err) - } - return client, nil -} diff --git a/pkg/bootstrap/docker/status.go b/pkg/bootstrap/docker/status.go new file mode 100644 index 000000000000..abe70dd3baa3 --- /dev/null +++ b/pkg/bootstrap/docker/status.go @@ -0,0 +1,86 @@ +package docker + +import ( + "fmt" + "io" + "time" + + "github.com/spf13/cobra" + + kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" + + "github.com/openshift/origin/pkg/bootstrap/docker/dockerhelper" + "github.com/openshift/origin/pkg/bootstrap/docker/errors" + "github.com/openshift/origin/pkg/cmd/util/clientcmd" +) + +const ( + // CmdStatusRecommendedName is the recommended command name + CmdStatusRecommendedName = "status" + + cmdStatusLong = ` +Show the status of the local OpenShift cluster. + +If you started your OpenShift with a specific docker-machine, you need to specify the +same machine using the --docker-machine argument. +` + cmdStatusExample = ` + # See status of local OpenShift cluster + %[1]s + + # See status of OpenShift cluster running on Docker machine 'mymachine' + %[1]s --docker-machine=mymachine +` +) + +// NewCmdStatus implements the OpenShift cluster status command. +func NewCmdStatus(name, fullName string, f *clientcmd.Factory, out io.Writer) *cobra.Command { + config := &ClientStatusConfig{} + cmd := &cobra.Command{ + Use: name, + Short: "Show OpenShift on Docker status", + Long: cmdStatusLong, + Example: fmt.Sprintf(cmdStatusExample, fullName), + Run: func(c *cobra.Command, args []string) { + kcmdutil.CheckErr(config.Status(f, out)) + }, + } + cmd.Flags().StringVar(&config.DockerMachine, "docker-machine", "", "Specify the Docker machine to use") + return cmd +} + +// ClientStatusConfig is the configuration for the client status command +type ClientStatusConfig struct { + DockerMachine string +} + +// Status prints the developer cluster status +func (c *ClientStatusConfig) Status(f *clientcmd.Factory, out io.Writer) error { + dockerClient, _, err := getDockerClient(out, c.DockerMachine, false) + if err != nil { + return errors.ErrNoDockerClient(err) + } + helper := dockerhelper.NewHelper(dockerClient, nil) + + _, running, err := helper.GetContainerState(openShiftContainer) + if err != nil { + return errors.NewError("cannot get state of OpenShift container %s", openShiftContainer).WithCause(err) + } + + if running { + client, _, err := f.Clients() + if err != nil { + return err + } + + var statusCode int + client.Client.Timeout = 10 * time.Second + client.Get().AbsPath("/healthz").Do().StatusCode(&statusCode) + if statusCode == 200 { + fmt.Fprintf(out, "success: OpenShift container is running\n") + return nil + } + } + + return errors.NewError("OpenShift cluster is not running") +} diff --git a/pkg/bootstrap/docker/up.go b/pkg/bootstrap/docker/up.go index 01494eb2ff0e..7b00dd71d990 100644 --- a/pkg/bootstrap/docker/up.go +++ b/pkg/bootstrap/docker/up.go @@ -398,15 +398,24 @@ func (c *ClientStartConfig) CheckOpenShiftClient(out io.Writer) error { // GetDockerClient will obtain a new Docker client from the environment or // from a Docker machine, starting it if necessary func (c *ClientStartConfig) GetDockerClient(out io.Writer) error { - var err error + dockerClient, engineAPIClient, err := getDockerClient(out, c.DockerMachine, true) + if err != nil { + return err + } + c.dockerClient, c.engineAPIClient = dockerClient, engineAPIClient + return nil +} - if len(c.DockerMachine) > 0 { - glog.V(2).Infof("Getting client for Docker machine %q", c.DockerMachine) - c.dockerClient, c.engineAPIClient, err = getDockerMachineClient(c.DockerMachine, out) +// getDockerClient will obtain a new Docker client from the environment or +// from a Docker machine, starting it if necessary and permitted +func getDockerClient(out io.Writer, dockerMachine string, canStartDockerMachine bool) (*docker.Client, *dockerclient.Client, error) { + if len(dockerMachine) > 0 { + glog.V(2).Infof("Getting client for Docker machine %q", dockerMachine) + dockerClient, engineAPIClient, err := getDockerMachineClient(dockerMachine, out, canStartDockerMachine) if err != nil { - return errors.ErrNoDockerMachineClient(c.DockerMachine, err) + return nil, nil, errors.ErrNoDockerMachineClient(dockerMachine, err) } - return nil + return dockerClient, engineAPIClient, nil } if glog.V(4) { @@ -428,9 +437,9 @@ func (c *ClientStartConfig) GetDockerClient(out io.Writer) error { glog.Infof("DOCKER_CERT_PATH=%s", dockerCertPath) } } - c.dockerClient, _, err = dockerutil.NewHelper().GetClient() + dockerClient, _, err := dockerutil.NewHelper().GetClient() if err != nil { - return errors.ErrNoDockerClient(err) + return nil, nil, errors.ErrNoDockerClient(err) } // FIXME: Workaround for docker engine API client on OS X - sets the default to // the wrong DOCKER_HOST string @@ -440,15 +449,15 @@ func (c *ClientStartConfig) GetDockerClient(out io.Writer) error { os.Setenv("DOCKER_HOST", "unix:///var/run/docker.sock") } } - c.engineAPIClient, err = dockerclient.NewEnvClient() + engineAPIClient, err := dockerclient.NewEnvClient() if err != nil { - return errors.ErrNoDockerClient(err) + return nil, nil, errors.ErrNoDockerClient(err) } - if err = c.dockerClient.Ping(); err != nil { - return errors.ErrCannotPingDocker(err) + if err = dockerClient.Ping(); err != nil { + return nil, nil, errors.ErrCannotPingDocker(err) } glog.V(4).Infof("Docker ping succeeded") - return nil + return dockerClient, engineAPIClient, nil } // CheckExistingOpenShiftContainer checks the state of an OpenShift container. If one @@ -806,8 +815,8 @@ func (c *ClientStartConfig) openShiftImage() string { return fmt.Sprintf("%s:%s", c.Image, c.ImageVersion) } -func getDockerMachineClient(machine string, out io.Writer) (*docker.Client, *dockerclient.Client, error) { - if !dockermachine.IsRunning(machine) { +func getDockerMachineClient(machine string, out io.Writer, canStart bool) (*docker.Client, *dockerclient.Client, error) { + if !dockermachine.IsRunning(machine) && canStart { fmt.Fprintf(out, "Starting Docker machine '%s'\n", machine) err := dockermachine.Start(machine) if err != nil { diff --git a/pkg/cmd/cli/cmd/cluster/cluster.go b/pkg/cmd/cli/cmd/cluster/cluster.go index c3539ec7ab99..555c01445046 100644 --- a/pkg/cmd/cli/cmd/cluster/cluster.go +++ b/pkg/cmd/cli/cmd/cluster/cluster.go @@ -21,7 +21,7 @@ The OpenShift cluster will run as an all-in-one container on a Docker host. The may be a local VM (ie. using docker-machine on OS X and Windows clients), remote machine, or the local Unix host. -To use an existing Docker connection, ensure that Docker commands are working and that you +To use an existing Docker connection, ensure that Docker commands are working and that you can create new containers. For OS X and Windows clients, a docker-machine with the VirtualBox driver can be created for you using the --create-machine option. @@ -44,5 +44,6 @@ func NewCmdCluster(name, fullName string, f *clientcmd.Factory, out io.Writer) * cmds.AddCommand(docker.NewCmdUp(docker.CmdUpRecommendedName, fullName+" "+docker.CmdUpRecommendedName, f, out)) cmds.AddCommand(docker.NewCmdDown(docker.CmdDownRecommendedName, fullName+" "+docker.CmdDownRecommendedName, f, out)) + cmds.AddCommand(docker.NewCmdStatus(docker.CmdStatusRecommendedName, fullName+" "+docker.CmdStatusRecommendedName, f, out)) return cmds }