From aca658b423730a59d44ac5e6cdf73a7ba742a1ef Mon Sep 17 00:00:00 2001 From: baude Date: Wed, 6 Sep 2017 12:30:34 -0500 Subject: [PATCH] kpod stop -- stop one or more containers Stop one or more containers. Specific a timeout value that if the stop operation exceeds, will forcibly stop the container. Signed-off-by: baude --- README.md | 1 + cmd/kpod/main.go | 1 + cmd/kpod/stop.go | 68 +++++++++++++++++++++++++++++++++++++++++++ completions/bash/kpod | 9 ++++++ docs/kpod-stop.1.md | 35 ++++++++++++++++++++++ docs/kpod.1.md | 3 ++ test/kpod_stop.bats | 51 ++++++++++++++++++++++++++++++++ 7 files changed, 168 insertions(+) create mode 100644 cmd/kpod/stop.go create mode 100644 docs/kpod-stop.1.md create mode 100644 test/kpod_stop.bats diff --git a/README.md b/README.md index 33555394..8cb90ff5 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ It is currently in active development in the Kubernetes community through the [d | [kpod-rmi(1)](/docs/kpod-rmi.1.md) | Removes one or more images |[![...](/docs/play.png)](https://asciinema.org/a/133799)| | [kpod-save(1)](/docs/kpod-save.1.md) | Saves an image to an archive |[![...](/docs/play.png)](https://asciinema.org/a/kp8kOaexEhEa20P1KLZ3L5X4g)| | [kpod-stats(1)](/docs/kpod-stats.1.md) | Display a live stream of one or more containers' resource usage statistics|| +| [kpod-stop(1)](/docs/kpod-stop.1.md) | Stops one or more running containers.|| | [kpod-tag(1)](/docs/kpod-tag.1.md) | Add an additional name to a local image |[![...](/docs/play.png)](https://asciinema.org/a/133803)| | [kpod-umount(1)](/docs/kpod-umount.1.md) | Unmount a working container's root filesystem || | [kpod-version(1)](/docs/kpod-version.1.md) | Display the version information |[![...](/docs/play.png)](https://asciinema.org/a/mfrn61pjZT9Fc8L4NbfdSqfgu)| diff --git a/cmd/kpod/main.go b/cmd/kpod/main.go index 2a51aa28..41d7d10e 100644 --- a/cmd/kpod/main.go +++ b/cmd/kpod/main.go @@ -36,6 +36,7 @@ func main() { rmiCommand, saveCommand, statsCommand, + stopCommand, tagCommand, umountCommand, versionCommand, diff --git a/cmd/kpod/stop.go b/cmd/kpod/stop.go new file mode 100644 index 00000000..93eed6f3 --- /dev/null +++ b/cmd/kpod/stop.go @@ -0,0 +1,68 @@ +package main + +import ( + "fmt" + "github.com/kubernetes-incubator/cri-o/libkpod" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/urfave/cli" + "os" +) + +var ( + defaultTimeout int64 = 10 + stopFlags = []cli.Flag{ + cli.Int64Flag{ + Name: "timeout, t", + Usage: "Seconds to wait for stop before killing the container", + Value: defaultTimeout, + }, + } + stopDescription = "Stop one or more containers" + stopCommand = cli.Command{ + Name: "stop", + Usage: "Stops one or more running containers. The container name or ID can be used. A timeout to forcibly" + + " stop the container can also be set but defaults to 10 seconds otherwise.", + Description: stopDescription, + Flags: stopFlags, + Action: stopCmd, + ArgsUsage: "CONTAINER-NAME", + } +) + +func stopCmd(c *cli.Context) error { + args := c.Args() + stopTimeout := c.Int64("timeout") + if len(args) < 1 { + return errors.Errorf("you must provide at least one container name or id") + } + + config, err := getConfig(c) + if err != nil { + return errors.Wrapf(err, "could not get config") + } + server, err := libkpod.New(config) + if err != nil { + return errors.Wrapf(err, "could not get container server") + } + defer server.Shutdown() + err = server.Update() + if err != nil { + return errors.Wrapf(err, "could not update list of containers") + } + hadError := false + for _, container := range c.Args() { + cid, err := server.ContainerStop(container, stopTimeout) + if err != nil { + hadError = true + logrus.Error(err) + } else { + fmt.Println(cid) + } + } + + if hadError { + os.Exit(1) + } + return nil +} diff --git a/completions/bash/kpod b/completions/bash/kpod index 4a0327c5..07022bc9 100644 --- a/completions/bash/kpod +++ b/completions/bash/kpod @@ -366,6 +366,14 @@ _kpod_ps() { _complete_ "$options_with_args" "$boolean_options" } +_kpod_stop() { + local options_with_args=" + --timeout -t + " + local boolean_options="" + _complete_ "$options_with_args" "$boolean_options" +} + _complete_() { local options_with_args=$1 local boolean_options="$2 -h --help" @@ -424,6 +432,7 @@ _kpod_kpod() { rmi save stats + stop tag umount unmount diff --git a/docs/kpod-stop.1.md b/docs/kpod-stop.1.md new file mode 100644 index 00000000..52a35815 --- /dev/null +++ b/docs/kpod-stop.1.md @@ -0,0 +1,35 @@ +% kpod(1) kpod-stop - Stop one or more containers +% Brent Baude +# kpod-stop "1" "September 2017" "kpod" + +## NAME +kpod stop - Stop one or more containers + +## SYNOPSIS +**kpod stop [OPTIONS] CONTAINER [...]** + +## DESCRIPTION +Stops one or more containers. You may use container IDs or names as input. The **--timeout** switch +allows you to specify the number of seconds to wait before forcibly stopping the container after the stop command +is issued to the container. The default is 10 seconds. + +## OPTIONS + +**--timeout, t** + +Timeout to wait before forcibly stopping the container + + +## EXAMPLE + +kpod stop mywebserver + +kpod stop 860a4b23 + +kpod stop --timeout 2 860a4b23 + +## SEE ALSO +kpod(1), kpod-rm(1) + +## HISTORY +September 2018, Originally compiled by Brent Baude diff --git a/docs/kpod.1.md b/docs/kpod.1.md index 1e2fc412..2db4e29c 100644 --- a/docs/kpod.1.md +++ b/docs/kpod.1.md @@ -100,6 +100,9 @@ Save an image to docker-archive or oci ### stats Display a live stream of one or more containers' resource usage statistics +### stop +Stops one or more running containers. + ### tag Add an additional name to a local image diff --git a/test/kpod_stop.bats b/test/kpod_stop.bats new file mode 100644 index 00000000..4532ff51 --- /dev/null +++ b/test/kpod_stop.bats @@ -0,0 +1,51 @@ +#!/usr/bin/env bats + +load helpers + +ROOT="$TESTDIR/crio" +RUNROOT="$TESTDIR/crio-run" +KPOD_OPTIONS="--root $ROOT --runroot $RUNROOT --storage-driver vfs" +function teardown() { + cleanup_test +} + +@test "stop a bogus container" { + run ${KPOD_BINARY} ${KPOD_OPTIONS} stop foobar + echo "$output" + [ "$status" -eq 1 ] +} + +@test "stop a running container by id" { + start_crio + run crioctl pod run --config "$TESTDATA"/sandbox_config.json + echo "$output" + [ "$status" -eq 0 ] + pod_id="$output" + run crioctl ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id" + echo "$output" + [ "$status" -eq 0 ] + ctr_id="$output" + run crioctl ctr start --id "$ctr_id" + echo "$output" + id="$output" + run ${KPOD_BINARY} ${KPOD_OPTIONS} stop "$id" + cleanup_pods + stop_crio +} + +@test "stop a running container by name" { + start_crio + run crioctl pod run --config "$TESTDATA"/sandbox_config.json + echo "$output" + [ "$status" -eq 0 ] + pod_id="$output" + run crioctl ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id" + echo "$output" + [ "$status" -eq 0 ] + ctr_id="$output" + run crioctl ctr start --id "$ctr_id" + echo "$output" + run ${KPOD_BINARY} ${KPOD_OPTIONS} stop "k8s_podsandbox1-redis_podsandbox1_redhat.test.crio_redhat-test-crio_0" + cleanup_pods + stop_crio +}