Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use oci image to run a task #2130

Merged
merged 2 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ check: lint test
test: test-unit ## run all tests

.PHONY: lint
lint: lint-go lint-yaml ## run all linters
lint: lint-go goimports lint-yaml ## run all linters

GOLANGCILINT = $(BIN)/golangci-lint
$(BIN)/golangci-lint: ; $(info $(M) getting golangci-lint $(GOLANGCI_VERSION))
Expand All @@ -104,12 +104,13 @@ lint-go: | $(GOLANGCILINT) ; $(info $(M) running golangci-lint…) @ ## Run gola
@rm -f $(GOLANGCILINT)

GOIMPORTS = $(BIN)/goimports
$(BIN)/goimports: PACKAGE=golang.org/x/tools/cmd/goimports
$(GOIMPORTS): ; $(info $(M) getting goimports )
GOBIN=$(BIN) $(GO) install -mod=mod golang.org/x/tools/cmd/goimports

.PHONY: goimports
goimports: | $(GOIMPORTS) ; $(info $(M) running goimports…) ## Run goimports
$Q $(GOIMPORTS) -l -e -w pkg cmd test

@rm -f $(GOIMPORTS)

.PHONY: lint-yaml
lint-yaml: ${YAML_FILES} ; $(info $(M) running yamllint…) ## runs yamllint on all yaml files
Expand Down
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"
Copy link
Contributor

Choose a reason for hiding this comment

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

not goimported

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤔 the linter seems happy enough, and i did run goimports -l -e -w ./pkg/cmd/task/start*.

I noticed the makefile has a goimports cmd, but its looking in a .bin/ of the current dir, and i dont have goimports installed there. Is there a way to setup the .bin/ from the makefile with the required dependencies? Not sure what the difference would be, running there vs where i have it installed, but happy to update, or if there is documentation I'm missing somewhere can you please point me in that direction? thanks 😸

Copy link
Member

Choose a reason for hiding this comment

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

@williamlfish it should "auto-install" it in the .bin folder on the make lint commands (or whatever the target name is). At least that's what it's supposed to do 😛

Copy link
Contributor Author

@williamlfish williamlfish Sep 27, 2023

Choose a reason for hiding this comment

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

@vdemeester I updated make lint to do that with the latest commit, it was previously just installing golangci-lint. I'm not sure what version or what binary yamllint is supposed to be, but we should have that auto install too, for now i just moved to to the end so it fails there if someone does not have it installed 🤷‍♀️

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 {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

here is where i think we can generalize the logic for a task and a pipeline? @vdemeester

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
Loading