Skip to content

Commit

Permalink
[TEP-0100] Implementation for embedded TaskRun and Run statuses in Pi…
Browse files Browse the repository at this point in the history
…pelineRuns

See:
* https://github.com/tektoncd/community/blob/main/teps/0100-embedded-taskruns-and-runs-status-in-pipelineruns.md
* tektoncd#4705
* tektoncd#4734
* tektoncd#3140

This implements TEP-0100, allowing for choosing between the original full embedded `TaskRun` and
`Run` statuses in `PipelineRun` statuses, minimal child references to the underlying `TaskRun` and
`Run`s, or both, building on top of the flags/fields/docs changes in tektoncd#4705 and the test changes in

Signed-off-by: Andrew Bayer <[email protected]>
  • Loading branch information
abayer committed Apr 8, 2022
1 parent e46259e commit 13fd232
Show file tree
Hide file tree
Showing 15 changed files with 2,238 additions and 268 deletions.
2 changes: 1 addition & 1 deletion docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ features](#alpha-features) to be used.
- `embedded-status`: set this flag to "full" to enable full embedding of `TaskRun` and `Run` statuses in the
`PipelineRun` status. Set it to "minimal" to populate the `ChildReferences` field in the `PipelineRun` status with
name, kind, and API version information for each `TaskRun` and `Run` in the `PipelineRun` instead. Set it to "both" to
do both. For more information, see [Configuring usage of `TaskRun` and `Run` embedded statuses](pipelineruns.md#configuring-usage-of-taskrun-and-run-embedded-statuses). **NOTE**: This functionality is not yet active.
do both. For more information, see [Configuring usage of `TaskRun` and `Run` embedded statuses](pipelineruns.md#configuring-usage-of-taskrun-and-run-embedded-statuses).

For example:

Expand Down
15 changes: 15 additions & 0 deletions pkg/apis/pipeline/v1beta1/pipelinerun_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,21 @@ type ChildStatusReference struct {
WhenExpressions []WhenExpression `json:"whenExpressions,omitempty"`
}

// GetConditionChecksAsMap returns a map representation of this ChildStatusReference's ConditionChecks, in the same form
// as PipelineRunTaskRunStatus.ConditionChecks.
func (cr ChildStatusReference) GetConditionChecksAsMap() map[string]*PipelineRunConditionCheckStatus {
if len(cr.ConditionChecks) == 0 {
return nil
}
ccMap := make(map[string]*PipelineRunConditionCheckStatus)

for _, cc := range cr.ConditionChecks {
ccMap[cc.ConditionCheckName] = &cc.PipelineRunConditionCheckStatus
}

return ccMap
}

// PipelineRunStatusFields holds the fields of PipelineRunStatus' status.
// This is defined separately and inlined so that other types can readily
// consume these fields via duck typing.
Expand Down
51 changes: 46 additions & 5 deletions pkg/reconciler/pipelinerun/cancel.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"strings"
"time"

"github.com/tektoncd/pipeline/pkg/apis/config"

"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
clientset "github.com/tektoncd/pipeline/pkg/client/clientset/versioned"
Expand Down Expand Up @@ -99,18 +101,21 @@ func cancelPipelineRun(ctx context.Context, logger *zap.SugaredLogger, pr *v1bet
func cancelPipelineTaskRuns(ctx context.Context, logger *zap.SugaredLogger, pr *v1beta1.PipelineRun, clientSet clientset.Interface) []string {
errs := []string{}

// Loop over the TaskRuns in the PipelineRun status.
// If a TaskRun is not in the status yet we should not cancel it anyways.
for taskRunName := range pr.Status.TaskRuns {
trNames, runNames, err := filterChildObjectsFromPRStatus(ctx, pr.Status)
if err != nil {
errs = append(errs, err.Error())
}

for _, taskRunName := range trNames {
logger.Infof("cancelling TaskRun %s", taskRunName)

if _, err := clientSet.TektonV1beta1().TaskRuns(pr.Namespace).Patch(ctx, taskRunName, types.JSONPatchType, cancelTaskRunPatchBytes, metav1.PatchOptions{}, ""); err != nil {
errs = append(errs, fmt.Errorf("Failed to patch TaskRun `%s` with cancellation: %s", taskRunName, err).Error())
continue
}
}
// Loop over the Runs in the PipelineRun status.
for runName := range pr.Status.Runs {

for _, runName := range runNames {
logger.Infof("cancelling Run %s", runName)

if err := cancelRun(ctx, runName, pr.Namespace, clientSet); err != nil {
Expand All @@ -122,6 +127,42 @@ func cancelPipelineTaskRuns(ctx context.Context, logger *zap.SugaredLogger, pr *
return errs
}

// filterChildObjectsFromPRStatus returns taskruns and runs owned by the pipelineRun, based on the value of the embedded status flag.
func filterChildObjectsFromPRStatus(ctx context.Context, prs v1beta1.PipelineRunStatus) ([]string, []string, error) {
cfg := config.FromContextOrDefaults(ctx)

var trNames []string
var runNames []string
unknownChildKinds := make(map[string]string)

if cfg.FeatureFlags.EmbeddedStatus != config.FullEmbeddedStatus {
for _, cr := range prs.ChildReferences {
switch cr.Kind {
case "TaskRun":
trNames = append(trNames, cr.Name)
case "Run":
runNames = append(runNames, cr.Name)
default:
unknownChildKinds[cr.Name] = cr.Kind
}
}
} else {
for trName := range prs.TaskRuns {
trNames = append(trNames, trName)
}
for runName := range prs.Runs {
runNames = append(runNames, runName)
}
}

var err error
if len(unknownChildKinds) > 0 {
err = fmt.Errorf("found child objects of unknown kinds: %v", unknownChildKinds)
}

return trNames, runNames, err
}

// gracefullyCancelPipelineRun marks any non-final resolved TaskRun(s) as cancelled and runs finally.
func gracefullyCancelPipelineRun(ctx context.Context, logger *zap.SugaredLogger, pr *v1beta1.PipelineRun, clientSet clientset.Interface) error {
errs := cancelPipelineTaskRuns(ctx, logger, pr, clientSet)
Expand Down
Loading

0 comments on commit 13fd232

Please sign in to comment.