Skip to content

Commit 8c8f2a5

Browse files
committed
Add Support for managedBy field in TaskRun and PipelineRun
Added a "managedBy" field to delegate responsibility of controlling the lifecycle of PipelineRuns/TaskRuns. The semantics of the field: Whenever the value is set, and it does not point to the built-in controller, then we skip the reconciliation. * The field is immutable * The field is not defaulted
1 parent c4cf850 commit 8c8f2a5

15 files changed

+416
-21
lines changed

config/300-crds/300-pipelinerun.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3130,6 +3130,11 @@ spec:
31303130
description: PipelineRunSpec defines the desired state of PipelineRun
31313131
type: object
31323132
properties:
3133+
managedBy:
3134+
description: |-
3135+
ManagedBy is the platform that is managing this PipelineRun.
3136+
This field is immutable.
3137+
type: string
31333138
params:
31343139
description: Params is a list of parameter names and values.
31353140
type: array

config/300-crds/300-taskrun.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2336,6 +2336,11 @@ spec:
23362336
if enabled, pause TaskRun on failure of a step
23372337
failed step will not exit
23382338
type: string
2339+
managedBy:
2340+
description: |-
2341+
ManagedBy is the platform that is managing this TaskRun.
2342+
This field is immutable.
2343+
type: string
23392344
params:
23402345
description: Params is a list of Param
23412346
type: array

pkg/apis/pipeline/register.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ const (
5555
// MemberOfLabelKey is used as the label identifier for a PipelineTask
5656
// Set to Tasks/Finally depending on the position of the PipelineTask
5757
MemberOfLabelKey = GroupName + "/memberOf"
58+
59+
// ManagedBy is the value of the "managedBy" field for resources
60+
// managed by the Tekton Pipeline controller.
61+
ManagedBy = GroupName + "/pipeline"
5862
)
5963

6064
var (

pkg/apis/pipeline/v1/openapi_generated.go

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/apis/pipeline/v1/pipelinerun_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ type PipelineRunSpec struct {
283283
// +optional
284284
// +listType=atomic
285285
TaskRunSpecs []PipelineTaskRunSpec `json:"taskRunSpecs,omitempty"`
286+
// ManagedBy is the platform that is managing this PipelineRun.
287+
// This field is immutable.
288+
// +optional
289+
ManagedBy string `json:"managedBy,omitempty"`
286290
}
287291

288292
// TimeoutFields allows granular specification of pipeline, task, and finally timeouts

pkg/apis/pipeline/v1/pipelinerun_validation.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,14 +140,18 @@ func (ps *PipelineRunSpec) ValidateUpdate(ctx context.Context) (errs *apis.Field
140140
old := &oldObj.Spec
141141

142142
// If already in the done state, the spec cannot be modified. Otherwise, only the status field can be modified.
143-
tips := "Once the PipelineRun is complete, no updates are allowed"
144-
if !oldObj.IsDone() {
145-
old = old.DeepCopy()
146-
old.Status = ps.Status
147-
tips = "Once the PipelineRun has started, only status updates are allowed"
148-
}
149-
if !equality.Semantic.DeepEqual(old, ps) {
150-
errs = errs.Also(apis.ErrInvalidValue(tips, ""))
143+
if old.ManagedBy != ps.ManagedBy {
144+
errs = errs.Also(apis.ErrInvalidValue("managedBy is immutable", "spec.managedBy"))
145+
} else {
146+
tips := "Once the PipelineRun is complete, no updates are allowed"
147+
if !oldObj.IsDone() {
148+
old = old.DeepCopy()
149+
old.Status = ps.Status
150+
tips = "Once the PipelineRun has started, only status updates are allowed"
151+
}
152+
if !equality.Semantic.DeepEqual(old, ps) {
153+
errs = errs.Also(apis.ErrInvalidValue(tips, ""))
154+
}
151155
}
152156

153157
return

pkg/apis/pipeline/v1/pipelinerun_validation_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,6 +1667,56 @@ func TestPipelineRunSpec_ValidateUpdate(t *testing.T) {
16671667
Message: `invalid value: Once the PipelineRun is complete, no updates are allowed`,
16681668
Paths: []string{""},
16691669
},
1670+
}, {
1671+
name: "is update ctx, baseline is not done, managedBy changes",
1672+
baselinePipelineRun: &v1.PipelineRun{
1673+
Spec: v1.PipelineRunSpec{
1674+
ManagedBy: "tekton.dev/pipeline",
1675+
},
1676+
Status: v1.PipelineRunStatus{
1677+
Status: duckv1.Status{
1678+
Conditions: duckv1.Conditions{
1679+
{Type: apis.ConditionSucceeded, Status: corev1.ConditionUnknown},
1680+
},
1681+
},
1682+
},
1683+
},
1684+
pipelineRun: &v1.PipelineRun{
1685+
Spec: v1.PipelineRunSpec{
1686+
ManagedBy: "some-other-controller",
1687+
},
1688+
},
1689+
isCreate: false,
1690+
isUpdate: true,
1691+
expectedError: apis.FieldError{
1692+
Message: `invalid value: managedBy is immutable`,
1693+
Paths: []string{"spec.managedBy"},
1694+
},
1695+
}, {
1696+
name: "is update ctx, baseline is unknown, managedBy changes",
1697+
baselinePipelineRun: &v1.PipelineRun{
1698+
Spec: v1.PipelineRunSpec{
1699+
ManagedBy: "tekton.dev/pipeline",
1700+
},
1701+
Status: v1.PipelineRunStatus{
1702+
Status: duckv1.Status{
1703+
Conditions: duckv1.Conditions{
1704+
{Type: apis.ConditionSucceeded, Status: corev1.ConditionUnknown},
1705+
},
1706+
},
1707+
},
1708+
},
1709+
pipelineRun: &v1.PipelineRun{
1710+
Spec: v1.PipelineRunSpec{
1711+
ManagedBy: "some-other-controller",
1712+
},
1713+
},
1714+
isCreate: false,
1715+
isUpdate: true,
1716+
expectedError: apis.FieldError{
1717+
Message: `invalid value: managedBy is immutable`,
1718+
Paths: []string{"spec.managedBy"},
1719+
},
16701720
},
16711721
}
16721722

pkg/apis/pipeline/v1/swagger.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,10 @@
661661
"description": "PipelineRunSpec defines the desired state of PipelineRun",
662662
"type": "object",
663663
"properties": {
664+
"managedBy": {
665+
"description": "ManagedBy is the platform that is managing this PipelineRun. This field is immutable.",
666+
"type": "string"
667+
},
664668
"params": {
665669
"description": "Params is a list of parameter names and values.",
666670
"type": "array",
@@ -2045,6 +2049,10 @@
20452049
"debug": {
20462050
"$ref": "#/definitions/v1.TaskRunDebug"
20472051
},
2052+
"managedBy": {
2053+
"description": "ManagedBy is the platform that is managing this TaskRun. This field is immutable.",
2054+
"type": "string"
2055+
},
20482056
"params": {
20492057
"type": "array",
20502058
"items": {

pkg/apis/pipeline/v1/taskrun_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ type TaskRunSpec struct {
8585
SidecarSpecs []TaskRunSidecarSpec `json:"sidecarSpecs,omitempty"`
8686
// Compute resources to use for this TaskRun
8787
ComputeResources *corev1.ResourceRequirements `json:"computeResources,omitempty"`
88+
// ManagedBy is the platform that is managing this TaskRun.
89+
// This field is immutable.
90+
// +optional
91+
ManagedBy string `json:"managedBy,omitempty"`
8892
}
8993

9094
// TaskRunSpecStatus defines the TaskRun spec status the user can provide

pkg/apis/pipeline/v1/taskrun_validation.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,20 @@ func (ts *TaskRunSpec) ValidateUpdate(ctx context.Context) (errs *apis.FieldErro
135135

136136
// If already in the done state, the spec cannot be modified.
137137
// Otherwise, only the status, statusMessage field can be modified.
138-
tips := "Once the TaskRun is complete, no updates are allowed"
139-
if !oldObj.IsDone() {
140-
old = old.DeepCopy()
141-
old.Status = ts.Status
142-
old.StatusMessage = ts.StatusMessage
143-
tips = "Once the TaskRun has started, only status and statusMessage updates are allowed"
144-
}
138+
if old.ManagedBy != ts.ManagedBy {
139+
errs = errs.Also(apis.ErrInvalidValue("managedBy is immutable", "spec.managedBy"))
140+
} else {
141+
tips := "Once the TaskRun is complete, no updates are allowed"
142+
if !oldObj.IsDone() {
143+
old = old.DeepCopy()
144+
old.Status = ts.Status
145+
old.StatusMessage = ts.StatusMessage
146+
tips = "Once the TaskRun has started, only status and statusMessage updates are allowed"
147+
}
145148

146-
if !equality.Semantic.DeepEqual(old, ts) {
147-
errs = errs.Also(apis.ErrInvalidValue(tips, ""))
149+
if !equality.Semantic.DeepEqual(old, ts) {
150+
errs = errs.Also(apis.ErrInvalidValue(tips, ""))
151+
}
148152
}
149153

150154
return

0 commit comments

Comments
 (0)