Skip to content

Commit 75f3776

Browse files
GregDritschlertekton-robot
authored andcommitted
Integrate custom tasks into Pipelines
A PipelineTask now can reference a custom task. This causes the PipelineRun reconciler to create a Run instead of a TaskRun. Pipeline parameters can be passed to the custom task. The custom task's results can be used by other Pipeline tasks and by the Pipeline results.
1 parent 79639cc commit 75f3776

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1694
-500
lines changed

config/config-feature-flags.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,8 @@ data:
8282
# This is an experimental feature and thus should still be considered
8383
# an alpha feature.
8484
enable-tekton-oci-bundles: "false"
85+
# Setting this flag to "true" enables the use of custom tasks from
86+
# within pipelines.
87+
# This is an experimental feature and thus should still be considered
88+
# an alpha feature.
89+
enable-custom-tasks: "false"

docs/install.md

+3
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,9 @@ not running.
353353
and use Workspaces to mount credentials from Secrets instead.
354354
The default is `false`. For more information, see the [associated issue](https://github.com/tektoncd/pipeline/issues/3399).
355355

356+
- `enable-custom-tasks`: set this flag to `"true"` to enable the
357+
use of custom tasks in pipelines.
358+
356359
For example:
357360

358361
```yaml

docs/pipelines.md

+85
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ weight: 3
2525
- [Configuring the `Task` execution order](#configuring-the-task-execution-order)
2626
- [Adding a description](#adding-a-description)
2727
- [Adding `Finally` to the `Pipeline`](#adding-finally-to-the-pipeline)
28+
- [Using Custom Tasks](#using-custom-tasks)
2829
- [Code examples](#code-examples)
2930

3031
## Overview
@@ -888,6 +889,90 @@ In this example, `PipelineResults` is set to:
888889
],
889890
```
890891

892+
## Using Custom Tasks
893+
894+
**Note: This is only allowed if `enable-custom-tasks` is set to
895+
`"true"` in the `feature-flags` configmap, see [`install.md`](./install.md#customizing-the-pipelines-controller-behavior)**
896+
897+
[Custom Tasks](https://github.com/tektoncd/community/blob/master/teps/0002-custom-tasks.md)
898+
can implement behavior that doesn't correspond directly to running a workload in a `Pod` on the cluster.
899+
For example, a custom task might execute some operation outside of the cluster and wait for its execution to complete.
900+
901+
A PipelineRun starts a custom task by creating a [`Run`](https://github.com/tektoncd/pipeline/blob/master/docs/runs.md) instead of a `TaskRun`.
902+
In order for a custom task to execute, there must be a custom task controller running on the cluster
903+
that is responsible for watching and updating `Run`s which reference their type.
904+
If no such controller is running, those `Run`s will never complete and Pipelines using them will time out.
905+
906+
Custom tasks are an **_experimental alpha feature_** and should be expected to change
907+
in breaking ways or even be removed.
908+
909+
### Specifying the target Custom Task
910+
911+
To specify the custom task type you want to execute, the `taskRef` field
912+
must include the custom task's `apiVersion` and `kind` as shown below:
913+
914+
```yaml
915+
spec:
916+
tasks:
917+
- name: run-custom-task
918+
taskRef:
919+
apiVersion: example.dev/v1alpha1
920+
kind: Example
921+
```
922+
923+
This creates a `Run` of a custom task of type `Example` in the `example.dev` API group with the version `v1alpha1`.
924+
925+
You can also specify the `name` of a custom task resource object previously defined in the cluster.
926+
927+
```yaml
928+
spec:
929+
tasks:
930+
- name: run-custom-task
931+
taskRef:
932+
apiVersion: example.dev/v1alpha1
933+
kind: Example
934+
name: myexample
935+
```
936+
937+
If the `taskRef` specifies a name, the custom task controller should look up the
938+
`Example` resource with that name and use that object to configure the execution.
939+
940+
If the `taskRef` does not specify a name, the custom task controller might support
941+
some default behavior for executing unnamed tasks.
942+
943+
### Specifying `Parameters`
944+
945+
If a custom task supports [`parameters`](tasks.md#parameters), you can use the
946+
`params` field to specify their values:
947+
948+
```yaml
949+
spec:
950+
spec:
951+
tasks:
952+
- name: run-custom-task
953+
taskRef:
954+
apiVersion: example.dev/v1alpha1
955+
kind: Example
956+
name: myexample
957+
params:
958+
- name: foo
959+
value: bah
960+
```
961+
962+
### Using `Results`
963+
964+
If the custom task produces results, you can reference them in a Pipeline using the normal syntax,
965+
`$(tasks.<task-name>.results.<result-name>)`.
966+
967+
### Limitations
968+
969+
Pipelines do not directly support passing the following items to custom tasks:
970+
* Pipeline Resources
971+
* Workspaces
972+
* Service account name
973+
* Pod templates
974+
975+
891976
## Code examples
892977

893978
For a better understanding of `Pipelines`, study [our code examples](https://github.com/tektoncd/pipeline/tree/master/examples).

docs/runs.md

-4
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,6 @@ will have no `.status` value and no further action will be taken.
3535
`Run`s are an **_experimental alpha feature_** and should be expected to change
3636
in breaking ways or even be removed.
3737

38-
`Run`s are not currently integrated with Pipelines, and require a running
39-
third-party controller to actually perform any work. Without a third-party
40-
controller, `Run`s will just exist without a status indefinitely.
41-
4238
## Configuring a `Run`
4339

4440
A `Run` definition supports the following fields:

go.sum

+2-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

hack/update-codegen.sh

+5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ ${PREFIX}/deepcopy-gen \
5858
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt \
5959
-i github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1/storage
6060

61+
${PREFIX}/deepcopy-gen \
62+
-O zz_generated.deepcopy \
63+
--go-header-file ${REPO_ROOT_DIR}/hack/boilerplate/boilerplate.go.txt \
64+
-i github.com/tektoncd/pipeline/pkg/apis/run/v1alpha1
65+
6166
# Knative Injection
6267
# This generates the knative injection packages for the resource package (v1alpha1).
6368
# This is separate from the pipeline package for the same reason as client and all (see above).

pkg/apis/config/feature_flags.go

+6
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@ const (
3232
runningInEnvWithInjectedSidecarsKey = "running-in-environment-with-injected-sidecars"
3333
requireGitSSHSecretKnownHostsKey = "require-git-ssh-secret-known-hosts" // nolint: gosec
3434
enableTektonOCIBundles = "enable-tekton-oci-bundles"
35+
enableCustomTasks = "enable-custom-tasks"
3536
DefaultDisableHomeEnvOverwrite = false
3637
DefaultDisableWorkingDirOverwrite = false
3738
DefaultDisableAffinityAssistant = false
3839
DefaultDisableCredsInit = false
3940
DefaultRunningInEnvWithInjectedSidecars = true
4041
DefaultRequireGitSSHSecretKnownHosts = false
4142
DefaultEnableTektonOciBundles = false
43+
DefaultEnableCustomTasks = false
4244
)
4345

4446
// FeatureFlags holds the features configurations
@@ -51,6 +53,7 @@ type FeatureFlags struct {
5153
RunningInEnvWithInjectedSidecars bool
5254
RequireGitSSHSecretKnownHosts bool
5355
EnableTektonOCIBundles bool
56+
EnableCustomTasks bool
5457
}
5558

5659
// GetFeatureFlagsConfigName returns the name of the configmap containing all
@@ -99,6 +102,9 @@ func NewFeatureFlagsFromMap(cfgMap map[string]string) (*FeatureFlags, error) {
99102
if err := setFeature(enableTektonOCIBundles, DefaultEnableTektonOciBundles, &tc.EnableTektonOCIBundles); err != nil {
100103
return nil, err
101104
}
105+
if err := setFeature(enableCustomTasks, DefaultEnableCustomTasks, &tc.EnableCustomTasks); err != nil {
106+
return nil, err
107+
}
102108
return &tc, nil
103109
}
104110

pkg/apis/config/feature_flags_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) {
4747
RunningInEnvWithInjectedSidecars: false,
4848
RequireGitSSHSecretKnownHosts: true,
4949
EnableTektonOCIBundles: true,
50+
EnableCustomTasks: true,
5051
},
5152
fileName: "feature-flags-all-flags-set",
5253
},

pkg/apis/config/testdata/feature-flags-all-flags-set.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ data:
2424
running-in-environment-with-injected-sidecars: "false"
2525
require-git-ssh-secret-known-hosts: "true"
2626
enable-tekton-oci-bundles: "true"
27+
enable-custom-tasks: "true"

pkg/apis/pipeline/v1alpha1/run_types.go

+10-95
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@ package v1alpha1
1818

1919
import (
2020
"fmt"
21-
"time"
2221

2322
"github.com/tektoncd/pipeline/pkg/apis/pipeline"
2423
v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
24+
runv1alpha1 "github.com/tektoncd/pipeline/pkg/apis/run/v1alpha1"
2525
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26-
"k8s.io/apimachinery/pkg/runtime"
2726
"k8s.io/apimachinery/pkg/runtime/schema"
28-
"k8s.io/apimachinery/pkg/util/json"
2927
"knative.dev/pkg/apis"
3028
duckv1 "knative.dev/pkg/apis/duck/v1"
3129
)
@@ -75,85 +73,16 @@ func (rs RunSpec) GetParam(name string) *v1beta1.Param {
7573
return nil
7674
}
7775

78-
type RunStatus struct {
79-
duckv1.Status `json:",inline"`
76+
const (
77+
// RunReasonCancelled must be used in the Condition Reason to indicate that a Run was cancelled.
78+
RunReasonCancelled = "RunCancelled"
79+
)
8080

81-
// RunStatusFields inlines the status fields.
82-
RunStatusFields `json:",inline"`
83-
}
81+
// RunStatus defines the observed state of Run.
82+
type RunStatus = runv1alpha1.RunStatus
8483

8584
var runCondSet = apis.NewBatchConditionSet()
8685

87-
// GetCondition returns the Condition matching the given type.
88-
func (r *RunStatus) GetCondition(t apis.ConditionType) *apis.Condition {
89-
return runCondSet.Manage(r).GetCondition(t)
90-
}
91-
92-
// InitializeConditions will set all conditions in runCondSet to unknown for the PipelineRun
93-
// and set the started time to the current time
94-
func (r *RunStatus) InitializeConditions() {
95-
started := false
96-
if r.StartTime.IsZero() {
97-
r.StartTime = &metav1.Time{Time: time.Now()}
98-
started = true
99-
}
100-
conditionManager := runCondSet.Manage(r)
101-
conditionManager.InitializeConditions()
102-
// Ensure the started reason is set for the "Succeeded" condition
103-
if started {
104-
initialCondition := conditionManager.GetCondition(apis.ConditionSucceeded)
105-
initialCondition.Reason = "Started"
106-
conditionManager.SetCondition(*initialCondition)
107-
}
108-
}
109-
110-
// SetCondition sets the condition, unsetting previous conditions with the same
111-
// type as necessary.
112-
func (r *RunStatus) SetCondition(newCond *apis.Condition) {
113-
if newCond != nil {
114-
runCondSet.Manage(r).SetCondition(*newCond)
115-
}
116-
}
117-
118-
// MarkRunSucceeded changes the Succeeded condition to True with the provided reason and message.
119-
func (r *RunStatus) MarkRunSucceeded(reason, messageFormat string, messageA ...interface{}) {
120-
runCondSet.Manage(r).MarkTrueWithReason(apis.ConditionSucceeded, reason, messageFormat, messageA...)
121-
succeeded := r.GetCondition(apis.ConditionSucceeded)
122-
r.CompletionTime = &succeeded.LastTransitionTime.Inner
123-
}
124-
125-
// MarkRunFailed changes the Succeeded condition to False with the provided reason and message.
126-
func (r *RunStatus) MarkRunFailed(reason, messageFormat string, messageA ...interface{}) {
127-
runCondSet.Manage(r).MarkFalse(apis.ConditionSucceeded, reason, messageFormat, messageA...)
128-
succeeded := r.GetCondition(apis.ConditionSucceeded)
129-
r.CompletionTime = &succeeded.LastTransitionTime.Inner
130-
}
131-
132-
// MarkRunRunning changes the Succeeded condition to Unknown with the provided reason and message.
133-
func (r *RunStatus) MarkRunRunning(reason, messageFormat string, messageA ...interface{}) {
134-
runCondSet.Manage(r).MarkUnknown(apis.ConditionSucceeded, reason, messageFormat, messageA...)
135-
}
136-
137-
// DecodeExtraFields deserializes the extra fields in the Run status.
138-
func (r *RunStatus) DecodeExtraFields(into interface{}) error {
139-
if len(r.ExtraFields.Raw) == 0 {
140-
return nil
141-
}
142-
return json.Unmarshal(r.ExtraFields.Raw, into)
143-
}
144-
145-
// EncodeExtraFields serializes the extra fields in the Run status.
146-
func (r *RunStatus) EncodeExtraFields(from interface{}) error {
147-
data, err := json.Marshal(from)
148-
if err != nil {
149-
return err
150-
}
151-
r.ExtraFields = runtime.RawExtension{
152-
Raw: data,
153-
}
154-
return nil
155-
}
156-
15786
// GetConditionSet retrieves the condition set for this resource. Implements
15887
// the KRShaped interface.
15988
func (r *Run) GetConditionSet() apis.ConditionSet { return runCondSet }
@@ -165,24 +94,10 @@ func (r *Run) GetStatus() *duckv1.Status { return &r.Status.Status }
16594
// RunStatusFields holds the fields of Run's status. This is defined
16695
// separately and inlined so that other types can readily consume these fields
16796
// via duck typing.
168-
type RunStatusFields struct {
169-
// StartTime is the time the build is actually started.
170-
// +optional
171-
StartTime *metav1.Time `json:"startTime,omitempty"`
172-
173-
// CompletionTime is the time the build completed.
174-
// +optional
175-
CompletionTime *metav1.Time `json:"completionTime,omitempty"`
176-
177-
// Results reports any output result values to be consumed by later
178-
// tasks in a pipeline.
179-
// +optional
180-
Results []v1beta1.TaskRunResult `json:"results,omitempty"`
97+
type RunStatusFields = runv1alpha1.RunStatusFields
18198

182-
// ExtraFields holds arbitrary fields provided by the custom task
183-
// controller.
184-
ExtraFields runtime.RawExtension `json:"extraFields,omitempty"`
185-
}
99+
// RunResult used to describe the results of a task
100+
type RunResult = runv1alpha1.RunResult
186101

187102
// +genclient
188103
// +genreconciler

0 commit comments

Comments
 (0)