Skip to content

Commit

Permalink
Allow Resources to be Optional
Browse files Browse the repository at this point in the history
Task inputs and outputs are considered required, there is no way
today to mark them optional. This change introduce a new field called
optional as part of the PipelineResourceDeclaration by default a resource
is required. To mark any resource optional, set optional to true:

apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
 name: task-check-workspace
spec:
 inputs:
   resources:
     - name: workspace
       type: git
       optional: true
 steps:
   - name: check-workspace
  • Loading branch information
pritidesai authored and tekton-robot committed Dec 13, 2019
1 parent 5830188 commit ccacb0c
Show file tree
Hide file tree
Showing 15 changed files with 604 additions and 27 deletions.
33 changes: 32 additions & 1 deletion docs/resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ For example:
--------------------------------------------------------------------------------

- [Syntax](#syntax)
- [Using Resources](#using-resources)
- [Variable substitution](#variable-substitution)
- [Controlling where resources are mounted](#controlling-where-resources-are-mounted)
- [Overriding where resources are copied from](#overriding-where-resources-are-copied-from)
- [Resource Status](#resource-status)
- [Optional Resources](#optional-resources)
- [Resource types](#resource-types)
- [Git Resource](#git-resource)
- [Pull Request Resource](#pull-request-resource)
Expand All @@ -25,7 +31,6 @@ For example:
- [GCS Storage Resource](#gcs-storage-resource)
- [BuildGCS Storage Resource](#buildgcs-storage-resource)
- [Cloud Event Resource](#cloud-event-resource)
- [Using Resources](#using-resources)

## Syntax

Expand All @@ -46,6 +51,8 @@ following fields:
- Optional:
- [`params`](#resource-types) - Parameters which are specific to each type
of `PipelineResource`
- [`optional`](#optional-resources) - Boolean flag to mark a resource optional
(by default, `optional` is set to `false` making resources mandatory).

[kubernetes-overview]:
https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields
Expand Down Expand Up @@ -218,6 +225,30 @@ resourcesResult:
name: skaffold-image-leeroy-web
```

### Optional Resources

By default, a resource is declared as mandatory unless `optional` is set `true` for that resource.
Resources declared as `optional` in a `Task` does not have be specified in `TaskRun`.

```yaml
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: task-check-optional-resources
spec:
inputs:
resources:
- name: git-repo
type: git
optional: true
```

You can refer to different examples demonstrating usage of optional resources in `Task` and `Condition`:

- [Task](../examples/taskruns/optional-resources.yaml)
- [Cluster Task](../examples/taskruns/optional-resources-with-clustertask.yaml)
- [Condition](../examples/pipelineruns/conditional-pipelinerun-with-optional-resources.yaml)

## Resource Types

### Git Resource
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
apiVersion: tekton.dev/v1alpha1
kind: Condition
metadata:
name: verify-no-file-exists-without-resource
spec:
params:
- name: "path"
resources:
- name: optional-workspace
type: git
optional: true
check:
image: alpine
command: ["/bin/sh"]
args: ['-c', 'test ! -f $(resources.optional-workspace.path)/$(params.path)']
---
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: pipeline-git-repo
spec:
type: git
params:
- name: revision
value: master
- name: url
value: https://github.com/tektoncd/pipeline
---
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: list-pipeline-repo-files
spec:
inputs:
resources:
- name: optional-workspace
type: git
optional: true
steps:
- name: run-ls
image: ubuntu
script: |
#!/usr/bin/env bash
ls -al $(inputs.resources.optional-workspace.path)
---
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
name: pipeline-list-pipeline-repo-files
spec:
resources:
- name: pipeline-source-repo
type: git
params:
- name: "path"
default: "README.md"
tasks:
- name: list-pipeline-repo-files-1
taskRef:
name: list-pipeline-repo-files
conditions:
- conditionRef: "verify-no-file-exists-without-resource"
params:
- name: "path"
value: "$(params.path)"
# NOTE: Resource "optional-workspace" is declared as optional in Condition
# No resource specified for the condition here since its optional
# "DO NOT UNCOMMENT THE FOLLOWING RESOURCE"
# resources:
# - name: optional-workspace
# resource: pipeline-source-repo
resources:
inputs:
- name: optional-workspace
resource: pipeline-source-repo
---
apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
name: demo-condtional-pr-without-condition-resource
spec:
pipelineRef:
name: pipeline-list-pipeline-repo-files
serviceAccountName: 'default'
resources:
- name: pipeline-source-repo
resourceRef:
name: pipeline-git-repo
35 changes: 35 additions & 0 deletions examples/taskruns/optional-resources-with-clustertask.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
apiVersion: tekton.dev/v1alpha1
kind: ClusterTask
metadata:
name: clustertask-with-optional-resources
spec:
inputs:
resources:
- name: git-repo
type: git
optional: true
params:
- name: filename
type: string
default: "README.md"
outputs:
resources:
- name: optionalimage
type: image
optional: true
steps:
- name: task-echo-success
image: ubuntu
script: |
#!/usr/bin/env bash
echo "success"
---

apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
name: clustertask-without-resources
spec:
taskRef:
name: clustertask-with-optional-resources
kind: ClusterTask
131 changes: 131 additions & 0 deletions examples/taskruns/optional-resources.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: task-check-optional-resources
spec:
inputs:
resources:
- name: git-repo
type: git
optional: true
params:
- name: filename
type: string
default: "README.md"
outputs:
resources:
- name: optionalimage
type: image
optional: true
steps:
- name: check-git-repo
image: ubuntu
script: |
#!/usr/bin/env bash
if [ -d $(inputs.resources.git-repo.path) ]; then
echo "Git repo was cloned at $(inputs.resources.git-repo.path)"
if [ -f $(inputs.resources.git-repo.path)/$(inputs.params.filename) ]; then
echo "$(inputs.params.filename) does exist at $(inputs.resources.git-repo.path)"
else
echo "$(inputs.params.filename) does not exist at $(inputs.resources.git-repo.path)"
fi
else
echo "Git repo was not cloned at $(inputs.resources.git-repo.path)"
fi
if [ "$(outputs.resources.optionalimage.url)" == "" ]; then
echo "Image URL: $(outputs.resources.optionalimage.url)"
else
echo "No image URL specified."
fi
echo "Yay, Input and Output Resources can be Optional!"
---

apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
name: demo-optional-inputs-resources-with-resources
spec:
inputs:
resources:
- name: git-repo
resourceSpec:
type: git
params:
- name: url
value: https://github.com/tektoncd/pipeline.git
params:
- name: filename
value: "README.md"
outputs:
resources:
- name: optionalimage
resourceSpec:
type: image
params:
- name: url
value: gcr.io/foo/bar
taskRef:
name: task-check-optional-resources
---

apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
name: demo-optional-inputs-resources-invalid-filename
spec:
inputs:
resources:
- name: git-repo
resourceSpec:
type: git
params:
- name: url
value: https://github.com/tektoncd/pipeline.git
params:
- name: filename
value: "invalid.md"
taskRef:
name: task-check-optional-resources
---

apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
name: demo-optional-inputs-resources-without-resources
spec:
inputs:
params:
- name: filename
value: "README.md"
taskRef:
name: task-check-optional-resources
---

apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
name: demo-optional-inputs-resources-without-resources-and-params
spec:
taskRef:
name: task-check-optional-resources
---

apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
name: demo-optional-outputs-resources-with-input-resources
spec:
inputs:
resources:
- name: git-repo
resourceSpec:
type: git
params:
- name: url
value: https://github.com/tektoncd/pipeline.git
params:
- name: filename
value: "README.md"
taskRef:
name: task-check-optional-resources
---
2 changes: 1 addition & 1 deletion pkg/apis/pipeline/v1alpha1/resource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ type PipelineResourceList struct {
type ResourceDeclaration = v1alpha2.ResourceDeclaration

// ResourceFromType returns an instance of the correct PipelineResource object type which can be
// used to add input and ouput containers as well as volumes to a TaskRun's pod in order to realize
// used to add input and output containers as well as volumes to a TaskRun's pod in order to realize
// a PipelineResource in a pod.
func ResourceFromType(r *PipelineResource, images pipeline.Images) (PipelineResourceInterface, error) {
switch r.Spec.Type {
Expand Down
48 changes: 48 additions & 0 deletions pkg/apis/pipeline/v1alpha1/task_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ var invalidResource = v1alpha1.TaskResource{
},
}

var optionalResource = v1alpha1.TaskResource{
ResourceDeclaration: v1alpha1.ResourceDeclaration{
Name: "source",
Type: "git",
Optional: true,
},
}

var requiredResource = v1alpha1.TaskResource{
ResourceDeclaration: v1alpha1.ResourceDeclaration{
Name: "source",
Type: "git",
Optional: false,
},
}

var validSteps = []v1alpha1.Step{{Container: corev1.Container{
Name: "mystep",
Image: "myimage",
Expand Down Expand Up @@ -105,6 +121,22 @@ func TestTaskSpecValidate(t *testing.T) {
},
Steps: validSteps,
},
}, {
name: "valid inputs (required)",
fields: fields{
Inputs: &v1alpha1.Inputs{
Resources: []v1alpha1.TaskResource{requiredResource},
},
Steps: validSteps,
},
}, {
name: "valid inputs (optional)",
fields: fields{
Inputs: &v1alpha1.Inputs{
Resources: []v1alpha1.TaskResource{optionalResource},
},
Steps: validSteps,
},
}, {
name: "valid outputs",
fields: fields{
Expand Down Expand Up @@ -135,6 +167,22 @@ func TestTaskSpecValidate(t *testing.T) {
},
Steps: validSteps,
},
}, {
name: "valid outputs (required)",
fields: fields{
Inputs: &v1alpha1.Inputs{
Resources: []v1alpha1.TaskResource{requiredResource},
},
Steps: validSteps,
},
}, {
name: "valid outputs (optional)",
fields: fields{
Inputs: &v1alpha1.Inputs{
Resources: []v1alpha1.TaskResource{optionalResource},
},
Steps: validSteps,
},
}, {
name: "valid template variable",
fields: fields{
Expand Down
Loading

0 comments on commit ccacb0c

Please sign in to comment.