diff --git a/cmd/kpod/main.go b/cmd/kpod/main.go index 7c1e7ac9..ff670824 100644 --- a/cmd/kpod/main.go +++ b/cmd/kpod/main.go @@ -29,6 +29,7 @@ func main() { pullCommand, pushCommand, rmiCommand, + stopCommand, tagCommand, versionCommand, } diff --git a/cmd/kpod/stop.go b/cmd/kpod/stop.go new file mode 100644 index 00000000..15e4cc05 --- /dev/null +++ b/cmd/kpod/stop.go @@ -0,0 +1,81 @@ +package main + +import ( + "fmt" + "github.com/Sirupsen/logrus" + "github.com/containers/storage/pkg/reexec" + "github.com/kubernetes-incubator/cri-o/server" + "github.com/pkg/errors" + "github.com/urfave/cli" + "golang.org/x/net/context" + pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" + "os" +) + +const crioConfigPath = "/etc/crio/crio.conf" + +var stopTimeout int64 +var configPath string + +var ( + stopFlags = []cli.Flag{ + cli.Int64Flag{ + Name: "timeout, t", + Usage: "Seconds to wait to kill the container after a graceful stop is requested (default 10", + Value: 10, + Destination: &stopTimeout, + }, + cli.StringFlag{ + Name: "config", + Usage: "path to configuration file", + Value: crioConfigPath, + Destination: &configPath, + }, + } + + stopDescription = "Stops one or more containers" + stopCommand = cli.Command{ + Name: "stop", + Usage: "Stop one or more containers", + Description: stopDescription, + Flags: stopFlags, + Action: stopCmd, + ArgsUsage: "CONTAINER-ID [CONTAINER-ID...]", + } +) + +func stopCmd(c *cli.Context) error { + var hasError bool = false + args := c.Args() + if len(args) < 1 { + return errors.Errorf("specify one or more container IDs") + } + config := new(server.Config) + if err := config.FromFile(configPath); err != nil { + return err + } + if reexec.Init() { + return nil + } + service, err := server.New(config) + if err != nil { + return err + } + for _, cid := range args { + r, err := service.StopContainer(context.Background(), &pb.StopContainerRequest{ + ContainerId: cid, + Timeout: stopTimeout, + }) + if err != nil { + hasError = true + fmt.Fprintf(os.Stderr, "%s\n", err) + } + logrus.Debugf("StopContainerResponse: %+v", r) + } + if hasError { + // mimics docker stop behaviour; errors are put on stdout + // but return code needs to 1, so returning a blank error message + os.Exit(1) + } + return nil +} diff --git a/completions/bash/kpod b/completions/bash/kpod index 0d5a728b..73e6a03f 100644 --- a/completions/bash/kpod +++ b/completions/bash/kpod @@ -147,6 +147,17 @@ _complete_() { esac } +_kpod_stop() { + local options_with_args=" + --timeout + -t + --configfile + " + local boolean_options=" + " + _complete_ "$options_with_args" "$boolean_options" +} + _kpod_kpod() { local options_with_args=" " diff --git a/docs/kpod-stop.1.md b/docs/kpod-stop.1.md new file mode 100644 index 00000000..39a1d336 --- /dev/null +++ b/docs/kpod-stop.1.md @@ -0,0 +1,33 @@ +## kpod-stop"1" "July 2017" "kpod" + +## NAME +kpod stop - Stops one or more containers + +## SYNOPSIS +**kpod** **stop** **containerID[...]** + +## DESCRIPTION +Stops one or more containers. + +## OPTIONS + +**--timeout, -t** + +Seconds to wait to kill the container after a graceful stop is requested. The default is 10. + +**--config** + +Path to an alternative configuration file. The default path is */etc/crio/crio.conf*. + +## EXAMPLE + +kpod stop containerID + +kpod stop containerID1 containerID2 + +kpod stop -t 3 containerID + +kpod stop --config ~/crio.conf containerID + +## SEE ALSO +kpod(1)