From e81c71586bad4b85985ae5ae460068d3c5a1a9f9 Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Thu, 13 Feb 2020 14:33:29 +0100 Subject: [PATCH] wip Signed-off-by: Vincent Demeester --- cmd/webhook/main.go | 12 +- config/300-clustertask.yaml | 7 + config/300-pipeline.yaml | 7 + config/300-pipelinerun.yaml | 7 + config/300-task.yaml | 7 + config/300-taskrun.yaml | 7 + .../pipeline/v1alpha1/conversion_error.go | 22 +- pkg/apis/pipeline/v1alpha1/task_defaults.go | 14 + pkg/apis/pipeline/v1alpha1/task_types.go | 4 +- pkg/apis/pipeline/v1alpha1/task_validation.go | 47 +- .../pipeline/v1alpha1/taskrun_defaults.go | 14 +- pkg/apis/pipeline/v1alpha1/taskrun_types.go | 9 +- .../pipeline/v1alpha1/taskrun_validation.go | 10 + .../v1alpha1/zz_generated.deepcopy.go | 63 +-- .../pipeline/v1alpha2/conversion_error.go | 51 +++ .../pipeline/v1alpha2/pipelinerun_types.go | 12 + pkg/apis/pipeline/v1alpha2/task_validation.go | 32 +- pkg/apis/pipeline/v1alpha2/taskrun_types.go | 28 +- .../v1alpha2/zz_generated.deepcopy.go | 16 + pkg/reconciler/pipelinerun/pipelinerun.go | 32 +- .../pipelinerun/pipelinerun_test.go | 33 +- .../resources/input_output_steps.go | 8 +- .../resources/input_output_steps_test.go | 4 +- .../resources/pipelinerunresolution.go | 17 +- .../resources/pipelinerunresolution_test.go | 59 ++- .../pipelinerun/resources/pipelinespec.go | 8 +- .../resources/pipelinespec_test.go | 9 +- pkg/reconciler/taskrun/resources/apply.go | 24 +- .../taskrun/resources/apply_test.go | 162 +++---- .../taskrun/resources/image_exporter.go | 15 +- .../taskrun/resources/image_exporter_test.go | 74 ++-- .../taskrun/resources/input_resource_test.go | 400 +++++++++-------- .../taskrun/resources/input_resources.go | 17 +- .../taskrun/resources/output_resource.go | 15 +- .../taskrun/resources/output_resource_test.go | 414 ++++++++++-------- .../resources/taskresourceresolution.go | 3 +- pkg/reconciler/taskrun/resources/taskspec.go | 10 +- .../taskrun/resources/taskspec_test.go | 9 +- pkg/reconciler/taskrun/taskrun.go | 34 +- pkg/reconciler/taskrun/validate_resources.go | 43 +- .../taskrun/validate_resources_test.go | 64 +-- test/builder/task.go | 114 +++++ test/builder/task_test.go | 5 +- 43 files changed, 1200 insertions(+), 742 deletions(-) create mode 100644 pkg/apis/pipeline/v1alpha2/conversion_error.go diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index 0f3f60fb8e9..551cf3f4a6e 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -22,6 +22,7 @@ import ( defaultconfig "github.com/tektoncd/pipeline/pkg/apis/config" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" "github.com/tektoncd/pipeline/pkg/contexts" "k8s.io/apimachinery/pkg/runtime/schema" "knative.dev/pkg/configmap" @@ -38,6 +39,7 @@ import ( ) var types = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{ + // v1alpha1 v1alpha1.SchemeGroupVersion.WithKind("Pipeline"): &v1alpha1.Pipeline{}, v1alpha1.SchemeGroupVersion.WithKind("Task"): &v1alpha1.Task{}, v1alpha1.SchemeGroupVersion.WithKind("ClusterTask"): &v1alpha1.ClusterTask{}, @@ -45,6 +47,12 @@ var types = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{ v1alpha1.SchemeGroupVersion.WithKind("PipelineRun"): &v1alpha1.PipelineRun{}, v1alpha1.SchemeGroupVersion.WithKind("Condition"): &v1alpha1.Condition{}, v1alpha1.SchemeGroupVersion.WithKind("PipelineResource"): &v1alpha1.PipelineResource{}, + // v1alpha2 + v1alpha2.SchemeGroupVersion.WithKind("Pipeline"): &v1alpha2.Pipeline{}, + v1alpha2.SchemeGroupVersion.WithKind("Task"): &v1alpha2.Task{}, + v1alpha2.SchemeGroupVersion.WithKind("ClusterTask"): &v1alpha2.ClusterTask{}, + v1alpha2.SchemeGroupVersion.WithKind("TaskRun"): &v1alpha2.TaskRun{}, + v1alpha2.SchemeGroupVersion.WithKind("PipelineRun"): &v1alpha2.PipelineRun{}, } func NewDefaultingAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl { @@ -65,9 +73,7 @@ func NewDefaultingAdmissionController(ctx context.Context, cmw configmap.Watcher // A function that infuses the context passed to Validate/SetDefaults with custom metadata. func(ctx context.Context) context.Context { - // FIXME(vdemeester) uncomment that for auto-conversion - // return v1alpha2.WithUpgradeViaDefaulting(store.ToContext(ctx)) - return contexts.WithDefaultConfigurationName(store.ToContext(ctx)) + return contexts.WithUpgradeViaDefaulting(store.ToContext(ctx)) }, // Whether to disallow unknown fields. diff --git a/config/300-clustertask.yaml b/config/300-clustertask.yaml index 77ec11966b9..8a58f066642 100644 --- a/config/300-clustertask.yaml +++ b/config/300-clustertask.yaml @@ -17,6 +17,13 @@ metadata: name: clustertasks.tekton.dev spec: group: tekton.dev + versions: + - name: v1alpha1 + served: true + storage: true + - name: v1alpha2 + served: true + storage: false names: kind: ClusterTask plural: clustertasks diff --git a/config/300-pipeline.yaml b/config/300-pipeline.yaml index 3419f424ee2..025aff50645 100644 --- a/config/300-pipeline.yaml +++ b/config/300-pipeline.yaml @@ -17,6 +17,13 @@ metadata: name: pipelines.tekton.dev spec: group: tekton.dev + versions: + - name: v1alpha1 + served: true + storage: true + - name: v1alpha2 + served: true + storage: false names: kind: Pipeline plural: pipelines diff --git a/config/300-pipelinerun.yaml b/config/300-pipelinerun.yaml index 3e822020a56..6402ee01bea 100644 --- a/config/300-pipelinerun.yaml +++ b/config/300-pipelinerun.yaml @@ -17,6 +17,13 @@ metadata: name: pipelineruns.tekton.dev spec: group: tekton.dev + versions: + - name: v1alpha1 + served: true + storage: true + - name: v1alpha2 + served: true + storage: false names: kind: PipelineRun plural: pipelineruns diff --git a/config/300-task.yaml b/config/300-task.yaml index 00f04eee937..e5f01bdf2e3 100644 --- a/config/300-task.yaml +++ b/config/300-task.yaml @@ -17,6 +17,13 @@ metadata: name: tasks.tekton.dev spec: group: tekton.dev + versions: + - name: v1alpha1 + served: true + storage: true + - name: v1alpha2 + served: true + storage: false names: kind: Task plural: tasks diff --git a/config/300-taskrun.yaml b/config/300-taskrun.yaml index 2f0deec788e..a26188829d4 100644 --- a/config/300-taskrun.yaml +++ b/config/300-taskrun.yaml @@ -17,6 +17,13 @@ metadata: name: taskruns.tekton.dev spec: group: tekton.dev + versions: + - name: v1alpha1 + served: true + storage: true + - name: v1alpha2 + served: true + storage: false names: kind: TaskRun plural: taskruns diff --git a/pkg/apis/pipeline/v1alpha1/conversion_error.go b/pkg/apis/pipeline/v1alpha1/conversion_error.go index 7282ea9e1ca..c2ab76388a8 100644 --- a/pkg/apis/pipeline/v1alpha1/conversion_error.go +++ b/pkg/apis/pipeline/v1alpha1/conversion_error.go @@ -17,8 +17,7 @@ limitations under the License. package v1alpha1 import ( - "fmt" - + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" "knative.dev/pkg/apis" ) @@ -26,26 +25,13 @@ const ( // ConditionTypeConvertible is a Warning condition that is set on // resources when they cannot be converted to warn of a forthcoming // breakage. - ConditionTypeConvertible apis.ConditionType = "Convertible" + ConditionTypeConvertible apis.ConditionType = v1alpha2.ConditionTypeConvertible ) // CannotConvertError is returned when a field cannot be converted. -type CannotConvertError struct { - Message string - Field string -} +type CannotConvertError = v1alpha2.CannotConvertError var _ error = (*CannotConvertError)(nil) -// Error implements error -func (cce *CannotConvertError) Error() string { - return cce.Message -} - // ConvertErrorf creates a CannotConvertError from the field name and format string. -func ConvertErrorf(field, msg string, args ...interface{}) error { - return &CannotConvertError{ - Message: fmt.Sprintf(msg, args...), - Field: field, - } -} +var ConvertErrorf = v1alpha2.ConvertErrorf diff --git a/pkg/apis/pipeline/v1alpha1/task_defaults.go b/pkg/apis/pipeline/v1alpha1/task_defaults.go index 53a69b4de0b..2baa6bfd3e6 100644 --- a/pkg/apis/pipeline/v1alpha1/task_defaults.go +++ b/pkg/apis/pipeline/v1alpha1/task_defaults.go @@ -19,6 +19,8 @@ package v1alpha1 import ( "context" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" + "github.com/tektoncd/pipeline/pkg/contexts" "knative.dev/pkg/apis" ) @@ -30,6 +32,18 @@ func (t *Task) SetDefaults(ctx context.Context) { // SetDefaults set any defaults for the task spec func (ts *TaskSpec) SetDefaults(ctx context.Context) { + if contexts.IsUpgradeViaDefaulting(ctx) { + v := v1alpha2.TaskSpec{} + if ts.ConvertUp(ctx, &v) == nil { + alpha := TaskSpec{} + if alpha.ConvertDown(ctx, &v) == nil { + *ts = alpha + } + } + } + for i := range ts.Params { + ts.Params[i].SetDefaults(ctx) + } if ts.Inputs != nil { ts.Inputs.SetDefaults(ctx) } diff --git a/pkg/apis/pipeline/v1alpha1/task_types.go b/pkg/apis/pipeline/v1alpha1/task_types.go index 544e6e0b77c..2fdb63e488c 100644 --- a/pkg/apis/pipeline/v1alpha1/task_types.go +++ b/pkg/apis/pipeline/v1alpha1/task_types.go @@ -105,9 +105,7 @@ type Inputs struct { // the Task definition, and when provided as an Input, the Name will be the // path to the volume mounted containing this Resource as an input (e.g. // an input Resource named `workspace` will be mounted at `/workspace`). -type TaskResource struct { - ResourceDeclaration `json:",inline"` -} +type TaskResource = v1alpha2.TaskResource // Outputs allow a task to declare what data the Build/Task will be producing, // i.e. results such as logs and artifacts such as images. diff --git a/pkg/apis/pipeline/v1alpha1/task_validation.go b/pkg/apis/pipeline/v1alpha1/task_validation.go index 3209e8aceb6..36004b8875c 100644 --- a/pkg/apis/pipeline/v1alpha1/task_validation.go +++ b/pkg/apis/pipeline/v1alpha1/task_validation.go @@ -22,6 +22,7 @@ import ( "path/filepath" "strings" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" "github.com/tektoncd/pipeline/pkg/apis/validate" "github.com/tektoncd/pipeline/pkg/substitution" corev1 "k8s.io/api/core/v1" @@ -79,9 +80,18 @@ func (ts *TaskSpec) Validate(ctx context.Context) *apis.FieldError { } } + // Validate Resources declaration + if err := ts.Resources.Validate(ctx); err != nil { + return err + } + // Validate that the parameters type are correct + if err := v1alpha2.ValidateParameterTypes(ts.Params); err != nil { + return err + } + // A task doesn't have to have inputs or outputs, but if it does they must be valid. // A task can't duplicate input or output names. - + // Deprecated if ts.Inputs != nil { for _, resource := range ts.Inputs.Resources { if err := validateResourceType(resource, fmt.Sprintf("taskspec.Inputs.Resources.%s.Type", resource.Name)); err != nil { @@ -95,6 +105,7 @@ func (ts *TaskSpec) Validate(ctx context.Context) *apis.FieldError { return err } } + // Deprecated if ts.Outputs != nil { for _, resource := range ts.Outputs.Resources { if err := validateResourceType(resource, fmt.Sprintf("taskspec.Outputs.Resources.%s.Type", resource.Name)); err != nil { @@ -117,10 +128,19 @@ func (ts *TaskSpec) Validate(ctx context.Context) *apis.FieldError { } } - if err := validateInputParameterVariables(ts.Steps, ts.Inputs); err != nil { + if err := v1alpha2.ValidateParameterVariables(ts.Steps, ts.Params); err != nil { + return err + } + // Deprecated + if err := validateInputParameterVariables(ts.Steps, ts.Inputs, ts.Params); err != nil { + return err + } + + if err := v1alpha2.ValidateResourcesVariables(ts.Steps, ts.Resources); err != nil { return err } - if err := validateResourceVariables(ts.Steps, ts.Inputs, ts.Outputs); err != nil { + // Deprecated + if err := validateResourceVariables(ts.Steps, ts.Inputs, ts.Outputs, ts.Resources); err != nil { return err } return nil @@ -251,10 +271,17 @@ func validateInputParameterTypes(inputs *Inputs) *apis.FieldError { return nil } -func validateInputParameterVariables(steps []Step, inputs *Inputs) *apis.FieldError { +func validateInputParameterVariables(steps []Step, inputs *Inputs, params []v1alpha2.ParamSpec) *apis.FieldError { parameterNames := map[string]struct{}{} arrayParameterNames := map[string]struct{}{} + for _, p := range params { + parameterNames[p.Name] = struct{}{} + if p.Type == ParamTypeArray { + arrayParameterNames[p.Name] = struct{}{} + } + } + // Deprecated if inputs != nil { for _, p := range inputs.Params { parameterNames[p.Name] = struct{}{} @@ -270,13 +297,23 @@ func validateInputParameterVariables(steps []Step, inputs *Inputs) *apis.FieldEr return validateArrayUsage(steps, "params", arrayParameterNames) } -func validateResourceVariables(steps []Step, inputs *Inputs, outputs *Outputs) *apis.FieldError { +func validateResourceVariables(steps []Step, inputs *Inputs, outputs *Outputs, resources *v1alpha2.TaskResources) *apis.FieldError { resourceNames := map[string]struct{}{} + if resources != nil { + for _, r := range resources.Inputs { + resourceNames[r.Name] = struct{}{} + } + for _, r := range resources.Outputs { + resourceNames[r.Name] = struct{}{} + } + } + // Deprecated if inputs != nil { for _, r := range inputs.Resources { resourceNames[r.Name] = struct{}{} } } + // Deprecated if outputs != nil { for _, r := range outputs.Resources { resourceNames[r.Name] = struct{}{} diff --git a/pkg/apis/pipeline/v1alpha1/taskrun_defaults.go b/pkg/apis/pipeline/v1alpha1/taskrun_defaults.go index cd6310228f3..d3415d6d603 100644 --- a/pkg/apis/pipeline/v1alpha1/taskrun_defaults.go +++ b/pkg/apis/pipeline/v1alpha1/taskrun_defaults.go @@ -21,6 +21,7 @@ import ( "time" "github.com/tektoncd/pipeline/pkg/apis/config" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" "github.com/tektoncd/pipeline/pkg/contexts" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/apis" @@ -31,7 +32,8 @@ var _ apis.Defaultable = (*TaskRun)(nil) const managedByLabelKey = "app.kubernetes.io/managed-by" func (tr *TaskRun) SetDefaults(ctx context.Context) { - tr.Spec.SetDefaults(ctx) + ctx = apis.WithinParent(ctx, tr.ObjectMeta) + tr.Spec.SetDefaults(apis.WithinSpec(ctx)) // If the TaskRun doesn't have a managed-by label, apply the default // specified in the config. @@ -45,6 +47,16 @@ func (tr *TaskRun) SetDefaults(ctx context.Context) { } func (trs *TaskRunSpec) SetDefaults(ctx context.Context) { + if contexts.IsUpgradeViaDefaulting(ctx) { + v := v1alpha2.TaskRunSpec{} + if trs.ConvertUp(ctx, &v) == nil { + alpha := TaskRunSpec{} + if alpha.ConvertDown(ctx, &v) == nil { + *trs = alpha + } + } + } + cfg := config.FromContextOrDefaults(ctx) if trs.TaskRef != nil && trs.TaskRef.Kind == "" { trs.TaskRef.Kind = NamespacedTaskKind diff --git a/pkg/apis/pipeline/v1alpha1/taskrun_types.go b/pkg/apis/pipeline/v1alpha1/taskrun_types.go index 67e61f1f2c0..23c6b545278 100644 --- a/pkg/apis/pipeline/v1alpha1/taskrun_types.go +++ b/pkg/apis/pipeline/v1alpha1/taskrun_types.go @@ -87,14 +87,7 @@ type TaskRunInputs struct { // TaskResourceBinding points to the PipelineResource that // will be used for the Task input or output called Name. -type TaskResourceBinding struct { - PipelineResourceBinding - // Paths will probably be removed in #1284, and then PipelineResourceBinding can be used instead. - // The optional Path field corresponds to a path on disk at which the Resource can be found - // (used when providing the resource via mounted volume, overriding the default logic to fetch the Resource). - // +optional - Paths []string `json:"paths,omitempty"` -} +type TaskResourceBinding = v1alpha2.TaskResourceBinding // TaskRunOutputs holds the output values that this task was invoked with. type TaskRunOutputs struct { diff --git a/pkg/apis/pipeline/v1alpha1/taskrun_validation.go b/pkg/apis/pipeline/v1alpha1/taskrun_validation.go index 1ce4bd15f15..f443254de8a 100644 --- a/pkg/apis/pipeline/v1alpha1/taskrun_validation.go +++ b/pkg/apis/pipeline/v1alpha1/taskrun_validation.go @@ -59,19 +59,29 @@ func (ts *TaskRunSpec) Validate(ctx context.Context) *apis.FieldError { } } + // Deprecated // check for input resources if err := ts.Inputs.Validate(ctx, "spec.Inputs"); err != nil { return err } + // Deprecated // check for output resources if err := ts.Outputs.Validate(ctx, "spec.Outputs"); err != nil { return err } + // Validate Resources + if err := ts.Resources.Validate(ctx); err != nil { + return err + } + if err := validateWorkspaceBindings(ctx, ts.Workspaces); err != nil { return err } + if err := validateParameters(ts.Params); err != nil { + return err + } if ts.Timeout != nil { // timeout should be a valid duration of at least 0. diff --git a/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go index 08d1de7a162..8a825617987 100644 --- a/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go @@ -87,22 +87,6 @@ func (in *BuildGCSResource) DeepCopy() *BuildGCSResource { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CannotConvertError) DeepCopyInto(out *CannotConvertError) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CannotConvertError. -func (in *CannotConvertError) DeepCopy() *CannotConvertError { - if in == nil { - return nil - } - out := new(CannotConvertError) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CloudEventResource) DeepCopyInto(out *CloudEventResource) { *out = *in @@ -372,7 +356,7 @@ func (in *Inputs) DeepCopyInto(out *Inputs) { *out = *in if in.Resources != nil { in, out := &in.Resources, &out.Resources - *out = make([]TaskResource, len(*in)) + *out = make([]v1alpha2.TaskResource, len(*in)) copy(*out, *in) } if in.Params != nil { @@ -405,7 +389,7 @@ func (in *Outputs) DeepCopyInto(out *Outputs) { } if in.Resources != nil { in, out := &in.Resources, &out.Resources - *out = make([]TaskResource, len(*in)) + *out = make([]v1alpha2.TaskResource, len(*in)) copy(*out, *in) } return @@ -823,45 +807,6 @@ func (in *TaskList) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TaskResource) DeepCopyInto(out *TaskResource) { - *out = *in - out.ResourceDeclaration = in.ResourceDeclaration - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TaskResource. -func (in *TaskResource) DeepCopy() *TaskResource { - if in == nil { - return nil - } - out := new(TaskResource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TaskResourceBinding) DeepCopyInto(out *TaskResourceBinding) { - *out = *in - in.PipelineResourceBinding.DeepCopyInto(&out.PipelineResourceBinding) - if in.Paths != nil { - in, out := &in.Paths, &out.Paths - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TaskResourceBinding. -func (in *TaskResourceBinding) DeepCopy() *TaskResourceBinding { - if in == nil { - return nil - } - out := new(TaskResourceBinding) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TaskRun) DeepCopyInto(out *TaskRun) { *out = *in @@ -895,7 +840,7 @@ func (in *TaskRunInputs) DeepCopyInto(out *TaskRunInputs) { *out = *in if in.Resources != nil { in, out := &in.Resources, &out.Resources - *out = make([]TaskResourceBinding, len(*in)) + *out = make([]v1alpha2.TaskResourceBinding, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -958,7 +903,7 @@ func (in *TaskRunOutputs) DeepCopyInto(out *TaskRunOutputs) { *out = *in if in.Resources != nil { in, out := &in.Resources, &out.Resources - *out = make([]TaskResourceBinding, len(*in)) + *out = make([]v1alpha2.TaskResourceBinding, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/pkg/apis/pipeline/v1alpha2/conversion_error.go b/pkg/apis/pipeline/v1alpha2/conversion_error.go new file mode 100644 index 00000000000..be489604de6 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha2/conversion_error.go @@ -0,0 +1,51 @@ +/* +Copyright 2020 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 v1alpha2 + +import ( + "fmt" + + "knative.dev/pkg/apis" +) + +const ( + // ConditionTypeConvertible is a Warning condition that is set on + // resources when they cannot be converted to warn of a forthcoming + // breakage. + ConditionTypeConvertible apis.ConditionType = "Convertible" +) + +// CannotConvertError is returned when a field cannot be converted. +type CannotConvertError struct { + Message string + Field string +} + +var _ error = (*CannotConvertError)(nil) + +// Error implements error +func (cce *CannotConvertError) Error() string { + return cce.Message +} + +// ConvertErrorf creates a CannotConvertError from the field name and format string. +func ConvertErrorf(field, msg string, args ...interface{}) error { + return &CannotConvertError{ + Message: fmt.Sprintf(msg, args...), + Field: field, + } +} diff --git a/pkg/apis/pipeline/v1alpha2/pipelinerun_types.go b/pkg/apis/pipeline/v1alpha2/pipelinerun_types.go index 8afb5267ffc..0298cde1c7f 100644 --- a/pkg/apis/pipeline/v1alpha2/pipelinerun_types.go +++ b/pkg/apis/pipeline/v1alpha2/pipelinerun_types.go @@ -217,6 +217,18 @@ func (pr *PipelineRunStatus) SetCondition(newCond *apis.Condition) { } } +// MarkResourceNotConvertible adds a Warning-severity condition to the resource noting +// that it cannot be converted to a higher version. +func (pr *PipelineRunStatus) MarkResourceNotConvertible(err *CannotConvertError) { + pipelineRunCondSet.Manage(pr).SetCondition(apis.Condition{ + Type: ConditionTypeConvertible, + Status: corev1.ConditionFalse, + Severity: apis.ConditionSeverityWarning, + Reason: err.Field, + Message: err.Message, + }) +} + // PipelineRunStatusFields holds the fields of PipelineRunStatus' status. // This is defined separately and inlined so that other types can readily // consume these fields via duck typing. diff --git a/pkg/apis/pipeline/v1alpha2/task_validation.go b/pkg/apis/pipeline/v1alpha2/task_validation.go index f916fa6eeb9..5fb9b19b63d 100644 --- a/pkg/apis/pipeline/v1alpha2/task_validation.go +++ b/pkg/apis/pipeline/v1alpha2/task_validation.go @@ -71,7 +71,7 @@ func (ts *TaskSpec) Validate(ctx context.Context) *apis.FieldError { } // Validate that the parameters type are correct - if err := validateParameterTypes(ts.Params); err != nil { + if err := ValidateParameterTypes(ts.Params); err != nil { return err } @@ -86,11 +86,13 @@ func (ts *TaskSpec) Validate(ctx context.Context) *apis.FieldError { } } - // FIXME(vdemeester) validate param variables - if err := validateParameterVariables(ts.Steps, ts.Params); err != nil { + if err := ValidateParameterVariables(ts.Steps, ts.Params); err != nil { + return err + } + + if err := ValidateResourcesVariables(ts.Steps, ts.Resources); err != nil { return err } - // FIXME(vdemeester) validate resource return nil } @@ -190,7 +192,7 @@ func validateSteps(steps []Step) *apis.FieldError { return nil } -func validateParameterTypes(params []ParamSpec) *apis.FieldError { +func ValidateParameterTypes(params []ParamSpec) *apis.FieldError { for _, p := range params { // Ensure param has a valid type. validType := false @@ -218,7 +220,7 @@ func validateParameterTypes(params []ParamSpec) *apis.FieldError { return nil } -func validateParameterVariables(steps []Step, params []ParamSpec) *apis.FieldError { +func ValidateParameterVariables(steps []Step, params []ParamSpec) *apis.FieldError { parameterNames := map[string]struct{}{} arrayParameterNames := map[string]struct{}{} @@ -235,6 +237,24 @@ func validateParameterVariables(steps []Step, params []ParamSpec) *apis.FieldErr return validateArrayUsage(steps, "params", arrayParameterNames) } +func ValidateResourcesVariables(steps []Step, resources *TaskResources) *apis.FieldError { + if resources == nil { + return nil + } + resourceNames := map[string]struct{}{} + if resources.Inputs != nil { + for _, r := range resources.Inputs { + resourceNames[r.Name] = struct{}{} + } + } + if resources.Outputs != nil { + for _, r := range resources.Outputs { + resourceNames[r.Name] = struct{}{} + } + } + return validateVariables(steps, "resources", resourceNames) +} + func validateArrayUsage(steps []Step, prefix string, vars map[string]struct{}) *apis.FieldError { for _, step := range steps { if err := validateTaskNoArrayReferenced("name", step.Name, prefix, vars); err != nil { diff --git a/pkg/apis/pipeline/v1alpha2/taskrun_types.go b/pkg/apis/pipeline/v1alpha2/taskrun_types.go index b41df6efa13..61955a50c39 100644 --- a/pkg/apis/pipeline/v1alpha2/taskrun_types.go +++ b/pkg/apis/pipeline/v1alpha2/taskrun_types.go @@ -104,6 +104,18 @@ type TaskRunStatus struct { TaskRunStatusFields `json:",inline"` } +// MarkResourceNotConvertible adds a Warning-severity condition to the resource noting +// that it cannot be converted to a higher version. +func (trs *TaskRunStatus) MarkResourceNotConvertible(err *CannotConvertError) { + taskRunCondSet.Manage(trs).SetCondition(apis.Condition{ + Type: ConditionTypeConvertible, + Status: corev1.ConditionFalse, + Severity: apis.ConditionSeverityWarning, + Reason: err.Field, + Message: err.Message, + }) +} + // TaskRunStatusFields holds the fields of TaskRun's status. This is defined // separately and inlined so that other types can readily consume these fields // via duck typing. @@ -157,24 +169,24 @@ type TaskRunResult struct { } // GetCondition returns the Condition matching the given type. -func (tr *TaskRunStatus) GetCondition(t apis.ConditionType) *apis.Condition { - return taskRunCondSet.Manage(tr).GetCondition(t) +func (trs *TaskRunStatus) GetCondition(t apis.ConditionType) *apis.Condition { + return taskRunCondSet.Manage(trs).GetCondition(t) } // InitializeConditions will set all conditions in taskRunCondSet to unknown for the TaskRun // and set the started time to the current time -func (tr *TaskRunStatus) InitializeConditions() { - if tr.StartTime.IsZero() { - tr.StartTime = &metav1.Time{Time: time.Now()} +func (trs *TaskRunStatus) InitializeConditions() { + if trs.StartTime.IsZero() { + trs.StartTime = &metav1.Time{Time: time.Now()} } - taskRunCondSet.Manage(tr).InitializeConditions() + taskRunCondSet.Manage(trs).InitializeConditions() } // SetCondition sets the condition, unsetting previous conditions with the same // type as necessary. -func (tr *TaskRunStatus) SetCondition(newCond *apis.Condition) { +func (trs *TaskRunStatus) SetCondition(newCond *apis.Condition) { if newCond != nil { - taskRunCondSet.Manage(tr).SetCondition(*newCond) + taskRunCondSet.Manage(trs).SetCondition(*newCond) } } diff --git a/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go index 70511c0252b..6e982a19786 100644 --- a/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go @@ -49,6 +49,22 @@ func (in *ArrayOrString) DeepCopy() *ArrayOrString { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CannotConvertError) DeepCopyInto(out *CannotConvertError) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CannotConvertError. +func (in *CannotConvertError) DeepCopy() *CannotConvertError { + if in == nil { + return nil + } + out := new(CannotConvertError) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CloudEventDelivery) DeepCopyInto(out *CloudEventDelivery) { *out = *in diff --git a/pkg/reconciler/pipelinerun/pipelinerun.go b/pkg/reconciler/pipelinerun/pipelinerun.go index f7da196712e..067d33de42d 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun.go +++ b/pkg/reconciler/pipelinerun/pipelinerun.go @@ -27,6 +27,7 @@ import ( apisconfig "github.com/tektoncd/pipeline/pkg/apis/config" "github.com/tektoncd/pipeline/pkg/apis/pipeline" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" "github.com/tektoncd/pipeline/pkg/artifacts" listers "github.com/tektoncd/pipeline/pkg/client/listers/pipeline/v1alpha1" resourcelisters "github.com/tektoncd/pipeline/pkg/client/resource/listers/resource/v1alpha1" @@ -235,9 +236,21 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1alpha1.PipelineRun) er // and may not have had all of the assumed default specified. pr.SetDefaults(contexts.WithUpgradeViaDefaulting(ctx)) + if err := pr.ConvertUp(ctx, &v1alpha2.PipelineRun{}); err != nil { + if ce, ok := err.(*v1alpha2.CannotConvertError); ok { + pr.Status.MarkResourceNotConvertible(ce) + return nil + } + return err + } + getPipelineFunc := c.getPipelineFunc(pr) - pipelineMeta, pipelineSpec, err := resources.GetPipelineData(pr, getPipelineFunc) + pipelineMeta, pipelineSpec, err := resources.GetPipelineData(ctx, pr, getPipelineFunc) if err != nil { + if ce, ok := err.(*v1alpha2.CannotConvertError); ok { + pr.Status.MarkResourceNotConvertible(ce) + return nil + } c.Logger.Errorf("Failed to determine Pipeline spec to use for pipelinerun %s: %v", pr.Name, err) pr.Status.SetCondition(&apis.Condition{ Type: apis.ConditionSucceeded, @@ -248,6 +261,7 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1alpha1.PipelineRun) er }) return nil } + c.Logger.Infof("pipelineSpec: %+v", pipelineSpec) // Propagate labels from Pipeline to PipelineRun. if pr.ObjectMeta.Labels == nil { @@ -345,7 +359,7 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1alpha1.PipelineRun) er // Apply parameter substitution from the PipelineRun pipelineSpec = resources.ApplyParameters(pipelineSpec, pr) - pipelineState, err := resources.ResolvePipelineRun( + pipelineState, err := resources.ResolvePipelineRun(ctx, *pr, func(name string) (v1alpha1.TaskInterface, error) { return c.taskLister.Tasks(pr.Namespace).Get(name) @@ -400,6 +414,10 @@ func (c *Reconciler) reconcile(ctx context.Context, pr *v1alpha1.PipelineRun) er } for _, rprt := range pipelineState { + c.Logger.Infof("PipelineTask: %+v", rprt.PipelineTask) + c.Logger.Infof("PipelineTask.Params: %+v", rprt.PipelineTask.Params) + c.Logger.Infof("ResolvedTaskResources: %+v", rprt.ResolvedTaskResources) + c.Logger.Infof("ResolvedTaskResources.TaskSpec: %+v", rprt.ResolvedTaskResources.TaskSpec) err := taskrun.ValidateResolvedTaskResources(rprt.PipelineTask.Params, rprt.ResolvedTaskResources) if err != nil { c.Logger.Errorf("Failed to validate pipelinerun %q with error %v", pr.Name, err) @@ -556,9 +574,7 @@ func (c *Reconciler) createTaskRun(rprt *resources.ResolvedPipelineRunTask, pr * Annotations: getTaskrunAnnotations(pr), }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Params: rprt.PipelineTask.Params, - }, + Params: rprt.PipelineTask.Params, ServiceAccountName: pr.GetServiceAccountName(rprt.PipelineTask.Name), Timeout: getTaskRunTimeout(pr), PodTemplate: pr.Spec.PodTemplate, @@ -710,9 +726,9 @@ func (c *Reconciler) makeConditionCheckContainer(rprt *resources.ResolvedPipelin Spec: v1alpha1.TaskRunSpec{ TaskSpec: taskSpec, ServiceAccountName: pr.GetServiceAccountName(rprt.PipelineTask.Name), - Inputs: v1alpha1.TaskRunInputs{ - Params: rcc.PipelineTaskCondition.Params, - Resources: rcc.ToTaskResourceBindings(), + Params: rcc.PipelineTaskCondition.Params, + Resources: &v1alpha2.TaskRunResources{ + Inputs: rcc.ToTaskResourceBindings(), }, Timeout: getTaskRunTimeout(pr), PodTemplate: pr.Spec.PodTemplate, diff --git a/pkg/reconciler/pipelinerun/pipelinerun_test.go b/pkg/reconciler/pipelinerun/pipelinerun_test.go index 702e9cbacbd..ba277047698 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun_test.go +++ b/pkg/reconciler/pipelinerun/pipelinerun_test.go @@ -228,25 +228,24 @@ func TestReconcile(t *testing.T) { tb.TaskRunSpec( tb.TaskRunTaskRef("unit-test-task"), tb.TaskRunServiceAccountName("test-sa"), - tb.TaskRunInputs( - tb.TaskRunInputsParam("foo", "somethingfun"), - tb.TaskRunInputsParam("bar", "somethingmorefun"), - tb.TaskRunInputsParam("templatedparam", "$(inputs.workspace.revision)"), - tb.TaskRunInputsResource("workspace", tb.TaskResourceBindingRef("some-repo")), - ), - tb.TaskRunOutputs( - tb.TaskRunOutputsResource("image-to-use", tb.TaskResourceBindingResourceSpec( - &v1alpha1.PipelineResourceSpec{ - Type: v1alpha1.PipelineResourceTypeImage, - Params: []v1alpha1.ResourceParam{{ - Name: "url", - Value: "gcr.io/sven", - }}, - }, - ), + tb.TaskRunParam("foo", "somethingfun"), + tb.TaskRunParam("bar", "somethingmorefun"), + tb.TaskRunParam("templatedparam", "$(inputs.workspace.revision)"), + tb.TaskRunResources( + tb.TaskRunResourcesInput("workspace", tb.TaskResourceBindingRef("some-repo")), + tb.TaskRunResourcesOutput("image-to-use", + tb.TaskResourceBindingResourceSpec( + &v1alpha1.PipelineResourceSpec{ + Type: v1alpha1.PipelineResourceTypeImage, + Params: []v1alpha1.ResourceParam{{ + Name: "url", + Value: "gcr.io/sven", + }}, + }, + ), tb.TaskResourceBindingPaths("/pvc/unit-test-1/image-to-use"), ), - tb.TaskRunOutputsResource("workspace", tb.TaskResourceBindingRef("some-repo"), + tb.TaskRunResourcesOutput("workspace", tb.TaskResourceBindingRef("some-repo"), tb.TaskResourceBindingPaths("/pvc/unit-test-1/workspace"), ), ), diff --git a/pkg/reconciler/pipelinerun/resources/input_output_steps.go b/pkg/reconciler/pipelinerun/resources/input_output_steps.go index 5b0e3bff3bf..eec7460b67c 100644 --- a/pkg/reconciler/pipelinerun/resources/input_output_steps.go +++ b/pkg/reconciler/pipelinerun/resources/input_output_steps.go @@ -20,6 +20,7 @@ import ( "path/filepath" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" ) // GetOutputSteps will add the correct `path` to the output resources for pt @@ -101,11 +102,14 @@ func WrapSteps(tr *v1alpha1.TaskRunSpec, pt *v1alpha1.PipelineTask, inputs, outp if pt == nil { return } + if tr.Resources == nil { + tr.Resources = &v1alpha2.TaskRunResources{} + } if pt.Resources != nil { // Add presteps to setup updated input - tr.Inputs.Resources = append(tr.Inputs.Resources, GetInputSteps(inputs, pt.Resources.Inputs, storageBasePath)...) + tr.Resources.Inputs = append(tr.Resources.Inputs, GetInputSteps(inputs, pt.Resources.Inputs, storageBasePath)...) } // Add poststeps to setup outputs - tr.Outputs.Resources = append(tr.Outputs.Resources, GetOutputSteps(outputs, pt.Name, storageBasePath)...) + tr.Resources.Outputs = append(tr.Resources.Outputs, GetOutputSteps(outputs, pt.Name, storageBasePath)...) } diff --git a/pkg/reconciler/pipelinerun/resources/input_output_steps_test.go b/pkg/reconciler/pipelinerun/resources/input_output_steps_test.go index 2b21bd62c11..13d6eac458f 100644 --- a/pkg/reconciler/pipelinerun/resources/input_output_steps_test.go +++ b/pkg/reconciler/pipelinerun/resources/input_output_steps_test.go @@ -347,10 +347,10 @@ func TestWrapSteps(t *testing.T) { sort.SliceStable(expectedtaskInputResources, func(i, j int) bool { return expectedtaskInputResources[i].Name < expectedtaskInputResources[j].Name }) sort.SliceStable(expectedtaskOuputResources, func(i, j int) bool { return expectedtaskOuputResources[i].Name < expectedtaskOuputResources[j].Name }) - if d := cmp.Diff(taskRunSpec.Inputs.Resources, expectedtaskInputResources, cmpopts.SortSlices(func(x, y v1alpha1.TaskResourceBinding) bool { return x.Name < y.Name })); d != "" { + if d := cmp.Diff(taskRunSpec.Resources.Inputs, expectedtaskInputResources, cmpopts.SortSlices(func(x, y v1alpha1.TaskResourceBinding) bool { return x.Name < y.Name })); d != "" { t.Errorf("error comparing input resources: %s", d) } - if d := cmp.Diff(taskRunSpec.Outputs.Resources, expectedtaskOuputResources, cmpopts.SortSlices(func(x, y v1alpha1.TaskResourceBinding) bool { return x.Name < y.Name })); d != "" { + if d := cmp.Diff(taskRunSpec.Resources.Outputs, expectedtaskOuputResources, cmpopts.SortSlices(func(x, y v1alpha1.TaskResourceBinding) bool { return x.Name < y.Name })); d != "" { t.Errorf("error comparing output resources: %s", d) } } diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go index d09618ca9e9..840c86c8526 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go @@ -17,6 +17,7 @@ limitations under the License. package resources import ( + "context" "fmt" "reflect" @@ -26,6 +27,8 @@ import ( "knative.dev/pkg/apis" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" + "github.com/tektoncd/pipeline/pkg/contexts" "github.com/tektoncd/pipeline/pkg/list" "github.com/tektoncd/pipeline/pkg/names" "github.com/tektoncd/pipeline/pkg/reconciler/pipeline/dag" @@ -267,6 +270,7 @@ func (e *ConditionNotFoundError) Error() string { // will return an error, otherwise it returns a list of all of the Tasks retrieved. // It will retrieve the Resources needed for the TaskRun using the mapping of providedResources. func ResolvePipelineRun( + ctx context.Context, pipelineRun v1alpha1.PipelineRun, getTask resources.GetTask, getTaskRun resources.GetTaskRun, @@ -312,6 +316,10 @@ func ResolvePipelineRun( } else { spec = *pt.TaskSpec } + spec.SetDefaults(contexts.WithUpgradeViaDefaulting(ctx)) + if err := spec.ConvertUp(ctx, &v1alpha2.TaskSpec{}); err != nil { + return nil, err + } rtr, err := ResolvePipelineTaskResources(pt, &spec, taskName, kind, providedResources) if err != nil { return nil, fmt.Errorf("couldn't match referenced resources with declared resources: %w", err) @@ -326,6 +334,7 @@ func ResolvePipelineRun( } } if taskRun != nil { + // taskRun.SetDefaults(contexts.WithUpgradeViaDefaulting(ctx)) rprt.TaskRun = taskRun } @@ -529,10 +538,10 @@ func ResolvePipelineTaskResources(pt v1alpha1.PipelineTask, ts *v1alpha1.TaskSpe if resource, ok := providedResources[taskInput.Resource]; ok { rtr.Inputs[taskInput.Name] = resource } else { - if ts.Inputs == nil { + if ts.Resources == nil || ts.Resources.Inputs == nil { return nil, fmt.Errorf("pipelineTask tried to use input resource %s not present in declared resources", taskInput.Resource) } - for _, r := range ts.Inputs.Resources { + for _, r := range ts.Resources.Inputs { if r.Name == taskInput.Name && !r.Optional { return nil, fmt.Errorf("pipelineTask tried to use input resource %s not present in declared resources", taskInput.Resource) } @@ -543,10 +552,10 @@ func ResolvePipelineTaskResources(pt v1alpha1.PipelineTask, ts *v1alpha1.TaskSpe if resource, ok := providedResources[taskOutput.Resource]; ok { rtr.Outputs[taskOutput.Name] = resource } else { - if ts.Outputs == nil { + if ts.Resources == nil || ts.Resources.Outputs == nil { return nil, fmt.Errorf("pipelineTask tried to use output resource %s not present in declared resources", taskOutput.Resource) } - for _, r := range ts.Outputs.Resources { + for _, r := range ts.Resources.Outputs { if r.Name == taskOutput.Name && !r.Optional { return nil, fmt.Errorf("pipelineTask tried to use output resource %s not present in declared resources", taskOutput.Resource) } diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go index acfc06c4cc5..bdcb40fe8bc 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go @@ -17,6 +17,7 @@ limitations under the License. package resources import ( + "context" "errors" "fmt" "testing" @@ -453,7 +454,7 @@ var taskCancelled = PipelineRunState{{ }, }} -var taskWithOptionalResources = &v1alpha1.Task{ +var taskWithOptionalResourcesDeprecated = &v1alpha1.Task{ ObjectMeta: metav1.ObjectMeta{ Name: "task", }, @@ -486,6 +487,38 @@ var taskWithOptionalResources = &v1alpha1.Task{ }, }, } +var taskWithOptionalResources = &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task", + }, + Spec: v1alpha1.TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "step1", + }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "optional-input", + Type: "git", + Optional: true, + }}, {ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "required-input", + Type: "git", + Optional: false, + }}}, + Outputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "optional-output", + Type: "git", + Optional: true, + }}, {ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "required-output", + Type: "git", + Optional: false, + }}}, + }, + }, + }, +} func DagFromState(state PipelineRunState) (*dag.Graph, error) { pts := []v1alpha1.PipelineTask{} @@ -1182,7 +1215,7 @@ func TestResolvePipelineRun(t *testing.T) { getClusterTask := func(name string) (v1alpha1.TaskInterface, error) { return nil, nil } getCondition := func(name string) (*v1alpha1.Condition, error) { return nil, nil } - pipelineState, err := ResolvePipelineRun(pr, getTask, getTaskRun, getClusterTask, getCondition, p.Spec.Tasks, providedResources) + pipelineState, err := ResolvePipelineRun(context.Background(), pr, getTask, getTaskRun, getClusterTask, getCondition, p.Spec.Tasks, providedResources) if err != nil { t.Fatalf("Error getting tasks for fake pipeline %s: %s", p.ObjectMeta.Name, err) } @@ -1261,7 +1294,7 @@ func TestResolvePipelineRun_PipelineTaskHasNoResources(t *testing.T) { Name: "pipelinerun", }, } - pipelineState, err := ResolvePipelineRun(pr, getTask, getTaskRun, getClusterTask, getCondition, pts, providedResources) + pipelineState, err := ResolvePipelineRun(context.Background(), pr, getTask, getTaskRun, getClusterTask, getCondition, pts, providedResources) if err != nil { t.Fatalf("Did not expect error when resolving PipelineRun without Resources: %v", err) } @@ -1308,7 +1341,7 @@ func TestResolvePipelineRun_TaskDoesntExist(t *testing.T) { Name: "pipelinerun", }, } - _, err := ResolvePipelineRun(pr, getTask, getTaskRun, getClusterTask, getCondition, pts, providedResources) + _, err := ResolvePipelineRun(context.Background(), pr, getTask, getTaskRun, getClusterTask, getCondition, pts, providedResources) switch err := err.(type) { case nil: t.Fatalf("Expected error getting non-existent Tasks for Pipeline %s but got none", p.Name) @@ -1354,7 +1387,7 @@ func TestResolvePipelineRun_ResourceBindingsDontExist(t *testing.T) { Name: "pipelinerun", }, } - _, err := ResolvePipelineRun(pr, getTask, getTaskRun, getClusterTask, getCondition, tt.p.Spec.Tasks, providedResources) + _, err := ResolvePipelineRun(context.Background(), pr, getTask, getTaskRun, getClusterTask, getCondition, tt.p.Spec.Tasks, providedResources) if err == nil { t.Fatalf("Expected error when bindings are in incorrect state for Pipeline %s but got none", p.Name) } @@ -1404,7 +1437,7 @@ func TestResolvePipelineRun_withExistingTaskRuns(t *testing.T) { getClusterTask := func(name string) (v1alpha1.TaskInterface, error) { return nil, nil } getTaskRun := func(name string) (*v1alpha1.TaskRun, error) { return nil, nil } getCondition := func(name string) (*v1alpha1.Condition, error) { return nil, nil } - pipelineState, err := ResolvePipelineRun(pr, getTask, getTaskRun, getClusterTask, getCondition, p.Spec.Tasks, providedResources) + pipelineState, err := ResolvePipelineRun(context.Background(), pr, getTask, getTaskRun, getClusterTask, getCondition, p.Spec.Tasks, providedResources) if err != nil { t.Fatalf("Error getting tasks for fake pipeline %s: %s", p.ObjectMeta.Name, err) } @@ -1452,12 +1485,12 @@ func TestResolvedPipelineRun_PipelineTaskHasOptionalResources(t *testing.T) { }, } - getTask := func(name string) (v1alpha1.TaskInterface, error) { return taskWithOptionalResources, nil } + getTask := func(name string) (v1alpha1.TaskInterface, error) { return taskWithOptionalResourcesDeprecated, nil } getTaskRun := func(name string) (*v1alpha1.TaskRun, error) { return nil, nil } getClusterTask := func(name string) (v1alpha1.TaskInterface, error) { return nil, nil } getCondition := func(name string) (*v1alpha1.Condition, error) { return nil, nil } - pipelineState, err := ResolvePipelineRun(pr, getTask, getTaskRun, getClusterTask, getCondition, p.Spec.Tasks, providedResources) + pipelineState, err := ResolvePipelineRun(context.Background(), pr, getTask, getTaskRun, getClusterTask, getCondition, p.Spec.Tasks, providedResources) if err != nil { t.Fatalf("Error getting tasks for fake pipeline %s: %s", p.ObjectMeta.Name, err) } @@ -1558,7 +1591,7 @@ func TestResolveConditionChecks(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - pipelineState, err := ResolvePipelineRun(pr, getTask, tc.getTaskRun, getClusterTask, getCondition, pts, providedResources) + pipelineState, err := ResolvePipelineRun(context.Background(), pr, getTask, tc.getTaskRun, getClusterTask, getCondition, pts, providedResources) if err != nil { t.Fatalf("Did not expect error when resolving PipelineRun without Conditions: %v", err) } @@ -1649,7 +1682,7 @@ func TestResolveConditionChecks_MultipleConditions(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - pipelineState, err := ResolvePipelineRun(pr, getTask, tc.getTaskRun, getClusterTask, getCondition, pts, providedResources) + pipelineState, err := ResolvePipelineRun(context.Background(), pr, getTask, tc.getTaskRun, getClusterTask, getCondition, pts, providedResources) if err != nil { t.Fatalf("Did not expect error when resolving PipelineRun without Conditions: %v", err) } @@ -1693,7 +1726,7 @@ func TestResolveConditionChecks_ConditionDoesNotExist(t *testing.T) { }, } - _, err := ResolvePipelineRun(pr, getTask, getTaskRun, getClusterTask, getCondition, pts, providedResources) + _, err := ResolvePipelineRun(context.Background(), pr, getTask, getTaskRun, getClusterTask, getCondition, pts, providedResources) switch err := err.(type) { case nil: @@ -1762,7 +1795,7 @@ func TestResolveConditionCheck_UseExistingConditionCheckName(t *testing.T) { }, } - pipelineState, err := ResolvePipelineRun(pr, getTask, getTaskRun, getClusterTask, getCondition, pts, providedResources) + pipelineState, err := ResolvePipelineRun(context.Background(), pr, getTask, getTaskRun, getClusterTask, getCondition, pts, providedResources) if err != nil { t.Fatalf("Did not expect error when resolving PipelineRun without Conditions: %v", err) } @@ -1837,7 +1870,7 @@ func TestResolvedConditionCheck_WithResources(t *testing.T) { for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { - pipelineState, err := ResolvePipelineRun(pr, getTask, getTaskRun, getClusterTask, getCondition, pts, tc.providedResources) + pipelineState, err := ResolvePipelineRun(context.Background(), pr, getTask, getTaskRun, getClusterTask, getCondition, pts, tc.providedResources) if tc.wantErr { if err == nil { diff --git a/pkg/reconciler/pipelinerun/resources/pipelinespec.go b/pkg/reconciler/pipelinerun/resources/pipelinespec.go index 800663ddfb7..c3bc2845e1b 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinespec.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinespec.go @@ -17,9 +17,11 @@ limitations under the License. package resources import ( + "context" "fmt" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -29,7 +31,7 @@ type GetPipeline func(string) (v1alpha1.PipelineInterface, error) // GetPipelineData will retrieve the Pipeline metadata and Spec associated with the // provided PipelineRun. This can come from a reference Pipeline or from the PipelineRun's // metadata and embedded PipelineSpec. -func GetPipelineData(pipelineRun *v1alpha1.PipelineRun, getPipeline GetPipeline) (*metav1.ObjectMeta, *v1alpha1.PipelineSpec, error) { +func GetPipelineData(ctx context.Context, pipelineRun *v1alpha1.PipelineRun, getPipeline GetPipeline) (*metav1.ObjectMeta, *v1alpha1.PipelineSpec, error) { pipelineMeta := metav1.ObjectMeta{} pipelineSpec := v1alpha1.PipelineSpec{} switch { @@ -41,6 +43,10 @@ func GetPipelineData(pipelineRun *v1alpha1.PipelineRun, getPipeline GetPipeline) } pipelineMeta = t.PipelineMetadata() pipelineSpec = t.PipelineSpec() + + if err := pipelineSpec.ConvertUp(ctx, &v1alpha2.PipelineSpec{}); err != nil { + return nil, nil, err + } case pipelineRun.Spec.PipelineSpec != nil: pipelineMeta = pipelineRun.ObjectMeta pipelineSpec = *pipelineRun.Spec.PipelineSpec diff --git a/pkg/reconciler/pipelinerun/resources/pipelinespec_test.go b/pkg/reconciler/pipelinerun/resources/pipelinespec_test.go index bd38a79c89c..9f2655cf83a 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinespec_test.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinespec_test.go @@ -17,6 +17,7 @@ limitations under the License. package resources import ( + "context" "errors" "testing" @@ -49,7 +50,7 @@ func TestGetPipelineSpec_Ref(t *testing.T) { }, } gt := func(n string) (v1alpha1.PipelineInterface, error) { return pipeline, nil } - pipelineMeta, pipelineSpec, err := GetPipelineData(pr, gt) + pipelineMeta, pipelineSpec, err := GetPipelineData(context.Background(), pr, gt) if err != nil { t.Fatalf("Did not expect error getting pipeline spec but got: %s", err) @@ -81,7 +82,7 @@ func TestGetPipelineSpec_Embedded(t *testing.T) { }, } gt := func(n string) (v1alpha1.PipelineInterface, error) { return nil, errors.New("shouldn't be called") } - pipelineMeta, pipelineSpec, err := GetPipelineData(pr, gt) + pipelineMeta, pipelineSpec, err := GetPipelineData(context.Background(), pr, gt) if err != nil { t.Fatalf("Did not expect error getting pipeline spec but got: %s", err) @@ -103,7 +104,7 @@ func TestGetPipelineSpec_Invalid(t *testing.T) { }, } gt := func(n string) (v1alpha1.PipelineInterface, error) { return nil, errors.New("shouldn't be called") } - _, _, err := GetPipelineData(tr, gt) + _, _, err := GetPipelineData(context.Background(), tr, gt) if err == nil { t.Fatalf("Expected error resolving spec with no embedded or referenced pipeline spec but didn't get error") } @@ -121,7 +122,7 @@ func TestGetPipelineSpec_Error(t *testing.T) { }, } gt := func(n string) (v1alpha1.PipelineInterface, error) { return nil, errors.New("something went wrong") } - _, _, err := GetPipelineData(tr, gt) + _, _, err := GetPipelineData(context.Background(), tr, gt) if err == nil { t.Fatalf("Expected error when unable to find referenced Pipeline but got none") } diff --git a/pkg/reconciler/taskrun/resources/apply.go b/pkg/reconciler/taskrun/resources/apply.go index 482a5a78a4f..41088773beb 100644 --- a/pkg/reconciler/taskrun/resources/apply.go +++ b/pkg/reconciler/taskrun/resources/apply.go @@ -40,21 +40,31 @@ func ApplyParameters(spec *v1alpha1.TaskSpec, tr *v1alpha1.TaskRun, defaults ... for _, p := range defaults { if p.Default != nil { if p.Default.Type == v1alpha1.ParamTypeString { + stringReplacements[fmt.Sprintf("params.%s", p.Name)] = p.Default.StringVal + // FIXME(vdemeester) Remove that with deprecating v1alpha1 stringReplacements[fmt.Sprintf("inputs.params.%s", p.Name)] = p.Default.StringVal } else { + arrayReplacements[fmt.Sprintf("params.%s", p.Name)] = p.Default.ArrayVal + // FIXME(vdemeester) Remove that with deprecating v1alpha1 arrayReplacements[fmt.Sprintf("inputs.params.%s", p.Name)] = p.Default.ArrayVal } } } // Set and overwrite params with the ones from the TaskRun - for _, p := range tr.Spec.Inputs.Params { + for _, p := range tr.Spec.Params { if p.Value.Type == v1alpha1.ParamTypeString { + stringReplacements[fmt.Sprintf("params.%s", p.Name)] = p.Value.StringVal + // FIXME(vdemeester) Remove that with deprecating v1alpha1 stringReplacements[fmt.Sprintf("inputs.params.%s", p.Name)] = p.Value.StringVal } else { + arrayReplacements[fmt.Sprintf("params.%s", p.Name)] = p.Value.ArrayVal + // FIXME(vdemeester) Remove that with deprecating v1alpha1 arrayReplacements[fmt.Sprintf("inputs.params.%s", p.Name)] = p.Value.ArrayVal } } + fmt.Println("stringReplacements", stringReplacements) + fmt.Println("arrayReplacements", arrayReplacements) return ApplyReplacements(spec, stringReplacements, arrayReplacements) } @@ -69,13 +79,17 @@ func ApplyResources(spec *v1alpha1.TaskSpec, resolvedResources map[string]v1alph } // We always add replacements for 'path' - if spec.Inputs != nil { - for _, r := range spec.Inputs.Resources { + if spec.Resources != nil && spec.Resources.Inputs != nil { + for _, r := range spec.Resources.Inputs { + replacements[fmt.Sprintf("resources.inputs.%s.path", r.Name)] = v1alpha1.InputResourcePath(r.ResourceDeclaration) + // FIXME(vdemeester) Remove that with deprecating v1alpha1 replacements[fmt.Sprintf("inputs.resources.%s.path", r.Name)] = v1alpha1.InputResourcePath(r.ResourceDeclaration) } } - if spec.Outputs != nil { - for _, r := range spec.Outputs.Resources { + if spec.Resources != nil && spec.Resources.Outputs != nil { + for _, r := range spec.Resources.Outputs { + replacements[fmt.Sprintf("resources.outputs.%s.path", r.Name)] = v1alpha1.OutputResourcePath(r.ResourceDeclaration) + // FIXME(vdemeester) Remove that with deprecating v1alpha1 replacements[fmt.Sprintf("outputs.resources.%s.path", r.Name)] = v1alpha1.OutputResourcePath(r.ResourceDeclaration) } } diff --git a/pkg/reconciler/taskrun/resources/apply_test.go b/pkg/reconciler/taskrun/resources/apply_test.go index b0e8dbf339b..a3d980cb77e 100644 --- a/pkg/reconciler/taskrun/resources/apply_test.go +++ b/pkg/reconciler/taskrun/resources/apply_test.go @@ -159,26 +159,24 @@ var ( }, }, }}, - }, - Inputs: &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "workspace", - }, - }}, - }, - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "imageToUse-ab", - TargetPath: "/foo/builtImage", - }, - }, { - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "imageToUse-re", - TargetPath: "foo/builtImage", - }, - }}, + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "workspace", + }, + }}, + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "imageToUse-ab", + TargetPath: "/foo/builtImage", + }, + }, { + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "imageToUse-re", + TargetPath: "foo/builtImage", + }, + }}, + }, }, } @@ -189,13 +187,13 @@ var ( Image: "someImage", Args: []string{"$(outputs.resources.bucket.path)"}, }}}, - }, - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "bucket", - }, - }}, + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "bucket", + }, + }}, + }, }, } @@ -249,85 +247,73 @@ var ( arrayTaskRun0Elements = &v1alpha1.TaskRun{ Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Params: []v1alpha1.Param{{ - Name: "array-param", - Value: v1alpha1.ArrayOrString{ - Type: v1alpha1.ParamTypeArray, - ArrayVal: []string{}, - }}, - }, + Params: []v1alpha1.Param{{ + Name: "array-param", + Value: v1alpha1.ArrayOrString{ + Type: v1alpha1.ParamTypeArray, + ArrayVal: []string{}, + }}, }, }, } arrayTaskRun1Elements = &v1alpha1.TaskRun{ Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Params: []v1alpha1.Param{{ - Name: "array-param", - Value: *builder.ArrayOrString("foo"), - }}, - }, + Params: []v1alpha1.Param{{ + Name: "array-param", + Value: *builder.ArrayOrString("foo"), + }}, }, } arrayTaskRun3Elements = &v1alpha1.TaskRun{ Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Params: []v1alpha1.Param{{ - Name: "array-param", - Value: *builder.ArrayOrString("foo", "bar", "third"), - }}, - }, + Params: []v1alpha1.Param{{ + Name: "array-param", + Value: *builder.ArrayOrString("foo", "bar", "third"), + }}, }, } arrayTaskRunMultipleArrays = &v1alpha1.TaskRun{ Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Params: []v1alpha1.Param{{ - Name: "array-param", - Value: *builder.ArrayOrString("foo", "bar", "third"), - }, { - Name: "another-array-param", - Value: *builder.ArrayOrString("part1", "part2"), - }}, - }, + Params: []v1alpha1.Param{{ + Name: "array-param", + Value: *builder.ArrayOrString("foo", "bar", "third"), + }, { + Name: "another-array-param", + Value: *builder.ArrayOrString("part1", "part2"), + }}, }, } arrayTaskRunWith1StringParam = &v1alpha1.TaskRun{ Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Params: []v1alpha1.Param{{ - Name: "array-param", - Value: *builder.ArrayOrString("middlefirst", "middlesecond"), - }, { - Name: "normal-param", - Value: *builder.ArrayOrString("foo"), - }}, - }, + Params: []v1alpha1.Param{{ + Name: "array-param", + Value: *builder.ArrayOrString("middlefirst", "middlesecond"), + }, { + Name: "normal-param", + Value: *builder.ArrayOrString("foo"), + }}, }, } arrayTaskRunMultipleArraysAndStrings = &v1alpha1.TaskRun{ Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Params: []v1alpha1.Param{{ - Name: "array-param1", - Value: *builder.ArrayOrString("1-param1", "2-param1", "3-param1", "4-param1"), - }, { - Name: "array-param2", - Value: *builder.ArrayOrString("1-param2", "2-param2", "2-param3"), - }, { - Name: "string-param1", - Value: *builder.ArrayOrString("foo"), - }, { - Name: "string-param2", - Value: *builder.ArrayOrString("bar"), - }}, - }, + Params: []v1alpha1.Param{{ + Name: "array-param1", + Value: *builder.ArrayOrString("1-param1", "2-param1", "3-param1", "4-param1"), + }, { + Name: "array-param2", + Value: *builder.ArrayOrString("1-param2", "2-param2", "2-param3"), + }, { + Name: "string-param1", + Value: *builder.ArrayOrString("foo"), + }, { + Name: "string-param2", + Value: *builder.ArrayOrString("bar"), + }}, }, } @@ -485,15 +471,13 @@ func TestApplyArrayParameters(t *testing.T) { func TestApplyParameters(t *testing.T) { tr := &v1alpha1.TaskRun{ Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Params: []v1alpha1.Param{{ - Name: "myimage", - Value: *builder.ArrayOrString("bar"), - }, { - Name: "FOO", - Value: *builder.ArrayOrString("world"), - }}, - }, + Params: []v1alpha1.Param{{ + Name: "myimage", + Value: *builder.ArrayOrString("bar"), + }, { + Name: "FOO", + Value: *builder.ArrayOrString("world"), + }}, }, } dp := []v1alpha1.ParamSpec{{ diff --git a/pkg/reconciler/taskrun/resources/image_exporter.go b/pkg/reconciler/taskrun/resources/image_exporter.go index bf3404ebd97..017d4e0ed19 100644 --- a/pkg/reconciler/taskrun/resources/image_exporter.go +++ b/pkg/reconciler/taskrun/resources/image_exporter.go @@ -37,9 +37,10 @@ func AddOutputImageDigestExporter( ) error { output := []*v1alpha1.ImageResource{} - if len(tr.Spec.Outputs.Resources) > 0 { - for _, trb := range tr.Spec.Outputs.Resources { - boundResource, err := getBoundResource(trb.Name, tr.Spec.Outputs.Resources) + fmt.Println(tr.Spec.Resources) + if tr.Spec.Resources != nil && len(tr.Spec.Resources.Outputs) > 0 { + for _, trb := range tr.Spec.Resources.Outputs { + boundResource, err := getBoundResource(trb.Name, tr.Spec.Resources.Outputs) if err != nil { return fmt.Errorf("failed to get bound resource: %w while adding output image digest exporter", err) } @@ -53,7 +54,11 @@ func AddOutputImageDigestExporter( if err != nil { return fmt.Errorf("invalid Image Resource for taskRun %q resource %v; error: %w", tr.Name, boundResource, err) } - for _, o := range taskSpec.Outputs.Resources { + if taskSpec.Resources == nil { + // Shouldn't happens as it would be a validation error before + return fmt.Errorf("invalid Image Resource for taskrun %q resource %v; doesn't exists in the task", tr.Name, boundResource) + } + for _, o := range taskSpec.Resources.Outputs { if o.Name == boundResource.Name { if o.TargetPath == "" { imageResource.OutputImageDir = filepath.Join(outputDir, boundResource.Name) @@ -67,6 +72,7 @@ func AddOutputImageDigestExporter( } } + fmt.Println(output) if len(output) > 0 { augmentedSteps := []v1alpha1.Step{} imagesJSON, err := json.Marshal(output) @@ -79,7 +85,6 @@ func AddOutputImageDigestExporter( taskSpec.Steps = augmentedSteps } - } return nil diff --git a/pkg/reconciler/taskrun/resources/image_exporter_test.go b/pkg/reconciler/taskrun/resources/image_exporter_test.go index e635973e1f9..a9ba08e2526 100644 --- a/pkg/reconciler/taskrun/resources/image_exporter_test.go +++ b/pkg/reconciler/taskrun/resources/image_exporter_test.go @@ -45,21 +45,20 @@ func TestAddOutputImageDigestExporter(t *testing.T) { Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "step1", }}}, - }, - Inputs: &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-image", - Type: "image", - }}}, - }, - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-image", - Type: "image", - }, - }}, + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-image", + Type: "image", + }, + }}, + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-image", + Type: "image", + }, + }}, + }, }, }, }, @@ -69,8 +68,8 @@ func TestAddOutputImageDigestExporter(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-image", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -78,9 +77,7 @@ func TestAddOutputImageDigestExporter(t *testing.T) { }, }, }}, - }, - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-image", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -114,21 +111,20 @@ func TestAddOutputImageDigestExporter(t *testing.T) { }}, {Container: corev1.Container{ Name: "step2", }}}, - }, - Inputs: &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-image", - Type: "image", - }}}, - }, - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-image", - Type: "image", - }, - }}, + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-image", + Type: "image", + }, + }}, + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-image", + Type: "image", + }, + }}, + }, }, }, }, @@ -138,8 +134,8 @@ func TestAddOutputImageDigestExporter(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-image", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -147,9 +143,7 @@ func TestAddOutputImageDigestExporter(t *testing.T) { }, }, }}, - }, - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-image", ResourceRef: &v1alpha1.PipelineResourceRef{ diff --git a/pkg/reconciler/taskrun/resources/input_resource_test.go b/pkg/reconciler/taskrun/resources/input_resource_test.go index ba55cc4501d..3ba84c70abd 100644 --- a/pkg/reconciler/taskrun/resources/input_resource_test.go +++ b/pkg/reconciler/taskrun/resources/input_resource_test.go @@ -48,72 +48,60 @@ var ( inputResourceInterfaces map[string]v1alpha1.PipelineResourceInterface logger *zap.SugaredLogger - gitInputs = &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "gitspace", - Type: "git", - }}}, - } - multipleGitInputs = &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "gitspace", - Type: "git", - }}, { - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "git-duplicate-space", - Type: "git", - }}, - }, + gitInputs = []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "gitspace", + Type: "git", + }}} + multipleGitInputs = []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "gitspace", + Type: "git", + }}, { + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "git-duplicate-space", + Type: "git", + }}, } - gcsInputs = &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ + gcsInputs = []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "workspace", + Type: "gcs", + TargetPath: "gcs-dir", + }}} + multipleGcsInputs = []v1alpha1.TaskResource{ + { ResourceDeclaration: v1alpha1.ResourceDeclaration{ Name: "workspace", Type: "gcs", TargetPath: "gcs-dir", - }}}, - } - multipleGcsInputs = &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{ - { - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "workspace", - Type: "gcs", - TargetPath: "gcs-dir", - }, - }, - { - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "workspace2", - Type: "gcs", - TargetPath: "gcs-dir", - }, }, }, - } - clusterInputs = &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "target-cluster", - Type: "cluster", - }}}, - } - optionalGitInputs = &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "gitspace", - Type: "git", - Optional: false, - }}, { + { ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "git-optional-space", - Type: "git", - Optional: true, - }}, + Name: "workspace2", + Type: "gcs", + TargetPath: "gcs-dir", + }, }, } + clusterInputs = []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "target-cluster", + Type: "cluster", + }}} + optionalGitInputs = []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "gitspace", + Type: "git", + Optional: false, + }}, { + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "git-optional-space", + Type: "git", + Optional: true, + }}, + } ) func setUp() { @@ -287,42 +275,49 @@ func setUp() { } func TestAddResourceToTask(t *testing.T) { - task := &v1alpha1.Task{ ObjectMeta: metav1.ObjectMeta{ Name: "build-from-repo", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: gitInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: gitInputs, + }, + }}, } taskWithMultipleGitSources := &v1alpha1.Task{ ObjectMeta: metav1.ObjectMeta{ Name: "build-from-repo", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: multipleGitInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: multipleGitInputs, + }, + }}, } taskWithTargetPath := &v1alpha1.Task{ ObjectMeta: metav1.ObjectMeta{ Name: "task-with-targetpath", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: gcsInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: gcsInputs, + }, + }}, } taskWithOptionalGitSources := &v1alpha1.Task{ ObjectMeta: metav1.ObjectMeta{ Name: "build-from-repo-with-optional-source", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: optionalGitInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: optionalGitInputs, + }, + }}, } taskRun := &v1alpha1.TaskRun{ @@ -334,8 +329,8 @@ func TestAddResourceToTask(t *testing.T) { TaskRef: &v1alpha1.TaskRef{ Name: "simpleTask", }, - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "the-git", @@ -359,7 +354,6 @@ func TestAddResourceToTask(t *testing.T) { taskRun: taskRun, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: gitInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "git-source-the-git-9l9zj", @@ -369,6 +363,9 @@ func TestAddResourceToTask(t *testing.T) { WorkingDir: "/workspace", Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git"}}, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: gitInputs, + }, }, }, }, { @@ -383,8 +380,8 @@ func TestAddResourceToTask(t *testing.T) { TaskRef: &v1alpha1.TaskRef{ Name: "simpleTask", }, - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "the-git-with-branch", @@ -397,7 +394,6 @@ func TestAddResourceToTask(t *testing.T) { }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: gitInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "git-source-the-git-with-branch-9l9zj", @@ -407,6 +403,9 @@ func TestAddResourceToTask(t *testing.T) { WorkingDir: "/workspace", Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: gitInputs, + }, }, }, }, { @@ -421,8 +420,8 @@ func TestAddResourceToTask(t *testing.T) { TaskRef: &v1alpha1.TaskRef{ Name: "simpleTask", }, - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "the-git-with-branch", @@ -442,7 +441,6 @@ func TestAddResourceToTask(t *testing.T) { }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: multipleGitInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "git-source-the-git-with-branch-mz4c7", @@ -459,6 +457,9 @@ func TestAddResourceToTask(t *testing.T) { WorkingDir: "/workspace", Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: multipleGitInputs, + }, }, }, }, { @@ -473,8 +474,8 @@ func TestAddResourceToTask(t *testing.T) { TaskRef: &v1alpha1.TaskRef{ Name: "simpleTask", }, - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "the-git", @@ -487,7 +488,6 @@ func TestAddResourceToTask(t *testing.T) { }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: gitInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "git-source-the-git-9l9zj", @@ -497,6 +497,9 @@ func TestAddResourceToTask(t *testing.T) { WorkingDir: "/workspace", Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git"}}, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: gitInputs, + }, }, }, }, { @@ -511,8 +514,8 @@ func TestAddResourceToTask(t *testing.T) { TaskRef: &v1alpha1.TaskRef{ Name: "simpleTask", }, - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "the-git-with-branch", @@ -525,7 +528,6 @@ func TestAddResourceToTask(t *testing.T) { }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: gitInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "git-source-the-git-with-branch-9l9zj", @@ -535,6 +537,9 @@ func TestAddResourceToTask(t *testing.T) { WorkingDir: "/workspace", Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: gitInputs, + }, }, }, }, { @@ -550,8 +555,8 @@ func TestAddResourceToTask(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "the-git", @@ -565,7 +570,6 @@ func TestAddResourceToTask(t *testing.T) { }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: gitInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "create-dir-gitspace-mz4c7", @@ -583,6 +587,9 @@ func TestAddResourceToTask(t *testing.T) { PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: "pipelinerun-pvc"}, }, }}, + Resources: &v1alpha2.TaskResources{ + Inputs: gitInputs, + }, }, }, }, { @@ -597,8 +604,8 @@ func TestAddResourceToTask(t *testing.T) { TaskRef: &v1alpha1.TaskRef{ Name: "simpleTask", }, - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "the-git-with-sslVerify-false", @@ -611,7 +618,6 @@ func TestAddResourceToTask(t *testing.T) { }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: gitInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "git-source-the-git-with-sslVerify-false-9l9zj", @@ -621,6 +627,9 @@ func TestAddResourceToTask(t *testing.T) { WorkingDir: "/workspace", Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-sslVerify-false"}}, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: gitInputs, + }, }, }, }, { @@ -632,8 +641,8 @@ func TestAddResourceToTask(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "storage1", @@ -646,7 +655,6 @@ func TestAddResourceToTask(t *testing.T) { }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: gcsInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "create-dir-storage1-9l9zj", @@ -665,6 +673,9 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir Image: "google/cloud-sdk", }, }}, + Resources: &v1alpha2.TaskResources{ + Inputs: gcsInputs, + }, }, }, }, { @@ -680,8 +691,8 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir }}, }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "storage1", @@ -695,7 +706,6 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: gcsInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "create-dir-workspace-mz4c7", @@ -713,6 +723,9 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: "pipelinerun-pvc"}, }, }}, + Resources: &v1alpha2.TaskResources{ + Inputs: gcsInputs, + }, }, }, }, { @@ -724,8 +737,8 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "storage-gcs-invalid", @@ -746,8 +759,8 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "storage-gcs-invalid", @@ -766,15 +779,15 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir Name: "build-from-repo", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha1.TaskResource{{ ResourceDeclaration: v1alpha1.ResourceDeclaration{ Name: "workspace-invalid", Type: "git", }}}, }, - }, + }}, }, taskRun: taskRun, wantErr: true, @@ -785,9 +798,11 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir Name: "build-from-repo", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: clusterInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: clusterInputs, + }, + }}, }, taskRun: &v1alpha1.TaskRun{ ObjectMeta: metav1.ObjectMeta{ @@ -798,8 +813,8 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir TaskRef: &v1alpha1.TaskRef{ Name: "build-from-repo", }, - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "target-cluster", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -812,7 +827,6 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: clusterInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "kubeconfig-9l9zj", @@ -822,6 +836,9 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir "-clusterConfig", `{"name":"cluster3","type":"cluster","url":"http://10.10.10.10","revision":"","username":"","password":"","namespace":"namespace1","token":"","Insecure":false,"cadata":"bXktY2EtY2VydAo=","secrets":null}`, }, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: clusterInputs, + }, }, }, }, { @@ -831,9 +848,11 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir Name: "build-from-repo", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: clusterInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: clusterInputs, + }, + }}, }, taskRun: &v1alpha1.TaskRun{ ObjectMeta: metav1.ObjectMeta{ @@ -844,8 +863,8 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir TaskRef: &v1alpha1.TaskRef{ Name: "build-from-repo", }, - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "target-cluster", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -858,7 +877,6 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: clusterInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "kubeconfig-9l9zj", @@ -879,6 +897,9 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir Name: "CADATA", }}, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: clusterInputs, + }, }, }, }, { @@ -893,8 +914,8 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir TaskRef: &v1alpha1.TaskRef{ Name: "simpleTask", }, - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "the-git-with-branch", @@ -907,7 +928,6 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: optionalGitInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "git-source-the-git-with-branch-9l9zj", @@ -917,6 +937,9 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir WorkingDir: "/workspace", Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: optionalGitInputs, + }, }, }, }} { @@ -938,20 +961,18 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir } func TestStorageInputResource(t *testing.T) { - gcsStorageInputs := &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "gcs-input-resource", - Type: "storage", - }}}, + gcsStorageInputs := []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "gcs-input-resource", + Type: "storage", + }}, } - optionalStorageInputs := &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "gcs-input-resource", - Type: "storage", - Optional: true, - }}}, + optionalStorageInputs := []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "gcs-input-resource", + Type: "storage", + Optional: true, + }}, } for _, c := range []struct { @@ -963,15 +984,15 @@ func TestStorageInputResource(t *testing.T) { }{{ desc: "inputs with no resource spec and resource ref", task: &v1alpha1.Task{ - Spec: v1alpha1.TaskSpec{ - Inputs: &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha1.TaskResource{{ ResourceDeclaration: v1alpha1.ResourceDeclaration{ Name: "gcs-input-resource", Type: "storage", }}}, }, - }, + }}, }, taskRun: &v1alpha1.TaskRun{ ObjectMeta: metav1.ObjectMeta{ @@ -979,8 +1000,8 @@ func TestStorageInputResource(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "gcs-input-resource", }, @@ -992,9 +1013,11 @@ func TestStorageInputResource(t *testing.T) { }, { desc: "inputs with resource spec and no resource ref", task: &v1alpha1.Task{ - Spec: v1alpha1.TaskSpec{ - Inputs: gcsStorageInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: gcsStorageInputs, + }, + }}, }, taskRun: &v1alpha1.TaskRun{ ObjectMeta: metav1.ObjectMeta{ @@ -1002,8 +1025,8 @@ func TestStorageInputResource(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "gcs-input-resource", ResourceSpec: &v1alpha1.PipelineResourceSpec{ @@ -1023,7 +1046,6 @@ func TestStorageInputResource(t *testing.T) { }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: gcsStorageInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "create-dir-gcs-input-resource-9l9zj", @@ -1042,6 +1064,9 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-input-resource Image: "google/cloud-sdk", }, }}, + Resources: &v1alpha2.TaskResources{ + Inputs: gcsStorageInputs, + }, }, }, }, { @@ -1067,9 +1092,11 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-input-resource Name: "get-storage", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: gcsStorageInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: gcsStorageInputs, + }, + }}, }, taskRun: &v1alpha1.TaskRun{ ObjectMeta: metav1.ObjectMeta{ @@ -1077,8 +1104,8 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-input-resource Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "gcs-input-resource", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -1091,7 +1118,6 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-input-resource }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: gcsStorageInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "create-dir-storage-gcs-keys-9l9zj", @@ -1116,6 +1142,9 @@ gsutil rsync -d -r gs://fake-bucket/rules.zip /workspace/gcs-input-resource }, }, }}, + Resources: &v1alpha2.TaskResources{ + Inputs: gcsStorageInputs, + }, Volumes: []corev1.Volume{{ Name: "volume-storage-gcs-keys-secret-name", VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "secret-name"}}, @@ -1128,9 +1157,11 @@ gsutil rsync -d -r gs://fake-bucket/rules.zip /workspace/gcs-input-resource }, { desc: "optional inputs with no resource spec and no resource ref", task: &v1alpha1.Task{ - Spec: v1alpha1.TaskSpec{ - Inputs: optionalStorageInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: optionalStorageInputs, + }, + }}, }, taskRun: &v1alpha1.TaskRun{ ObjectMeta: metav1.ObjectMeta{ @@ -1138,17 +1169,19 @@ gsutil rsync -d -r gs://fake-bucket/rules.zip /workspace/gcs-input-resource Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: nil, - Params: nil, + Params: nil, + Resources: &v1alpha2.TaskRunResources{ + Inputs: nil, }, }, }, wantErr: false, want: &v1alpha1.TaskSpec{ - Inputs: optionalStorageInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: nil, + Resources: &v1alpha2.TaskResources{ + Inputs: optionalStorageInputs, + }, }, }, }} { @@ -1173,27 +1206,33 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { Name: "build-from-repo", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: gitInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: gitInputs, + }, + }}, } taskWithTargetPath := &v1alpha1.Task{ ObjectMeta: metav1.ObjectMeta{ Name: "task-with-targetpath", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: gcsInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: gcsInputs, + }, + }}, } taskWithMultipleGcsInputs := &v1alpha1.Task{ ObjectMeta: metav1.ObjectMeta{ Name: "task-with-multiple-gcs-inputs", Namespace: "marshmallow", }, - Spec: v1alpha1.TaskSpec{ - Inputs: multipleGcsInputs, - }, + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: multipleGcsInputs, + }, + }}, } gcsVolumes := []corev1.Volume{ @@ -1232,8 +1271,8 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "the-git", @@ -1246,7 +1285,6 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }, }, want: &v1alpha1.TaskSpec{ - Inputs: gitInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "artifact-dest-mkdir-gitspace-9l9zj", @@ -1260,6 +1298,9 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { Env: gcsEnv, VolumeMounts: gcsVolumeMounts, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: gitInputs, + }, Volumes: gcsVolumes, }, }, @@ -1276,8 +1317,8 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "storage1", @@ -1290,7 +1331,6 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }, }, want: &v1alpha1.TaskSpec{ - Inputs: gcsInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "artifact-dest-mkdir-workspace-mssqb", @@ -1304,6 +1344,9 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { Env: gcsEnv, VolumeMounts: gcsVolumeMounts, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: gcsInputs, + }, Volumes: gcsVolumes, }, }, @@ -1320,8 +1363,8 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ ResourceRef: &v1alpha1.PipelineResourceRef{ Name: "storage1", @@ -1342,7 +1385,6 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }, }, want: &v1alpha1.TaskSpec{ - Inputs: multipleGcsInputs, TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "artifact-dest-mkdir-workspace-vr6ds", @@ -1367,6 +1409,9 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { Env: gcsEnv, VolumeMounts: gcsVolumeMounts, }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: multipleGcsInputs, + }, Volumes: gcsVolumes, }, }, @@ -1399,7 +1444,10 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { func mockResolveTaskResources(taskRun *v1alpha1.TaskRun) map[string]v1alpha1.PipelineResourceInterface { resolved := make(map[string]v1alpha1.PipelineResourceInterface) - for _, r := range taskRun.Spec.Inputs.Resources { + if taskRun.Spec.Resources == nil { + return resolved + } + for _, r := range taskRun.Spec.Resources.Inputs { var i v1alpha1.PipelineResourceInterface switch { case r.ResourceRef != nil && r.ResourceRef.Name != "": diff --git a/pkg/reconciler/taskrun/resources/input_resources.go b/pkg/reconciler/taskrun/resources/input_resources.go index 15893910317..cb9bff2a83a 100644 --- a/pkg/reconciler/taskrun/resources/input_resources.go +++ b/pkg/reconciler/taskrun/resources/input_resources.go @@ -53,7 +53,10 @@ func AddInputResource( logger *zap.SugaredLogger, ) (*v1alpha1.TaskSpec, error) { - if taskSpec.Inputs == nil { + logger.Infof("taskSpec: %+v", taskSpec) + logger.Infof("taskSpec.Resources: %+v", taskSpec.Resources) + logger.Infof("taskRun: %+v", taskRun) + if taskSpec == nil || taskSpec.Resources == nil || taskSpec.Resources.Inputs == nil { return taskSpec, nil } taskSpec = taskSpec.DeepCopy() @@ -72,9 +75,15 @@ func AddInputResource( } // Iterate in reverse through the list, each element prepends but we want the first one to remain first. - for i := len(taskSpec.Inputs.Resources) - 1; i >= 0; i-- { - input := taskSpec.Inputs.Resources[i] - boundResource, err := getBoundResource(input.Name, taskRun.Spec.Inputs.Resources) + for i := len(taskSpec.Resources.Inputs) - 1; i >= 0; i-- { + input := taskSpec.Resources.Inputs[i] + if taskRun.Spec.Resources == nil { + if input.Optional { + continue + } + return nil, fmt.Errorf("couldnt find resource named %q, no bounded resources", input.Name) + } + boundResource, err := getBoundResource(input.Name, taskRun.Spec.Resources.Inputs) // Continue if the declared resource is optional and not specified in TaskRun // boundResource is nil if the declared resource in Task does not have any resource specified in the TaskRun if input.Optional && boundResource == nil { diff --git a/pkg/reconciler/taskrun/resources/output_resource.go b/pkg/reconciler/taskrun/resources/output_resource.go index d2fca9bf40e..599cbddf2c9 100644 --- a/pkg/reconciler/taskrun/resources/output_resource.go +++ b/pkg/reconciler/taskrun/resources/output_resource.go @@ -53,7 +53,10 @@ func AddOutputResources( logger *zap.SugaredLogger, ) (*v1alpha1.TaskSpec, error) { - if taskSpec == nil || taskSpec.Outputs == nil { + logger.Infof("taskSpec: %+v", taskSpec) + logger.Infof("taskSpec.Resources: %+v", taskSpec.Resources) + logger.Infof("taskRun: %+v", taskRun) + if taskSpec == nil || taskSpec.Resources == nil || taskSpec.Resources.Outputs == nil { return taskSpec, nil } @@ -65,8 +68,14 @@ func AddOutputResources( return nil, err } needsPvc := false - for _, output := range taskSpec.Outputs.Resources { - boundResource, err := getBoundResource(output.Name, taskRun.Spec.Outputs.Resources) + for _, output := range taskSpec.Resources.Outputs { + if taskRun.Spec.Resources == nil { + if output.Optional { + continue + } + return nil, fmt.Errorf("couldnt find resource named %q, no bounded resources", output.Name) + } + boundResource, err := getBoundResource(output.Name, taskRun.Spec.Resources.Outputs) // Continue if the declared resource is optional and not specified in TaskRun // boundResource is nil if the declared resource in Task does not have any resource specified in the TaskRun if output.Optional && boundResource == nil { diff --git a/pkg/reconciler/taskrun/resources/output_resource_test.go b/pkg/reconciler/taskrun/resources/output_resource_test.go index a56a9c090d5..7fd0647f569 100644 --- a/pkg/reconciler/taskrun/resources/output_resource_test.go +++ b/pkg/reconciler/taskrun/resources/output_resource_test.go @@ -21,6 +21,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" "github.com/tektoncd/pipeline/pkg/artifacts" "github.com/tektoncd/pipeline/pkg/logging" "github.com/tektoncd/pipeline/test/names" @@ -120,8 +121,8 @@ func TestValidOutputResources(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -129,9 +130,7 @@ func TestValidOutputResources(t *testing.T) { }, }, }}, - }, - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -149,19 +148,19 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Inputs: &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - }}}, - }, - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + }}}, + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + }}}, + }, }, }, }, @@ -210,8 +209,8 @@ func TestValidOutputResources(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -229,12 +228,14 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + }}}, + }, }, }, }, @@ -283,8 +284,8 @@ func TestValidOutputResources(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -302,12 +303,14 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "image", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "image", + }}}, + }, }, }, }, @@ -326,8 +329,8 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -344,12 +347,14 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + }}}, + }, }, }, }, @@ -371,8 +376,8 @@ func TestValidOutputResources(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -380,9 +385,7 @@ func TestValidOutputResources(t *testing.T) { }, }, }}, - }, - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -400,20 +403,20 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Inputs: &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "storage", - TargetPath: "faraway-disk", - }}}, - }, - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "storage", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "storage", + TargetPath: "faraway-disk", + }}}, + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "storage", + }}}, + }, }, }, }, @@ -479,8 +482,8 @@ func TestValidOutputResources(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -498,12 +501,14 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "storage", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "storage", + }}}, + }, }, }, }, @@ -562,8 +567,8 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -581,12 +586,14 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "storage", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "storage", + }}}, + }, }, }, }, @@ -624,8 +631,8 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -642,12 +649,14 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "storage", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "storage", + }}}, + }, }, }, }, @@ -689,8 +698,8 @@ func TestValidOutputResources(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -707,12 +716,14 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "image", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "image", + }}}, + }, }, }, }, @@ -734,8 +745,8 @@ func TestValidOutputResources(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -752,13 +763,15 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "image", - TargetPath: "/workspace", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "image", + TargetPath: "/workspace", + }}}, + }, }, }, }, @@ -775,8 +788,8 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -793,12 +806,14 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "image", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "image", + }}}, + }, }, }, }, @@ -815,8 +830,8 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -840,16 +855,18 @@ func TestValidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "image", - }}, { - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace-1", - Type: "image", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "image", + }}, { + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace-1", + Type: "image", + }}}, + }, }, }, }, @@ -904,8 +921,8 @@ func TestValidOutputResourcesWithBucketStorage(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -913,9 +930,7 @@ func TestValidOutputResourcesWithBucketStorage(t *testing.T) { }, }, }}, - }, - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -933,19 +948,19 @@ func TestValidOutputResourcesWithBucketStorage(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Inputs: &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - }}}, - }, - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + }}}, + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + }}}, + }, }, }, }, @@ -972,8 +987,8 @@ func TestValidOutputResourcesWithBucketStorage(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -991,12 +1006,14 @@ func TestValidOutputResourcesWithBucketStorage(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + }}}, + }, }, }, }, @@ -1019,8 +1036,8 @@ func TestValidOutputResourcesWithBucketStorage(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -1037,12 +1054,14 @@ func TestValidOutputResourcesWithBucketStorage(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + }}}, + }, }, }, }, @@ -1113,12 +1132,14 @@ func TestInvalidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + }}}, + }, }, }, }, @@ -1132,8 +1153,8 @@ func TestInvalidOutputResources(t *testing.T) { }}, }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -1154,12 +1175,14 @@ func TestInvalidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "storage", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "storage", + }}}, + }, }, }, }, @@ -1182,8 +1205,8 @@ func TestInvalidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha1.TaskResourceBinding{{ PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ Name: "source-workspace", ResourceRef: &v1alpha1.PipelineResourceRef{ @@ -1200,12 +1223,14 @@ func TestInvalidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "storage", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "storage", + }}}, + }, }, }, }, @@ -1218,12 +1243,14 @@ func TestInvalidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - Optional: true, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + Optional: true, + }}}, + }, }, }, }, @@ -1246,12 +1273,14 @@ func TestInvalidOutputResources(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ResourceDeclaration: v1alpha1.ResourceDeclaration{ - Name: "source-workspace", - Type: "git", - Optional: false, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha1.TaskResource{{ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "source-workspace", + Type: "git", + Optional: false, + }}}, + }, }, }, }, @@ -1280,7 +1309,10 @@ func TestInvalidOutputResources(t *testing.T) { func resolveOutputResources(taskRun *v1alpha1.TaskRun) map[string]v1alpha1.PipelineResourceInterface { resolved := make(map[string]v1alpha1.PipelineResourceInterface) - for _, r := range taskRun.Spec.Outputs.Resources { + if taskRun.Spec.Resources == nil { + return resolved + } + for _, r := range taskRun.Spec.Resources.Outputs { var i v1alpha1.PipelineResourceInterface if name := r.ResourceRef.Name; name != "" { i = outputResources[name] diff --git a/pkg/reconciler/taskrun/resources/taskresourceresolution.go b/pkg/reconciler/taskrun/resources/taskresourceresolution.go index 880490a19c1..31546992cd7 100644 --- a/pkg/reconciler/taskrun/resources/taskresourceresolution.go +++ b/pkg/reconciler/taskrun/resources/taskresourceresolution.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -44,7 +45,7 @@ type GetResource func(string) (*v1alpha1.PipelineResource, error) // ResolveTaskResources looks up PipelineResources referenced by inputs and outputs and returns // a structure that unites the resolved references and the Task Spec. If referenced PipelineResources // can't be found, an error is returned. -func ResolveTaskResources(ts *v1alpha1.TaskSpec, taskName string, kind v1alpha1.TaskKind, inputs []v1alpha1.TaskResourceBinding, outputs []v1alpha1.TaskResourceBinding, gr GetResource) (*ResolvedTaskResources, error) { +func ResolveTaskResources(ts *v1alpha1.TaskSpec, taskName string, kind v1alpha1.TaskKind, inputs []v1alpha2.TaskResourceBinding, outputs []v1alpha2.TaskResourceBinding, gr GetResource) (*ResolvedTaskResources, error) { rtr := ResolvedTaskResources{ TaskName: taskName, TaskSpec: ts, diff --git a/pkg/reconciler/taskrun/resources/taskspec.go b/pkg/reconciler/taskrun/resources/taskspec.go index 049ccb537d4..b2d19f09660 100644 --- a/pkg/reconciler/taskrun/resources/taskspec.go +++ b/pkg/reconciler/taskrun/resources/taskspec.go @@ -17,9 +17,12 @@ limitations under the License. package resources import ( + "context" "fmt" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" + "github.com/tektoncd/pipeline/pkg/contexts" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -33,7 +36,7 @@ type GetClusterTask func(name string) (v1alpha1.TaskInterface, error) // GetTaskData will retrieve the Task metadata and Spec associated with the // provided TaskRun. This can come from a reference Task or from the TaskRun's // metadata and embedded TaskSpec. -func GetTaskData(taskRun *v1alpha1.TaskRun, getTask GetTask) (*metav1.ObjectMeta, *v1alpha1.TaskSpec, error) { +func GetTaskData(ctx context.Context, taskRun *v1alpha1.TaskRun, getTask GetTask) (*metav1.ObjectMeta, *v1alpha1.TaskSpec, error) { taskMeta := metav1.ObjectMeta{} taskSpec := v1alpha1.TaskSpec{} switch { @@ -45,6 +48,11 @@ func GetTaskData(taskRun *v1alpha1.TaskRun, getTask GetTask) (*metav1.ObjectMeta } taskMeta = t.TaskMetadata() taskSpec = t.TaskSpec() + taskSpec.SetDefaults(contexts.WithUpgradeViaDefaulting(ctx)) + + if err := taskSpec.ConvertUp(ctx, &v1alpha2.TaskSpec{}); err != nil { + return nil, nil, err + } case taskRun.Spec.TaskSpec != nil: taskMeta = taskRun.ObjectMeta taskSpec = *taskRun.Spec.TaskSpec diff --git a/pkg/reconciler/taskrun/resources/taskspec_test.go b/pkg/reconciler/taskrun/resources/taskspec_test.go index 9a95ebd7c5d..a5f74996211 100644 --- a/pkg/reconciler/taskrun/resources/taskspec_test.go +++ b/pkg/reconciler/taskrun/resources/taskspec_test.go @@ -17,6 +17,7 @@ limitations under the License. package resources import ( + "context" "errors" "testing" @@ -48,7 +49,7 @@ func TestGetTaskSpec_Ref(t *testing.T) { }, } gt := func(n string) (v1alpha1.TaskInterface, error) { return task, nil } - taskMeta, taskSpec, err := GetTaskData(tr, gt) + taskMeta, taskSpec, err := GetTaskData(context.Background(), tr, gt) if err != nil { t.Fatalf("Did not expect error getting task spec but got: %s", err) @@ -77,7 +78,7 @@ func TestGetTaskSpec_Embedded(t *testing.T) { }, } gt := func(n string) (v1alpha1.TaskInterface, error) { return nil, errors.New("shouldn't be called") } - taskMeta, taskSpec, err := GetTaskData(tr, gt) + taskMeta, taskSpec, err := GetTaskData(context.Background(), tr, gt) if err != nil { t.Fatalf("Did not expect error getting task spec but got: %s", err) @@ -99,7 +100,7 @@ func TestGetTaskSpec_Invalid(t *testing.T) { }, } gt := func(n string) (v1alpha1.TaskInterface, error) { return nil, errors.New("shouldn't be called") } - _, _, err := GetTaskData(tr, gt) + _, _, err := GetTaskData(context.Background(), tr, gt) if err == nil { t.Fatalf("Expected error resolving spec with no embedded or referenced task spec but didn't get error") } @@ -117,7 +118,7 @@ func TestGetTaskSpec_Error(t *testing.T) { }, } gt := func(n string) (v1alpha1.TaskInterface, error) { return nil, errors.New("something went wrong") } - _, _, err := GetTaskData(tr, gt) + _, _, err := GetTaskData(context.Background(), tr, gt) if err == nil { t.Fatalf("Expected error when unable to find referenced Task but got none") } diff --git a/pkg/reconciler/taskrun/taskrun.go b/pkg/reconciler/taskrun/taskrun.go index 30823d88f96..6234657b83f 100644 --- a/pkg/reconciler/taskrun/taskrun.go +++ b/pkg/reconciler/taskrun/taskrun.go @@ -27,6 +27,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/config" "github.com/tektoncd/pipeline/pkg/apis/pipeline" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" listers "github.com/tektoncd/pipeline/pkg/client/listers/pipeline/v1alpha1" resourcelisters "github.com/tektoncd/pipeline/pkg/client/resource/listers/resource/v1alpha1" "github.com/tektoncd/pipeline/pkg/contexts" @@ -223,6 +224,14 @@ func (c *Reconciler) reconcile(ctx context.Context, tr *v1alpha1.TaskRun) error // and may not have had all of the assumed default specified. tr.SetDefaults(contexts.WithUpgradeViaDefaulting(ctx)) + if err := tr.ConvertUp(ctx, &v1alpha2.TaskRun{}); err != nil { + if ce, ok := err.(*v1alpha2.CannotConvertError); ok { + tr.Status.MarkResourceNotConvertible(ce) + return nil + } + return err + } + // If the taskrun is cancelled, kill resources and update status if tr.IsCancelled() { before := tr.Status.GetCondition(apis.ConditionSucceeded) @@ -233,8 +242,12 @@ func (c *Reconciler) reconcile(ctx context.Context, tr *v1alpha1.TaskRun) error } getTaskFunc, kind := c.getTaskFunc(tr) - taskMeta, taskSpec, err := resources.GetTaskData(tr, getTaskFunc) + taskMeta, taskSpec, err := resources.GetTaskData(ctx, tr, getTaskFunc) if err != nil { + if ce, ok := err.(*v1alpha2.CannotConvertError); ok { + tr.Status.MarkResourceNotConvertible(ce) + return nil + } c.Logger.Errorf("Failed to determine Task spec to use for taskrun %s: %v", tr.Name, err) tr.Status.SetCondition(&apis.Condition{ Type: apis.ConditionSucceeded, @@ -276,7 +289,13 @@ func (c *Reconciler) reconcile(ctx context.Context, tr *v1alpha1.TaskRun) error return nil } - rtr, err := resources.ResolveTaskResources(taskSpec, taskMeta.Name, kind, tr.Spec.Inputs.Resources, tr.Spec.Outputs.Resources, c.resourceLister.PipelineResources(tr.Namespace).Get) + inputs := []v1alpha2.TaskResourceBinding{} + outputs := []v1alpha2.TaskResourceBinding{} + if tr.Spec.Resources != nil { + inputs = tr.Spec.Resources.Inputs + outputs = tr.Spec.Resources.Outputs + } + rtr, err := resources.ResolveTaskResources(taskSpec, taskMeta.Name, kind, inputs, outputs, c.resourceLister.PipelineResources(tr.Namespace).Get) if err != nil { c.Logger.Errorf("Failed to resolve references for taskrun %s: %v", tr.Name, err) tr.Status.SetCondition(&apis.Condition{ @@ -288,7 +307,7 @@ func (c *Reconciler) reconcile(ctx context.Context, tr *v1alpha1.TaskRun) error return nil } - if err := ValidateResolvedTaskResources(tr.Spec.Inputs.Params, rtr); err != nil { + if err := ValidateResolvedTaskResources(tr.Spec.Params, rtr); err != nil { c.Logger.Errorf("TaskRun %q resources are invalid: %v", tr.Name, err) tr.Status.SetCondition(&apis.Condition{ Type: apis.ConditionSucceeded, @@ -494,14 +513,17 @@ func (c *Reconciler) createPod(tr *v1alpha1.TaskRun, rtr *resources.ResolvedTask return nil, err } - // Get actual resource + c.Logger.Infof("steps (before:outputimagedigestexporter): %d %+v", len(ts.Steps), ts.Steps) + // Get actual resource err = resources.AddOutputImageDigestExporter(c.Images.ImageDigestExporterImage, tr, ts, c.resourceLister.PipelineResources(tr.Namespace).Get) if err != nil { c.Logger.Errorf("Failed to create a pod for taskrun: %s due to output image resource error %v", tr.Name, err) return nil, err } + c.Logger.Infof("steps (after:outputimagedigestexporter): %d %+v", len(ts.Steps), ts.Steps) + ts, err = resources.AddInputResource(c.KubeClientSet, c.Images, rtr.TaskName, ts, tr, inputResources, c.Logger) if err != nil { c.Logger.Errorf("Failed to create a pod for taskrun: %s due to input resource error %v", tr.Name, err) @@ -515,8 +537,8 @@ func (c *Reconciler) createPod(tr *v1alpha1.TaskRun, rtr *resources.ResolvedTask } var defaults []v1alpha1.ParamSpec - if ts.Inputs != nil { - defaults = append(defaults, ts.Inputs.Params...) + if len(ts.Params) > 0 { + defaults = append(defaults, ts.Params...) } // Apply parameter substitution from the taskrun. ts = resources.ApplyParameters(ts, tr, defaults...) diff --git a/pkg/reconciler/taskrun/validate_resources.go b/pkg/reconciler/taskrun/validate_resources.go index a5137a30493..567dbfa3097 100644 --- a/pkg/reconciler/taskrun/validate_resources.go +++ b/pkg/reconciler/taskrun/validate_resources.go @@ -20,25 +20,12 @@ import ( "fmt" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" "github.com/tektoncd/pipeline/pkg/list" "github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources" ) -func validateInputResources(inputs *v1alpha1.Inputs, providedResources map[string]*v1alpha1.PipelineResource) error { - if inputs != nil { - return validateResources(inputs.Resources, providedResources) - } - return validateResources([]v1alpha1.TaskResource{}, providedResources) -} - -func validateOutputResources(outputs *v1alpha1.Outputs, providedResources map[string]*v1alpha1.PipelineResource) error { - if outputs != nil { - return validateResources(outputs.Resources, providedResources) - } - return validateResources([]v1alpha1.TaskResource{}, providedResources) -} - -func validateResources(requiredResources []v1alpha1.TaskResource, providedResources map[string]*v1alpha1.PipelineResource) error { +func validateResources(requiredResources []v1alpha2.TaskResource, providedResources map[string]*v1alpha1.PipelineResource) error { required := make([]string, 0, len(requiredResources)) optional := make([]string, 0, len(requiredResources)) for _, resource := range requiredResources { @@ -77,15 +64,13 @@ func validateResources(requiredResources []v1alpha1.TaskResource, providedResour return nil } -func validateParams(inputs *v1alpha1.Inputs, params []v1alpha1.Param) error { +func validateParams(paramSpecs []v1alpha2.ParamSpec, params []v1alpha1.Param) error { var neededParams []string paramTypes := make(map[string]v1alpha1.ParamType) - if inputs != nil { - neededParams = make([]string, 0, len(inputs.Params)) - for _, inputResourceParam := range inputs.Params { - neededParams = append(neededParams, inputResourceParam.Name) - paramTypes[inputResourceParam.Name] = inputResourceParam.Type - } + neededParams = make([]string, 0, len(paramSpecs)) + for _, inputResourceParam := range paramSpecs { + neededParams = append(neededParams, inputResourceParam.Name) + paramTypes[inputResourceParam.Name] = inputResourceParam.Type } providedParams := make([]string, 0, len(params)) for _, param := range params { @@ -94,7 +79,7 @@ func validateParams(inputs *v1alpha1.Inputs, params []v1alpha1.Param) error { missingParams := list.DiffLeft(neededParams, providedParams) var missingParamsNoDefaults []string for _, param := range missingParams { - for _, inputResourceParam := range inputs.Params { + for _, inputResourceParam := range paramSpecs { if inputResourceParam.Name == param && inputResourceParam.Default == nil { missingParamsNoDefaults = append(missingParamsNoDefaults, param) } @@ -125,13 +110,19 @@ func validateParams(inputs *v1alpha1.Inputs, params []v1alpha1.Param) error { // ValidateResolvedTaskResources validates task inputs, params and output matches taskrun func ValidateResolvedTaskResources(params []v1alpha1.Param, rtr *resources.ResolvedTaskResources) error { - if err := validateParams(rtr.TaskSpec.Inputs, params); err != nil { + if err := validateParams(rtr.TaskSpec.Params, params); err != nil { return fmt.Errorf("invalid input params: %w", err) } - if err := validateInputResources(rtr.TaskSpec.Inputs, rtr.Inputs); err != nil { + inputs := []v1alpha2.TaskResource{} + outputs := []v1alpha2.TaskResource{} + if rtr.TaskSpec.Resources != nil { + inputs = rtr.TaskSpec.Resources.Inputs + outputs = rtr.TaskSpec.Resources.Outputs + } + if err := validateResources(inputs, rtr.Inputs); err != nil { return fmt.Errorf("invalid input resources: %w", err) } - if err := validateOutputResources(rtr.TaskSpec.Outputs, rtr.Outputs); err != nil { + if err := validateResources(outputs, rtr.Outputs); err != nil { return fmt.Errorf("invalid output resources: %w", err) } diff --git a/pkg/reconciler/taskrun/validate_resources_test.go b/pkg/reconciler/taskrun/validate_resources_test.go index 10550360a09..a71ed8c5d41 100644 --- a/pkg/reconciler/taskrun/validate_resources_test.go +++ b/pkg/reconciler/taskrun/validate_resources_test.go @@ -29,13 +29,11 @@ func TestValidateResolvedTaskResources_ValidResources(t *testing.T) { rtr := tb.ResolvedTaskResources( tb.ResolvedTaskResourcesTaskSpec( tb.Step("myimage", tb.StepCommand("mycmd")), - tb.TaskInputs( - tb.InputsResource("resource-to-build", v1alpha1.PipelineResourceTypeGit), - tb.InputsResource("optional-resource-to-build", v1alpha1.PipelineResourceTypeGit, tb.ResourceOptional(true)), - ), - tb.TaskOutputs( - tb.OutputsResource("resource-to-provide", v1alpha1.PipelineResourceTypeImage), - tb.OutputsResource("optional-resource-to-provide", v1alpha1.PipelineResourceTypeImage, tb.ResourceOptional(true)), + tb.TaskResources( + tb.TaskResourcesInput("resource-to-build", v1alpha1.PipelineResourceTypeGit), + tb.TaskResourcesInput("optional-resource-to-build", v1alpha1.PipelineResourceTypeGit, tb.ResourceOptional(true)), + tb.TaskResourcesOutput("resource-to-provide", v1alpha1.PipelineResourceTypeImage), + tb.TaskResourcesOutput("optional-resource-to-provide", v1alpha1.PipelineResourceTypeImage, tb.ResourceOptional(true)), ), ), tb.ResolvedTaskResourcesInputs("resource-to-build", tb.PipelineResource("example-resource", "foo", @@ -60,7 +58,8 @@ func TestValidateResolvedTaskResources_ValidResources(t *testing.T) { func TestValidateResolvedTaskResources_ValidParams(t *testing.T) { rtr := tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( tb.Step("myimage", tb.StepCommand("mycmd")), - tb.TaskInputs(tb.InputsParamSpec("foo", v1alpha1.ParamTypeString), tb.InputsParamSpec("bar", v1alpha1.ParamTypeString)), + tb.TaskParam("foo", v1alpha1.ParamTypeString), + tb.TaskParam("bar", v1alpha1.ParamTypeString), )) p := []v1alpha1.Param{{ Name: "foo", @@ -123,81 +122,90 @@ func TestValidateResolvedTaskResources_InvalidResources(t *testing.T) { }{{ name: "bad-inputkey", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskInputs(tb.InputsResource("testinput", v1alpha1.PipelineResourceTypeGit)), + tb.TaskResources(tb.TaskResourcesInput("testinput", v1alpha1.PipelineResourceTypeGit)), + // tb.TaskResources(tb.TaskResourcesInput()), ), tb.ResolvedTaskResourcesInputs("wrong-resource-name", r)), }, { name: "bad-outputkey", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskOutputs(tb.OutputsResource("testoutput", v1alpha1.PipelineResourceTypeGit)), + tb.TaskResources(tb.TaskResourcesOutput("testoutput", v1alpha1.PipelineResourceTypeGit)), ), tb.ResolvedTaskResourcesOutputs("wrong-resource-name", r)), }, { name: "input-resource-mismatch", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskInputs(tb.InputsResource("testimageinput", v1alpha1.PipelineResourceTypeImage)), + tb.TaskResources(tb.TaskResourcesInput("testimageinput", v1alpha1.PipelineResourceTypeImage)), ), tb.ResolvedTaskResourcesInputs("testimageinput", r)), }, { name: "input-resource-missing", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskInputs(tb.InputsResource("testimageinput", v1alpha1.PipelineResourceTypeImage)), + tb.TaskResources(tb.TaskResourcesInput("testimageinput", v1alpha1.PipelineResourceTypeImage)), )), }, { name: "output-resource-mismatch", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskOutputs(tb.OutputsResource("testimageoutput", v1alpha1.PipelineResourceTypeImage)), + tb.TaskResources(tb.TaskResourcesOutput("testimageoutput", v1alpha1.PipelineResourceTypeImage)), ), tb.ResolvedTaskResourcesOutputs("testimageoutput", r)), }, { name: "output-resource-missing", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskOutputs(tb.OutputsResource("testimageoutput", v1alpha1.PipelineResourceTypeImage)), + tb.TaskResources(tb.TaskResourcesOutput("testimageoutput", v1alpha1.PipelineResourceTypeImage)), )), }, { name: "extra-input-resource", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskInputs(tb.InputsResource("testoutput", v1alpha1.PipelineResourceTypeGit))), + tb.TaskResources(tb.TaskResourcesInput("testoutput", v1alpha1.PipelineResourceTypeGit))), tb.ResolvedTaskResourcesInputs("testoutput", r), tb.ResolvedTaskResourcesInputs("someextrainput", r), ), }, { name: "extra-output-resource", - rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskOutputs(tb.OutputsResource("testoutput", v1alpha1.PipelineResourceTypeGit))), + rtr: tb.ResolvedTaskResources( + tb.ResolvedTaskResourcesTaskSpec( + tb.TaskResources(tb.TaskResourcesOutput("testoutput", v1alpha1.PipelineResourceTypeGit)), + ), tb.ResolvedTaskResourcesOutputs("testoutput", r), tb.ResolvedTaskResourcesOutputs("someextraoutput", r), ), }, { name: "extra-input-resource-none-required", - rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskOutputs(tb.OutputsResource("testoutput", v1alpha1.PipelineResourceTypeGit))), + rtr: tb.ResolvedTaskResources( + tb.ResolvedTaskResourcesTaskSpec( + tb.TaskResources(tb.TaskResourcesOutput("testoutput", v1alpha1.PipelineResourceTypeGit)), + ), tb.ResolvedTaskResourcesOutputs("testoutput", r), tb.ResolvedTaskResourcesInputs("someextrainput", r), ), }, { name: "extra-output-resource-none-required", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskInputs(tb.InputsResource("testinput", v1alpha1.PipelineResourceTypeGit))), + tb.TaskResources(tb.TaskResourcesInput("testinput", v1alpha1.PipelineResourceTypeGit))), tb.ResolvedTaskResourcesInputs("testinput", r), tb.ResolvedTaskResourcesOutputs("someextraoutput", r), ), }, { name: "required-input-resource-missing", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskInputs(tb.InputsResource("requiredgitinput", v1alpha1.PipelineResourceTypeGit, + tb.TaskResources(tb.TaskResourcesInput("requiredgitinput", v1alpha1.PipelineResourceTypeGit, tb.ResourceOptional(false)))), ), }, { name: "required-output-resource-missing", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskOutputs(tb.OutputsResource("requiredgitoutput", v1alpha1.PipelineResourceTypeGit, - tb.ResourceOptional(false)))), + tb.TaskResources(tb.TaskResourcesOutput( + "requiredgitoutput", v1alpha1.PipelineResourceTypeGit, + tb.ResourceOptional(false)), + )), ), }, { name: "required-input-and-output-resource-missing", rtr: tb.ResolvedTaskResources(tb.ResolvedTaskResourcesTaskSpec( - tb.TaskInputs(tb.InputsResource("requiredimageinput", v1alpha1.PipelineResourceTypeImage, - tb.ResourceOptional(false))), - tb.TaskOutputs(tb.OutputsResource("requiredimageoutput", v1alpha1.PipelineResourceTypeImage, - tb.ResourceOptional(false)))), - ), + tb.TaskResources( + tb.TaskResourcesInput("requiredimageinput", v1alpha1.PipelineResourceTypeImage, + tb.ResourceOptional(false)), + tb.TaskResourcesOutput("requiredimageoutput", v1alpha1.PipelineResourceTypeImage, + tb.ResourceOptional(false)), + ), + )), }} for _, tc := range tcs { diff --git a/test/builder/task.go b/test/builder/task.go index 73dedad26d5..f33f94cdf91 100644 --- a/test/builder/task.go +++ b/test/builder/task.go @@ -21,6 +21,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/config" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" "github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -36,6 +37,9 @@ type ClusterTaskOp func(*v1alpha1.ClusterTask) // TaskSpeOp is an operation which modify a TaskSpec struct. type TaskSpecOp func(*v1alpha1.TaskSpec) +// TaskResourcesOp is an operation which modify a TaskResources struct. +type TaskResourcesOp func(*v1alpha2.TaskResources) + // InputsOp is an operation which modify an Inputs struct. type InputsOp func(*v1alpha1.Inputs) @@ -48,6 +52,9 @@ type TaskRunOp func(*v1alpha1.TaskRun) // TaskRunSpecOp is an operation which modify a TaskRunSpec struct. type TaskRunSpecOp func(*v1alpha1.TaskRunSpec) +// TaskRunResourcesOp is an operation which modify a TaskRunResources struct. +type TaskRunResourcesOp func(*v1alpha2.TaskRunResources) + // TaskResourceOp is an operation which modify a TaskResource struct. type TaskResourceOp func(*v1alpha1.TaskResource) @@ -208,6 +215,60 @@ func VolumeSource(s corev1.VolumeSource) VolumeOp { } } +// TaskParam sets the Params to the TaskSpec +func TaskParam(name string, pt v1alpha1.ParamType, ops ...ParamSpecOp) TaskSpecOp { + return func(spec *v1alpha1.TaskSpec) { + ps := &v1alpha1.ParamSpec{Name: name, Type: pt} + for _, op := range ops { + op(ps) + } + spec.Params = append(spec.Params, *ps) + } +} + +// TaskResources sets the Resources to the TaskSpec +func TaskResources(ops ...TaskResourcesOp) TaskSpecOp { + return func(spec *v1alpha1.TaskSpec) { + r := &v1alpha2.TaskResources{} + for _, op := range ops { + op(r) + } + spec.Resources = r + } +} + +// TaskResourcesInput adds a TaskResource as Inputs to the TaskResources +func TaskResourcesInput(name string, resourceType v1alpha1.PipelineResourceType, ops ...TaskResourceOp) TaskResourcesOp { + return func(r *v1alpha2.TaskResources) { + i := &v1alpha2.TaskResource{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: name, + Type: resourceType, + }, + } + for _, op := range ops { + op(i) + } + r.Inputs = append(r.Inputs, *i) + } +} + +// TaskResourcesOutput adds a TaskResource as Outputs to the TaskResources +func TaskResourcesOutput(name string, resourceType v1alpha1.PipelineResourceType, ops ...TaskResourceOp) TaskResourcesOp { + return func(r *v1alpha2.TaskResources) { + o := &v1alpha2.TaskResource{ + ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: name, + Type: resourceType, + }, + } + for _, op := range ops { + op(o) + } + r.Outputs = append(r.Outputs, *o) + } +} + // TaskInputs sets inputs to the TaskSpec. // Any number of Inputs modifier can be passed to transform it. func TaskInputs(ops ...InputsOp) TaskSpecOp { @@ -532,6 +593,7 @@ func TaskRunSelfLink(selflink string) TaskRunOp { func TaskRunSpec(ops ...TaskRunSpecOp) TaskRunOp { return func(tr *v1alpha1.TaskRun) { spec := &tr.Spec + spec.Resources = &v1alpha2.TaskRunResources{} // Set a default timeout spec.Timeout = &metav1.Duration{Duration: config.DefaultTimeoutMinutes * time.Minute} for _, op := range ops { @@ -599,6 +661,58 @@ func TaskRunServiceAccountName(sa string) TaskRunSpecOp { } } +// TaskRunParam sets the Params to the TaskSpec +func TaskRunParam(name, value string, additionalValues ...string) TaskRunSpecOp { + arrayOrString := ArrayOrString(value, additionalValues...) + return func(spec *v1alpha1.TaskRunSpec) { + spec.Params = append(spec.Params, v1alpha1.Param{ + Name: name, + Value: *arrayOrString, + }) + } +} + +// TaskRunResources sets the TaskRunResources to the TaskRunSpec +func TaskRunResources(ops ...TaskRunResourcesOp) TaskRunSpecOp { + return func(spec *v1alpha1.TaskRunSpec) { + r := &v1alpha2.TaskRunResources{} + for _, op := range ops { + op(r) + } + spec.Resources = r + } +} + +// TaskRunResourcesInput adds a TaskRunResource as Inputs to the TaskRunResources +func TaskRunResourcesInput(name string, ops ...TaskResourceBindingOp) TaskRunResourcesOp { + return func(r *v1alpha2.TaskRunResources) { + binding := &v1alpha1.TaskResourceBinding{ + PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ + Name: name, + }, + } + for _, op := range ops { + op(binding) + } + r.Inputs = append(r.Inputs, *binding) + } +} + +// TaskRunResourcesOutput adds a TaskRunResource as Outputs to the TaskRunResources +func TaskRunResourcesOutput(name string, ops ...TaskResourceBindingOp) TaskRunResourcesOp { + return func(r *v1alpha2.TaskRunResources) { + binding := &v1alpha1.TaskResourceBinding{ + PipelineResourceBinding: v1alpha1.PipelineResourceBinding{ + Name: name, + }, + } + for _, op := range ops { + op(binding) + } + r.Outputs = append(r.Outputs, *binding) + } +} + // TaskRunInputs sets inputs to the TaskRunSpec. // Any number of TaskRunInputs modifier can be passed to transform it. func TaskRunInputs(ops ...TaskRunInputsOp) TaskRunSpecOp { diff --git a/test/builder/task_test.go b/test/builder/task_test.go index abc3cc81e1f..a4f79d2b499 100644 --- a/test/builder/task_test.go +++ b/test/builder/task_test.go @@ -258,7 +258,8 @@ func TestTaskRunWithTaskRef(t *testing.T) { Paths: []string{"output-folder"}, }}, }, - Timeout: &metav1.Duration{Duration: config.DefaultTimeoutMinutes * time.Minute}, + Resources: &v1alpha2.TaskRunResources{}, + Timeout: &metav1.Duration{Duration: config.DefaultTimeoutMinutes * time.Minute}, TaskRef: &v1alpha1.TaskRef{ Name: "task-output", Kind: v1alpha1.ClusterTaskKind, @@ -326,6 +327,7 @@ func TestTaskRunWithTaskSpec(t *testing.T) { Params: nil, }, }, + Resources: &v1alpha2.TaskRunResources{}, ServiceAccountName: "sa", Status: v1alpha1.TaskRunSpecStatusCancelled, Timeout: &metav1.Duration{Duration: 2 * time.Minute}, @@ -377,6 +379,7 @@ func TestTaskRunWithPodTemplate(t *testing.T) { "label": "value", }, }, + Resources: &v1alpha2.TaskRunResources{}, ServiceAccountName: "sa", Status: v1alpha1.TaskRunSpecStatusCancelled, Timeout: &metav1.Duration{Duration: 2 * time.Minute},