Skip to content

Commit

Permalink
Add context variables for PipelineRun and TaskRun UIDs
Browse files Browse the repository at this point in the history
A user may want to tag an oci image with the TaskRun or PipelineRun UIDs.
Currently, they can't do that because `metadata.uid` for TaskRuns and
PipelineRuns are not exposed.

In this PR, we add the UID context variable for TaskRuns and
PipelineRun. Users can now use `$(context.taskRun.uid)` and
`$(context.pipelineRun.uid)` to access and use UIDs.

In addition, we add validation for all context variables that are
supported so far -- `context.task.name`, `context.taskRun.name`,
`context.taskRun.namespace`, `context.taskRun.uid`,
`context.pipeline.name`, `context.pipelineRun.name`,
`context.pipelineRun.namespace`, `context.pipelineRun.uid`.

Partially fixes #2958
  • Loading branch information
Scott authored and jerop committed Jul 27, 2020
1 parent 7453c40 commit f5867de
Show file tree
Hide file tree
Showing 20 changed files with 678 additions and 43 deletions.
2 changes: 2 additions & 0 deletions docs/variables.md
Expand Up @@ -16,6 +16,7 @@ This page documents the variable substitions supported by `Tasks` and `Pipelines
| `tasks.<taskName>.results.<resultName>` | The value of the `Task's` result. Can alter `Task` execution order within a `Pipeline`.) |
| `context.pipelineRun.name` | The name of the `PipelineRun` that this `Pipeline` is running in. |
| `context.pipelineRun.namespace` | The namespace of the `PipelineRun` that this `Pipeline` is running in. |
| `context.pipelineRun.uid` | The uid of the `PipelineRun` that this `Pipeline` is running in. |
| `context.pipeline.name` | The name of this `Pipeline` . |


Expand All @@ -33,6 +34,7 @@ This page documents the variable substitions supported by `Tasks` and `Pipelines
| `credentials.path` | The path to credentials injected from Secrets with matching annotations. |
| `context.taskRun.name` | The name of the `TaskRun` that this `Task` is running in. |
| `context.taskRun.namespace` | The namespace of the `TaskRun` that this `Task` is running in. |
| `context.taskRun.uid` | The uid of the `TaskRun` that this `Task` is running in. |
| `context.task.name` | The name of this `Task`. |

### `PipelineResource` variables available in a `Task`
Expand Down
35 changes: 35 additions & 0 deletions examples/v1beta1/pipelineruns/using_context_variables.yaml
@@ -0,0 +1,35 @@
kind: PipelineRun
apiVersion: tekton.dev/v1beta1
metadata:
generateName: test-pipelinerun-
spec:
pipelineSpec:
tasks:
- name: task1
params:
- name: pipeline-uid
value: "$(context.pipelineRun.uid)"
- name: pipeline-name
value: "$(context.pipeline.name)"
- name: pipelineRun-name
value: "$(context.pipelineRun.name)"
- name: pipelineRun-name-uid
value: ["$(context.pipelineRun.name)", "$(context.pipelineRun.uid)"]
taskSpec:
params:
- name: pipeline-uid
- name: pipeline-name
- name: pipelineRun-name
steps:
- image: ubuntu
name: print-uid
script: |
echo "TaskRun UID: $(context.taskRun.uid)"
echo "PipelineRun UID from params: $(params.pipeline-uid)"
- image: ubuntu
name: print-names
script: |
echo "Task name: $(context.task.name)"
echo "TaskRun name: $(context.taskRun.name)"
echo "Pipeline name from params: $(params.pipeline-name)"
echo "PipelineRun name from params: $(params.pipelineRun-name)"
16 changes: 16 additions & 0 deletions examples/v1beta1/taskruns/using_context_variables.yaml
@@ -0,0 +1,16 @@
kind: TaskRun
apiVersion: tekton.dev/v1beta1
metadata:
generateName: test-taskrun-
spec:
taskSpec:
steps:
- image: ubuntu
name: print-uid
script: |
echo "TaskRunUID name: $(context.taskRun.uid)"
- image: ubuntu
name: print-names
script: |
echo "Task name: $(context.task.name)"
echo "TaskRun name: $(context.taskRun.name)"
6 changes: 6 additions & 0 deletions internal/builder/v1beta1/owner_reference.go
Expand Up @@ -18,6 +18,7 @@ package builder

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

// OwnerReferenceOp is an operation which modifies an OwnerReference struct.
Expand All @@ -39,3 +40,8 @@ func Controller(o *metav1.OwnerReference) {
func BlockOwnerDeletion(o *metav1.OwnerReference) {
o.BlockOwnerDeletion = &trueB
}

// OwnerUID sets the UID to the OwnerReference.
func OwnerUID(o *metav1.OwnerReference){
o.UID = types.UID("uid-1")
}
7 changes: 7 additions & 0 deletions internal/builder/v1beta1/pipeline.go
Expand Up @@ -24,6 +24,7 @@ import (
resource "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"knative.dev/pkg/apis"
)

Expand Down Expand Up @@ -353,6 +354,12 @@ func PipelineRun(name string, ops ...PipelineRunOp) *v1beta1.PipelineRun {

return pr
}
// PipelineRunUID sets the namespace on a PipelineRun
func PipelineRunUID(uid string) PipelineRunOp {
return func(t *v1beta1.PipelineRun) {
t.ObjectMeta.UID = types.UID(uid)
}
}

// PipelineRunNamespace sets the namespace on a PipelineRun
func PipelineRunNamespace(namespace string) PipelineRunOp {
Expand Down
8 changes: 8 additions & 0 deletions internal/builder/v1beta1/task.go
Expand Up @@ -24,6 +24,7 @@ import (
resource "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"knative.dev/pkg/apis"
)

Expand Down Expand Up @@ -356,6 +357,13 @@ func TaskRunNamespace(namespace string) TaskRunOp {
}
}

// TaskRunUID sets the uid for the TaskRun.
func TaskRunUID(uid string) TaskRunOp {
return func(t *v1beta1.TaskRun) {
t.ObjectMeta.UID = types.UID(uid)
}
}

// TaskRunStatus sets the TaskRunStatus to tshe TaskRun
func TaskRunStatus(ops ...TaskRunStatusOp) TaskRunOp {
return func(tr *v1beta1.TaskRun) {
Expand Down
6 changes: 3 additions & 3 deletions pkg/apis/pipeline/v1beta1/task_validation.go
Expand Up @@ -242,7 +242,7 @@ func ValidateParameterVariables(steps []Step, params []ParamSpec) *apis.FieldErr
}
}

if err := validateVariables(steps, "params", parameterNames); err != nil {
if err := ValidateVariables(steps, "params", parameterNames); err != nil {
return err
}
return validateArrayUsage(steps, "params", arrayParameterNames)
Expand All @@ -263,7 +263,7 @@ func ValidateResourcesVariables(steps []Step, resources *TaskResources) *apis.Fi
resourceNames.Insert(r.Name)
}
}
return validateVariables(steps, "resources.(?:inputs|outputs)", resourceNames)
return ValidateVariables(steps, "resources.(?:inputs|outputs)", resourceNames)
}

func validateArrayUsage(steps []Step, prefix string, vars sets.String) *apis.FieldError {
Expand Down Expand Up @@ -310,7 +310,7 @@ func validateArrayUsage(steps []Step, prefix string, vars sets.String) *apis.Fie
return nil
}

func validateVariables(steps []Step, prefix string, vars sets.String) *apis.FieldError {
func ValidateVariables(steps []Step, prefix string, vars sets.String) *apis.FieldError {
for _, step := range steps {
if err := validateTaskVariable("name", step.Name, prefix, vars); err != nil {
return err
Expand Down
11 changes: 11 additions & 0 deletions pkg/reconciler/pipelinerun/pipelinerun.go
Expand Up @@ -97,6 +97,9 @@ const (
// ReasonCouldntCancel indicates that a PipelineRun was cancelled but attempting to update
// all of the running TaskRuns as cancelled failed.
ReasonCouldntCancel = "PipelineRunCouldntCancel"
// ReasonFailedContextValidation indicates that the reason for failure is that the PipelineRun
// failed to resolve the contexts.
ReasonFailedContextValidation = "ReasonFailedContextValidation"
)

// Reconciler implements controller.Reconciler for Configuration resources.
Expand Down Expand Up @@ -362,6 +365,14 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1beta1.PipelineRun) err
return controller.NewPermanentError(err)
}

// Ensure that the context variables in the PipelineRun parameters are valid.
if err := resources.ValidateContextVariables(pipelineSpec, pr); err != nil {
pr.Status.MarkFailed(ReasonFailedContextValidation,
"PipelineRun %s/%s parameters has invalid context variable %s/%s's: %s",
pr.Namespace, pr.Name, pr.Namespace, pipelineMeta.Name, err)
return controller.NewPermanentError(err)
}

// Ensure that the ServiceAccountNames defined correct.
if err := resources.ValidateServiceaccountMapping(pipelineSpec, pr); err != nil {
pr.Status.MarkFailed(ReasonInvalidServiceAccountMapping,
Expand Down

0 comments on commit f5867de

Please sign in to comment.