Skip to content

Commit 5cb9498

Browse files
committed
fix: panic may occur when calculating the final task timeout waiting time
1 parent 9f8fbb4 commit 5cb9498

File tree

2 files changed

+71
-20
lines changed

2 files changed

+71
-20
lines changed

pkg/reconciler/pipelinerun/pipelinerun.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, pr *v1.PipelineRun) pkgr
276276
waitTime := pr.PipelineTimeout(ctx) - elapsed
277277
if pr.Status.FinallyStartTime == nil && pr.TasksTimeout() != nil {
278278
waitTime = pr.TasksTimeout().Duration - elapsed
279-
} else if pr.FinallyTimeout() != nil {
279+
} else if pr.Status.FinallyStartTime != nil && pr.FinallyTimeout() != nil {
280280
finallyWaitTime := pr.FinallyTimeout().Duration - c.Clock.Since(pr.Status.FinallyStartTime.Time)
281281
if finallyWaitTime < waitTime {
282282
waitTime = finallyWaitTime
@@ -700,7 +700,7 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1.PipelineRun, getPipel
700700
errs := timeoutPipelineTasksForTaskNames(ctx, logger, pr, c.PipelineClientSet, tasksToTimeOut)
701701
if len(errs) > 0 {
702702
errString := strings.Join(errs, "\n")
703-
logger.Errorf("Failed to timeout tasks for PipelineRun %s/%s: %s", pr.Name, pr.Name, errString)
703+
logger.Errorf("Failed to timeout tasks for PipelineRun %s/%s: %s", pr.Namespace, pr.Name, errString)
704704
return fmt.Errorf("error(s) from cancelling TaskRun(s) from PipelineRun %s: %s", pr.Name, errString)
705705
}
706706
}
@@ -717,7 +717,7 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1.PipelineRun, getPipel
717717
errs := timeoutPipelineTasksForTaskNames(ctx, logger, pr, c.PipelineClientSet, tasksToTimeOut)
718718
if len(errs) > 0 {
719719
errString := strings.Join(errs, "\n")
720-
logger.Errorf("Failed to timeout finally tasks for PipelineRun %s/%s: %s", pr.Name, pr.Name, errString)
720+
logger.Errorf("Failed to timeout finally tasks for PipelineRun %s/%s: %s", pr.Namespace, pr.Name, errString)
721721
return fmt.Errorf("error(s) from cancelling TaskRun(s) from PipelineRun %s: %s", pr.Name, errString)
722722
}
723723
}

pkg/reconciler/pipelinerun/pipelinerun_test.go

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2694,7 +2694,7 @@ spec:
26942694
`)}
26952695
prName := "test-pipeline-run-with-timeout"
26962696
ts := []*v1.Task{simpleHelloWorldTask}
2697-
trs := []*v1.TaskRun{
2697+
oneFinishedTRs := []*v1.TaskRun{
26982698
getTaskRun(
26992699
t,
27002700
"test-pipeline-run-with-timeout-hello-world",
@@ -2711,12 +2711,26 @@ spec:
27112711
name: hello-world
27122712
kind: Task
27132713
`)}
2714+
oneStartedTRs := []*v1.TaskRun{
2715+
getTaskRun(
2716+
t,
2717+
"test-pipeline-run-with-timeout-hello-world",
2718+
prName,
2719+
ps[0].Name,
2720+
"hello-world",
2721+
corev1.ConditionUnknown,
2722+
),
2723+
}
27142724

27152725
tcs := []struct {
2716-
name string
2717-
pr *v1.PipelineRun
2726+
name string
2727+
trs []*v1.TaskRun
2728+
pr *v1.PipelineRun
2729+
wantFinallyTimeout bool
2730+
wantOneFinalTaskSkipped bool
27182731
}{{
27192732
name: "finally timeout specified",
2733+
trs: oneFinishedTRs,
27202734
pr: parse.MustParseV1PipelineRun(t, fmt.Sprintf(`
27212735
metadata:
27222736
name: %s
@@ -2749,8 +2763,11 @@ status:
27492763
status: "Unknown"
27502764
type: Succeeded
27512765
`, prName)),
2766+
wantFinallyTimeout: true,
2767+
wantOneFinalTaskSkipped: true,
27522768
}, {
27532769
name: "finally timeout calculated",
2770+
trs: oneFinishedTRs,
27542771
pr: parse.MustParseV1PipelineRun(t, fmt.Sprintf(`
27552772
metadata:
27562773
name: %s
@@ -2784,13 +2801,43 @@ status:
27842801
status: "Unknown"
27852802
type: Succeeded
27862803
`, prName)),
2804+
wantFinallyTimeout: true,
2805+
wantOneFinalTaskSkipped: true,
2806+
}, {
2807+
name: "finally timeout specified and pipeline timeout set to 0",
2808+
trs: oneStartedTRs,
2809+
pr: parse.MustParseV1PipelineRun(t, fmt.Sprintf(`
2810+
metadata:
2811+
name: %s
2812+
namespace: foo
2813+
spec:
2814+
pipelineRef:
2815+
name: test-pipeline-with-finally
2816+
timeouts:
2817+
finally: 15m
2818+
pipeline: 0s
2819+
status:
2820+
startTime: "2021-12-31T23:40:00Z"
2821+
childReferences:
2822+
- name: test-pipeline-run-with-timeout-hello-world
2823+
apiVersion: tekton.dev/v1
2824+
kind: TaskRun
2825+
pipelineTaskName: task1
2826+
status:
2827+
conditions:
2828+
- lastTransitionTime: null
2829+
status: Unknown
2830+
type: Succeeded
2831+
`, prName)),
2832+
wantFinallyTimeout: false,
2833+
wantOneFinalTaskSkipped: false,
27872834
}}
27882835
for _, tc := range tcs {
27892836
d := test.Data{
27902837
PipelineRuns: []*v1.PipelineRun{tc.pr},
27912838
Pipelines: ps,
27922839
Tasks: ts,
2793-
TaskRuns: trs,
2840+
TaskRuns: tc.trs,
27942841
}
27952842
prt := newPipelineRunTest(t, d)
27962843
defer prt.Cancel()
@@ -2810,22 +2857,26 @@ status:
28102857
}
28112858

28122859
// Check that there is a skipped task for the expected reason
2813-
if len(reconciledRun.Status.SkippedTasks) != 1 {
2814-
t.Errorf("expected one skipped task, found %d", len(reconciledRun.Status.SkippedTasks))
2815-
} else if reconciledRun.Status.SkippedTasks[0].Reason != v1.FinallyTimedOutSkip {
2816-
t.Errorf("expected skipped reason to be '%s', but was '%s", v1.FinallyTimedOutSkip, reconciledRun.Status.SkippedTasks[0].Reason)
2860+
if tc.wantOneFinalTaskSkipped {
2861+
if len(reconciledRun.Status.SkippedTasks) != 1 {
2862+
t.Errorf("expected one skipped task, found %d", len(reconciledRun.Status.SkippedTasks))
2863+
} else if reconciledRun.Status.SkippedTasks[0].Reason != v1.FinallyTimedOutSkip {
2864+
t.Errorf("expected skipped reason to be '%s', but was '%s", v1.FinallyTimedOutSkip, reconciledRun.Status.SkippedTasks[0].Reason)
2865+
}
28172866
}
28182867

2819-
updatedTaskRun, err := clients.Pipeline.TektonV1().TaskRuns("foo").Get(context.Background(), trs[1].Name, metav1.GetOptions{})
2820-
if err != nil {
2821-
t.Fatalf("error getting updated TaskRun: %#v", err)
2822-
}
2868+
if tc.wantFinallyTimeout {
2869+
updatedTaskRun, err := clients.Pipeline.TektonV1().TaskRuns("foo").Get(context.Background(), tc.trs[1].Name, metav1.GetOptions{})
2870+
if err != nil {
2871+
t.Fatalf("error getting updated TaskRun: %#v", err)
2872+
}
28232873

2824-
if updatedTaskRun.Spec.Status != v1.TaskRunSpecStatusCancelled {
2825-
t.Errorf("expected existing TaskRun Spec.Status to be set to %s, but was %s", v1.TaskRunSpecStatusCancelled, updatedTaskRun.Spec.Status)
2826-
}
2827-
if updatedTaskRun.Spec.StatusMessage != v1.TaskRunCancelledByPipelineTimeoutMsg {
2828-
t.Errorf("expected existing TaskRun Spec.StatusMessage to be set to %s, but was %s", v1.TaskRunCancelledByPipelineTimeoutMsg, updatedTaskRun.Spec.StatusMessage)
2874+
if updatedTaskRun.Spec.Status != v1.TaskRunSpecStatusCancelled {
2875+
t.Errorf("expected existing TaskRun Spec.Status to be set to %s, but was %s", v1.TaskRunSpecStatusCancelled, updatedTaskRun.Spec.Status)
2876+
}
2877+
if updatedTaskRun.Spec.StatusMessage != v1.TaskRunCancelledByPipelineTimeoutMsg {
2878+
t.Errorf("expected existing TaskRun Spec.StatusMessage to be set to %s, but was %s", v1.TaskRunCancelledByPipelineTimeoutMsg, updatedTaskRun.Spec.StatusMessage)
2879+
}
28292880
}
28302881
}
28312882
}

0 commit comments

Comments
 (0)