Send stop signal specified in image config.
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
parent
1a9d95244a
commit
7d5ea4401d
@ -20,12 +20,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/api/services/execution"
|
||||||
|
"github.com/docker/docker/pkg/signal"
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/containerd/containerd/api/services/execution"
|
|
||||||
|
|
||||||
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1"
|
runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1"
|
||||||
|
|
||||||
"github.com/kubernetes-incubator/cri-containerd/pkg/metadata"
|
"github.com/kubernetes-incubator/cri-containerd/pkg/metadata"
|
||||||
@ -76,10 +75,24 @@ func (c *criContainerdService) stopContainer(ctx context.Context, meta *metadata
|
|||||||
}
|
}
|
||||||
|
|
||||||
if timeout > 0 {
|
if timeout > 0 {
|
||||||
// TODO(random-liu): [P1] Get stop signal from image config.
|
|
||||||
stopSignal := unix.SIGTERM
|
stopSignal := unix.SIGTERM
|
||||||
|
imageMeta, err := c.imageMetadataStore.Get(meta.ImageRef)
|
||||||
|
if err != nil {
|
||||||
|
// NOTE(random-liu): It's possible that the container is stopped,
|
||||||
|
// deleted and image is garbage collected before this point. However,
|
||||||
|
// the chance is really slim, even it happens, it's still fine to return
|
||||||
|
// an error here.
|
||||||
|
return fmt.Errorf("failed to get image metadata %q: %v", meta.ImageRef, err)
|
||||||
|
}
|
||||||
|
if imageMeta.Config.StopSignal != "" {
|
||||||
|
stopSignal, err = signal.ParseSignal(imageMeta.Config.StopSignal)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse stop signal %q: %v",
|
||||||
|
imageMeta.Config.StopSignal, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
glog.V(2).Infof("Stop container %q with signal %v", id, stopSignal)
|
glog.V(2).Infof("Stop container %q with signal %v", id, stopSignal)
|
||||||
_, err := c.taskService.Kill(ctx, &execution.KillRequest{
|
_, err = c.taskService.Kill(ctx, &execution.KillRequest{
|
||||||
ContainerID: id,
|
ContainerID: id,
|
||||||
Signal: uint32(stopSignal),
|
Signal: uint32(stopSignal),
|
||||||
PidOrAll: &execution.KillRequest_All{All: true},
|
PidOrAll: &execution.KillRequest_All{All: true},
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/api/services/execution"
|
"github.com/containerd/containerd/api/services/execution"
|
||||||
"github.com/containerd/containerd/api/types/task"
|
"github.com/containerd/containerd/api/types/task"
|
||||||
|
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
@ -96,9 +97,14 @@ func TestStopContainer(t *testing.T) {
|
|||||||
testMetadata := metadata.ContainerMetadata{
|
testMetadata := metadata.ContainerMetadata{
|
||||||
ID: testID,
|
ID: testID,
|
||||||
Pid: testPid,
|
Pid: testPid,
|
||||||
|
ImageRef: "test-image-id",
|
||||||
CreatedAt: time.Now().UnixNano(),
|
CreatedAt: time.Now().UnixNano(),
|
||||||
StartedAt: time.Now().UnixNano(),
|
StartedAt: time.Now().UnixNano(),
|
||||||
}
|
}
|
||||||
|
testImageMetadata := metadata.ImageMetadata{
|
||||||
|
ID: "test-image-id",
|
||||||
|
Config: &imagespec.ImageConfig{},
|
||||||
|
}
|
||||||
testContainer := task.Task{
|
testContainer := task.Task{
|
||||||
ID: testID,
|
ID: testID,
|
||||||
Pid: testPid,
|
Pid: testPid,
|
||||||
@ -107,6 +113,7 @@ func TestStopContainer(t *testing.T) {
|
|||||||
for desc, test := range map[string]struct {
|
for desc, test := range map[string]struct {
|
||||||
metadata *metadata.ContainerMetadata
|
metadata *metadata.ContainerMetadata
|
||||||
containerdContainer *task.Task
|
containerdContainer *task.Task
|
||||||
|
stopSignal string
|
||||||
stopErr error
|
stopErr error
|
||||||
noTimeout bool
|
noTimeout bool
|
||||||
expectErr bool
|
expectErr bool
|
||||||
@ -222,6 +229,27 @@ func TestStopContainer(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"should use stop signal specified in image config if not empty": {
|
||||||
|
metadata: &testMetadata,
|
||||||
|
containerdContainer: &testContainer,
|
||||||
|
stopSignal: "SIGHUP",
|
||||||
|
expectErr: false,
|
||||||
|
// deleted by the event monitor.
|
||||||
|
expectCalls: []servertesting.CalledDetail{
|
||||||
|
{
|
||||||
|
Name: "kill",
|
||||||
|
Argument: &execution.KillRequest{
|
||||||
|
ContainerID: testID,
|
||||||
|
Signal: uint32(unix.SIGHUP),
|
||||||
|
PidOrAll: &execution.KillRequest_All{All: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "delete",
|
||||||
|
Argument: &execution.DeleteRequest{ContainerID: testID},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"should directly kill container if timeout is 0": {
|
"should directly kill container if timeout is 0": {
|
||||||
metadata: &testMetadata,
|
metadata: &testMetadata,
|
||||||
containerdContainer: &testContainer,
|
containerdContainer: &testContainer,
|
||||||
@ -259,6 +287,8 @@ func TestStopContainer(t *testing.T) {
|
|||||||
if test.containerdContainer != nil {
|
if test.containerdContainer != nil {
|
||||||
fake.SetFakeTasks([]task.Task{*test.containerdContainer})
|
fake.SetFakeTasks([]task.Task{*test.containerdContainer})
|
||||||
}
|
}
|
||||||
|
testImageMetadata.Config.StopSignal = test.stopSignal
|
||||||
|
assert.NoError(t, c.imageMetadataStore.Create(testImageMetadata))
|
||||||
if test.stopErr != nil {
|
if test.stopErr != nil {
|
||||||
fake.InjectError("kill", test.stopErr)
|
fake.InjectError("kill", test.stopErr)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user