Skip to content

Commit

Permalink
update the task start cmd to also allow an oci bundle with a task n…
Browse files Browse the repository at this point in the history
…ame to be created from the cli
  • Loading branch information
williamlfish authored and tekton-robot committed Nov 21, 2023
1 parent ada31c2 commit 4fcd2b8
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 26 deletions.
15 changes: 13 additions & 2 deletions docs/cmd/tkn_task_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ Start Task foo by creating a TaskRun named "foo-run-xyz123" from namespace 'bar'

tkn task start foo -s ServiceAccountName -n bar

The Task can either be specified by reference in a cluster using the positional argument
or in a file using the --filename argument.
The Task can either be specified by reference in a cluster using the positional argument,
an oci bundle using the --image argument and the positional argument or in a file using the --filename argument

Authentication:
There are three ways to authenticate against your registry when using the --image argument.
1. By default, your docker.config in your home directory and podman's auth.json are used.
2. Additionally, you can supply a Bearer Token via --remote-bearer
3. Additionally, you can use Basic auth via --remote-username and --remote-password

For params values, if you want to provide multiple values, provide them comma separated
like cat,foo,bar
Expand Down Expand Up @@ -53,12 +59,17 @@ For passing the workspaces via flags:
--dry-run preview TaskRun without running it
-f, --filename string local or remote file name containing a Task definition to start a TaskRun
-h, --help help for start
-i, --image string use an oci bundle
-l, --labels strings pass labels as label=value.
-L, --last re-run the Task using last TaskRun values
--output string format of TaskRun (yaml or json)
-p, --param stringArray pass the param as key=value for string type, or key=value1,value2,... for array type, or key="key1:value1, key2:value2" for object type
--pod-template string local or remote file containing a PodTemplate definition
--prefix-name string specify a prefix for the TaskRun name (must be lowercase alphanumeric characters)
--remote-bearer string A Bearer token to authenticate against the repository
--remote-password string A password to pass to the registry for basic auth. Must be used with --remote-username
--remote-skip-tls If set to true, skips TLS check when connecting to the registry
--remote-username string A username to pass to the registry for basic auth. Must be used with --remote-password
-s, --serviceaccount string pass the serviceaccount name
--showlog show logs right after starting the Task
--skip-optional-workspace skips the prompt for optional workspaces
Expand Down
31 changes: 29 additions & 2 deletions docs/man/man1/tkn-task-start.1
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ Start Tasks
\fB\-h\fP, \fB\-\-help\fP[=false]
help for start

.PP
\fB\-i\fP, \fB\-\-image\fP=""
use an oci bundle

.PP
\fB\-l\fP, \fB\-\-labels\fP=[]
pass labels as label=value.
Expand All @@ -55,6 +59,22 @@ Start Tasks
\fB\-\-prefix\-name\fP=""
specify a prefix for the TaskRun name (must be lowercase alphanumeric characters)

.PP
\fB\-\-remote\-bearer\fP=""
A Bearer token to authenticate against the repository

.PP
\fB\-\-remote\-password\fP=""
A password to pass to the registry for basic auth. Must be used with \-\-remote\-username

.PP
\fB\-\-remote\-skip\-tls\fP[=false]
If set to true, skips TLS check when connecting to the registry

.PP
\fB\-\-remote\-username\fP=""
A username to pass to the registry for basic auth. Must be used with \-\-remote\-password

.PP
\fB\-s\fP, \fB\-\-serviceaccount\fP=""
pass the serviceaccount name
Expand Down Expand Up @@ -116,8 +136,15 @@ tkn task start foo \-s ServiceAccountName \-n bar
.RE

.PP
The Task can either be specified by reference in a cluster using the positional argument
or in a file using the \-\-filename argument.
The Task can either be specified by reference in a cluster using the positional argument,
an oci bundle using the \-\-image argument and the positional argument or in a file using the \-\-filename argument

.PP
Authentication:
There are three ways to authenticate against your registry when using the \-\-image argument.
1. By default, your docker.config in your home directory and podman's auth.json are used.
2. Additionally, you can supply a Bearer Token via \-\-remote\-bearer
3. Additionally, you can use Basic auth via \-\-remote\-username and \-\-remote\-password

.PP
For params values, if you want to provide multiple values, provide them comma separated
Expand Down
96 changes: 75 additions & 21 deletions pkg/cmd/task/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"os"
"strings"
"time"

"github.com/google/go-containerregistry/pkg/name"
remoteimg "github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/tektoncd/cli/pkg/bundle"
"k8s.io/apimachinery/pkg/runtime"

"fmt"

"github.com/AlecAivazis/survey/v2"
"github.com/AlecAivazis/survey/v2/terminal"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -61,6 +66,7 @@ type startOptions struct {
Labels []string
ShowLog bool
Filename string
Image string
TimeOut string
DryRun bool
Output string
Expand All @@ -73,6 +79,7 @@ type startOptions struct {
UseParamDefaults bool
PodTemplate string
SkipOptionalWorkspace bool
remoteOptions bundle.RemoteOptions
}

// NameArg validates that the first argument is a valid task name
Expand Down Expand Up @@ -123,8 +130,14 @@ func startCommand(p cli.Params) *cobra.Command {
tkn task start foo -s ServiceAccountName -n bar
The Task can either be specified by reference in a cluster using the positional argument
or in a file using the --filename argument.
The Task can either be specified by reference in a cluster using the positional argument,
an oci bundle using the --image argument and the positional argument or in a file using the --filename argument
Authentication:
There are three ways to authenticate against your registry when using the --image argument.
1. By default, your docker.config in your home directory and podman's auth.json are used.
2. Additionally, you can supply a Bearer Token via --remote-bearer
3. Additionally, you can use Basic auth via --remote-username and --remote-password
For params values, if you want to provide multiple values, provide them comma separated
like cat,foo,bar
Expand Down Expand Up @@ -167,16 +180,26 @@ For passing the workspaces via flags:
if format != "" && opt.ShowLog {
return errors.New("cannot use --output option with --showlog option")
}
if len(args) != 0 {
// classic with no image
if len(args) != 0 && opt.Image == "" {
return NameArg(args, p, &opt)
}
if opt.Filename == "" {
// image but no task name
if len(args) == 0 && opt.Image != "" {
return errors.New("task name required with --image option")
}
// trying to use a file and image
if opt.Filename != "" && opt.Image != "" {
return errors.New("cannot use --filename option with --image option")
}
// not passing enough
if opt.Filename == "" && len(args) == 0 {
return errors.New("either a Task name or a --filename argument must be supplied")
}
if opt.Filename != "" && opt.Last {
return errors.New("cannot use --last option with --filename option")
// cant mix image/file with --last ( I think this is true? )
if (opt.Filename != "" || opt.Image != "") && opt.Last {
return errors.New("cannot use --last option with --filename or --image option")
}

return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -212,24 +235,24 @@ For passing the workspaces via flags:
c.Flags().StringArrayVarP(&opt.Workspaces, "workspace", "w", []string{}, "pass one or more workspaces to map to the corresponding physical volumes")
c.Flags().BoolVarP(&opt.ShowLog, "showlog", "", false, "show logs right after starting the Task")
c.Flags().StringVarP(&opt.Filename, "filename", "f", "", "local or remote file name containing a Task definition to start a TaskRun")
c.Flags().StringVarP(&opt.Image, "image", "i", "", "use an oci bundle")

c.Flags().StringVarP(&opt.TimeOut, "timeout", "", "", "timeout for TaskRun")
c.Flags().BoolVarP(&opt.DryRun, "dry-run", "", false, "preview TaskRun without running it")
c.Flags().StringVarP(&opt.Output, "output", "", "", "format of TaskRun (yaml or json)")
c.Flags().StringVarP(&opt.PrefixName, "prefix-name", "", "", "specify a prefix for the TaskRun name (must be lowercase alphanumeric characters)")
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().BoolVarP(&opt.SkipOptionalWorkspace, "skip-optional-workspace", "", false, "skips the prompt for optional workspaces")
bundle.AddRemoteFlags(c.Flags(), &opt.remoteOptions)

return c
}

func parseTask(taskLocation string, httpClient http.Client) (*v1beta1.Task, error) {
b, err := file.LoadFileContent(httpClient, taskLocation, file.IsYamlFile(), fmt.Errorf("invalid file format for %s: .yaml or .yml file extension and format required", taskLocation))
if err != nil {
return nil, err
}
func parseTask(b []byte) (*v1beta1.Task, error) {

m := map[string]interface{}{}
err = yaml.UnmarshalStrict(b, &m)
err := yaml.UnmarshalStrict(b, &m)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -277,28 +300,59 @@ func startTask(opt startOptions, args []string) error {
Namespace: opt.cliparams.Namespace(),
},
}

var tname string
if len(args) > 0 {

switch {
case len(args) > 0 && opt.Image == "":
tname = args[0]
tr.Spec = v1beta1.TaskRunSpec{
TaskRef: &v1beta1.TaskRef{Name: tname},
}
} else {
task, err := parseTask(opt.Filename, cs.HTTPClient)
case opt.Filename != "":
b, err := file.LoadFileContent(cs.HTTPClient, opt.Filename, file.IsYamlFile(), fmt.Errorf("invalid file format for %s: .yaml or .yml file extension and format required", opt.Filename))
if err != nil {
return err
}
task, err := parseTask(b)
if err != nil {
return err
}
opt.task = task
tname = task.ObjectMeta.Name

if task.Spec.Params != nil {
params.FilterParamsByType(task.Spec.Params)
}

tr.Spec = v1beta1.TaskRunSpec{
TaskSpec: &task.Spec,
}
case opt.Image != "":
ref, err := name.ParseReference(opt.Image)
if err != nil {
return err
}
img, err := remoteimg.Image(ref, opt.remoteOptions.ToOptions()...)
if err != nil {
return err
}
err = bundle.Get(img, "task", args[0], func(_, _, _ string, element runtime.Object, b []byte) {
task, intErr := parseTask(b)
if intErr != nil {
err = intErr
}
opt.task = task
tname = task.ObjectMeta.Name

if task.Spec.Params != nil {
params.FilterParamsByType(task.Spec.Params)
}

tr.Spec = v1beta1.TaskRunSpec{
TaskSpec: &task.Spec,
}
})
if err != nil {
return err
}
}

if err := opt.getInputs(); err != nil {
Expand Down
22 changes: 21 additions & 1 deletion pkg/cmd/task/start_v1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,27 @@ func Test_start_has_filename_arg_with_last(t *testing.T) {
if err == nil {
t.Error("Expecting an error but it's empty")
}
test.AssertOutput(t, "cannot use --last option with --filename option", err.Error())
test.AssertOutput(t, "cannot use --last option with --filename or --image option", err.Error())
}

func Test_start_has_image_arg_no_taskname(t *testing.T) {
c := Command(&test.Params{})

_, err := test.ExecuteCommand(c, "start", "-n", "ns", "--image=oci.rad.com/task:0.1", "--last")
if err == nil {
t.Error("Expecting an error but it's empty")
}
test.AssertOutput(t, "task name required with --image option", err.Error())
}

func Test_start_has_image_arg_with_last(t *testing.T) {
c := Command(&test.Params{})

_, err := test.ExecuteCommand(c, "start", "rad-task", "-n", "ns", "--image=oci.rad.com/task:0.1", "--last")
if err == nil {
t.Error("Expecting an error but it's empty")
}
test.AssertOutput(t, "cannot use --last option with --filename or --image option", err.Error())
}

func Test_start_has_task_filename(t *testing.T) {
Expand Down

0 comments on commit 4fcd2b8

Please sign in to comment.