Skip to content

Commit 0f20c35

Browse files
imjasonhtekton-robot
authored andcommitted
Don't rely on .status.podName to find Pod associated with a TaskRun
This adds Reconciler.getPod, which looks up the Pod for a TaskRun by performing a label selector query on Pods, looking for the label we apply to Pods generated by TaskRuns. If zero Pods are returned, it's the same as .status.podName being "". If multiple Pods are returned, that's an error. Also, clean up metrics_test.go a bit while I'm in that area
1 parent fd07ff9 commit 0f20c35

File tree

6 files changed

+310
-416
lines changed

6 files changed

+310
-416
lines changed

pkg/reconciler/taskrun/cancel.go

+5-14
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,19 @@ import (
2626
"knative.dev/pkg/apis"
2727
)
2828

29-
type logger interface {
30-
Warn(args ...interface{})
31-
Warnf(template string, args ...interface{})
32-
}
33-
3429
// cancelTaskRun marks the TaskRun as cancelled and delete pods linked to it.
35-
func cancelTaskRun(tr *v1alpha1.TaskRun, clientSet kubernetes.Interface, logger logger) error {
36-
logger.Warn("task run %q has been cancelled", tr.Name)
30+
func cancelTaskRun(tr *v1alpha1.TaskRun, clientset kubernetes.Interface) error {
3731
tr.Status.SetCondition(&apis.Condition{
3832
Type: apis.ConditionSucceeded,
3933
Status: corev1.ConditionFalse,
4034
Reason: "TaskRunCancelled",
4135
Message: fmt.Sprintf("TaskRun %q was cancelled", tr.Name),
4236
})
4337

44-
if tr.Status.PodName == "" {
45-
logger.Warnf("task run %q has no pod running yet", tr.Name)
46-
return nil
47-
}
48-
49-
if err := clientSet.CoreV1().Pods(tr.Namespace).Delete(tr.Status.PodName, &metav1.DeleteOptions{}); err != nil {
38+
pod, err := getPod(tr, clientset)
39+
if err != nil {
5040
return err
5141
}
52-
return nil
42+
43+
return clientset.CoreV1().Pods(tr.Namespace).Delete(pod.Name, &metav1.DeleteOptions{})
5344
}

pkg/reconciler/taskrun/cancel_test.go

+52-53
Original file line numberDiff line numberDiff line change
@@ -22,78 +22,77 @@ import (
2222

2323
"github.com/google/go-cmp/cmp"
2424
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
25-
ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing"
2625
"github.com/tektoncd/pipeline/test"
27-
tb "github.com/tektoncd/pipeline/test/builder"
28-
"go.uber.org/zap"
29-
"go.uber.org/zap/zaptest/observer"
3026
corev1 "k8s.io/api/core/v1"
27+
kerrors "k8s.io/apimachinery/pkg/api/errors"
3128
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3229
"knative.dev/pkg/apis"
3330
)
3431

3532
func TestCancelTaskRun(t *testing.T) {
36-
testCases := []struct {
37-
name string
38-
taskRun *v1alpha1.TaskRun
39-
pod *corev1.Pod
40-
expectedStatus apis.Condition
33+
namespace := "the-namespace"
34+
taskRunName := "the-taskrun"
35+
wantStatus := &apis.Condition{
36+
Type: apis.ConditionSucceeded,
37+
Status: corev1.ConditionFalse,
38+
Reason: "TaskRunCancelled",
39+
Message: `TaskRun "the-taskrun" was cancelled`,
40+
}
41+
for _, c := range []struct {
42+
desc string
43+
taskRun *v1alpha1.TaskRun
44+
pod *corev1.Pod
4145
}{{
42-
name: "no-pod-scheduled",
43-
taskRun: tb.TaskRun("test-taskrun-run-cancelled", "foo", tb.TaskRunSpec(
44-
tb.TaskRunTaskRef(simpleTask.Name),
45-
tb.TaskRunCancelled,
46-
), tb.TaskRunStatus(tb.StatusCondition(apis.Condition{
47-
Type: apis.ConditionSucceeded,
48-
Status: corev1.ConditionUnknown,
49-
}))),
50-
expectedStatus: apis.Condition{
51-
Type: apis.ConditionSucceeded,
52-
Status: corev1.ConditionFalse,
53-
Reason: "TaskRunCancelled",
54-
Message: `TaskRun "test-taskrun-run-cancelled" was cancelled`,
46+
desc: "no pod scheduled",
47+
taskRun: &v1alpha1.TaskRun{
48+
ObjectMeta: metav1.ObjectMeta{
49+
Name: taskRunName,
50+
Namespace: namespace,
51+
},
52+
Spec: v1alpha1.TaskRunSpec{
53+
Status: v1alpha1.TaskRunSpecStatusCancelled,
54+
},
5555
},
5656
}, {
57-
name: "pod-scheduled",
58-
taskRun: tb.TaskRun("test-taskrun-run-cancelled", "foo", tb.TaskRunSpec(
59-
tb.TaskRunTaskRef(simpleTask.Name),
60-
tb.TaskRunCancelled,
61-
), tb.TaskRunStatus(tb.StatusCondition(apis.Condition{
62-
Type: apis.ConditionSucceeded,
63-
Status: corev1.ConditionUnknown,
64-
}), tb.PodName("foo-is-bar"))),
57+
desc: "pod scheduled",
58+
taskRun: &v1alpha1.TaskRun{
59+
ObjectMeta: metav1.ObjectMeta{
60+
Name: taskRunName,
61+
Namespace: namespace,
62+
},
63+
Spec: v1alpha1.TaskRunSpec{
64+
Status: v1alpha1.TaskRunSpecStatusCancelled,
65+
},
66+
},
6567
pod: &corev1.Pod{ObjectMeta: metav1.ObjectMeta{
66-
Namespace: "foo",
67-
Name: "foo-is-bar",
68+
Namespace: namespace,
69+
Name: "the-pod",
70+
Labels: map[string]string{
71+
"tekton.dev/taskRun": taskRunName,
72+
},
6873
}},
69-
expectedStatus: apis.Condition{
70-
Type: apis.ConditionSucceeded,
71-
Status: corev1.ConditionFalse,
72-
Reason: "TaskRunCancelled",
73-
Message: `TaskRun "test-taskrun-run-cancelled" was cancelled`,
74-
},
75-
}}
76-
77-
for _, tc := range testCases {
78-
t.Run(tc.name, func(t *testing.T) {
74+
}} {
75+
t.Run(c.desc, func(t *testing.T) {
7976
d := test.Data{
80-
TaskRuns: []*v1alpha1.TaskRun{tc.taskRun},
77+
TaskRuns: []*v1alpha1.TaskRun{c.taskRun},
8178
}
82-
if tc.pod != nil {
83-
d.Pods = []*corev1.Pod{tc.pod}
79+
if c.pod != nil {
80+
d.Pods = []*corev1.Pod{c.pod}
8481
}
8582

86-
ctx, _ := ttesting.SetupFakeContext(t)
87-
ctx, cancel := context.WithCancel(ctx)
83+
testAssets, cancel := getTaskRunController(t, d)
8884
defer cancel()
89-
c, _ := test.SeedTestData(t, ctx, d)
90-
observer, _ := observer.New(zap.InfoLevel)
91-
err := cancelTaskRun(tc.taskRun, c.Kube, zap.New(observer).Sugar())
92-
if err != nil {
85+
if err := testAssets.Controller.Reconciler.Reconcile(context.Background(), getRunName(c.taskRun)); err != nil {
9386
t.Fatal(err)
9487
}
95-
if d := cmp.Diff(tc.taskRun.Status.GetCondition(apis.ConditionSucceeded), &tc.expectedStatus, ignoreLastTransitionTime); d != "" {
96-
t.Fatalf("-want, +got: %v", d)
88+
if d := cmp.Diff(wantStatus, c.taskRun.Status.GetCondition(apis.ConditionSucceeded), ignoreLastTransitionTime); d != "" {
89+
t.Errorf("Diff(-want, +got): %s", d)
90+
}
91+
92+
if c.pod != nil {
93+
if _, err := testAssets.Controller.Reconciler.(*Reconciler).KubeClientSet.CoreV1().Pods(c.taskRun.Namespace).Get(c.pod.Name, metav1.GetOptions{}); !kerrors.IsNotFound(err) {
94+
t.Errorf("Pod was not deleted; wanted not-found error, got %v", err)
95+
}
9796
}
9897
})
9998
}

pkg/reconciler/taskrun/metrics.go

+10-16
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func NewRecorder() (*Recorder, error) {
120120
}
121121
r.pod = pod
122122

123-
err = view.Register(
123+
if err := view.Register(
124124
&view.View{
125125
Description: trDuration.Description(),
126126
Measure: trDuration,
@@ -150,9 +150,7 @@ func NewRecorder() (*Recorder, error) {
150150
Aggregation: view.LastValue(),
151151
TagKeys: []tag.Key{r.task, r.taskRun, r.namespace, r.pod},
152152
},
153-
)
154-
155-
if err != nil {
153+
); err != nil {
156154
r.initialized = false
157155
return r, err
158156
}
@@ -257,9 +255,15 @@ func (r *Recorder) RecordPodLatency(pod *corev1.Pod, tr *v1alpha1.TaskRun) error
257255
return errors.New("ignoring the metrics recording for pod , failed to initialize the metrics recorder")
258256
}
259257

260-
scheduledTime := getScheduledTime(pod)
258+
var scheduledTime metav1.Time
259+
for _, c := range pod.Status.Conditions {
260+
if c.Type == corev1.PodScheduled {
261+
scheduledTime = c.LastTransitionTime
262+
break
263+
}
264+
}
261265
if scheduledTime.IsZero() {
262-
return errors.New("pod has never got scheduled")
266+
return errors.New("pod was never scheduled")
263267
}
264268

265269
latency := scheduledTime.Sub(pod.CreationTimestamp.Time)
@@ -283,13 +287,3 @@ func (r *Recorder) RecordPodLatency(pod *corev1.Pod, tr *v1alpha1.TaskRun) error
283287

284288
return nil
285289
}
286-
287-
func getScheduledTime(pod *corev1.Pod) metav1.Time {
288-
for _, c := range pod.Status.Conditions {
289-
if c.Type == corev1.PodScheduled {
290-
return c.LastTransitionTime
291-
}
292-
}
293-
294-
return metav1.Time{}
295-
}

0 commit comments

Comments
 (0)