Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/cmd/tkn_pipeline_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ my-secret, my-empty-dir and my-volume-claim-template)
-s, --serviceaccount string pass the serviceaccount name
--showlog show logs right after starting the Pipeline
--skip-optional-workspace skips the prompt for optional workspaces
--task-run-spec string local or remote file containing a TaskRunSpec definition
--task-serviceaccount strings pass the service account corresponding to the task
--tasks-timeout string timeout for Pipeline TaskRuns
--use-param-defaults use default parameter values without prompting for input
Expand Down
4 changes: 4 additions & 0 deletions docs/man/man1/tkn-pipeline-start.1
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ Parameters, at least those that have no default value
\fB\-\-skip\-optional\-workspace\fP[=false]
skips the prompt for optional workspaces

.PP
\fB\-\-task\-run\-spec\fP=""
local or remote file containing a TaskRunSpec definition

.PP
\fB\-\-task\-serviceaccount\fP=[]
pass the service account corresponding to the task
Expand Down
11 changes: 11 additions & 0 deletions pkg/cmd/pipeline/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type startOptions struct {
UseParamDefaults bool
TektonOptions flags.TektonOptions
PodTemplate string
TaskRunSpec string
SkipOptionalWorkspace bool
}

Expand Down Expand Up @@ -206,6 +207,7 @@ For passing the workspaces via flags:
c.Flags().StringVarP(&opt.Filename, "filename", "f", "", "local or remote file name containing a Pipeline definition to start a PipelineRun")
c.Flags().BoolVarP(&opt.UseParamDefaults, "use-param-defaults", "", false, "use default parameter values without prompting for input")
c.Flags().StringVar(&opt.PodTemplate, "pod-template", "", "local or remote file containing a PodTemplate definition")
c.Flags().StringVar(&opt.TaskRunSpec, "task-run-spec", "", "local or remote file containing a TaskRunSpec definition")
c.Flags().BoolVarP(&opt.SkipOptionalWorkspace, "skip-optional-workspace", "", false, "skips the prompt for optional workspaces")

c.Flags().StringVarP(&opt.ServiceAccountName, "serviceaccount", "s", "", "pass the serviceaccount name")
Expand Down Expand Up @@ -355,6 +357,15 @@ func (opt *startOptions) startPipeline(pipelineStart *v1beta1.Pipeline) error {
pr.Spec.PodTemplate = &podTemplate
}

taskRunSpecLocation := opt.TaskRunSpec
if taskRunSpecLocation != "" {
taskRunSpec, err := pods.ParseTaskRunSpec(cs.HTTPClient, taskRunSpecLocation, file.IsYamlFile(), fmt.Errorf("invalid file format for %s: .yaml or .yml file extension and format required", taskRunSpecLocation))
if err != nil {
return err
}
pr.Spec.TaskRunSpecs = taskRunSpec
}

if opt.DryRun {
format := strings.ToLower(opt.Output)
if format == "name" {
Expand Down
19 changes: 19 additions & 0 deletions pkg/cmd/pipeline/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,25 @@ func TestPipelineStart_ExecuteCommand_v1beta1(t *testing.T) {
wantError: false,
goldenFile: true,
},

{
name: "Dry Run with TaskRunSpec",
command: []string{
"start", "test-pipeline",
"-s=svc1",
"-r=source=scaffold-git",
"-p=pipeline-param=value1",
"-p=rev-param=value2",
"-l=jemange=desfrites",
"-n", "ns",
"--dry-run",
"--task-run-spec", "./testdata/taskrunspec.yaml",
},
namespace: "",
input: c2,
wantError: false,
goldenFile: true,
},
}

for _, tp := range testParams {
Expand Down
18 changes: 18 additions & 0 deletions pkg/cmd/pipeline/start_v1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,24 @@ func TestPipelineStart_ExecuteCommand(t *testing.T) {
wantError: false,
goldenFile: true,
},

{
name: "Dry Run with TaskRunSpec",
command: []string{
"start", "test-pipeline",
"-s=svc1",
"-p=pipeline-param=value1",
"-p=rev-param=value2",
"-l=jemange=desfrites",
"-n", "ns",
"--dry-run",
"--task-run-spec", "./testdata/taskrunspec.yaml",
},
namespace: "",
input: c2,
wantError: false,
goldenFile: true,
},
}

for _, tp := range testParams {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
creationTimestamp: null
generateName: test-pipeline-run-
labels:
jemange: desfrites
namespace: ns
spec:
params:
- name: pipeline-param
value: value1
- name: rev-param
value: value2
pipelineRef:
name: test-pipeline
taskRunSpecs:
- pipelineTaskName: unit-test-task
podTemplate:
schedulerName: SchedulerName
securityContext:
runAsNonRoot: true
runAsUser: 1001
taskRunTemplate:
serviceAccountName: svc1
status: {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Flag --resource has been deprecated, pipelineresources have been deprecated, this flag will be removed soon
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
creationTimestamp: null
generateName: test-pipeline-run-
labels:
jemange: desfrites
namespace: ns
spec:
params:
- name: pipeline-param
value: value1
- name: rev-param
value: value2
pipelineRef:
name: test-pipeline
resources:
- name: source
resourceRef:
name: scaffold-git
serviceAccountName: svc1
taskRunSpecs:
- pipelineTaskName: unit-test-task
taskPodTemplate:
schedulerName: SchedulerName
securityContext:
runAsNonRoot: true
runAsUser: 1001
status: {}
6 changes: 6 additions & 0 deletions pkg/cmd/pipeline/testdata/taskrunspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- pipelineTaskName: unit-test-task
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I referred #1088 writing this pr, and it's mostly the same but here hardcoded pipelineTaskName maybe seems fragile to future change. maybe ok?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@haedaal what could be the other options ? multiple flags --tasrun-spec, one fore each task ? what else ?
I think the one is ok, but I won't if there could be other alternative to look into.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may be we can add a check in parsing to have multiple tasks

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vdemeester I feel like there's no better alternatives, as it looks exactly same as k8s spec. I think simplicity is worth a bit of fragility.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need license header here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed @ 0663311

taskPodTemplate:
schedulerName: SchedulerName
securityContext:
runAsNonRoot: true
runAsUser: 1001
39 changes: 39 additions & 0 deletions pkg/pods/task_run_spec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright © 2020 The Tekton Authors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be 2023

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed @ 5f4ffd5

//
// 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 pods

import (
"net/http"

"github.com/tektoncd/cli/pkg/file"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
"sigs.k8s.io/yaml"
)

type TaskRunSpec = []v1beta1.PipelineTaskRunSpec

func ParseTaskRunSpec(httpClient http.Client, taskRunSpecLocation string, validate file.TypeValidator, errorMsg error) (TaskRunSpec, error) {
taskRunSpec := TaskRunSpec{}
b, err := file.LoadFileContent(httpClient, taskRunSpecLocation, validate, errorMsg)
if err != nil {
return taskRunSpec, err
}

if err := yaml.UnmarshalStrict(b, &taskRunSpec); err != nil {
return taskRunSpec, err
}

return taskRunSpec, nil
}
98 changes: 98 additions & 0 deletions pkg/pods/task_run_spec_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright © 2020 The Tekton Authors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be 2023

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed @ 5f4ffd5

//
// 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 pods

import (
"fmt"
"net/http"
"testing"

"github.com/tektoncd/cli/pkg/file"
"github.com/tektoncd/cli/pkg/test"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/pod"
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
corev1 "k8s.io/api/core/v1"
)

func getTestTaskRunSpec() TaskRunSpec {
runAsNonRoot := true
runAsUser := int64(1001)

return TaskRunSpec{
v1beta1.PipelineTaskRunSpec{
PipelineTaskName: "first-create-file",
TaskPodTemplate: &pod.PodTemplate{
ImagePullSecrets: nil,
HostNetwork: false,
SchedulerName: "SchedulerName",
SecurityContext: &corev1.PodSecurityContext{
RunAsNonRoot: &runAsNonRoot,
RunAsUser: &runAsUser,
},
},
},
}
}

func TestTaskRunSpec_Local_File(t *testing.T) {
httpClient := *http.DefaultClient
podTemplateLocation := "./testdata/taskrunspec.yaml"

podTemplate, err := ParseTaskRunSpec(httpClient, podTemplateLocation, file.IsYamlFile(), fmt.Errorf("invalid file format for %s: .yaml or .yml file extension and format required", podTemplateLocation))
if err != nil {
t.Errorf("Unexpected error: %v", err)
}

test.AssertOutput(t, getTestTaskRunSpec(), podTemplate)
}

func TestTaskRunSpec_Local_File_Typo(t *testing.T) {
httpClient := *http.DefaultClient
podTemplateLocation := "./testdata/taskrunspec-typo.yaml"

_, err := ParseTaskRunSpec(httpClient, podTemplateLocation, file.IsYamlFile(), fmt.Errorf("invalid file format for %s: .yaml or .yml file extension and format required", podTemplateLocation))
if err == nil {
t.Fatalf("Expected error for local file typo, but error was nil")
}

expected := `error unmarshaling JSON: while decoding JSON: json: unknown field "ecurityContext"`
test.AssertOutput(t, expected, err.Error())
}

func TestTaskRunSpec_Local_File_Not_YAML(t *testing.T) {
httpClient := *http.DefaultClient
podTemplateLocation := "./testdata/taskrunspec-not-yaml"

_, err := ParseTaskRunSpec(httpClient, podTemplateLocation, file.IsYamlFile(), fmt.Errorf("invalid file format for %s: .yaml or .yml file extension and format required", podTemplateLocation))
if err == nil {
t.Fatalf("Expected error for local file typo, but error was nil")
}

expected := "invalid file format for ./testdata/taskrunspec-not-yaml: .yaml or .yml file extension and format required"
test.AssertOutput(t, expected, err.Error())
}

func TestTaskRunSpec_Local_File_Not_Found(t *testing.T) {
httpClient := *http.DefaultClient
podTemplateLocation := "./testdata/not-exist.yaml"

_, err := ParseTaskRunSpec(httpClient, podTemplateLocation, file.IsYamlFile(), fmt.Errorf("invalid file format for %s: .yaml or .yml file extension and format required", podTemplateLocation))
if err == nil {
t.Fatalf("Expected error for local file typo, but error was nil")
}

expected := "open ./testdata/not-exist.yaml: no such file or directory"
test.AssertOutput(t, expected, err.Error())
}
20 changes: 20 additions & 0 deletions pkg/pods/testdata/taskrunspec-not-yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2020 The Tekton Authors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be 2023

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed @ 5f4ffd5

#
# 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.

- pipelineTaskName: first-create-file
taskPodTemplate:
schedulerName: SchedulerName
securityContext:
runAsNonRoot: true
runAsUser: 1001
20 changes: 20 additions & 0 deletions pkg/pods/testdata/taskrunspec-typo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2020 The Tekton Authors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be 2023

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed @ 5f4ffd5

#
# 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.

- pipelineTaskName: first-create-file
taskPodTemplate:
schedulerName: SchedulerName
ecurityContext:
runAsNonRoot: true
runAsUser: 1001
20 changes: 20 additions & 0 deletions pkg/pods/testdata/taskrunspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2020 The Tekton Authors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be 2023

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed @ 5f4ffd5

#
# 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.

- pipelineTaskName: first-create-file
taskPodTemplate:
schedulerName: SchedulerName
securityContext:
runAsNonRoot: true
runAsUser: 1001
17 changes: 17 additions & 0 deletions test/e2e/pipeline/pipeline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,23 @@ Waiting for logs to be available...
}
})

t.Run("Start PipelineRun with --task-run-spec", func(t *testing.T) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I try to run e2e test, I'm seeing following log

package github.com/tektoncd/cli/test/e2e/pipeline: build constraints exclude all Go files in /Users/minjaekim/workspace/oss/cli/test/e2e/pipeline

So I've written this code, but never have run it. What should I do?

tkn.MustSucceed(t, "pipeline", "start", tePipelineName,
"-p=filename=output",
"-w=name=shared-data,emptyDir=",
"--task-run-spec="+helper.GetResourcePath("/taskrunspec/taskrunspec.yaml"),
"--use-param-defaults",
"--showlog")

time.Sleep(1 * time.Second)

pipelineRunGeneratedName := builder.GetPipelineRunListWithName(c, tePipelineName, true).Items[0].Name
timeout := 5 * time.Minute
if err := wait.ForPipelineRunState(c, pipelineRunGeneratedName, timeout, wait.PipelineRunSucceed(pipelineRunGeneratedName), "PipelineRunSucceeded"); err != nil {
t.Errorf("Error waiting for PipelineRun to Succeed: %s", err)
}
})

t.Run("Cancel finished PipelineRun with tkn pipelinerun cancel", func(t *testing.T) {
// Get last PipelineRun for pipeline-with-workspace
pipelineRunLast := builder.GetPipelineRunListWithName(c, tePipelineName, true).Items[0]
Expand Down
6 changes: 6 additions & 0 deletions test/resources/taskrunspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- pipelineTaskName: first-create-file
taskPodTemplate:
schedulerName: SchedulerName
securityContext:
runAsNonRoot: true
runAsUser: 1001