diff --git a/pkg/kubelet/status/status_manager.go b/pkg/kubelet/status/status_manager.go index 70381df836a..9c93a746b58 100644 --- a/pkg/kubelet/status/status_manager.go +++ b/pkg/kubelet/status/status_manager.go @@ -334,7 +334,7 @@ func (m *manager) TerminatePod(pod *v1.Pod) { } status := *oldStatus.DeepCopy() for i := range status.ContainerStatuses { - if status.ContainerStatuses[i].State.Terminated != nil || status.ContainerStatuses[i].State.Waiting != nil { + if status.ContainerStatuses[i].State.Terminated != nil { continue } status.ContainerStatuses[i].State = v1.ContainerState{ @@ -346,7 +346,7 @@ func (m *manager) TerminatePod(pod *v1.Pod) { } } for i := range status.InitContainerStatuses { - if status.InitContainerStatuses[i].State.Terminated != nil || status.InitContainerStatuses[i].State.Waiting != nil { + if status.InitContainerStatuses[i].State.Terminated != nil { continue } status.InitContainerStatuses[i].State = v1.ContainerState{ diff --git a/pkg/kubelet/status/status_manager_test.go b/pkg/kubelet/status/status_manager_test.go index 26e8db86717..855fac52ecd 100644 --- a/pkg/kubelet/status/status_manager_test.go +++ b/pkg/kubelet/status/status_manager_test.go @@ -622,6 +622,64 @@ func TestTerminatePod(t *testing.T) { assert.Equal(t, newStatus.Message, firstStatus.Message) } +func TestTerminatePodWaiting(t *testing.T) { + syncer := newTestManager(&fake.Clientset{}) + testPod := getTestPod() + t.Logf("update the pod's status to Failed. TerminatePod should preserve this status update.") + firstStatus := getRandomPodStatus() + firstStatus.Phase = v1.PodFailed + firstStatus.InitContainerStatuses = []v1.ContainerStatus{ + {Name: "init-test-1"}, + {Name: "init-test-2", State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{Reason: "InitTest", ExitCode: 0}}}, + {Name: "init-test-3", State: v1.ContainerState{Waiting: &v1.ContainerStateWaiting{Reason: "InitTest"}}}, + } + firstStatus.ContainerStatuses = []v1.ContainerStatus{ + {Name: "test-1"}, + {Name: "test-2", State: v1.ContainerState{Terminated: &v1.ContainerStateTerminated{Reason: "Test", ExitCode: 2}}}, + {Name: "test-3", State: v1.ContainerState{Waiting: &v1.ContainerStateWaiting{Reason: "Test"}}}, + } + syncer.SetPodStatus(testPod, firstStatus) + + t.Logf("set the testPod to a pod with Phase running, to simulate a stale pod") + testPod.Status = getRandomPodStatus() + testPod.Status.Phase = v1.PodRunning + + syncer.TerminatePod(testPod) + + t.Logf("we expect the container statuses to have changed to terminated") + newStatus := expectPodStatus(t, syncer, testPod) + for i := range newStatus.ContainerStatuses { + assert.False(t, newStatus.ContainerStatuses[i].State.Terminated == nil, "expected containers to be terminated") + } + for i := range newStatus.InitContainerStatuses { + assert.False(t, newStatus.InitContainerStatuses[i].State.Terminated == nil, "expected init containers to be terminated") + } + + expectUnknownState := v1.ContainerState{Terminated: &v1.ContainerStateTerminated{Reason: "ContainerStatusUnknown", Message: "The container could not be located when the pod was terminated", ExitCode: 137}} + if !reflect.DeepEqual(newStatus.InitContainerStatuses[0].State, expectUnknownState) { + t.Errorf("terminated container state not defaulted: %s", diff.ObjectReflectDiff(newStatus.InitContainerStatuses[0].State, expectUnknownState)) + } + if !reflect.DeepEqual(newStatus.InitContainerStatuses[1].State, firstStatus.InitContainerStatuses[1].State) { + t.Errorf("existing terminated container state not preserved: %#v", newStatus.ContainerStatuses) + } + if !reflect.DeepEqual(newStatus.InitContainerStatuses[2].State, expectUnknownState) { + t.Errorf("waiting container state not defaulted: %s", diff.ObjectReflectDiff(newStatus.InitContainerStatuses[2].State, expectUnknownState)) + } + if !reflect.DeepEqual(newStatus.ContainerStatuses[0].State, expectUnknownState) { + t.Errorf("terminated container state not defaulted: %s", diff.ObjectReflectDiff(newStatus.ContainerStatuses[0].State, expectUnknownState)) + } + if !reflect.DeepEqual(newStatus.ContainerStatuses[1].State, firstStatus.ContainerStatuses[1].State) { + t.Errorf("existing terminated container state not preserved: %#v", newStatus.ContainerStatuses) + } + if !reflect.DeepEqual(newStatus.ContainerStatuses[2].State, expectUnknownState) { + t.Errorf("waiting container state not defaulted: %s", diff.ObjectReflectDiff(newStatus.ContainerStatuses[2].State, expectUnknownState)) + } + + t.Logf("we expect the previous status update to be preserved.") + assert.Equal(t, newStatus.Phase, firstStatus.Phase) + assert.Equal(t, newStatus.Message, firstStatus.Message) +} + func TestSetContainerReadiness(t *testing.T) { cID1 := kubecontainer.ContainerID{Type: "test", ID: "1"} cID2 := kubecontainer.ContainerID{Type: "test", ID: "2"}