mirror of
https://github.com/aljazceru/kata-containers.git
synced 2025-12-22 16:54:25 +01:00
Instead of pausing the sanbox, this patch just pauses the container allowing the communication with the agent. The communication with the agent should be still possible even if all containers are paused, because of we don't know when a new container can be created in the same sandbox. Depends-on: github.com/kata-containers/agent#246 fixes #317 Signed-off-by: Julio Montes <julio.montes@intel.com>
165 lines
4.1 KiB
Go
165 lines
4.1 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/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
|
|
|
|
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)
|
|
}
|