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 28, 2020
1 parent ae87d00 commit 293beab
Show file tree
Hide file tree
Showing 22 changed files with 711 additions and 66 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
36 changes: 36 additions & 0 deletions examples/v1beta1/pipelineruns/using_context_variables.yaml
@@ -0,0 +1,36 @@
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)"
echo "PipelineRun name and uid from params: $(params.pipelineRun-name-uid)"
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)"
8 changes: 8 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 @@ -354,6 +355,13 @@ 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 {
return func(t *v1beta1.PipelineRun) {
Expand Down
15 changes: 10 additions & 5 deletions internal/builder/v1beta1/pipeline_test.go
Expand Up @@ -158,7 +158,7 @@ func TestPipelineRun(t *testing.T) {
startTime := time.Now()
completedTime := startTime.Add(5 * time.Minute)

pipelineRun := tb.PipelineRun("pear", tb.PipelineRunNamespace("foo"), tb.PipelineRunSpec(
pipelineRun := tb.PipelineRun("pear", tb.PipelineRunUID("uid"), tb.PipelineRunNamespace("foo"), tb.PipelineRunSpec(
"tomatoes", tb.PipelineRunServiceAccountName("sa"),
tb.PipelineRunParam("first-param-string", "first-value"),
tb.PipelineRunParam("second-param-array", "some", "array"),
Expand All @@ -176,6 +176,7 @@ func TestPipelineRun(t *testing.T) {
expectedPipelineRun := &v1beta1.PipelineRun{
ObjectMeta: metav1.ObjectMeta{
Name: "pear",
UID: "uid",
Namespace: "foo",
Labels: map[string]string{
"label-key": "label-value",
Expand Down Expand Up @@ -222,7 +223,7 @@ func TestPipelineRunWithPodTemplate(t *testing.T) {
startTime := time.Now()
completedTime := startTime.Add(5 * time.Minute)

pipelineRun := tb.PipelineRun("pear", tb.PipelineRunNamespace("foo"), tb.PipelineRunSpec(
pipelineRun := tb.PipelineRun("pear", tb.PipelineRunUID("uid"), tb.PipelineRunNamespace("foo"), tb.PipelineRunSpec(
"tomatoes", tb.PipelineRunServiceAccountName("sa"),
tb.PipelineRunParam("first-param-string", "first-value"),
tb.PipelineRunParam("second-param-array", "some", "array"),
Expand All @@ -243,6 +244,7 @@ func TestPipelineRunWithPodTemplate(t *testing.T) {
expectedPipelineRun := &v1beta1.PipelineRun{
ObjectMeta: metav1.ObjectMeta{
Name: "pear",
UID: "uid",
Namespace: "foo",
Labels: map[string]string{
"label-key": "label-value",
Expand Down Expand Up @@ -294,7 +296,7 @@ func TestPipelineRunWithResourceSpec(t *testing.T) {
startTime := time.Now()
completedTime := startTime.Add(5 * time.Minute)

pipelineRun := tb.PipelineRun("pear", tb.PipelineRunNamespace("foo"), tb.PipelineRunSpec(
pipelineRun := tb.PipelineRun("pear", tb.PipelineRunUID("uid"), tb.PipelineRunNamespace("foo"), tb.PipelineRunSpec(
"tomatoes", tb.PipelineRunServiceAccountName("sa"),
tb.PipelineRunParam("first-param-string", "first-value"),
tb.PipelineRunParam("second-param-array", "some", "array"),
Expand All @@ -318,6 +320,7 @@ func TestPipelineRunWithResourceSpec(t *testing.T) {
expectedPipelineRun := &v1beta1.PipelineRun{
ObjectMeta: metav1.ObjectMeta{
Name: "pear",
UID: "uid",
Namespace: "foo",
Labels: map[string]string{
"label-key": "label-value",
Expand Down Expand Up @@ -366,14 +369,15 @@ func TestPipelineRunWithResourceSpec(t *testing.T) {
}

func TestPipelineRunWithPipelineSpec(t *testing.T) {
pipelineRun := tb.PipelineRun("pear", tb.PipelineRunNamespace("foo"), tb.PipelineRunSpec("", tb.PipelineRunPipelineSpec(
pipelineRun := tb.PipelineRun("pear", tb.PipelineRunUID("uid"), tb.PipelineRunNamespace("foo"), tb.PipelineRunSpec("", tb.PipelineRunPipelineSpec(
tb.PipelineTask("a-task", "some-task")),
tb.PipelineRunServiceAccountName("sa"),
))

expectedPipelineRun := &v1beta1.PipelineRun{
ObjectMeta: metav1.ObjectMeta{
Name: "pear",
UID: "uid",
Namespace: "foo",
},
Spec: v1beta1.PipelineRunSpec{
Expand All @@ -395,7 +399,7 @@ func TestPipelineRunWithPipelineSpec(t *testing.T) {
}

func TestPipelineRunWithFinalTask(t *testing.T) {
pipelineRun := tb.PipelineRun("pear", tb.PipelineRunNamespace("foo"), tb.PipelineRunSpec("", tb.PipelineRunPipelineSpec(
pipelineRun := tb.PipelineRun("pear", tb.PipelineRunUID("uid"), tb.PipelineRunNamespace("foo"), tb.PipelineRunSpec("", tb.PipelineRunPipelineSpec(
tb.PipelineTask("dag-task", "some-task"),
tb.FinalPipelineTask("final-task", "some-task")),
tb.PipelineRunServiceAccountName("sa"),
Expand All @@ -404,6 +408,7 @@ func TestPipelineRunWithFinalTask(t *testing.T) {
expectedPipelineRun := &v1beta1.PipelineRun{
ObjectMeta: metav1.ObjectMeta{
Name: "pear",
UID: "uid",
Namespace: "foo",
},
Spec: v1beta1.PipelineRunSpec{
Expand Down
11 changes: 10 additions & 1 deletion 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 Expand Up @@ -541,11 +549,12 @@ func SetStepStateWaiting(waiting corev1.ContainerStateWaiting) StepStateOp {
}

// TaskRunOwnerReference sets the OwnerReference, with specified kind and name, to the TaskRun.
func TaskRunOwnerReference(kind, name string, ops ...OwnerReferenceOp) TaskRunOp {
func TaskRunOwnerReference(kind, name string, uid string, ops ...OwnerReferenceOp) TaskRunOp {
return func(tr *v1beta1.TaskRun) {
o := &metav1.OwnerReference{
Kind: kind,
Name: name,
UID: types.UID(uid),
}
for _, op := range ops {
op(o)
Expand Down
18 changes: 14 additions & 4 deletions internal/builder/v1beta1/task_test.go
Expand Up @@ -172,8 +172,9 @@ func TestTaskRunWithTaskRef(t *testing.T) {
terminatedState := corev1.ContainerStateTerminated{Reason: "Completed"}

taskRun := tb.TaskRun("test-taskrun",
tb.TaskRunUID("uid"),
tb.TaskRunNamespace("foo"),
tb.TaskRunOwnerReference("PipelineRun", "test",
tb.TaskRunOwnerReference("PipelineRun", "test", "uid",
tb.OwnerReferenceAPIVersion("a1"),
tb.Controller, tb.BlockOwnerDeletion,
),
Expand Down Expand Up @@ -219,11 +220,14 @@ func TestTaskRunWithTaskRef(t *testing.T) {
)
expectedTaskRun := &v1beta1.TaskRun{
ObjectMeta: metav1.ObjectMeta{
Name: "test-taskrun", Namespace: "foo",
Name: "test-taskrun",
UID: "uid",
Namespace: "foo",
OwnerReferences: []metav1.OwnerReference{{
Name: "test",
Kind: "PipelineRun",
APIVersion: "a1",
UID: "uid",
Controller: &trueB,
BlockOwnerDeletion: &trueB,
}},
Expand Down Expand Up @@ -319,6 +323,7 @@ func TestTaskRunWithTaskRef(t *testing.T) {

func TestTaskRunWithTaskSpec(t *testing.T) {
taskRun := tb.TaskRun("test-taskrun",
tb.TaskRunUID("uid"),
tb.TaskRunNamespace("foo"),
tb.TaskRunSpec(
tb.TaskRunTaskSpec(
Expand All @@ -333,7 +338,9 @@ func TestTaskRunWithTaskSpec(t *testing.T) {
))
expectedTaskRun := &v1beta1.TaskRun{
ObjectMeta: metav1.ObjectMeta{
Name: "test-taskrun", Namespace: "foo",
Name: "test-taskrun",
UID: "uid",
Namespace: "foo",
Annotations: map[string]string{},
},
Spec: v1beta1.TaskRunSpec{
Expand Down Expand Up @@ -364,6 +371,7 @@ func TestTaskRunWithTaskSpec(t *testing.T) {

func TestTaskRunWithPodTemplate(t *testing.T) {
taskRun := tb.TaskRun("test-taskrun",
tb.TaskRunUID("uid"),
tb.TaskRunNamespace("foo"),
tb.TaskRunSpec(
tb.TaskRunTaskSpec(
Expand All @@ -381,7 +389,9 @@ func TestTaskRunWithPodTemplate(t *testing.T) {
))
expectedTaskRun := &v1beta1.TaskRun{
ObjectMeta: metav1.ObjectMeta{
Name: "test-taskrun", Namespace: "foo",
Name: "test-taskrun",
UID: "uid",
Namespace: "foo",
Annotations: map[string]string{},
},
Spec: v1beta1.TaskRunSpec{
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 @@ -98,6 +98,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 @@ -366,6 +369,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",
pr.Namespace, pr.Name)
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 293beab

Please sign in to comment.