diff --git a/pkg/controller/job/backoff_utils.go b/pkg/controller/job/backoff_utils.go index ecd86dc3113..fd03dfe4670 100644 --- a/pkg/controller/job/backoff_utils.go +++ b/pkg/controller/job/backoff_utils.go @@ -183,12 +183,18 @@ func getFinishedTime(p *v1.Pod) time.Time { } func getFinishTimeFromContainers(p *v1.Pod) *time.Time { - var finishTime *time.Time - for _, containerState := range p.Status.ContainerStatuses { - if containerState.State.Terminated == nil { - return nil - } - if containerState.State.Terminated.FinishedAt.Time.IsZero() { + finishTime := latestFinishTime(nil, p.Status.ContainerStatuses) + // We need to check InitContainerStatuses here also, + // because with the sidecar (restartable init) containers, + // sidecar containers will always finish later than regular containers. + return latestFinishTime(finishTime, p.Status.InitContainerStatuses) +} + +func latestFinishTime(prevFinishTime *time.Time, cs []v1.ContainerStatus) *time.Time { + var finishTime = prevFinishTime + for _, containerState := range cs { + if containerState.State.Terminated == nil || + containerState.State.Terminated.FinishedAt.Time.IsZero() { return nil } if finishTime == nil || finishTime.Before(containerState.State.Terminated.FinishedAt.Time) { diff --git a/pkg/controller/job/backoff_utils_test.go b/pkg/controller/job/backoff_utils_test.go index e300982c0b8..f402ab681b8 100644 --- a/pkg/controller/job/backoff_utils_test.go +++ b/pkg/controller/job/backoff_utils_test.go @@ -355,6 +355,30 @@ func TestGetFinishedTime(t *testing.T) { }, wantFinishTime: defaultTestTime, }, + // In this case, init container is stopped after the regular containers. + // This is because with the sidecar (restartable init) containers, + // sidecar containers will always finish later than regular containers. + "Pod with init container and all containers terminated": { + pod: v1.Pod{ + Status: v1.PodStatus{ + ContainerStatuses: []v1.ContainerStatus{ + { + State: v1.ContainerState{ + Terminated: &v1.ContainerStateTerminated{FinishedAt: metav1.NewTime(defaultTestTime.Add(-1 * time.Second))}, + }, + }, + }, + InitContainerStatuses: []v1.ContainerStatus{ + { + State: v1.ContainerState{ + Terminated: &v1.ContainerStateTerminated{FinishedAt: metav1.NewTime(defaultTestTime)}, + }, + }, + }, + }, + }, + wantFinishTime: defaultTestTime, + }, } for name, tc := range testCases {