Skip to content

Commit

Permalink
Adds resource support to conditions
Browse files Browse the repository at this point in the history
Allow condition to declare pipeline resources in their definitions.
The resource can be accessed by the condition container during a check.
Only input resources are supported. The declared resources can be specified
in a PipelineTaskCondition and variable substitution for the resource is
supported just like with a `TaskResource`.

Signed-off-by: Dibyo Mukherjee <dibyo@google.com>
  • Loading branch information
dibyom committed Aug 16, 2019
1 parent 53c936b commit 1a13076
Show file tree
Hide file tree
Showing 14 changed files with 436 additions and 45 deletions.
24 changes: 23 additions & 1 deletion docs/conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This document defines `Conditions` and their capabilities.
- [Syntax](#syntax)
- [Check](#check)
- [Parameters](#parameters)
- [Resources](#resources)
- [Examples](#examples)

## Syntax
Expand Down Expand Up @@ -57,10 +58,31 @@ only start with alpha characters and `_`. For example, `fooIs-Bar_` is a valid
parameter name, `barIsBa$` or `0banana` are not.

Each declared parameter has a type field, assumed to be string if not provided by the user.
The other possible type is array — useful, checking a pushed branch name doesn't match any of
The other possible type is array — useful, for instance, checking that a pushed branch name doesn't match any of
multiple protected branch names. When the actual parameter value is supplied, its parsed type
is validated against the type field.

### Resources

Conditions can declare input [`PipelineResources`](resources.md) via the `resources` field to
provide the Condition container step with data or context that is needed to perform the check.

Input resources, like source code (git), are dumped at path
`/workspace/resource_name` within a mounted
[volume](https://kubernetes.io/docs/concepts/storage/volumes/). The condition container can use the `path`
[template](./tasks.md#Templating) key to refer to the local path to the mounted resource.

```yaml
spec:
resources:
- name: workspace
type: git
check:
image: alpine
command: ["/bin/sh"]
args: ['-c', 'test -f ${resources.workspace.path}/README.md']
```

## Examples

For complete examples, see
Expand Down
6 changes: 6 additions & 0 deletions docs/pipelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,12 @@ tasks:
name: build-push
conditions:
- conditionRef: my-condition
params:
- name: my-param
value: my-value
resources:
- name: workspace
resource: source-repo
```

In this example, `my-condition` refers to a [Condition](#conditions) custom resource. The `build-push`
Expand Down
49 changes: 32 additions & 17 deletions examples/pipelineruns/conditional-pipelinerun.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,33 @@
#apiVersion: tekton.dev/v1alpha1
#kind: Condition
#metadata:
# name: strings-equal
#spec:
# params:
# - name: "x"
# type: string
# - name: "y"
# type: string
# check:
# image: alpine
# command: ["/bin/sh"]
# args: ['-c', 'echo "Comparing ${params.x} and ${params.y}" && [ "${params.x}" == "${params.y}" ]']
---
apiVersion: tekton.dev/v1alpha1
kind: Condition
metadata:
name: strings-equal
name: file-exists
spec:
params:
- name: "x"
type: string
- name: "y"
type: string
check:
params:
- name: "path"
type: string
resources:
- name: workspace
type: git
check:
image: alpine
command: ["/bin/sh"]
args: ['-c', 'echo "Comparing ${params.x} and ${params.y}" && [ "${params.x}" == "${params.y}" ]']
args: ['-c', 'test -f ${resources.workspace.path}/${params.path}']
---
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
Expand Down Expand Up @@ -49,21 +65,20 @@ spec:
- name: source-repo
type: git
params:
- name: "x"
default: "abc"
- name: "y"
default: "abc"
- name: "path"
default: "README.md"
tasks:
- name: list-files-1
taskRef:
name: list-files
conditions:
- conditionRef: "strings-equal"
- conditionRef: "file-exists"
params:
- name: "x"
value: "${params.x}"
- name: "y"
value: "${params.y}"
- name: "path"
value: "${params.path}"
resources:
- name: workspace
resource: source-repo
resources:
inputs:
- name: workspace
Expand Down
20 changes: 20 additions & 0 deletions pkg/apis/pipeline/v1alpha1/condition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,26 @@ type ConditionSpec struct {
// is evaluated
// +optional
Params []ParamSpec `json:"params,omitempty"`

// Resources is a list of the ConditionResources required to run the condition.
// +optional
Resources []ConditionResource `json:"resources,omitempty"`
}

// ConditionResource defines an input PipelineResource declared as a requirement
// by a Task. The Name field will be used to refer to these Resources within
// the Condition definition and will be the path to the volume mounted containing this
// Resource as an input (e.g. an Resource named `workspace` will be mounted at `/workspace`).
type ConditionResource struct {
// Name declares the name by which a resource is referenced in the Condition's
// definition.
Name string `json:"name"`
// Type is the type of this resource;
Type PipelineResourceType `json:"type"`
// TargetPath is the path in workspace directory where the resource
// will be copied.
// +optional
TargetPath string `json:"targetPath"`
}

// ConditionCheck represents a single evaluation of a Condition step.
Expand Down
12 changes: 12 additions & 0 deletions pkg/apis/pipeline/v1alpha1/pipeline_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ type PipelineTaskCondition struct {
// Params declare parameters passed to this Condition
// +optional
Params []Param `json:"params,omitempty"`

// Resources declare the resources provided to this Condition as input
Resources []PipelineConditionResource `json:"resources,omitempty"`
}

// PipelineDeclaredResource is used by a Pipeline to declare the types of the
Expand All @@ -135,6 +138,15 @@ type PipelineDeclaredResource struct {
Type PipelineResourceType `json:"type"`
}

// PipelineTaskResources allows a Pipeline to declare how its DeclaredPipelineResources
// should be provided to a Condition as its inputs.
type PipelineConditionResource struct {
// Name is the name of the PipelineResource as declared by the Condition.
Name string `json:"name"`
// Resource is the name of the DeclaredPipelineResource to use.
Resource string `json:"resource"`
}

// PipelineTaskResources allows a Pipeline to declare how its DeclaredPipelineResources
// should be provided to a Task as its inputs and outputs.
type PipelineTaskResources struct {
Expand Down
42 changes: 42 additions & 0 deletions pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions pkg/reconciler/v1alpha1/pipelinerun/pipelinerun.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ func getTaskRunTimeout(pr *v1alpha1.PipelineRun) *metav1.Duration {
}

func getServiceAccount(pr *v1alpha1.PipelineRun, pipelineTaskName string) string {
// If service account is configured for a given PipelineTask, override PipelineRun's seviceAccount
// If service account is configured for a given PipelineTask, override PipelineRun's serviceAccount
serviceAccount := pr.Spec.ServiceAccount
for _, sa := range pr.Spec.ServiceAccounts {
if sa.TaskName == pipelineTaskName {
Expand Down Expand Up @@ -625,6 +625,11 @@ func (c *Reconciler) makeConditionCheckContainer(rprt *resources.ResolvedPipelin
labels := getTaskrunLabels(pr, rprt.PipelineTask.Name)
labels[pipeline.GroupName+pipeline.ConditionCheckKey] = rcc.ConditionCheckName

taskSpec, err := rcc.ConditionToTaskSpec()
if err != nil {
return nil, err
}

tr := &v1alpha1.TaskRun{
ObjectMeta: metav1.ObjectMeta{
Name: rcc.ConditionCheckName,
Expand All @@ -634,10 +639,11 @@ func (c *Reconciler) makeConditionCheckContainer(rprt *resources.ResolvedPipelin
Annotations: getTaskrunAnnotations(pr), // Propagate annotations from PipelineRun to TaskRun.
},
Spec: v1alpha1.TaskRunSpec{
TaskSpec: rcc.ConditionToTaskSpec(),
TaskSpec: taskSpec,
ServiceAccount: getServiceAccount(pr, rprt.PipelineTask.Name),
Inputs: v1alpha1.TaskRunInputs{
Params: rcc.PipelineTaskCondition.Params,
Params: rcc.PipelineTaskCondition.Params,
Resources: rcc.ToTaskResourceBindings(),
},
Timeout: getTaskRunTimeout(pr),
NodeSelector: pr.Spec.NodeSelector,
Expand Down
5 changes: 4 additions & 1 deletion pkg/reconciler/v1alpha1/pipelinerun/pipelinerun_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1421,7 +1421,10 @@ func makeExpectedTr(condName, ccName string) *v1alpha1.TaskRun {
tb.TaskRunLabel("tekton.dev/conditionCheck", ccName),
tb.TaskRunAnnotation("PipelineRunAnnotation", "PipelineRunValue"),
tb.TaskRunSpec(
tb.TaskRunTaskSpec(tb.Step("condition-check-"+condName, "foo", tb.StepArgs("bar"))),
tb.TaskRunTaskSpec(
tb.Step("condition-check-"+condName, "foo", tb.StepArgs("bar")),
tb.TaskInputs(),
),
tb.TaskRunServiceAccount("test-sa"),
),
)
Expand Down
Loading

0 comments on commit 1a13076

Please sign in to comment.