commit
a40aa7ad54
10 changed files with 322 additions and 0 deletions
|
@ -48,6 +48,7 @@ It is currently in active development in the Kubernetes community through the [d
|
||||||
| [kpod-images(1)](/docs/kpod-images.1.md) | List images in local storage |[![...](/docs/play.png)](https://asciinema.org/a/133649)|
|
| [kpod-images(1)](/docs/kpod-images.1.md) | List images in local storage |[![...](/docs/play.png)](https://asciinema.org/a/133649)|
|
||||||
| [kpod-info(1)](/docs/kpod-info.1.md) | Display system information ||
|
| [kpod-info(1)](/docs/kpod-info.1.md) | Display system information ||
|
||||||
| [kpod-inspect(1)](/docs/kpod-inspect.1.md) | Display the configuration of a container or image |[![...](/docs/play.png)](https://asciinema.org/a/133418)|
|
| [kpod-inspect(1)](/docs/kpod-inspect.1.md) | Display the configuration of a container or image |[![...](/docs/play.png)](https://asciinema.org/a/133418)|
|
||||||
|
| [kpod-kill(1)](/docs/kpod-kill.1.md) | Kill the main process in one or more running containers
|
||||||
| [kpod-load(1)](/docs/kpod-load.1.md) | Load an image from docker archive or oci |[![...](/docs/play.png)](https://asciinema.org/a/kp8kOaexEhEa20P1KLZ3L5X4g)|
|
| [kpod-load(1)](/docs/kpod-load.1.md) | Load an image from docker archive or oci |[![...](/docs/play.png)](https://asciinema.org/a/kp8kOaexEhEa20P1KLZ3L5X4g)|
|
||||||
| [kpod-logs(1)](/docs/kpod-logs.1.md) | Display the logs of a container ||
|
| [kpod-logs(1)](/docs/kpod-logs.1.md) | Display the logs of a container ||
|
||||||
| [kpod-mount(1)](/docs/kpod-mount.1.md) | Mount a working container's root filesystem ||
|
| [kpod-mount(1)](/docs/kpod-mount.1.md) | Mount a working container's root filesystem ||
|
||||||
|
|
71
cmd/kpod/kill.go
Normal file
71
cmd/kpod/kill.go
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/signal"
|
||||||
|
"github.com/kubernetes-incubator/cri-o/libkpod"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
killFlags = []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "signal, s",
|
||||||
|
Usage: "Signal to send to the container",
|
||||||
|
Value: "KILL",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
killDescription = "The main process inside each container specified will be sent SIGKILL, or any signal specified with option --signal."
|
||||||
|
killCommand = cli.Command{
|
||||||
|
Name: "kill",
|
||||||
|
Usage: "Kill one or more running containers with a specific signal",
|
||||||
|
Description: killDescription,
|
||||||
|
Flags: killFlags,
|
||||||
|
Action: killCmd,
|
||||||
|
ArgsUsage: "[CONTAINER_NAME_OR_ID]",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// killCmd kills one or more containers with a signal
|
||||||
|
func killCmd(c *cli.Context) error {
|
||||||
|
args := c.Args()
|
||||||
|
if len(args) == 0 {
|
||||||
|
return errors.Errorf("specify one or more containers to kill")
|
||||||
|
}
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
killSignal := c.String("signal")
|
||||||
|
// Check if the signalString provided by the user is valid
|
||||||
|
// Invalid signals will return err
|
||||||
|
sysSignal, err := signal.ParseSignal(killSignal)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer server.Shutdown()
|
||||||
|
err = server.Update()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "could not update list of containers")
|
||||||
|
}
|
||||||
|
var lastError error
|
||||||
|
for _, container := range c.Args() {
|
||||||
|
id, err := server.ContainerKill(container, sysSignal)
|
||||||
|
if err != nil {
|
||||||
|
if lastError != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, lastError)
|
||||||
|
}
|
||||||
|
lastError = errors.Wrapf(err, "unable to kill %v", container)
|
||||||
|
} else {
|
||||||
|
fmt.Println(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastError
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ func main() {
|
||||||
imagesCommand,
|
imagesCommand,
|
||||||
infoCommand,
|
infoCommand,
|
||||||
inspectCommand,
|
inspectCommand,
|
||||||
|
killCommand,
|
||||||
loadCommand,
|
loadCommand,
|
||||||
logsCommand,
|
logsCommand,
|
||||||
mountCommand,
|
mountCommand,
|
||||||
|
|
|
@ -137,6 +137,15 @@ _kpod_inspect() {
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
_kpod_kill() {
|
||||||
|
local options_with_args="
|
||||||
|
--signal -s
|
||||||
|
"
|
||||||
|
local boolean_options="
|
||||||
|
--help
|
||||||
|
-h"
|
||||||
|
_complete_ "$options_with_args" "$boolean_options"
|
||||||
|
}
|
||||||
|
|
||||||
_kpod_logs() {
|
_kpod_logs() {
|
||||||
local options_with_args="
|
local options_with_args="
|
||||||
|
@ -442,6 +451,7 @@ _kpod_kpod() {
|
||||||
images
|
images
|
||||||
info
|
info
|
||||||
inspect
|
inspect
|
||||||
|
kill
|
||||||
load
|
load
|
||||||
logs
|
logs
|
||||||
mount
|
mount
|
||||||
|
|
33
docs/kpod-kill.1.md
Normal file
33
docs/kpod-kill.1.md
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
% kpod(1) kpod-kill- Kill one or more containers with a signal
|
||||||
|
% Brent Baude
|
||||||
|
# kpod-kill"1" "September 2017" "kpod"
|
||||||
|
|
||||||
|
## NAME
|
||||||
|
kpod kill - Kills one or more containers with a signal
|
||||||
|
|
||||||
|
## SYNOPSIS
|
||||||
|
**kpod kill [OPTIONS] CONTAINER [...]**
|
||||||
|
|
||||||
|
## DESCRIPTION
|
||||||
|
The main process inside each container specified will be sent SIGKILL, or any signal specified with option --signal.
|
||||||
|
|
||||||
|
## OPTIONS
|
||||||
|
|
||||||
|
**--signal, s**
|
||||||
|
|
||||||
|
Signal to send to the container. For more information on Linux signals, refer to *man signal(7)*.
|
||||||
|
|
||||||
|
|
||||||
|
## EXAMPLE
|
||||||
|
|
||||||
|
kpod kill mywebserver
|
||||||
|
|
||||||
|
kpod kill 860a4b23
|
||||||
|
|
||||||
|
kpod kill --signal TERM 860a4b23
|
||||||
|
|
||||||
|
## SEE ALSO
|
||||||
|
kpod(1), kpod-stop(1)
|
||||||
|
|
||||||
|
## HISTORY
|
||||||
|
September 2017, Originally compiled by Brent Baude <bbaude@redhat.com>
|
|
@ -67,6 +67,9 @@ Displays system information
|
||||||
### inspect
|
### inspect
|
||||||
Display a container or image's configuration
|
Display a container or image's configuration
|
||||||
|
|
||||||
|
### kill
|
||||||
|
Kill the main process in one or more containers
|
||||||
|
|
||||||
### load
|
### load
|
||||||
Load an image from docker archive
|
Load an image from docker archive
|
||||||
|
|
||||||
|
|
45
libkpod/kill.go
Normal file
45
libkpod/kill.go
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package libkpod
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/docker/docker/pkg/signal"
|
||||||
|
"github.com/kubernetes-incubator/cri-o/oci"
|
||||||
|
"github.com/kubernetes-incubator/cri-o/utils"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reverse lookup signal string from its map
|
||||||
|
func findStringInSignalMap(killSignal syscall.Signal) (string, error) {
|
||||||
|
for k, v := range signal.SignalMap {
|
||||||
|
if v == killSignal {
|
||||||
|
return k, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", errors.Errorf("unable to convert signal to string")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerKill sends the user provided signal to the containers primary process.
|
||||||
|
func (c *ContainerServer) ContainerKill(container string, killSignal syscall.Signal) (string, error) { // nolint
|
||||||
|
ctr, err := c.LookupContainer(container)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrapf(err, "failed to find container %s", container)
|
||||||
|
}
|
||||||
|
c.runtime.UpdateStatus(ctr)
|
||||||
|
cStatus := c.runtime.ContainerStatus(ctr)
|
||||||
|
|
||||||
|
// If the container is not running, error and move on.
|
||||||
|
if cStatus.Status != oci.ContainerStateRunning {
|
||||||
|
return "", errors.Errorf("cannot kill container %s: it is not running", container)
|
||||||
|
}
|
||||||
|
signalString, err := findStringInSignalMap(killSignal)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err := utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, c.runtime.Path(ctr), "kill", ctr.ID(), signalString); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
c.ContainerStateToDisk(ctr)
|
||||||
|
return ctr.ID(), nil
|
||||||
|
}
|
86
test/kpod_kill.bats
Normal file
86
test/kpod_kill.bats
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
load helpers
|
||||||
|
|
||||||
|
ROOT="$TESTDIR/crio"
|
||||||
|
RUNROOT="$TESTDIR/crio-run"
|
||||||
|
KPOD_OPTIONS="--root $ROOT --runroot $RUNROOT ${STORAGE_OPTS} --runtime $RUNTIME_BINARY"
|
||||||
|
function teardown() {
|
||||||
|
cleanup_test
|
||||||
|
}
|
||||||
|
|
||||||
|
function start_sleep_container () {
|
||||||
|
pod_id=$(crioctl pod run --config "$TESTDATA"/sandbox_config.json)
|
||||||
|
ctr_id=$(crioctl ctr create --config "$TESTDATA"/container_config_sleep.json --pod "$pod_id")
|
||||||
|
crioctl ctr start --id "$ctr_id"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "kill a bogus container" {
|
||||||
|
run ${KPOD_BINARY} ${KPOD_OPTIONS} kill foobar
|
||||||
|
echo "$output"
|
||||||
|
[ "$status" -ne 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "kill a running container by id" {
|
||||||
|
start_crio
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} pull docker.io/library/busybox:latest
|
||||||
|
ctr_id=$( start_sleep_container )
|
||||||
|
crioctl ctr status --id "$ctr_id"
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} ps -a
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} logs "$ctr_id"
|
||||||
|
crioctl ctr status --id "$ctr_id"
|
||||||
|
run ${KPOD_BINARY} ${KPOD_OPTIONS} kill "$ctr_id"
|
||||||
|
echo "$output"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
cleanup_ctrs
|
||||||
|
cleanup_pods
|
||||||
|
stop_crio
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "kill a running container by id with TERM" {
|
||||||
|
start_crio
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} pull docker.io/library/busybox:latest
|
||||||
|
ctr_id=$( start_sleep_container )
|
||||||
|
crioctl ctr status --id "$ctr_id"
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} ps -a
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} logs "$ctr_id"
|
||||||
|
crioctl ctr status --id "$ctr_id"
|
||||||
|
run ${KPOD_BINARY} ${KPOD_OPTIONS} kill -s TERM "$ctr_id"
|
||||||
|
echo "$output"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
cleanup_ctrs
|
||||||
|
cleanup_pods
|
||||||
|
stop_crio
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "kill a running container by name" {
|
||||||
|
start_crio
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} pull docker.io/library/busybox:latest
|
||||||
|
ctr_id=$( start_sleep_container )
|
||||||
|
crioctl ctr status --id "$ctr_id"
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} ps -a
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} logs "$ctr_id"
|
||||||
|
crioctl ctr status --id "$ctr_id"
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} ps -a
|
||||||
|
run ${KPOD_BINARY} ${KPOD_OPTIONS} kill "k8s_container999_podsandbox1_redhat.test.crio_redhat-test-crio_1"
|
||||||
|
echo "$output"
|
||||||
|
[ "$status" -eq 0 ]
|
||||||
|
cleanup_ctrs
|
||||||
|
cleanup_pods
|
||||||
|
stop_crio
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "kill a running container by id with a bogus signal" {
|
||||||
|
start_crio
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} pull docker.io/library/busybox:latest
|
||||||
|
ctr_id=$( start_sleep_container )
|
||||||
|
crioctl ctr status --id "$ctr_id"
|
||||||
|
${KPOD_BINARY} ${KPOD_OPTIONS} logs "$ctr_id"
|
||||||
|
crioctl ctr status --id "$ctr_id"
|
||||||
|
run ${KPOD_BINARY} ${KPOD_OPTIONS} kill -s foobar "$ctr_id"
|
||||||
|
echo "$output"
|
||||||
|
[ "$status" -ne 0 ]
|
||||||
|
cleanup_ctrs
|
||||||
|
cleanup_pods
|
||||||
|
stop_crio
|
||||||
|
}
|
71
test/testdata/container_config_sleep.json
vendored
Normal file
71
test/testdata/container_config_sleep.json
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
{
|
||||||
|
"metadata": {
|
||||||
|
"name": "container999",
|
||||||
|
"attempt": 1
|
||||||
|
},
|
||||||
|
"image": {
|
||||||
|
"image": "docker.io/library/busybox:latest"
|
||||||
|
},
|
||||||
|
"command": [
|
||||||
|
"sleep",
|
||||||
|
"9999"
|
||||||
|
],
|
||||||
|
"args": [],
|
||||||
|
"working_dir": "/",
|
||||||
|
"envs": [
|
||||||
|
{
|
||||||
|
"key": "PATH",
|
||||||
|
"value": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TERM",
|
||||||
|
"value": "xterm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TESTDIR",
|
||||||
|
"value": "test/dir1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "TESTFILE",
|
||||||
|
"value": "test/file1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"labels": {
|
||||||
|
"type": "small",
|
||||||
|
"batch": "no"
|
||||||
|
},
|
||||||
|
"annotations": {
|
||||||
|
"owner": "dragon",
|
||||||
|
"daemon": "crio"
|
||||||
|
},
|
||||||
|
"privileged": true,
|
||||||
|
"log_path": "",
|
||||||
|
"stdin": false,
|
||||||
|
"stdin_once": false,
|
||||||
|
"tty": false,
|
||||||
|
"linux": {
|
||||||
|
"resources": {
|
||||||
|
"cpu_period": 10000,
|
||||||
|
"cpu_quota": 20000,
|
||||||
|
"cpu_shares": 512,
|
||||||
|
"oom_score_adj": 30
|
||||||
|
},
|
||||||
|
"security_context": {
|
||||||
|
"readonly_rootfs": false,
|
||||||
|
"selinux_options": {
|
||||||
|
"user": "system_u",
|
||||||
|
"role": "system_r",
|
||||||
|
"type": "svirt_lxc_net_t",
|
||||||
|
"level": "s0:c4,c5"
|
||||||
|
},
|
||||||
|
"capabilities": {
|
||||||
|
"add_capabilities": [
|
||||||
|
"setuid",
|
||||||
|
"setgid"
|
||||||
|
],
|
||||||
|
"drop_capabilities": [
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ There are other equivalents for these tools
|
||||||
| `docker export` | [`kpod export`](./docs/kpod-export.1.md) |
|
| `docker export` | [`kpod export`](./docs/kpod-export.1.md) |
|
||||||
| `docker history`| [`kpod history`](./docs/kpod-history.1.md)|
|
| `docker history`| [`kpod history`](./docs/kpod-history.1.md)|
|
||||||
| `docker images` | [`kpod images`](./docs/kpod-images.1.md) |
|
| `docker images` | [`kpod images`](./docs/kpod-images.1.md) |
|
||||||
|
| `docker kill` | [`kpod kill`](./docs/kpod-kill.1.md) |
|
||||||
| `docker load` | [`kpod load`](./docs/kpod-load.1.md) |
|
| `docker load` | [`kpod load`](./docs/kpod-load.1.md) |
|
||||||
| `docker pause` | [`kpod pause`](./docs/kpod-pause.1.md) |
|
| `docker pause` | [`kpod pause`](./docs/kpod-pause.1.md) |
|
||||||
| `docker ps` | [`kpod ps`](./docs/kpod-ps.1.md) |
|
| `docker ps` | [`kpod ps`](./docs/kpod-ps.1.md) |
|
||||||
|
|
Loading…
Reference in a new issue