From 2690461cbb3584fa0ebc1b5a1a71c429107d5725 Mon Sep 17 00:00:00 2001 From: Random-Liu Date: Wed, 8 Mar 2017 16:15:06 -0800 Subject: [PATCH] Stop sandbox container when hit network error. --- pkg/kubelet/dockershim/docker_sandbox.go | 7 ++- pkg/kubelet/dockershim/docker_sandbox_test.go | 46 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/pkg/kubelet/dockershim/docker_sandbox.go b/pkg/kubelet/dockershim/docker_sandbox.go index 7c5298d0b65..667ad59e038 100644 --- a/pkg/kubelet/dockershim/docker_sandbox.go +++ b/pkg/kubelet/dockershim/docker_sandbox.go @@ -105,7 +105,12 @@ func (ds *dockerService) RunPodSandbox(config *runtimeapi.PodSandboxConfig) (str // recognized by the CNI standard yet. cID := kubecontainer.BuildContainerID(runtimeName, createResp.ID) err = ds.network.SetUpPod(config.GetMetadata().Namespace, config.GetMetadata().Name, cID, config.Annotations) - // TODO: Do we need to teardown on failure or can we rely on a StopPodSandbox call with the given ID? + if err != nil { + // TODO(random-liu): Do we need to teardown network here? + if err := ds.client.StopContainer(createResp.ID, defaultSandboxGracePeriod); err != nil { + glog.Warningf("Failed to stop sandbox container %q for pod %q: %v", createResp.ID, config.Metadata.Name, err) + } + } return createResp.ID, err } diff --git a/pkg/kubelet/dockershim/docker_sandbox_test.go b/pkg/kubelet/dockershim/docker_sandbox_test.go index bd1cda1ce72..d68f5b0aa78 100644 --- a/pkg/kubelet/dockershim/docker_sandbox_test.go +++ b/pkg/kubelet/dockershim/docker_sandbox_test.go @@ -17,7 +17,9 @@ limitations under the License. package dockershim import ( + "errors" "fmt" + "net" "os" "testing" "time" @@ -203,3 +205,47 @@ func TestHostNetworkPluginInvocation(t *testing.T) { assert.NoError(t, err) assert.NoError(t, ds.StopPodSandbox(cID.ID)) } + +// TestSetUpPodFailure checks that the sandbox should be not ready when it +// hits a SetUpPod failure. +func TestSetUpPodFailure(t *testing.T) { + ds, _, _ := newTestDockerService() + mockPlugin := newTestNetworkPlugin(t) + ds.network = network.NewPluginManager(mockPlugin) + defer mockPlugin.Finish() + + name := "foo0" + ns := "bar0" + c := makeSandboxConfigWithLabelsAndAnnotations( + name, ns, "0", 0, + map[string]string{"label": name}, + map[string]string{"annotation": ns}, + ) + cID := kubecontainer.ContainerID{Type: runtimeName, ID: dockertools.GetFakeContainerID(fmt.Sprintf("/%v", makeSandboxName(c)))} + mockPlugin.EXPECT().Name().Return("mockNetworkPlugin").AnyTimes() + mockPlugin.EXPECT().SetUpPod(ns, name, cID).Return(errors.New("setup pod error")).AnyTimes() + // Assume network plugin doesn't return error, dockershim should still be able to return not ready correctly. + mockPlugin.EXPECT().GetPodNetworkStatus(ns, name, cID).Return(&network.PodNetworkStatus{IP: net.IP("127.0.0.01")}, nil).AnyTimes() + + t.Logf("RunPodSandbox should return error") + _, err := ds.RunPodSandbox(c) + assert.Error(t, err) + + t.Logf("PodSandboxStatus should be not ready") + status, err := ds.PodSandboxStatus(cID.ID) + assert.NoError(t, err) + assert.Equal(t, runtimeapi.PodSandboxState_SANDBOX_NOTREADY, status.State) + + t.Logf("ListPodSandbox should also show not ready") + sandboxes, err := ds.ListPodSandbox(nil) + assert.NoError(t, err) + var sandbox *runtimeapi.PodSandbox + for _, s := range sandboxes { + if s.Id == cID.ID { + sandbox = s + break + } + } + assert.NotNil(t, sandbox) + assert.Equal(t, runtimeapi.PodSandboxState_SANDBOX_NOTREADY, sandbox.State) +}