Skip to content

Commit 287fd76

Browse files
Add support for custom tasks to use workspaces, service accounts, and pod templates.
These features will be needed to build more complex custom tasks.
1 parent 8947104 commit 287fd76

File tree

12 files changed

+506
-110
lines changed

12 files changed

+506
-110
lines changed

docs/pipelineruns.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,9 @@ set for the target [`namespace`](https://kubernetes.io/docs/concepts/overview/wo
258258

259259
For more information, see [`ServiceAccount`](auth.md).
260260

261+
[`Custom tasks`](pipelines.md#using-custom-tasks) may or may not use a service account name.
262+
Consult the documentation of the custom task that you are using to determine whether it supports a service account name.
263+
261264
### Mapping `ServiceAccount` credentials to `Tasks`
262265

263266
If you require more granularity in specifying execution credentials, use the `serviceAccountNames` field to
@@ -341,6 +344,9 @@ spec:
341344
claimName: my-volume-claim
342345
```
343346

347+
[`Custom tasks`](pipelines.md#using-custom-tasks) may or may not use a pod template.
348+
Consult the documentation of the custom task that you are using to determine whether it supports a pod template.
349+
344350
### Specifying taskRunSpecs
345351

346352
Specifies a list of `PipelineTaskRunSpec` which contains `TaskServiceAccountName`, `TaskPodTemplate`
@@ -385,6 +391,9 @@ For more information, see the following topics:
385391
- For a list of supported `Volume` types, see [Specifying `VolumeSources` in `Workspaces`](workspaces.md#specifying-volumesources-in-workspaces).
386392
- For an end-to-end example, see [`Workspaces` in a `PipelineRun`](../examples/v1beta1/pipelineruns/workspaces.yaml).
387393

394+
[`Custom tasks`](pipelines.md#using-custom-tasks) may or may not use workspaces.
395+
Consult the documentation of the custom task that you are using to determine whether it supports workspaces.
396+
388397
### Specifying `LimitRange` values
389398

390399
In order to only consume the bare minimum amount of resources needed to execute one `Step` at a

docs/pipelines.md

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -954,13 +954,12 @@ If the `taskRef` specifies a name, the custom task controller should look up the
954954
If the `taskRef` does not specify a name, the custom task controller might support
955955
some default behavior for executing unnamed tasks.
956956

957-
### Specifying `Parameters`
957+
### Specifying parameters
958958

959959
If a custom task supports [`parameters`](tasks.md#parameters), you can use the
960960
`params` field to specify their values:
961961

962962
```yaml
963-
spec:
964963
spec:
965964
tasks:
966965
- name: run-custom-task
@@ -973,21 +972,36 @@ spec:
973972
value: bah
974973
```
975974

975+
### Specifying workspaces
976+
977+
If the custom task supports it, you can provide [`Workspaces`](workspaces.md#using-workspaces-in-tasks) to share data with the custom task.
978+
979+
```yaml
980+
spec:
981+
tasks:
982+
- name: run-custom-task
983+
taskRef:
984+
apiVersion: example.dev/v1alpha1
985+
kind: Example
986+
name: myexample
987+
workspaces:
988+
- name: my-workspace
989+
```
990+
991+
Consult the documentation of the custom task that you are using to determine whether it supports workspaces and how to name them.
992+
976993
### Using `Results`
977994

978995
If the custom task produces results, you can reference them in a Pipeline using the normal syntax,
979996
`$(tasks.<task-name>.results.<result-name>)`.
980997

981998
### Limitations
982999

983-
Pipelines do not directly support passing the following items to custom tasks:
1000+
Pipelines do not support the following items with custom tasks:
9841001
* Pipeline Resources
985-
* Workspaces
986-
* Service account name
987-
* Pod templates
988-
989-
A pipeline task that references a custom task cannot reference `Conditions`.
990-
`Conditions` are deprecated. Use [`WhenExpressions`](#guard-task-execution-using-whenexpressions) instead.
1002+
* [`retries`](#using-the-retries-parameter)
1003+
* [`timeout`](#configuring-the-failure-timeout)
1004+
* Conditions (`Conditions` are deprecated. Use [`WhenExpressions`](#guard-task-execution-using-whenexpressions) instead.)
9911005

9921006
## Code examples
9931007

docs/runs.md

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ weight: 2
1010
- [Overview](#overview)
1111
- [Configuring a `Run`](#configuring-a-run)
1212
- [Specifying the target Custom Task](#specifying-the-target-custom-task)
13-
- [Specifying `Parameters`](#specifying-parameters)
13+
- [Specifying Parameters](#specifying-parameters)
14+
- [Specifying Workspaces, Service Account, and Pod Template](#specifying-workspaces-service-account-and-pod-template)
1415
- [Monitoring execution status](#monitoring-execution-status)
1516
- [Monitoring `Results`](#monitoring-results)
1617
- [Code examples](#code-examples)
@@ -51,6 +52,12 @@ A `Run` definition supports the following fields:
5152
- Optional:
5253
- [`params`](#specifying-parameters) - Specifies the desired execution
5354
parameters for the custom task.
55+
- [`serviceAccountName`](#specifying-a-serviceaccount) - Specifies a `ServiceAccount`
56+
object that provides custom credentials for executing the `Run`.
57+
- [`workspaces`](#specifying-workspaces) - Specifies the physical volumes to use for the
58+
[`Workspaces`](workspaces.md) required by a custom task.
59+
- [`podTemplate`](#specifying-a-pod-template) - Specifies a [`Pod` template](podtemplates.md) to use
60+
to configure pods created by the custom task.
5461

5562
[kubernetes-overview]:
5663
https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
@@ -108,6 +115,57 @@ If the custom task controller knows how to interpret the parameter value, it
108115
will do so. It might enforce that some parameter values must be specified, or
109116
reject unknown parameter values.
110117

118+
### Specifying Workspaces, Service Account, and Pod Template
119+
120+
A `Run` object can specify workspaces, a service account name, or a pod template.
121+
These are intended to be used with custom tasks that create Pods or other resources that embed a Pod specification.
122+
The custom task can use these specifications to construct the Pod specification.
123+
Not all custom tasks will support these values.
124+
Consult the documentation of the custom task that you are using to determine whether these values apply.
125+
126+
#### Specifying workspaces
127+
128+
If the custom task supports it, you can provide [`Workspaces`](workspaces.md) to share data with the custom task.
129+
130+
```yaml
131+
spec:
132+
workspaces:
133+
- name: my-workspace
134+
emptyDir: {}
135+
```
136+
137+
Consult the documentation of the custom task that you are using to determine whether it supports workspaces and how to name them.
138+
139+
#### Specifying a ServiceAccount
140+
141+
If the custom task supports it, you can execute the `Run` with a specific set of credentials by
142+
specifying a `ServiceAccount` object name in the `serviceAccountName` field in your `Run`
143+
definition. If you do not explicitly specify this, the `Run` executes with the service account
144+
specified in the `configmap-defaults` `ConfigMap`. If this default is not specified, `Runs`
145+
will execute with the [`default` service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server)
146+
set for the target [`namespace`](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/).
147+
148+
```yaml
149+
spec:
150+
serviceAccountName: my-account
151+
```
152+
153+
Consult the documentation of the custom task that you are using to determine whether it supports a service account name.
154+
155+
#### Specifying a pod template
156+
157+
If the custom task supports it, you can specify a [`Pod` template](podtemplates.md) configuration that the custom task will
158+
use to configure Pods (or other resources that embed a Pod specification) that it creates.
159+
160+
```yaml
161+
spec:
162+
podTemplate:
163+
securityContext:
164+
runAsUser: 1001
165+
```
166+
167+
Consult the documentation of the custom task that you are using to determine whether it supports a pod template.
168+
111169
## Monitoring execution status
112170

113171
As your `Run` executes, its `status` field accumulates information on the

pkg/apis/pipeline/v1alpha1/run_defaults.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package v1alpha1
1919
import (
2020
"context"
2121

22+
"github.com/tektoncd/pipeline/pkg/apis/config"
2223
"knative.dev/pkg/apis"
2324
)
2425

@@ -30,5 +31,13 @@ func (r *Run) SetDefaults(ctx context.Context) {
3031
}
3132

3233
func (rs *RunSpec) SetDefaults(ctx context.Context) {
33-
// No defaults to set.
34+
cfg := config.FromContextOrDefaults(ctx)
35+
defaultSA := cfg.Defaults.DefaultServiceAccount
36+
if rs.ServiceAccountName == "" && defaultSA != "" {
37+
rs.ServiceAccountName = defaultSA
38+
}
39+
defaultPodTemplate := cfg.Defaults.DefaultPodTemplate
40+
if rs.PodTemplate == nil {
41+
rs.PodTemplate = defaultPodTemplate
42+
}
3443
}

pkg/apis/pipeline/v1alpha1/run_types.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,20 @@ type RunSpec struct {
4848
// +optional
4949
Status RunSpecStatus `json:"status,omitempty"`
5050

51+
// +optional
52+
ServiceAccountName string `json:"serviceAccountName"`
53+
54+
// PodTemplate holds pod specific configuration
55+
// +optional
56+
PodTemplate *PodTemplate `json:"podTemplate,omitempty"`
57+
58+
// Workspaces is a list of WorkspaceBindings from volumes to workspaces.
59+
// +optional
60+
Workspaces []v1beta1.WorkspaceBinding `json:"workspaces,omitempty"`
61+
5162
// TODO(https://github.com/tektoncd/community/pull/128)
5263
// - timeout
5364
// - inline task spec
54-
// - workspaces ?
5565
}
5666

5767
// RunSpecStatus defines the taskrun spec status the user can provide

pkg/apis/pipeline/v1alpha1/run_validation.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,9 @@ func (rs *RunSpec) Validate(ctx context.Context) *apis.FieldError {
5454
return err
5555
}
5656

57+
if err := validateWorkspaceBindings(ctx, rs.Workspaces); err != nil {
58+
return err
59+
}
60+
5761
return nil
5862
}

pkg/apis/pipeline/v1alpha1/run_validation_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1"
2525
v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
2626
"github.com/tektoncd/pipeline/test/diff"
27+
corev1 "k8s.io/api/core/v1"
2728
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2829
"knative.dev/pkg/apis"
2930
)
@@ -145,6 +146,20 @@ func TestRun_Valid(t *testing.T) {
145146
}},
146147
},
147148
},
149+
}, {
150+
name: "valid workspace",
151+
run: &v1alpha1.Run{
152+
Spec: v1alpha1.RunSpec{
153+
Ref: &v1alpha1.TaskRef{
154+
APIVersion: "blah",
155+
Kind: "blah",
156+
},
157+
Workspaces: []v1beta1.WorkspaceBinding{{
158+
Name: "workspace",
159+
EmptyDir: &corev1.EmptyDirVolumeSource{},
160+
}},
161+
},
162+
},
148163
}} {
149164
t.Run(c.name, func(t *testing.T) {
150165
if err := c.run.Validate(context.Background()); err != nil {
@@ -153,3 +168,56 @@ func TestRun_Valid(t *testing.T) {
153168
})
154169
}
155170
}
171+
172+
func TestRun_Workspaces_Invalid(t *testing.T) {
173+
tests := []struct {
174+
name string
175+
run *v1alpha1.Run
176+
wantErr *apis.FieldError
177+
}{{
178+
name: "make sure WorkspaceBinding validation invoked",
179+
run: &v1alpha1.Run{
180+
Spec: v1alpha1.RunSpec{
181+
Ref: &v1alpha1.TaskRef{
182+
APIVersion: "blah",
183+
Kind: "blah",
184+
},
185+
Workspaces: []v1beta1.WorkspaceBinding{{
186+
Name: "workspace",
187+
PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
188+
ClaimName: "",
189+
},
190+
}},
191+
},
192+
},
193+
wantErr: apis.ErrMissingField("workspace.persistentvolumeclaim.claimname"),
194+
}, {
195+
name: "bind same workspace twice",
196+
run: &v1alpha1.Run{
197+
Spec: v1alpha1.RunSpec{
198+
Ref: &v1alpha1.TaskRef{
199+
APIVersion: "blah",
200+
Kind: "blah",
201+
},
202+
Workspaces: []v1beta1.WorkspaceBinding{{
203+
Name: "workspace",
204+
EmptyDir: &corev1.EmptyDirVolumeSource{},
205+
}, {
206+
Name: "workspace",
207+
EmptyDir: &corev1.EmptyDirVolumeSource{},
208+
}},
209+
},
210+
},
211+
wantErr: apis.ErrMultipleOneOf("spec.workspaces.name"),
212+
}}
213+
for _, ts := range tests {
214+
t.Run(ts.name, func(t *testing.T) {
215+
err := ts.run.Validate(context.Background())
216+
if err == nil {
217+
t.Errorf("Expected error for invalid Run but got none")
218+
} else if d := cmp.Diff(ts.wantErr.Error(), err.Error()); d != "" {
219+
t.Errorf("Did not get expected error for %q: %s", ts.name, diff.PrintWantGot(d))
220+
}
221+
})
222+
}
223+
}

pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go

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

pkg/apis/pipeline/v1beta1/pipeline_validation.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,6 @@ func validatePipelineTask(ctx context.Context, t PipelineTask, taskNames sets.St
156156
if t.Resources != nil {
157157
errs = errs.Also(apis.ErrInvalidValue("custom tasks do not support PipelineResources", "resources"))
158158
}
159-
if len(t.Workspaces) > 0 {
160-
errs = errs.Also(apis.ErrInvalidValue("custom tasks do not support Workspaces", "workspaces"))
161-
}
162159
if t.Timeout != nil {
163160
errs = errs.Also(apis.ErrInvalidValue("custom tasks do not support timeout", "timeout"))
164161
}

pkg/apis/pipeline/v1beta1/pipeline_validation_test.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -620,18 +620,6 @@ func TestValidatePipelineTasks_Failure(t *testing.T) {
620620
Paths: []string{"tasks[0].resources"},
621621
},
622622
wc: enableFeature(t, "enable-custom-tasks"),
623-
}, {
624-
name: "pipelinetask custom task doesn't support workspaces",
625-
tasks: []PipelineTask{{
626-
Name: "foo",
627-
Workspaces: []WorkspacePipelineTaskBinding{{}},
628-
TaskRef: &TaskRef{APIVersion: "example.dev/v0", Kind: "Example"},
629-
}},
630-
expectedError: apis.FieldError{
631-
Message: `invalid value: custom tasks do not support Workspaces`,
632-
Paths: []string{"tasks[0].workspaces"},
633-
},
634-
wc: enableFeature(t, "enable-custom-tasks"),
635623
}, {
636624
name: "pipelinetask custom task doesn't support timeout",
637625
tasks: []PipelineTask{{

0 commit comments

Comments
 (0)