mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-10-22 04:18:53 +00:00
Once `containerID` and `sandboxID` fields are available, re-register the logger with the external packages to ensure they too display these important fields. Fixes #467. Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
173 lines
4.2 KiB
Go
173 lines
4.2 KiB
Go
// Copyright (c) 2014,2015,2016 Docker, Inc.
|
|
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"syscall"
|
|
|
|
vc "github.com/kata-containers/runtime/virtcontainers"
|
|
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
var killCLICommand = cli.Command{
|
|
Name: "kill",
|
|
Usage: "Kill sends signals to the container's init process",
|
|
ArgsUsage: `<container-id> [signal]
|
|
|
|
<container-id> is the name for the instance of the container
|
|
[signal] is the signal to be sent to the init process (default: SIGTERM)
|
|
|
|
EXAMPLE:
|
|
If the container id is "ubuntu01" the following will send a "KILL" signal
|
|
to the init process of the "ubuntu01" container:
|
|
|
|
# ` + name + ` kill ubuntu01 KILL`,
|
|
Flags: []cli.Flag{
|
|
cli.BoolFlag{
|
|
Name: "all, a",
|
|
Usage: "send the specified signal to all processes inside the container",
|
|
},
|
|
},
|
|
Action: func(context *cli.Context) error {
|
|
args := context.Args()
|
|
if args.Present() == false {
|
|
return fmt.Errorf("Missing container ID")
|
|
}
|
|
|
|
// If signal is provided, it has to be the second argument.
|
|
signal := args.Get(1)
|
|
if signal == "" {
|
|
signal = "SIGTERM"
|
|
}
|
|
|
|
return kill(args.First(), signal, context.Bool("all"))
|
|
},
|
|
}
|
|
|
|
var signals = map[string]syscall.Signal{
|
|
"SIGABRT": syscall.SIGABRT,
|
|
"SIGALRM": syscall.SIGALRM,
|
|
"SIGBUS": syscall.SIGBUS,
|
|
"SIGCHLD": syscall.SIGCHLD,
|
|
"SIGCLD": syscall.SIGCLD,
|
|
"SIGCONT": syscall.SIGCONT,
|
|
"SIGFPE": syscall.SIGFPE,
|
|
"SIGHUP": syscall.SIGHUP,
|
|
"SIGILL": syscall.SIGILL,
|
|
"SIGINT": syscall.SIGINT,
|
|
"SIGIO": syscall.SIGIO,
|
|
"SIGIOT": syscall.SIGIOT,
|
|
"SIGKILL": syscall.SIGKILL,
|
|
"SIGPIPE": syscall.SIGPIPE,
|
|
"SIGPOLL": syscall.SIGPOLL,
|
|
"SIGPROF": syscall.SIGPROF,
|
|
"SIGPWR": syscall.SIGPWR,
|
|
"SIGQUIT": syscall.SIGQUIT,
|
|
"SIGSEGV": syscall.SIGSEGV,
|
|
"SIGSTKFLT": syscall.SIGSTKFLT,
|
|
"SIGSTOP": syscall.SIGSTOP,
|
|
"SIGSYS": syscall.SIGSYS,
|
|
"SIGTERM": syscall.SIGTERM,
|
|
"SIGTRAP": syscall.SIGTRAP,
|
|
"SIGTSTP": syscall.SIGTSTP,
|
|
"SIGTTIN": syscall.SIGTTIN,
|
|
"SIGTTOU": syscall.SIGTTOU,
|
|
"SIGUNUSED": syscall.SIGUNUSED,
|
|
"SIGURG": syscall.SIGURG,
|
|
"SIGUSR1": syscall.SIGUSR1,
|
|
"SIGUSR2": syscall.SIGUSR2,
|
|
"SIGVTALRM": syscall.SIGVTALRM,
|
|
"SIGWINCH": syscall.SIGWINCH,
|
|
"SIGXCPU": syscall.SIGXCPU,
|
|
"SIGXFSZ": syscall.SIGXFSZ,
|
|
}
|
|
|
|
func kill(containerID, signal string, all bool) error {
|
|
// Checks the MUST and MUST NOT from OCI runtime specification
|
|
status, sandboxID, err := getExistingContainerInfo(containerID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
containerID = status.ID
|
|
|
|
kataLog = kataLog.WithFields(logrus.Fields{
|
|
"container": containerID,
|
|
"sandbox": sandboxID,
|
|
})
|
|
|
|
setExternalLoggers(kataLog)
|
|
|
|
signum, err := processSignal(signal)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// container MUST be created, running or paused
|
|
if status.State.State != vc.StateReady && status.State.State != vc.StateRunning && status.State.State != vc.StatePaused {
|
|
return fmt.Errorf("Container %s not ready, running or paused, cannot send a signal", containerID)
|
|
}
|
|
|
|
if err := vci.KillContainer(sandboxID, containerID, signum, all); err != nil {
|
|
return err
|
|
}
|
|
|
|
if signum != syscall.SIGKILL && signum != syscall.SIGTERM {
|
|
return nil
|
|
}
|
|
|
|
containerType, err := oci.GetContainerType(status.Annotations)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
switch containerType {
|
|
case vc.PodSandbox:
|
|
_, err = vci.StopSandbox(sandboxID)
|
|
case vc.PodContainer:
|
|
_, err = vci.StopContainer(sandboxID, containerID)
|
|
default:
|
|
return fmt.Errorf("Invalid container type found")
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
func processSignal(signal string) (syscall.Signal, error) {
|
|
signum, signalOk := signals[signal]
|
|
if signalOk {
|
|
return signum, nil
|
|
}
|
|
|
|
// Support for short name signals (INT)
|
|
signum, signalOk = signals["SIG"+signal]
|
|
if signalOk {
|
|
return signum, nil
|
|
}
|
|
|
|
// Support for numeric signals
|
|
s, err := strconv.Atoi(signal)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("Failed to convert signal %s to int", signal)
|
|
}
|
|
|
|
signum = syscall.Signal(s)
|
|
// Check whether signal is valid or not
|
|
for _, sig := range signals {
|
|
if sig == signum {
|
|
// signal is a valid signal
|
|
return signum, nil
|
|
}
|
|
}
|
|
|
|
return 0, fmt.Errorf("Signal %s is not supported", signal)
|
|
}
|