cli: Stop the sandbox on a KILL

The same way a caller of "kata-runtime kill 12345" expects
the container 12345 to be killed, the same call to a container
representing a sandbox should actually kill the sandbox, meaning
it would be stopped after the container has been killed.

This way, the caller knows the VM is stopped after kill returns.
This is an issue raised by Openshift and Kubernetes tests. They
call into delete way after the call to kill has been submitted,
and in the meantime they kill all processes related to the container,
meaning they do kill the VM before we could do it ourselves. In this
case, the delete responsible of stopping the VM comes too late and it
returns an error when trying to destroy the sandbox while trying to
communicate with the agent since the VM is not here anymore.

This commit addresses this issue by letting "kill" call into
StopSandbox() if the command relates to a sandbox instead of
a simple container.

Fixes #246

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2018-04-25 09:07:34 -07:00
parent 163a081776
commit 07af4edea9
2 changed files with 85 additions and 4 deletions

View File

@ -12,6 +12,7 @@ import (
"syscall"
vc "github.com/kata-containers/runtime/virtcontainers"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/urfave/cli"
)
@ -115,7 +116,20 @@ func kill(containerID, signal string, all bool) error {
return nil
}
_, err = vci.StopContainer(sandboxID, containerID)
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
}

View File

@ -12,6 +12,7 @@ import (
"testing"
vc "github.com/kata-containers/runtime/virtcontainers"
vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations"
"github.com/kata-containers/runtime/virtcontainers/pkg/vcmock"
"github.com/stretchr/testify/assert"
)
@ -24,6 +25,10 @@ var (
testStopContainerFuncReturnNil = func(sandboxID, containerID string) (vc.VCContainer, error) {
return &vcmock.Container{}, nil
}
testStopSandboxFuncReturnNil = func(sandboxID string) (vc.VCSandbox, error) {
return &vcmock.Sandbox{}, nil
}
)
func TestProcessSignal(t *testing.T) {
@ -61,13 +66,18 @@ func testKillCLIFunctionTerminationSignalSuccessful(t *testing.T, sig string) {
State: vc.StateRunning,
}
annotations := map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
}
testingImpl.KillContainerFunc = testKillContainerFuncReturnNil
testingImpl.StopContainerFunc = testStopContainerFuncReturnNil
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return newSingleContainerSandboxStatusList(testSandboxID, testContainerID, state, state, map[string]string{}), nil
return newSingleContainerSandboxStatusList(testSandboxID, testContainerID, state, state, annotations), nil
}
defer func() {
testingImpl.KillContainerFunc = nil
testingImpl.StopContainerFunc = nil
testingImpl.ListSandboxFunc = nil
}()
@ -75,6 +85,21 @@ func testKillCLIFunctionTerminationSignalSuccessful(t *testing.T, sig string) {
set.Parse([]string{testContainerID, sig})
execCLICommandFunc(assert, killCLICommand, set, false)
annotations = map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodSandbox),
}
testingImpl.StopContainerFunc = nil
testingImpl.StopSandboxFunc = testStopSandboxFuncReturnNil
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return newSingleContainerSandboxStatusList(testSandboxID, testContainerID, state, state, annotations), nil
}
defer func() {
testingImpl.StopSandboxFunc = nil
}()
execCLICommandFunc(assert, killCLICommand, set, false)
}
func TestKillCLIFunctionSigkillSuccessful(t *testing.T) {
@ -114,12 +139,18 @@ func TestKillCLIFunctionNoSignalSuccessful(t *testing.T) {
State: vc.StateRunning,
}
annotations := map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
}
testingImpl.KillContainerFunc = testKillContainerFuncReturnNil
testingImpl.StopContainerFunc = testStopContainerFuncReturnNil
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return newSingleContainerSandboxStatusList(testSandboxID, testContainerID, state, state, map[string]string{}), nil
return newSingleContainerSandboxStatusList(testSandboxID, testContainerID, state, state, annotations), nil
}
defer func() {
testingImpl.KillContainerFunc = nil
testingImpl.StopContainerFunc = nil
testingImpl.ListSandboxFunc = nil
}()
@ -127,6 +158,21 @@ func TestKillCLIFunctionNoSignalSuccessful(t *testing.T) {
set.Parse([]string{testContainerID})
execCLICommandFunc(assert, killCLICommand, set, false)
annotations = map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodSandbox),
}
testingImpl.StopContainerFunc = nil
testingImpl.StopSandboxFunc = testStopSandboxFuncReturnNil
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return newSingleContainerSandboxStatusList(testSandboxID, testContainerID, state, state, annotations), nil
}
defer func() {
testingImpl.StopSandboxFunc = nil
}()
execCLICommandFunc(assert, killCLICommand, set, false)
}
func TestKillCLIFunctionEnableAllSuccessful(t *testing.T) {
@ -136,6 +182,10 @@ func TestKillCLIFunctionEnableAllSuccessful(t *testing.T) {
State: vc.StateRunning,
}
annotations := map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
}
testingImpl.KillContainerFunc = func(sandboxID, containerID string, signal syscall.Signal, all bool) error {
if !all {
return fmt.Errorf("Expecting -all flag = true, Got false")
@ -143,11 +193,13 @@ func TestKillCLIFunctionEnableAllSuccessful(t *testing.T) {
return nil
}
testingImpl.StopContainerFunc = testStopContainerFuncReturnNil
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return newSingleContainerSandboxStatusList(testSandboxID, testContainerID, state, state, map[string]string{}), nil
return newSingleContainerSandboxStatusList(testSandboxID, testContainerID, state, state, annotations), nil
}
defer func() {
testingImpl.KillContainerFunc = nil
testingImpl.StopContainerFunc = nil
testingImpl.ListSandboxFunc = nil
}()
@ -156,6 +208,21 @@ func TestKillCLIFunctionEnableAllSuccessful(t *testing.T) {
set.Parse([]string{testContainerID})
execCLICommandFunc(assert, killCLICommand, set, false)
annotations = map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodSandbox),
}
testingImpl.StopContainerFunc = nil
testingImpl.StopSandboxFunc = testStopSandboxFuncReturnNil
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return newSingleContainerSandboxStatusList(testSandboxID, testContainerID, state, state, annotations), nil
}
defer func() {
testingImpl.StopSandboxFunc = nil
}()
execCLICommandFunc(assert, killCLICommand, set, false)
}
func TestKillCLIFunctionNoContainerIDFailure(t *testing.T) {