diff --git a/pkg/reconciler/pipelinerun/pipelinerun.go b/pkg/reconciler/pipelinerun/pipelinerun.go index 68b640ee1f7..8f74f38bccf 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun.go +++ b/pkg/reconciler/pipelinerun/pipelinerun.go @@ -206,6 +206,18 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, pr *v1beta1.PipelineRun) return c.finishReconcileUpdateEmitEvents(ctx, pr, before, nil) } + pipelineMeta, pipelineSpec, err := resources.GetPipelineData(ctx, pr, getPipelineFunc) + if err != nil { + logger.Errorf("Failed to determine Pipeline spec to use for pipelinerun %s: %v", pr.Name, err) + pr.Status.MarkFailed(ReasonCouldntGetPipeline, + "Error retrieving pipeline for pipelinerun %s/%s: %s", + pr.Namespace, pr.Name, err) + return c.finishReconcileUpdateEmitEvents(ctx, pr, before, controller.NewPermanentError(err)) + } + + propagateLabelsFromPipelineToPipelineRun(pr, pipelineMeta) + propagateAnnotationsFromPipelineToPipelineRun(pr, pipelineMeta) + // If the pipelinerun is cancelled, cancel tasks and update status if pr.IsCancelled() { err := cancelPipelineRun(ctx, logger, pr, c.PipelineClientSet) @@ -222,7 +234,7 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, pr *v1beta1.PipelineRun) // Reconcile this copy of the pipelinerun and then write back any status or label // updates regardless of whether the reconciliation errored out. - if err = c.reconcile(ctx, pr, getPipelineFunc); err != nil { + if err = c.reconcile(ctx, pr, pipelineMeta, pipelineSpec); err != nil { logger.Errorf("Reconcile error: %v", err.Error()) } @@ -312,7 +324,7 @@ func (c *Reconciler) resolvePipelineState( return pst, nil } -func (c *Reconciler) reconcile(ctx context.Context, pr *v1beta1.PipelineRun, getPipelineFunc resources.GetPipeline) error { +func (c *Reconciler) reconcile(ctx context.Context, pr *v1beta1.PipelineRun, pipelineMeta *metav1.ObjectMeta, pipelineSpec *v1beta1.PipelineSpec) error { logger := logging.FromContext(ctx) cfg := config.FromContextOrDefaults(ctx) // We may be reading a version of the object that was stored at an older version @@ -330,37 +342,11 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1beta1.PipelineRun, get return nil } - pipelineMeta, pipelineSpec, err := resources.GetPipelineData(ctx, pr, getPipelineFunc) - if err != nil { - logger.Errorf("Failed to determine Pipeline spec to use for pipelinerun %s: %v", pr.Name, err) - pr.Status.MarkFailed(ReasonCouldntGetPipeline, - "Error retrieving pipeline for pipelinerun %s/%s: %s", - pr.Namespace, pr.Name, err) - return controller.NewPermanentError(err) - } - // Store the fetched PipelineSpec on the PipelineRun for auditing if err := storePipelineSpec(ctx, pr, pipelineSpec); err != nil { logger.Errorf("Failed to store PipelineSpec on PipelineRun.Status for pipelinerun %s: %v", pr.Name, err) } - // Propagate labels from Pipeline to PipelineRun. - if pr.ObjectMeta.Labels == nil { - pr.ObjectMeta.Labels = make(map[string]string, len(pipelineMeta.Labels)+1) - } - for key, value := range pipelineMeta.Labels { - pr.ObjectMeta.Labels[key] = value - } - pr.ObjectMeta.Labels[pipeline.PipelineLabelKey] = pipelineMeta.Name - - // Propagate annotations from Pipeline to PipelineRun. - if pr.ObjectMeta.Annotations == nil { - pr.ObjectMeta.Annotations = make(map[string]string, len(pipelineMeta.Annotations)) - } - for key, value := range pipelineMeta.Annotations { - pr.ObjectMeta.Annotations[key] = value - } - d, err := dag.Build(v1beta1.PipelineTaskList(pipelineSpec.Tasks), v1beta1.PipelineTaskList(pipelineSpec.Tasks).Deps()) if err != nil { // This Run has failed, so we need to mark it as failed and stop reconciling it @@ -931,6 +917,26 @@ func getTaskrunAnnotations(pr *v1beta1.PipelineRun) map[string]string { return annotations } +func propagateLabelsFromPipelineToPipelineRun(pr *v1beta1.PipelineRun, pipelineMeta *metav1.ObjectMeta) { + if pr.ObjectMeta.Labels == nil { + pr.ObjectMeta.Labels = make(map[string]string, len(pipelineMeta.Labels)+1) + } + for key, value := range pipelineMeta.Labels { + pr.ObjectMeta.Labels[key] = value + } + pr.ObjectMeta.Labels[pipeline.PipelineLabelKey] = pipelineMeta.Name +} + +func propagateAnnotationsFromPipelineToPipelineRun(pr *v1beta1.PipelineRun, pipelineMeta *metav1.ObjectMeta) { + if pr.ObjectMeta.Annotations == nil { + pr.ObjectMeta.Annotations = make(map[string]string, len(pipelineMeta.Annotations)) + } + for key, value := range pipelineMeta.Annotations { + pr.ObjectMeta.Annotations[key] = value + } + +} + func getTaskrunLabels(pr *v1beta1.PipelineRun, pipelineTaskName string, includePipelineLabels bool) map[string]string { // Propagate labels from PipelineRun to TaskRun. labels := make(map[string]string, len(pr.ObjectMeta.Labels)+1) diff --git a/pkg/reconciler/pipelinerun/pipelinerun_test.go b/pkg/reconciler/pipelinerun/pipelinerun_test.go index 20e9725916c..5b36c3c1bc0 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun_test.go +++ b/pkg/reconciler/pipelinerun/pipelinerun_test.go @@ -2557,9 +2557,14 @@ func TestReconcileCancelledFailsTaskRunCancellation(t *testing.T) { tb.PipelineRunStartTime(time.Now()), ), )} + ps := []*v1beta1.Pipeline{tb.Pipeline("test-pipeline", tb.PipelineNamespace("foo"), tb.PipelineSpec( + tb.PipelineTask("hello-world-1", "hello-world"), + tb.PipelineTask("hello-world-2", "hello-world"), + ))} d := test.Data{ PipelineRuns: prs, + Pipelines: ps, } testAssets, cancel := getPipelineRunController(t, d) @@ -2583,6 +2588,13 @@ func TestReconcileCancelledFailsTaskRunCancellation(t *testing.T) { t.Fatalf("Somehow had error getting reconciled run out of fake client: %s", err) } + if val, ok := reconciledRun.GetLabels()[pipeline.PipelineLabelKey]; !ok { + t.Fatalf("expected pipeline label") + if d := cmp.Diff("test-pipelines", val); d != "" { + t.Errorf("expected to see pipeline label. Diff %s", diff.PrintWantGot(d)) + } + } + // The PipelineRun should not be cancelled b/c we couldn't cancel the TaskRun condition := reconciledRun.Status.GetCondition(apis.ConditionSucceeded) if !condition.IsUnknown() { @@ -2701,6 +2713,82 @@ func TestReconcilePropagateLabels(t *testing.T) { } } +func TestReconcilePropagateLabelsPending(t *testing.T) { + names.TestingSeed() + taskName := "hello-world-1" + + ps := []*v1beta1.Pipeline{tb.Pipeline("test-pipeline", tb.PipelineNamespace("foo"), tb.PipelineSpec( + tb.PipelineTask(taskName, "hello-world"), + ))} + prs := []*v1beta1.PipelineRun{tb.PipelineRun("test-pipeline-run-with-labels", tb.PipelineRunNamespace("foo"), + tb.PipelineRunLabel("PipelineRunLabel", "PipelineRunValue"), + tb.PipelineRunSpec("test-pipeline", + tb.PipelineRunServiceAccountName("test-sa"), + tb.PipelineRunPending, + ), + )} + ts := []*v1beta1.Task{tb.Task("hello-world", tb.TaskNamespace("foo"))} + + d := test.Data{ + PipelineRuns: prs, + Pipelines: ps, + Tasks: ts, + } + prt := newPipelineRunTest(d, t) + defer prt.Cancel() + + _, clients := prt.reconcileRun("foo", "test-pipeline-run-with-labels", []string{}, false) + + reconciledRun, err := clients.Pipeline.TektonV1beta1().PipelineRuns("foo").Get(prt.TestAssets.Ctx, "test-pipeline-run-with-labels", metav1.GetOptions{}) + if err != nil { + t.Fatalf("unexpected error when updating status: %v", err) + } + + want := "test-pipeline" + got := reconciledRun.ObjectMeta.Labels["tekton.dev/pipeline"] + if d := cmp.Diff(want, got); d != "" { + t.Errorf("expected to see label %v created. Diff %s", want, diff.PrintWantGot(d)) + } +} + +func TestReconcilePropagateLabelsCancelled(t *testing.T) { + names.TestingSeed() + taskName := "hello-world-1" + + ps := []*v1beta1.Pipeline{tb.Pipeline("test-pipeline", tb.PipelineNamespace("foo"), tb.PipelineSpec( + tb.PipelineTask(taskName, "hello-world"), + ))} + prs := []*v1beta1.PipelineRun{tb.PipelineRun("test-pipeline-run-with-labels", tb.PipelineRunNamespace("foo"), + tb.PipelineRunLabel("PipelineRunLabel", "PipelineRunValue"), + tb.PipelineRunSpec("test-pipeline", + tb.PipelineRunServiceAccountName("test-sa"), + tb.PipelineRunCancelled, + ), + )} + ts := []*v1beta1.Task{tb.Task("hello-world", tb.TaskNamespace("foo"))} + + d := test.Data{ + PipelineRuns: prs, + Pipelines: ps, + Tasks: ts, + } + prt := newPipelineRunTest(d, t) + defer prt.Cancel() + + _, clients := prt.reconcileRun("foo", "test-pipeline-run-with-labels", []string{}, false) + + reconciledRun, err := clients.Pipeline.TektonV1beta1().PipelineRuns("foo").Get(prt.TestAssets.Ctx, "test-pipeline-run-with-labels", metav1.GetOptions{}) + if err != nil { + t.Fatalf("unexpected error when updating status: %v", err) + } + + want := "test-pipeline" + got := reconciledRun.ObjectMeta.Labels["tekton.dev/pipeline"] + if d := cmp.Diff(want, got); d != "" { + t.Errorf("expected to see label %v created. Diff %s", want, diff.PrintWantGot(d)) + } +} + func TestReconcileWithDifferentServiceAccounts(t *testing.T) { names.TestingSeed()