Skip to content

Commit 0cb253c

Browse files
pritidesaitekton-robot
authored andcommitted
check initContainers for kubernetes sidecar implementation
This code checks if all containers in a Pod, including init containers, have completed their execution before marking a TaskRun as complete when kubernetes native sidecar is enabled. It's part of the TaskRun status determination logic. Signed-off-by: Priti Desai <[email protected]>
1 parent 8669ca1 commit 0cb253c

File tree

2 files changed

+249
-0
lines changed

2 files changed

+249
-0
lines changed

pkg/pod/status.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,13 @@ func MakeTaskRunStatus(ctx context.Context, logger *zap.SugaredLogger, tr v1.Tas
127127

128128
complete := areContainersCompleted(ctx, pod) || isPodCompleted(pod)
129129

130+
// When EnableKubernetesSidecar is true, we need to ensure all init containers
131+
// are completed before considering the taskRun complete, in addition to the regular containers.
132+
// This is because sidecars in Kubernetes can keep running after the main containers complete.
133+
if config.FromContextOrDefaults(ctx).FeatureFlags.EnableKubernetesSidecar {
134+
complete = complete && areInitContainersCompleted(ctx, pod)
135+
}
136+
130137
if complete {
131138
onError, ok := tr.Annotations[v1.PipelineTaskOnErrorAnnotation]
132139
if ok {
@@ -157,6 +164,7 @@ func MakeTaskRunStatus(ctx context.Context, logger *zap.SugaredLogger, tr v1.Tas
157164
}
158165

159166
err := setTaskRunStatusBasedOnStepStatus(ctx, logger, stepStatuses, &tr, pod.Status.Phase, kubeclient, ts)
167+
160168
setTaskRunStatusBasedOnSidecarStatus(sidecarStatuses, trs)
161169

162170
trs.Results = removeDuplicateResults(trs.Results)
@@ -699,6 +707,21 @@ func isMatchingAnyFilter(name string, filters []containerNameFilter) bool {
699707
return false
700708
}
701709

710+
// areInitContainersCompleted returns true if all init containers in the pod are completed.
711+
func areInitContainersCompleted(ctx context.Context, pod *corev1.Pod) bool {
712+
if len(pod.Status.InitContainerStatuses) == 0 ||
713+
!(pod.Status.Phase == corev1.PodRunning || pod.Status.Phase == corev1.PodSucceeded) {
714+
return false
715+
}
716+
for _, containerStatus := range pod.Status.InitContainerStatuses {
717+
if containerStatus.State.Terminated == nil {
718+
// if any init container is not completed, return false
719+
return false
720+
}
721+
}
722+
return true
723+
}
724+
702725
// areContainersCompleted returns true if all related containers in the pod are completed.
703726
func areContainersCompleted(ctx context.Context, pod *corev1.Pod) bool {
704727
nameFilters := []containerNameFilter{IsContainerStep}

pkg/pod/status_test.go

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package pod
1818

1919
import (
2020
"fmt"
21+
"reflect"
2122
"strings"
2223
"testing"
2324
"time"
@@ -2193,6 +2194,231 @@ func TestMakeTaskRunStatus_SidecarNotCompleted(t *testing.T) {
21932194
}
21942195
}
21952196

2197+
func TestMakeTaskRunStatus_KubernetesNativeSidecar(t *testing.T) {
2198+
for _, c := range []struct {
2199+
desc string
2200+
podStatus corev1.PodStatus
2201+
pod corev1.Pod
2202+
taskSpec v1.TaskSpec
2203+
want v1.TaskRunStatus
2204+
}{{
2205+
desc: "test sidecar not completed - single sidecar",
2206+
podStatus: corev1.PodStatus{
2207+
Phase: corev1.PodRunning,
2208+
ContainerStatuses: []corev1.ContainerStatus{
2209+
{
2210+
Name: "step-foo",
2211+
State: corev1.ContainerState{
2212+
Terminated: &corev1.ContainerStateTerminated{
2213+
Message: `[{"key":"resultName","value":"", "type":1}, {"key":"digest","value":"sha256:1234","resourceName":"source-image"}]`,
2214+
},
2215+
},
2216+
},
2217+
{
2218+
Name: "step-bar",
2219+
State: corev1.ContainerState{
2220+
Terminated: &corev1.ContainerStateTerminated{
2221+
Message: `[{"key":"digest","value":"sha256:1234","resourceName":"source-image"}]`,
2222+
},
2223+
},
2224+
}},
2225+
InitContainerStatuses: []corev1.ContainerStatus{
2226+
{
2227+
Name: "sidecar-baz-1",
2228+
State: corev1.ContainerState{
2229+
Terminated: nil,
2230+
},
2231+
},
2232+
},
2233+
},
2234+
taskSpec: v1.TaskSpec{
2235+
Steps: []v1.Step{{Name: "step-foo"}, {Name: "step-bar"}},
2236+
Sidecars: []v1.Sidecar{{Name: "sidecar-baz"}},
2237+
Results: []v1.TaskResult{
2238+
{
2239+
Name: "resultName",
2240+
Type: v1.ResultsTypeString,
2241+
},
2242+
},
2243+
},
2244+
pod: corev1.Pod{
2245+
ObjectMeta: metav1.ObjectMeta{
2246+
Name: "pod",
2247+
Namespace: "foo",
2248+
CreationTimestamp: metav1.Now(),
2249+
},
2250+
Spec: corev1.PodSpec{
2251+
Containers: []corev1.Container{{
2252+
Name: "step-foo",
2253+
}, {
2254+
Name: "step-bar",
2255+
}},
2256+
InitContainers: []corev1.Container{{
2257+
Name: "sidecar-baz-1",
2258+
}},
2259+
},
2260+
},
2261+
want: v1.TaskRunStatus{
2262+
Status: statusRunning(),
2263+
},
2264+
}, {
2265+
desc: "test sidecar not completed - two sidecars",
2266+
podStatus: corev1.PodStatus{
2267+
Phase: corev1.PodRunning,
2268+
ContainerStatuses: []corev1.ContainerStatus{
2269+
{
2270+
Name: "step-foo",
2271+
State: corev1.ContainerState{
2272+
Terminated: &corev1.ContainerStateTerminated{
2273+
Message: `[{"key":"resultName","value":"", "type":1}, {"key":"digest","value":"sha256:1234","resourceName":"source-image"}]`,
2274+
},
2275+
},
2276+
},
2277+
{
2278+
Name: "step-bar",
2279+
State: corev1.ContainerState{
2280+
Terminated: &corev1.ContainerStateTerminated{
2281+
Message: `[{"key":"digest","value":"sha256:1234","resourceName":"source-image"}]`,
2282+
},
2283+
},
2284+
}},
2285+
InitContainerStatuses: []corev1.ContainerStatus{
2286+
{
2287+
Name: "sidecar-baz-1",
2288+
State: corev1.ContainerState{
2289+
Terminated: nil,
2290+
},
2291+
},
2292+
{
2293+
Name: "sidecar-baz-2",
2294+
State: corev1.ContainerState{
2295+
Terminated: &corev1.ContainerStateTerminated{
2296+
ExitCode: 0,
2297+
},
2298+
},
2299+
},
2300+
},
2301+
},
2302+
taskSpec: v1.TaskSpec{
2303+
Steps: []v1.Step{{Name: "step-foo"}, {Name: "step-bar"}},
2304+
Sidecars: []v1.Sidecar{{Name: "sidecar-baz"}},
2305+
Results: []v1.TaskResult{
2306+
{
2307+
Name: "resultName",
2308+
Type: v1.ResultsTypeString,
2309+
},
2310+
},
2311+
},
2312+
want: v1.TaskRunStatus{
2313+
Status: statusRunning(),
2314+
},
2315+
}, {
2316+
desc: "test sidecar already completed",
2317+
podStatus: corev1.PodStatus{
2318+
Phase: corev1.PodRunning,
2319+
ContainerStatuses: []corev1.ContainerStatus{
2320+
{
2321+
Name: "step-foo",
2322+
State: corev1.ContainerState{
2323+
Terminated: &corev1.ContainerStateTerminated{
2324+
Message: `[{"key":"digest","value":"sha256:1234","resourceName":"source-image"}]`,
2325+
},
2326+
},
2327+
},
2328+
{
2329+
Name: "step-bar",
2330+
State: corev1.ContainerState{
2331+
Terminated: &corev1.ContainerStateTerminated{
2332+
Message: `[{"key":"resultName","value":"", "type":1}, {"key":"digest","value":"sha256:1234","resourceName":"source-image"}]`,
2333+
},
2334+
},
2335+
}},
2336+
InitContainerStatuses: []corev1.ContainerStatus{
2337+
{
2338+
Name: "sidecar-baz-1",
2339+
State: corev1.ContainerState{
2340+
Terminated: &corev1.ContainerStateTerminated{
2341+
ExitCode: 0,
2342+
},
2343+
},
2344+
},
2345+
{
2346+
Name: "sidecar-baz-2",
2347+
State: corev1.ContainerState{
2348+
Terminated: &corev1.ContainerStateTerminated{
2349+
ExitCode: 0,
2350+
},
2351+
},
2352+
},
2353+
},
2354+
},
2355+
taskSpec: v1.TaskSpec{
2356+
Steps: []v1.Step{{Name: "step-bar"}},
2357+
Sidecars: []v1.Sidecar{{Name: "sidecar-baz"}},
2358+
Results: []v1.TaskResult{
2359+
{
2360+
Name: "resultName",
2361+
Type: v1.ResultsTypeString,
2362+
},
2363+
},
2364+
},
2365+
want: v1.TaskRunStatus{
2366+
Status: statusSuccess(),
2367+
},
2368+
}} {
2369+
t.Run(c.desc, func(t *testing.T) {
2370+
if reflect.DeepEqual(c.pod, corev1.Pod{}) {
2371+
c.pod = corev1.Pod{
2372+
ObjectMeta: metav1.ObjectMeta{
2373+
Name: "pod",
2374+
Namespace: "foo",
2375+
CreationTimestamp: metav1.Now(),
2376+
},
2377+
Spec: corev1.PodSpec{
2378+
Containers: []corev1.Container{{
2379+
Name: "step-foo",
2380+
}, {
2381+
Name: "step-bar",
2382+
}},
2383+
InitContainers: []corev1.Container{{
2384+
Name: "sidecar-baz-1",
2385+
}, {
2386+
Name: "sidecar-baz-2",
2387+
}},
2388+
},
2389+
}
2390+
}
2391+
2392+
c.pod.Status = c.podStatus
2393+
2394+
tr := v1.TaskRun{
2395+
ObjectMeta: metav1.ObjectMeta{
2396+
Name: "task-run",
2397+
Namespace: "foo",
2398+
},
2399+
Status: v1.TaskRunStatus{
2400+
TaskRunStatusFields: v1.TaskRunStatusFields{
2401+
TaskSpec: &c.taskSpec,
2402+
},
2403+
},
2404+
}
2405+
logger, _ := logging.NewLogger("", "status")
2406+
kubeclient := fakek8s.NewSimpleClientset()
2407+
ctx := config.ToContext(t.Context(), &config.Config{
2408+
FeatureFlags: &config.FeatureFlags{
2409+
ResultExtractionMethod: config.ResultExtractionMethodSidecarLogs,
2410+
MaxResultSize: 1024,
2411+
EnableKubernetesSidecar: true,
2412+
},
2413+
})
2414+
got, _ := MakeTaskRunStatus(ctx, logger, tr, &c.pod, kubeclient, &c.taskSpec)
2415+
if d := cmp.Diff(c.want.Status, got.Status, ignoreVolatileTime); d != "" {
2416+
t.Errorf("Unexpected status: %s", diff.PrintWantGot(d))
2417+
}
2418+
})
2419+
}
2420+
}
2421+
21962422
func TestMakeTaskRunStatusAlpha(t *testing.T) {
21972423
for _, c := range []struct {
21982424
desc string

0 commit comments

Comments
 (0)