From 067890ce209fb4b3de835c78c491cc6bbbbdd691 Mon Sep 17 00:00:00 2001 From: rajasec Date: Mon, 3 Aug 2015 16:12:20 +0530 Subject: [PATCH] container kill support Signed-off-by: rajasec --- README.md | 8 ++++++++ kill.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 1 + signal_linux.go | 43 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 kill.go create mode 100644 signal_linux.go diff --git a/README.md b/README.md index 4e83fe9d..6f6e719f 100644 --- a/README.md +++ b/README.md @@ -237,3 +237,11 @@ WorkingDirectory=/containers/minecraftbuild [Install] WantedBy=multi-user.target ``` +##Usage: +runc --id=runc kill +##Arguments can be signal number or signal name in string + +##Example +runc --id=runc kill TERM +runc --id=runc kill 15 +##if the shell is interactive, few signals can not be forwarded. /bin/sh can not forward the signal diff --git a/kill.go b/kill.go new file mode 100644 index 00000000..1141682d --- /dev/null +++ b/kill.go @@ -0,0 +1,53 @@ +// +build linux + +package main + +import ( + "fmt" + "github.com/codegangsta/cli" + "strconv" + "strings" + "syscall" +) + +var killCommand = cli.Command{ + Name: "kill", + Usage: "kill a container", + Action: func(context *cli.Context) { + container, err := getContainer(context) + if err != nil { + fatal(fmt.Errorf("%s", err)) + } + sigStr := context.Args().First() + state, err := container.Status() + if err != nil { + fatal(fmt.Errorf("Container not running %d", state)) + // return here + } + var sig uint64 + sigN, err := strconv.ParseUint(sigStr, 10, 5) + if err != nil { + //The signal is not a number, treat it as a string (either like + //KILL" or like "SIGKILL") + syscallSig, ok := SignalMap[strings.TrimPrefix(sigStr, "SIG")] + if !ok { + fatal(fmt.Errorf("Invalid Signal: %s", sigStr)) + } + sig = uint64(syscallSig) + errVal := container.Signal(syscall.Signal(sig)) + if errVal != nil { + fatal(fmt.Errorf("%s", errVal)) + } + } else { + sig = sigN + errVar := container.Signal(syscall.Signal(sig)) + if errVar != nil { + fatal(fmt.Errorf("%s", errVar)) + } + + } + if sig == 0 { + fatal(fmt.Errorf("Invalid signal: %s", sigStr)) + } + }, +} diff --git a/main.go b/main.go index bf431350..c05198d1 100644 --- a/main.go +++ b/main.go @@ -55,6 +55,7 @@ func main() { checkpointCommand, eventsCommand, restoreCommand, + killCommand, specCommand, } app.Before = func(context *cli.Context) error { diff --git a/signal_linux.go b/signal_linux.go new file mode 100644 index 00000000..81adb59e --- /dev/null +++ b/signal_linux.go @@ -0,0 +1,43 @@ +package main + +import ( + "syscall" +) + +var SignalMap = map[string]syscall.Signal{ + "ABRT": syscall.SIGABRT, + "ALRM": syscall.SIGALRM, + "BUS": syscall.SIGBUS, + "CHLD": syscall.SIGCHLD, + "CLD": syscall.SIGCLD, + "CONT": syscall.SIGCONT, + "FPE": syscall.SIGFPE, + "HUP": syscall.SIGHUP, + "ILL": syscall.SIGILL, + "INT": syscall.SIGINT, + "IO": syscall.SIGIO, + "IOT": syscall.SIGIOT, + "KILL": syscall.SIGKILL, + "PIPE": syscall.SIGPIPE, + "POLL": syscall.SIGPOLL, + "PROF": syscall.SIGPROF, + "PWR": syscall.SIGPWR, + "QUIT": syscall.SIGQUIT, + "SEGV": syscall.SIGSEGV, + "STKFLT": syscall.SIGSTKFLT, + "STOP": syscall.SIGSTOP, + "SYS": syscall.SIGSYS, + "TERM": syscall.SIGTERM, + "TRAP": syscall.SIGTRAP, + "TSTP": syscall.SIGTSTP, + "TTIN": syscall.SIGTTIN, + "TTOU": syscall.SIGTTOU, + "UNUSED": syscall.SIGUNUSED, + "URG": syscall.SIGURG, + "USR1": syscall.SIGUSR1, + "USR2": syscall.SIGUSR2, + "VTALRM": syscall.SIGVTALRM, + "WINCH": syscall.SIGWINCH, + "XCPU": syscall.SIGXCPU, + "XFSZ": syscall.SIGXFSZ, +}