Skip to content

Commit

Permalink
Add support for optional workspaces in tkn start
Browse files Browse the repository at this point in the history
As of now if the resource contains an optional workspace we still have
to bind the corresponding workspace value at the time of doing tkn
<resource> start.

With this commit, it will ask interactively whether we want to provide
details for workspace or not if it's optional.
Added e2e tests for the same.

Signed-off-by: vinamra28 <[email protected]>
  • Loading branch information
vinamra28 committed May 29, 2021
1 parent bd86190 commit b0781ab
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 2 deletions.
9 changes: 9 additions & 0 deletions pkg/cmd/pipeline/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,15 @@ func parsePipeline(pipelineLocation string, httpClient http.Client) (*v1beta1.Pi

func (opt *startOptions) getInputWorkspaces(pipeline *v1beta1.Pipeline) error {
for _, ws := range pipeline.Spec.Workspaces {
if ws.Optional {
isOptional, err := askParam(fmt.Sprintf("Do you want to give specifications for the optional workspace `%s`: (y/N)", ws.Name), opt.askOpts)
if err != nil {
return err
}
if isOptional == "N" || isOptional == "n" {
continue
}
}
fmt.Fprintf(opt.stream.Out, "Please give specifications for the workspace: %s \n", ws.Name)
name, err := askParam("Name for the workspace :", opt.askOpts)
if err != nil {
Expand Down
22 changes: 20 additions & 2 deletions pkg/options/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,15 @@ func (intOpts *InteractiveOpts) TaskParams(task *v1beta1.Task, skipParams map[st

func (intOpts *InteractiveOpts) TaskWorkspaces(task *v1beta1.Task) error {
for _, ws := range task.Spec.Workspaces {
if ws.Optional {
isOptional, err := askParam(fmt.Sprintf("Do you want to give specifications for the optional workspace `%s`: (y/N)", ws.Name), intOpts.AskOpts)
if err != nil {
return err
}
if isOptional == "N" || isOptional == "n" {
continue
}
}
fmt.Fprintf(intOpts.Stream.Out, "Please give specifications for the workspace: %s \n", ws.Name)
name, err := askParam("Name for the workspace :", intOpts.AskOpts)
if err != nil {
Expand All @@ -346,7 +355,7 @@ func (intOpts *InteractiveOpts) TaskWorkspaces(task *v1beta1.Task) error {
{
Name: "workspace param",
Prompt: &survey.Select{
Message: " Type of the Workspace :",
Message: "Type of the Workspace :",
Options: []string{"config", "emptyDir", "secret", "pvc"},
Default: "emptyDir",
},
Expand Down Expand Up @@ -553,6 +562,15 @@ func (intOpts *InteractiveOpts) ClusterTaskParams(clustertask *v1beta1.ClusterTa

func (intOpts *InteractiveOpts) ClusterTaskWorkspaces(clustertask *v1beta1.ClusterTask) error {
for _, ws := range clustertask.Spec.Workspaces {
if ws.Optional {
isOptional, err := askParam(fmt.Sprintf("Do you want to give specifications for the optional workspace `%s`: (y/N)", ws.Name), intOpts.AskOpts)
if err != nil {
return err
}
if isOptional == "N" || isOptional == "n" {
continue
}
}
fmt.Fprintf(intOpts.Stream.Out, "Please give specifications for the workspace: %s \n", ws.Name)
name, err := askParam("Name for the workspace:", intOpts.AskOpts)
if err != nil {
Expand All @@ -572,7 +590,7 @@ func (intOpts *InteractiveOpts) ClusterTaskWorkspaces(clustertask *v1beta1.Clust
{
Name: "workspace param",
Prompt: &survey.Select{
Message: " Type of the Workspace:",
Message: "Type of the Workspace:",
Options: []string{"config", "emptyDir", "secret", "pvc"},
Default: "emptyDir",
},
Expand Down
80 changes: 80 additions & 0 deletions test/e2e/clustertask/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,72 @@ Waiting for logs to be available...
}
})

t.Logf("Creating clustertask clustertask-optional-ws")
res = kubectl.MustSucceed(t, "create", "-f", helper.GetResourcePath("clustertask-with-optional-workspace.yaml"))
regex = regexp.MustCompile(`clustertask-optional-ws-[a-z0-9]+`)
clusterTaskName2 := regex.FindString(res.Stdout())

t.Run("Start ClusterTask interactively with optional workspace (yes)", func(t *testing.T) {
tkn.RunInteractiveTests(t, &cli.Prompt{
CmdArgs: []string{"clustertask", "start", clusterTaskName2},
Procedure: func(c *expect.Console) error {
if _, err := c.ExpectString("Do you want to give specifications for the optional workspace `read-allowed`: (y/N)"); err != nil {
return err
}

if _, err := c.SendLine("y"); err != nil {
return err
}

if _, err := c.ExpectString("Please give specifications for the workspace: read-allowed"); err != nil {
return err
}

if _, err := c.ExpectString("Name for the workspace: "); err != nil {
return err
}

if _, err := c.SendLine("read-allowed"); err != nil {
return err
}

if _, err := c.ExpectString("Value of the Sub Path: "); err != nil {
return err
}

if _, err := c.Send(string(terminal.KeyEnter)); err != nil {
return err
}

if _, err := c.ExpectString("Type of the Workspace:"); err != nil {
return err
}

if _, err := c.SendLine("emptyDir"); err != nil {
return err
}

if _, err := c.ExpectString("Type of EmptyDir: "); err != nil {
return err
}

if _, err := c.SendLine(""); err != nil {
return err
}

if _, err := c.ExpectEOF(); err != nil {
return err
}

c.Close()
return nil
}})
taskRunGeneratedName := builder.GetTaskRunListWithClusterTaskName(c, clusterTaskName2, true).Items[0].Name
if err := wait.ForTaskRunState(c, taskRunGeneratedName, wait.TaskRunSucceed(taskRunGeneratedName), "TaskRunSucceed"); err != nil {
t.Errorf("Error waiting for TaskRun to Succeed: %s", err)
}
})

t.Logf("Deleting clustertask %s", clusterTaskName)
t.Run(fmt.Sprintf("Delete clustertask %s", clusterTaskName), func(t *testing.T) {
res := tkn.MustSucceed(t, "clustertask", "delete", clusterTaskName, "-f")
Expand All @@ -286,4 +352,18 @@ Waiting for logs to be available...
assert.Assert(t, !strings.Contains(res.Stdout(), clusterTaskName))
})

t.Logf("Deleting clustertask %s", clusterTaskName2)
t.Run(fmt.Sprintf("Delete clustertask %s", clusterTaskName2), func(t *testing.T) {
res := tkn.MustSucceed(t, "clustertask", "delete", clusterTaskName2, "-f")
expected := fmt.Sprintf("ClusterTasks deleted: \"%s\"", clusterTaskName2)
res.Assert(t, icmd.Expected{
Err: icmd.None,
Out: expected,
})

// Check if clustertask %s got deleted
res = tkn.Run("clustertask", "list")
assert.Assert(t, !strings.Contains(res.Stdout(), clusterTaskName2))
})

}
64 changes: 64 additions & 0 deletions test/e2e/task/start_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,68 @@ Waiting for logs to be available...
t.Fatalf("-got, +want: %v", d)
}
})

t.Logf("Creating Task task-optional-ws in namespace: %s ", namespace)
kubectl.MustSucceed(t, "create", "-f", helper.GetResourcePath("task-with-optional-workspace.yaml"))

t.Run("Start Task interactively with optional workspace (yes)", func(t *testing.T) {
tkn.RunInteractiveTests(t, &cli.Prompt{
CmdArgs: []string{"task", "start", "task-optional-ws"},
Procedure: func(c *expect.Console) error {
if _, err := c.ExpectString("Do you want to give specifications for the optional workspace `read-allowed`: (y/N)"); err != nil {
return err
}

if _, err := c.SendLine("y"); err != nil {
return err
}

if _, err := c.ExpectString("Please give specifications for the workspace: read-allowed"); err != nil {
return err
}

if _, err := c.ExpectString("Name for the workspace :"); err != nil {
return err
}

if _, err := c.SendLine("read-allowed"); err != nil {
return err
}

if _, err := c.ExpectString("Value of the Sub Path :"); err != nil {
return err
}

if _, err := c.Send(string(terminal.KeyEnter)); err != nil {
return err
}

if _, err := c.ExpectString("Type of the Workspace :"); err != nil {
return err
}

if _, err := c.SendLine("emptyDir"); err != nil {
return err
}

if _, err := c.ExpectString("Type of EmptyDir :"); err != nil {
return err
}

if _, err := c.SendLine(""); err != nil {
return err
}

if _, err := c.ExpectEOF(); err != nil {
return err
}

c.Close()
return nil
}})
taskRunGeneratedName := builder.GetTaskRunListWithTaskName(c, "task-optional-ws", true).Items[0].Name
if err := wait.ForTaskRunState(c, taskRunGeneratedName, wait.TaskRunSucceed(taskRunGeneratedName), "TaskRunSucceed"); err != nil {
t.Errorf("Error waiting for TaskRun to Succeed: %s", err)
}
})
}
30 changes: 30 additions & 0 deletions test/resources/clustertask-with-optional-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2021 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.

apiVersion: tekton.dev/v1alpha1
kind: ClusterTask
metadata:
generateName: clustertask-optional-ws-
spec:
steps:
- name: list-files
image: ubuntu
script: |
#!/bin/bash
[ "$(workspaces.read-allowed.bound)" == "true" ] && \
ls $(workspaces.read-allowed.path)
workspaces:
- name: read-allowed
optional: true
39 changes: 39 additions & 0 deletions test/resources/pipeline-with-optional-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Copyright 2021 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.

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: pipeline-optional-ws
spec:
tasks:
- name: reader
taskSpec:
steps:
- name: list-files
image: ubuntu
script: |
#!/bin/bash
[ "$(workspaces.read-allowed.bound)" == "true" ] && \
ls $(workspaces.read-allowed.path)
workspaces:
- name: myws
optional: true
workspaces:
- name: myws
workspace: ws
workspaces:
- name: ws
optional: true
30 changes: 30 additions & 0 deletions test/resources/task-with-optional-workspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2021 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.

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: task-optional-ws
spec:
steps:
- name: list-files
image: ubuntu
script: |
#!/bin/bash
[ "$(workspaces.read-allowed.bound)" == "true" ] && \
ls $(workspaces.read-allowed.path)
workspaces:
- name: read-allowed
optional: true

0 comments on commit b0781ab

Please sign in to comment.