From 1b8f851979099cfa8c5d6de4d363b1d25a0699cc Mon Sep 17 00:00:00 2001 From: Dawn Chen Date: Fri, 16 Oct 2015 13:02:00 -0700 Subject: [PATCH 1/2] Fix PodPhase issue caused by backoff --- pkg/kubelet/kubelet.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index e0a186ced96..027b4fd5e78 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -2513,7 +2513,11 @@ func GetPhase(spec *api.PodSpec, info []api.ContainerStatus) api.PodPhase { failed++ } } else if containerStatus.State.Waiting != nil { - waiting++ + if containerStatus.LastTerminationState.Terminated != nil { + stopped++ + } else { + waiting++ + } } else { unknown++ } From 6f46780cbf9bc67e6fe57d553a221e6859bfd405 Mon Sep 17 00:00:00 2001 From: Dawn Chen Date: Fri, 16 Oct 2015 15:15:25 -0700 Subject: [PATCH 2/2] Add tests to reproduce the issue and verify the fix. --- pkg/kubelet/kubelet_test.go | 86 +++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index d3d7940c7f3..75d16b86a79 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -1462,6 +1462,27 @@ func TestMakeEnvironmentVariables(t *testing.T) { } } +func waitingState(cName string) api.ContainerStatus { + return api.ContainerStatus{ + Name: cName, + State: api.ContainerState{ + Waiting: &api.ContainerStateWaiting{}, + }, + } +} +func waitingStateWithLastTermination(cName string) api.ContainerStatus { + return api.ContainerStatus{ + Name: cName, + State: api.ContainerState{ + Waiting: &api.ContainerStateWaiting{}, + }, + LastTerminationState: api.ContainerState{ + Terminated: &api.ContainerStateTerminated{ + ExitCode: 0, + }, + }, + } +} func runningState(cName string) api.ContainerStatus { return api.ContainerStatus{ Name: cName, @@ -1566,6 +1587,32 @@ func TestPodPhaseWithRestartAlways(t *testing.T) { api.PodPending, "mixed state #2 with restart always", }, + { + &api.Pod{ + Spec: desiredState, + Status: api.PodStatus{ + ContainerStatuses: []api.ContainerStatus{ + runningState("containerA"), + waitingState("containerB"), + }, + }, + }, + api.PodPending, + "mixed state #3 with restart always", + }, + { + &api.Pod{ + Spec: desiredState, + Status: api.PodStatus{ + ContainerStatuses: []api.ContainerStatus{ + runningState("containerA"), + waitingStateWithLastTermination("containerB"), + }, + }, + }, + api.PodRunning, + "backoff crashloop container with restart always", + }, } for _, test := range tests { if status := GetPhase(&test.pod.Spec, test.pod.Status.ContainerStatuses); status != test.status { @@ -1654,6 +1701,19 @@ func TestPodPhaseWithRestartNever(t *testing.T) { api.PodPending, "mixed state #2 with restart never", }, + { + &api.Pod{ + Spec: desiredState, + Status: api.PodStatus{ + ContainerStatuses: []api.ContainerStatus{ + runningState("containerA"), + waitingState("containerB"), + }, + }, + }, + api.PodPending, + "mixed state #3 with restart never", + }, } for _, test := range tests { if status := GetPhase(&test.pod.Spec, test.pod.Status.ContainerStatuses); status != test.status { @@ -1742,6 +1802,32 @@ func TestPodPhaseWithRestartOnFailure(t *testing.T) { api.PodPending, "mixed state #2 with restart onfailure", }, + { + &api.Pod{ + Spec: desiredState, + Status: api.PodStatus{ + ContainerStatuses: []api.ContainerStatus{ + runningState("containerA"), + waitingState("containerB"), + }, + }, + }, + api.PodPending, + "mixed state #3 with restart onfailure", + }, + { + &api.Pod{ + Spec: desiredState, + Status: api.PodStatus{ + ContainerStatuses: []api.ContainerStatus{ + runningState("containerA"), + waitingStateWithLastTermination("containerB"), + }, + }, + }, + api.PodRunning, + "backoff crashloop container with restart onfailure", + }, } for _, test := range tests { if status := GetPhase(&test.pod.Spec, test.pod.Status.ContainerStatuses); status != test.status {