Skip to content

Commit

Permalink
TEP-0111 - Propagating workspaces in Taskrun
Browse files Browse the repository at this point in the history
This POC illustrates propagating workspaces defined at the `pipelinerun` stage and directly referred at the `spec`. There is no need to specify it in the `pipelinespec` followed by `tasks` and `taskspec`.
  • Loading branch information
chitrangpatel committed Sep 9, 2022
1 parent 11e5c37 commit 93a8d35
Show file tree
Hide file tree
Showing 16 changed files with 486 additions and 98 deletions.
1 change: 1 addition & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ Features currently in "alpha" are:
| [Isolated `Step` & `Sidecar` `Workspaces`](./workspaces.md#isolated-workspaces) | [TEP-0029](https://github.com/tektoncd/community/blob/main/teps/0029-step-workspaces.md) | [v0.24.0](https://github.com/tektoncd/pipeline/releases/tag/v0.24.0) | |
| [Hermetic Execution Mode](./hermetic.md) | [TEP-0025](https://github.com/tektoncd/community/blob/main/teps/0025-hermekton.md) | [v0.25.0](https://github.com/tektoncd/pipeline/releases/tag/v0.25.0) | |
| [Propagated `Parameters`](./taskruns.md#propagated-parameters) | [TEP-0107](https://github.com/tektoncd/community/blob/main/teps/0107-propagating-parameters.md) | [v0.36.0](https://github.com/tektoncd/pipeline/releases/tag/v0.36.0) | |
| [Propagated `Workspaces`](./pipelineruns.md#propagated-workspaces) | [TEP-0111](https://github.com/tektoncd/community/blob/main/teps/0111-propagating-workspaces.md) | | |
| [Windows Scripts](./tasks.md#windows-scripts) | [TEP-0057](https://github.com/tektoncd/community/blob/main/teps/0057-windows-support.md) | [v0.28.0](https://github.com/tektoncd/pipeline/releases/tag/v0.28.0) | |
| [Remote Tasks](./taskruns.md#remote-tasks) and [Remote Pipelines](./pipelineruns.md#remote-pipelines) | [TEP-0060](https://github.com/tektoncd/community/blob/main/teps/0060-remote-resolutiond.md) | | |
| [Debug](./debug.md) | [TEP-0042](https://github.com/tektoncd/community/blob/main/teps/0042-taskrun-breakpoint-on-failure.md) | [v0.26.0](https://github.com/tektoncd/pipeline/releases/tag/v0.26.0) | |
Expand Down
2 changes: 2 additions & 0 deletions docs/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,8 @@ spec:
For more information, see [Using `Workspaces` in `Tasks`](workspaces.md#using-workspaces-in-tasks)
and the [`Workspaces` in a `TaskRun`](../examples/v1beta1/taskruns/workspace.yaml) example YAML file.

Workspaces can be propagated to embedded task specs, not referenced Tasks. For more information, see [Referenced TaskRuns within Embedded PipelineRuns](pipelineruns.md#referenced-taskruns-within-embedded-pipelineruns).

### Emitting `Results`

A Task is able to emit string results that can be viewed by users and passed to other Tasks in a Pipeline. These
Expand Down
16 changes: 16 additions & 0 deletions examples/v1beta1/taskruns/alpha/propagating_workspaces.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
generateName: propagating-workspaces-
spec:
taskSpec:
steps:
- name: simple-step
image: ubuntu
command:
- echo
args:
- $(workspaces.tr-workspace.path)
workspaces:
- emptyDir: {}
name: tr-workspace
55 changes: 55 additions & 0 deletions pkg/apis/pipeline/v1/task_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"knative.dev/pkg/kmeta"
)

Expand Down Expand Up @@ -95,6 +96,60 @@ type TaskSpec struct {
Results []TaskResult `json:"results,omitempty"`
}

func findWorkspaceSubstitutionLocationsInSidecars(sidecars []Sidecar) sets.String {
locationsToCheck := sets.NewString()
for _, sidecar := range sidecars {
locationsToCheck.Insert(sidecar.Script)

for i := range sidecar.Args {
locationsToCheck.Insert(sidecar.Args[i])
}

for i := range sidecar.Command {
locationsToCheck.Insert(sidecar.Command[i])
}
}
return locationsToCheck
}

func findWorkspaceSubstitutionLocationsInSteps(steps []Step) sets.String {
locationsToCheck := sets.NewString()
for _, step := range steps {
locationsToCheck.Insert(step.Script)

for i := range step.Args {
locationsToCheck.Insert(step.Args[i])
}

for i := range step.Command {
locationsToCheck.Insert(step.Command[i])
}
}
return locationsToCheck
}

func findWorkspaceSubstitutionLocationsInStepTemplate(stepTemplate *StepTemplate) sets.String {
locationsToCheck := sets.NewString()

for i := range stepTemplate.Args {
locationsToCheck.Insert(stepTemplate.Args[i])
}

for i := range stepTemplate.Command {
locationsToCheck.Insert(stepTemplate.Command[i])
}
return locationsToCheck
}

// FindWorkspaceSubstitutionLocationsInTask returns a set of all the locations in the TaskSpec where we can apply substitutions.
func (ts *TaskSpec) FindWorkspaceSubstitutionLocationsInTask() sets.String {
locationsToCheck := sets.NewString()
locationsToCheck.Insert(findWorkspaceSubstitutionLocationsInSteps(ts.Steps).List()...)
locationsToCheck.Insert(findWorkspaceSubstitutionLocationsInSidecars(ts.Sidecars).List()...)
locationsToCheck.Insert(findWorkspaceSubstitutionLocationsInStepTemplate(ts.StepTemplate).List()...)
return locationsToCheck
}

// TaskList contains a list of Task
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type TaskList struct {
Expand Down
75 changes: 75 additions & 0 deletions pkg/apis/pipeline/v1/task_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
Copyright 2019 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1_test

import (
"testing"

"github.com/google/go-cmp/cmp"
v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
"github.com/tektoncd/pipeline/test/diff"
"k8s.io/apimachinery/pkg/util/sets"
)

func TestTaskSpec_FindWorkspaceSubstitutionLocationsInTask(t *testing.T) {
tests := []struct {
name string
ts *v1.TaskSpec
want sets.String
}{{
name: "completespec",
ts: &v1.TaskSpec{
Steps: []v1.Step{{
Name: "step-name",
Image: "step-image",
Script: "step-script",
Command: []string{"step-command"},
Args: []string{"step-args"},
}},
Sidecars: []v1.Sidecar{{
Name: "sidecar-name",
Image: "sidecar-image",
Script: "sidecar-script",
Command: []string{"sidecar-command"},
Args: []string{"sidecar-args"},
}},
StepTemplate: &v1.StepTemplate{
Image: "steptemplate-image",
Command: []string{"steptemplate-command"},
Args: []string{"steptemplate-args"},
},
},
want: sets.NewString(
"step-script",
"step-args",
"step-command",
"sidecar-script",
"sidecar-args",
"sidecar-command",
"steptemplate-args",
"steptemplate-command",
),
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.ts.FindWorkspaceSubstitutionLocationsInTask()
if d := cmp.Diff(tt.want, got); d != "" {
t.Error(diff.PrintWantGot(d))
}
})
}
}
1 change: 0 additions & 1 deletion pkg/apis/pipeline/v1beta1/pipelinerun_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ func (ps *PipelineRunSpec) validatePipelineRunParameters(ctx context.Context) (e
}
}
}

return errs
}

Expand Down
56 changes: 56 additions & 0 deletions pkg/apis/pipeline/v1beta1/task_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
"knative.dev/pkg/kmeta"
)

Expand Down Expand Up @@ -78,6 +79,61 @@ func (*Task) GetGroupVersionKind() schema.GroupVersionKind {
return SchemeGroupVersion.WithKind(pipeline.TaskControllerName)
}

func findWorkspaceSubstitutionLocationsInSidecars(sidecars []Sidecar) sets.String {
locationsToCheck := sets.NewString()
for _, sidecar := range sidecars {
locationsToCheck.Insert(sidecar.Script)

for i := range sidecar.Args {
locationsToCheck.Insert(sidecar.Args[i])
}

for i := range sidecar.Command {
locationsToCheck.Insert(sidecar.Command[i])
}
}
return locationsToCheck
}

func findWorkspaceSubstitutionLocationsInSteps(steps []Step) sets.String {
locationsToCheck := sets.NewString()
for _, step := range steps {
locationsToCheck.Insert(step.Script)

for i := range step.Args {
locationsToCheck.Insert(step.Args[i])
}

for i := range step.Command {
locationsToCheck.Insert(step.Command[i])
}
}
return locationsToCheck
}

func findWorkspaceSubstitutionLocationsInStepTemplate(stepTemplate *StepTemplate) sets.String {
locationsToCheck := sets.NewString()

if stepTemplate != nil {
for i := range stepTemplate.Args {
locationsToCheck.Insert(stepTemplate.Args[i])
}
for i := range stepTemplate.Command {
locationsToCheck.Insert(stepTemplate.Command[i])
}
}
return locationsToCheck
}

// FindWorkspaceSubstitutionLocationsInTask returns a set of all the locations in the TaskSpec where we can apply substitutions.
func (ts *TaskSpec) FindWorkspaceSubstitutionLocationsInTask() sets.String {
locationsToCheck := sets.NewString()
locationsToCheck.Insert(findWorkspaceSubstitutionLocationsInSteps(ts.Steps).List()...)
locationsToCheck.Insert(findWorkspaceSubstitutionLocationsInSidecars(ts.Sidecars).List()...)
locationsToCheck.Insert(findWorkspaceSubstitutionLocationsInStepTemplate(ts.StepTemplate).List()...)
return locationsToCheck
}

// TaskSpec defines the desired state of Task.
type TaskSpec struct {
// Resources is a list input and output resource to run the task
Expand Down
75 changes: 75 additions & 0 deletions pkg/apis/pipeline/v1beta1/task_types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
Copyright 2019 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1beta1_test

import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
"github.com/tektoncd/pipeline/test/diff"
"k8s.io/apimachinery/pkg/util/sets"
)

func TestTaskSpec_FindWorkspaceSubstitutionLocationsInTask(t *testing.T) {
tests := []struct {
name string
ts *v1beta1.TaskSpec
want sets.String
}{{
name: "completespec",
ts: &v1beta1.TaskSpec{
Steps: []v1beta1.Step{{
Name: "step-name",
Image: "step-image",
Script: "step-script",
Command: []string{"step-command"},
Args: []string{"step-args"},
}},
Sidecars: []v1beta1.Sidecar{{
Name: "sidecar-name",
Image: "sidecar-image",
Script: "sidecar-script",
Command: []string{"sidecar-command"},
Args: []string{"sidecar-args"},
}},
StepTemplate: &v1beta1.StepTemplate{
Image: "steptemplate-image",
Command: []string{"steptemplate-command"},
Args: []string{"steptemplate-args"},
},
},
want: sets.NewString(
"step-script",
"step-args",
"step-command",
"sidecar-script",
"sidecar-args",
"sidecar-command",
"steptemplate-args",
"steptemplate-command",
),
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.ts.FindWorkspaceSubstitutionLocationsInTask()
if d := cmp.Diff(tt.want, got); d != "" {
t.Error(diff.PrintWantGot(d))
}
})
}
}
1 change: 1 addition & 0 deletions pkg/reconciler/pipelinerun/pipelinerun.go
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,7 @@ func getTaskrunWorkspaces(pr *v1beta1.PipelineRun, rpt *resources.ResolvedPipeli
for _, binding := range pr.Spec.Workspaces {
pipelineRunWorkspaces[binding.Name] = binding
}

for _, ws := range rpt.PipelineTask.Workspaces {
taskWorkspaceName, pipelineTaskSubPath, pipelineWorkspaceName := ws.Name, ws.SubPath, ws.Workspace

Expand Down
Loading

0 comments on commit 93a8d35

Please sign in to comment.