ctr: make kill use stop-signal by default

The OCI image specification includes a `StopSignal` field in the image
configuration, denoting the system call signal to be sent to the
container to exit.  This commit adds a new `WithImageStopSignal` container
option that can be used for storing the `StopSignal` field as a label on
the container.  This commit also adjusts `ctr run` to call
`WithImageStopSignal` and `ctr tasks kill` to send the signal stored in
that label by default.

Signed-off-by: Samuel Karp <skarp@amazon.com>
This commit is contained in:
Samuel Karp
2018-09-27 14:56:34 -07:00
parent b392a3a8e4
commit 607888ce29
4 changed files with 97 additions and 5 deletions

View File

@@ -17,12 +17,73 @@
package containerd
import (
"context"
"encoding/json"
"fmt"
"strconv"
"strings"
"syscall"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/images"
"github.com/opencontainers/image-spec/specs-go/v1"
)
// StopSignalLabel is a well-known containerd label for storing the stop
// signal specified in the OCI image config
const StopSignalLabel = "io.containerd.image.config.stop-signal"
// GetStopSignal retrieves the container stop signal, specified by the
// well-known containerd label (StopSignalLabel)
func GetStopSignal(ctx context.Context, container Container, defaultSignal syscall.Signal) (syscall.Signal, error) {
labels, err := container.Labels(ctx)
if err != nil {
return -1, err
}
if stopSignal, ok := labels[StopSignalLabel]; ok {
return ParseSignal(stopSignal)
}
return defaultSignal, nil
}
// GetOCIStopSignal retrieves the stop signal specified in the OCI image config
func GetOCIStopSignal(ctx context.Context, image Image, defaultSignal string) (string, error) {
_, err := ParseSignal(defaultSignal)
if err != nil {
return "", err
}
ic, err := image.Config(ctx)
if err != nil {
return "", err
}
var (
ociimage v1.Image
config v1.ImageConfig
)
switch ic.MediaType {
case v1.MediaTypeImageConfig, images.MediaTypeDockerSchema2Config:
p, err := content.ReadBlob(ctx, image.ContentStore(), ic)
if err != nil {
return "", err
}
if err := json.Unmarshal(p, &ociimage); err != nil {
return "", err
}
config = ociimage.Config
default:
return "", fmt.Errorf("unknown image config media type %s", ic.MediaType)
}
if config.StopSignal == "" {
return defaultSignal, nil
}
return config.StopSignal, nil
}
// ParseSignal parses a given string into a syscall.Signal
// it checks that the signal exists in the platform-appropriate signalMap
func ParseSignal(rawSignal string) (syscall.Signal, error) {