package main import ( gocontext "context" "fmt" "strconv" "strings" "syscall" "github.com/containerd/containerd/api/services/execution" "github.com/pkg/errors" "github.com/urfave/cli" ) 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, } var killCommand = cli.Command{ Name: "kill", Usage: "signal a container", Flags: []cli.Flag{ cli.StringFlag{ Name: "id", Usage: "id of the container", }, cli.BoolFlag{ Name: "all, a", Usage: "send signal to all processes inside the container", }, }, Action: func(context *cli.Context) error { id := context.String("id") if id == "" { return errors.New("container id must be provided") } sigstr := context.Args().First() if sigstr == "" { sigstr = "SIGTERM" } signal, err := parseSignal(sigstr) if err != nil { return err } containers, err := getExecutionService(context) if err != nil { return err } killRequest := &execution.KillRequest{ ID: id, Signal: uint32(signal), All: context.Bool("all"), } _, err = containers.Kill(gocontext.Background(), killRequest) if err != nil { return err } return nil }, } func parseSignal(rawSignal string) (syscall.Signal, error) { s, err := strconv.Atoi(rawSignal) if err == nil { sig := syscall.Signal(s) for _, msig := range signalMap { if sig == msig { return sig, nil } } return -1, fmt.Errorf("unknown signal %q", rawSignal) } signal, ok := signalMap[strings.TrimPrefix(strings.ToUpper(rawSignal), "SIG")] if !ok { return -1, fmt.Errorf("unknown signal %q", rawSignal) } return signal, nil }