diff --git a/pkg/apis/pipeline/v1alpha1/cluster_task_conversion.go b/pkg/apis/pipeline/v1alpha1/cluster_task_conversion.go new file mode 100644 index 00000000000..cc08819fd10 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha1/cluster_task_conversion.go @@ -0,0 +1,50 @@ +/* +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. +*/ + +// nolint: golint +package v1alpha1 + +import ( + "context" + "fmt" + + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" + "knative.dev/pkg/apis" +) + +var _ apis.Convertible = (*ClusterTask)(nil) + +// ConvertUp implements api.Convertible +func (source *ClusterTask) ConvertUp(ctx context.Context, obj apis.Convertible) error { + switch sink := obj.(type) { + case *v1alpha2.ClusterTask: + sink.ObjectMeta = source.ObjectMeta + return source.Spec.ConvertUp(ctx, &sink.Spec) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +// ConvertDown implements api.Convertible +func (sink *ClusterTask) ConvertDown(ctx context.Context, obj apis.Convertible) error { + switch source := obj.(type) { + case *v1alpha2.ClusterTask: + sink.ObjectMeta = source.ObjectMeta + return sink.Spec.ConvertDown(ctx, &source.Spec) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} diff --git a/pkg/apis/pipeline/v1alpha1/cluster_task_conversion_test.go b/pkg/apis/pipeline/v1alpha1/cluster_task_conversion_test.go new file mode 100644 index 00000000000..287897a6f2a --- /dev/null +++ b/pkg/apis/pipeline/v1alpha1/cluster_task_conversion_test.go @@ -0,0 +1,321 @@ +/* +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 v1alpha1 + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" + resource "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/apis" +) + +func TestClusterTaskConversionBadType(t *testing.T) { + good, bad := &ClusterTask{}, &Pipeline{} + + if err := good.ConvertUp(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } + + if err := good.ConvertDown(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } +} + +func TestClusterTaskConversion(t *testing.T) { + versions := []apis.Convertible{&v1alpha2.ClusterTask{}} + + tests := []struct { + name string + in *ClusterTask + wantErr bool + }{{ + name: "simple conversion", + in: &ClusterTask{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha2.Step{{Container: corev1.Container{ + Image: "foo", + }}}, + Volumes: []corev1.Volume{{}}, + Params: []v1alpha2.ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + Outputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + }, + }, { + name: "deprecated and non deprecated inputs", + in: &ClusterTask{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + Inputs: &Inputs{ + Resources: []TaskResource{{ResourceDeclaration: ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + wantErr: true, + }, { + name: "deprecated and non deprecated inputs", + in: &ClusterTask{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Params: []v1alpha2.ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + }, + Inputs: &Inputs{ + Params: []ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + }, + }, + }, + wantErr: true, + }, { + name: "deprecated and non deprecated outputs", + in: &ClusterTask{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + Outputs: &Outputs{ + Resources: []TaskResource{{ResourceDeclaration: ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + wantErr: true, + }} + + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := test.in.ConvertUp(context.Background(), ver); err != nil { + if !test.wantErr { + t.Errorf("ConvertUp() = %v", err) + } + return + } + t.Logf("ConvertUp() = %#v", ver) + got := &ClusterTask{} + if err := got.ConvertDown(context.Background(), ver); err != nil { + t.Errorf("ConvertDown() = %v", err) + } + t.Logf("ConvertDown() = %#v", got) + if diff := cmp.Diff(test.in, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} + +func TestClusterTaskConversionFromDeprecated(t *testing.T) { + versions := []apis.Convertible{&v1alpha2.ClusterTask{}} + tests := []struct { + name string + in *ClusterTask + want *ClusterTask + badField string + }{{ + name: "inputs params", + in: &ClusterTask{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + Inputs: &Inputs{ + Params: []ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + }, + }, + }, + want: &ClusterTask{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Params: []v1alpha2.ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + }, + }, + }, + }, { + name: "inputs resource", + in: &ClusterTask{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + Inputs: &Inputs{ + Resources: []TaskResource{{ResourceDeclaration: ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + want: &ClusterTask{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + }, + }, { + name: "outputs resource", + in: &ClusterTask{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + Outputs: &Outputs{ + Resources: []TaskResource{{ResourceDeclaration: ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + want: &ClusterTask{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + }, + }} + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := test.in.ConvertUp(context.Background(), ver); err != nil { + if test.badField != "" { + cce, ok := err.(*CannotConvertError) + if ok && cce.Field == test.badField { + return + } + } + t.Errorf("ConvertUp() = %v", err) + } + t.Logf("ConvertUp() = %#v", ver) + got := &ClusterTask{} + if err := got.ConvertDown(context.Background(), ver); err != nil { + t.Errorf("ConvertDown() = %v", err) + } + t.Logf("ConvertDown() = %#v", got) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} diff --git a/pkg/apis/pipeline/v1alpha1/conversion_error.go b/pkg/apis/pipeline/v1alpha1/conversion_error.go new file mode 100644 index 00000000000..7282ea9e1ca --- /dev/null +++ b/pkg/apis/pipeline/v1alpha1/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 v1alpha1 + +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/v1alpha1/pipeline_conversion.go b/pkg/apis/pipeline/v1alpha1/pipeline_conversion.go new file mode 100644 index 00000000000..ea1f0491bf1 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha1/pipeline_conversion.go @@ -0,0 +1,116 @@ +/* +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. +*/ + +// nolint: golint +package v1alpha1 + +import ( + "context" + "fmt" + + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" + "knative.dev/pkg/apis" +) + +var _ apis.Convertible = (*Pipeline)(nil) + +// ConvertUp implements api.Convertible +func (source *Pipeline) ConvertUp(ctx context.Context, obj apis.Convertible) error { + switch sink := obj.(type) { + case *v1alpha2.Pipeline: + sink.ObjectMeta = source.ObjectMeta + return source.Spec.ConvertUp(ctx, &sink.Spec) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +func (source *PipelineSpec) ConvertUp(ctx context.Context, sink *v1alpha2.PipelineSpec) error { + sink.Resources = source.Resources + sink.Params = source.Params + sink.Workspaces = source.Workspaces + if len(source.Tasks) > 0 { + sink.Tasks = make([]v1alpha2.PipelineTask, len(source.Tasks)) + for i := range source.Tasks { + if err := source.Tasks[i].ConvertUp(ctx, &sink.Tasks[i]); err != nil { + return err + } + } + } + return nil +} + +func (source *PipelineTask) ConvertUp(ctx context.Context, sink *v1alpha2.PipelineTask) error { + sink.Name = source.Name + sink.TaskRef = source.TaskRef + if source.TaskSpec != nil { + sink.TaskSpec = &v1alpha2.TaskSpec{} + if err := source.TaskSpec.ConvertUp(ctx, sink.TaskSpec); err != nil { + return err + } + } + sink.Conditions = source.Conditions + sink.Retries = source.Retries + sink.RunAfter = source.RunAfter + sink.Resources = source.Resources + sink.Params = source.Params + sink.Workspaces = source.Workspaces + return nil +} + +// ConvertDown implements api.Convertible +func (sink *Pipeline) ConvertDown(ctx context.Context, obj apis.Convertible) error { + switch source := obj.(type) { + case *v1alpha2.Pipeline: + sink.ObjectMeta = source.ObjectMeta + return sink.Spec.ConvertDown(ctx, source.Spec) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +func (sink *PipelineSpec) ConvertDown(ctx context.Context, source v1alpha2.PipelineSpec) error { + sink.Resources = source.Resources + sink.Params = source.Params + sink.Workspaces = source.Workspaces + if len(source.Tasks) > 0 { + sink.Tasks = make([]PipelineTask, len(source.Tasks)) + for i := range source.Tasks { + if err := sink.Tasks[i].ConvertDown(ctx, source.Tasks[i]); err != nil { + return err + } + } + } + return nil +} + +func (sink *PipelineTask) ConvertDown(ctx context.Context, source v1alpha2.PipelineTask) error { + sink.Name = source.Name + sink.TaskRef = source.TaskRef + if source.TaskSpec != nil { + sink.TaskSpec = &TaskSpec{} + if err := sink.TaskSpec.ConvertDown(ctx, source.TaskSpec); err != nil { + return err + } + } + sink.Conditions = source.Conditions + sink.Retries = source.Retries + sink.RunAfter = source.RunAfter + sink.Resources = source.Resources + sink.Params = source.Params + sink.Workspaces = source.Workspaces + return nil +} diff --git a/pkg/apis/pipeline/v1alpha1/pipeline_conversion_test.go b/pkg/apis/pipeline/v1alpha1/pipeline_conversion_test.go new file mode 100644 index 00000000000..cb23f42a84c --- /dev/null +++ b/pkg/apis/pipeline/v1alpha1/pipeline_conversion_test.go @@ -0,0 +1,176 @@ +/* +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 v1alpha1 + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" + resource "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/apis" +) + +func TestPipelineConversionBadType(t *testing.T) { + good, bad := &Pipeline{}, &Task{} + + if err := good.ConvertUp(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } + + if err := good.ConvertDown(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } +} + +func TestPipelineConversion(t *testing.T) { + versions := []apis.Convertible{&v1alpha2.Pipeline{}} + + tests := []struct { + name string + in *Pipeline + wantErr bool + }{{ + name: "simple conversion", + in: &Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: PipelineSpec{ + Resources: []PipelineDeclaredResource{{ + Name: "resource1", + Type: resource.PipelineResourceTypeGit, + }, { + Name: "resource2", + Type: resource.PipelineResourceTypeImage, + }}, + Params: []ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + Workspaces: []WorkspacePipelineDeclaration{{ + Name: "workspace1", + }}, + Tasks: []PipelineTask{{ + Name: "task1", + TaskRef: &TaskRef{ + Name: "taskref", + }, + Conditions: []PipelineTaskCondition{{ + ConditionRef: "condition1", + }}, + Retries: 10, + RunAfter: []string{"task1"}, + Resources: &PipelineTaskResources{ + Inputs: []v1alpha2.PipelineTaskInputResource{{ + Name: "input1", + Resource: "resource1", + }}, + Outputs: []v1alpha2.PipelineTaskOutputResource{{ + Name: "output1", + Resource: "resource2", + }}, + }, + Params: []Param{{ + Name: "param1", + Value: v1alpha2.ArrayOrString{StringVal: "str", Type: v1alpha2.ParamTypeString}, + }}, + Workspaces: []WorkspacePipelineTaskBinding{{ + Name: "w1", + Workspace: "workspace1", + }}, + }, { + Name: "task2", + TaskSpec: &TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha2.Step{{Container: corev1.Container{ + Image: "foo", + }}}, + }}, + RunAfter: []string{"task1"}, + }}, + }, + }, + }, { + name: "simple conversion with task spec error", + in: &Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: PipelineSpec{ + Params: []ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + Tasks: []PipelineTask{{ + Name: "task2", + TaskSpec: &TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha2.Step{{Container: corev1.Container{ + Image: "foo", + }}}, + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + Inputs: &Inputs{ + Resources: []TaskResource{{ResourceDeclaration: ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }}, + RunAfter: []string{"task1"}, + }}, + }, + }, + wantErr: true, + }} + + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := test.in.ConvertUp(context.Background(), ver); err != nil { + if !test.wantErr { + t.Errorf("ConvertUp() = %v", err) + } + return + } + t.Logf("ConvertUp() = %#v", ver) + got := &Pipeline{} + if err := got.ConvertDown(context.Background(), ver); err != nil { + t.Errorf("ConvertDown() = %v", err) + } + t.Logf("ConvertDown() = %#v", got) + if diff := cmp.Diff(test.in, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} diff --git a/pkg/apis/pipeline/v1alpha1/pipeline_validation_test.go b/pkg/apis/pipeline/v1alpha1/pipeline_validation_test.go index 0cef1fee166..4ccb37b37a0 100644 --- a/pkg/apis/pipeline/v1alpha1/pipeline_validation_test.go +++ b/pkg/apis/pipeline/v1alpha1/pipeline_validation_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" tb "github.com/tektoncd/pipeline/test/builder" corev1 "k8s.io/api/core/v1" ) @@ -84,10 +85,12 @@ func TestPipeline_Validate(t *testing.T) { name: "pipeline spec with taskref and taskspec", p: tb.Pipeline("pipeline", "namespace", tb.PipelineSpec( tb.PipelineTask("foo", "foo-task", tb.PipelineTaskSpec(&v1alpha1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "foo", - Image: "bar", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "foo", + Image: "bar", + }}}, + }, }, )))), failureExpected: true, @@ -101,10 +104,12 @@ func TestPipeline_Validate(t *testing.T) { name: "pipeline spec valid taskspec", p: tb.Pipeline("pipeline", "namespace", tb.PipelineSpec( tb.PipelineTask("", "", tb.PipelineTaskSpec(&v1alpha1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "foo", - Image: "bar", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "foo", + Image: "bar", + }}}, + }, }, )))), failureExpected: false, diff --git a/pkg/apis/pipeline/v1alpha1/resource_types_test.go b/pkg/apis/pipeline/v1alpha1/resource_types_test.go index ef4449de0c3..1623e30ea65 100644 --- a/pkg/apis/pipeline/v1alpha1/resource_types_test.go +++ b/pkg/apis/pipeline/v1alpha1/resource_types_test.go @@ -18,6 +18,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" corev1 "k8s.io/api/core/v1" ) @@ -69,11 +70,11 @@ func TestApplyTaskModifier(t *testing.T) { ts: v1alpha1.TaskSpec{}, }, { name: "identical volume already added", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ // Trying to add the same Volume that has already been added shouldn't be an error // and it should not be added twice Volumes: []corev1.Volume{volume}, - }, + }}, }} for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { @@ -81,7 +82,7 @@ func TestApplyTaskModifier(t *testing.T) { t.Fatalf("Did not expect error modifying TaskSpec but got %v", err) } - expectedTaskSpec := v1alpha1.TaskSpec{ + expectedTaskSpec := v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{ Container: prependStep, }, { @@ -90,7 +91,7 @@ func TestApplyTaskModifier(t *testing.T) { Volumes: []corev1.Volume{ volume, }, - } + }} if d := cmp.Diff(expectedTaskSpec, tc.ts); d != "" { t.Errorf("TaskSpec was not modified as expected (-want, +got): %s", d) @@ -105,34 +106,34 @@ func TestApplyTaskModifier_AlreadyAdded(t *testing.T) { ts v1alpha1.TaskSpec }{{ name: "prepend already added", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: prependStep}}, - }, + }}, }, { name: "append already added", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: appendStep}}, - }, + }}, }, { name: "both steps already added", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: prependStep}, {Container: appendStep}}, - }, + }}, }, { name: "both steps already added reverse order", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: appendStep}, {Container: prependStep}}, - }, + }}, }, { name: "volume with same name but diff content already added", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Volumes: []corev1.Volume{{ Name: "magic-volume", VolumeSource: corev1.VolumeSource{ EmptyDir: &corev1.EmptyDirVolumeSource{}, }, }}, - }, + }}, }} for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { diff --git a/pkg/apis/pipeline/v1alpha1/task_conversion.go b/pkg/apis/pipeline/v1alpha1/task_conversion.go new file mode 100644 index 00000000000..f614b75938b --- /dev/null +++ b/pkg/apis/pipeline/v1alpha1/task_conversion.go @@ -0,0 +1,124 @@ +/* +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. +*/ + +// nolint: golint +package v1alpha1 + +import ( + "context" + "fmt" + + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" + "knative.dev/pkg/apis" +) + +var _ apis.Convertible = (*Task)(nil) + +// ConvertUp implements api.Convertible +func (source *Task) ConvertUp(ctx context.Context, obj apis.Convertible) error { + switch sink := obj.(type) { + case *v1alpha2.Task: + sink.ObjectMeta = source.ObjectMeta + return source.Spec.ConvertUp(ctx, &sink.Spec) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +func (source *TaskSpec) ConvertUp(ctx context.Context, sink *v1alpha2.TaskSpec) error { + sink.Steps = source.Steps + sink.Volumes = source.Volumes + sink.StepTemplate = source.StepTemplate + sink.Sidecars = source.Sidecars + sink.Workspaces = source.Workspaces + sink.Results = source.Results + sink.Resources = source.Resources + sink.Params = source.Params + if source.Inputs != nil { + if len(source.Inputs.Params) > 0 && len(source.Params) > 0 { + // This shouldn't happen as it shouldn't pass validation + return apis.ErrMultipleOneOf("inputs.params", "params") + } + if len(source.Inputs.Params) > 0 { + sink.Params = make([]v1alpha2.ParamSpec, len(source.Inputs.Params)) + for i, param := range source.Inputs.Params { + sink.Params[i] = *param.DeepCopy() + } + } + if len(source.Inputs.Resources) > 0 { + if sink.Resources == nil { + sink.Resources = &v1alpha2.TaskResources{} + } + if len(source.Inputs.Resources) > 0 && source.Resources != nil && len(source.Resources.Inputs) > 0 { + // This shouldn't happen as it shouldn't pass validation but just in case + return apis.ErrMultipleOneOf("inputs.resources", "resources.inputs") + } + sink.Resources.Inputs = make([]v1alpha2.TaskResource, len(source.Inputs.Resources)) + for i, resource := range source.Inputs.Resources { + sink.Resources.Inputs[i] = v1alpha2.TaskResource{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: resource.Name, + Type: resource.Type, + Description: resource.Description, + TargetPath: resource.TargetPath, + Optional: resource.Optional, + }} + } + } + } + if source.Outputs != nil && len(source.Outputs.Resources) > 0 { + if sink.Resources == nil { + sink.Resources = &v1alpha2.TaskResources{} + } + if len(source.Outputs.Resources) > 0 && source.Resources != nil && len(source.Resources.Outputs) > 0 { + // This shouldn't happen as it shouldn't pass validation but just in case + return apis.ErrMultipleOneOf("outputs.resources", "resources.outputs") + } + sink.Resources.Outputs = make([]v1alpha2.TaskResource, len(source.Outputs.Resources)) + for i, resource := range source.Outputs.Resources { + sink.Resources.Outputs[i] = v1alpha2.TaskResource{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: resource.Name, + Type: resource.Type, + Description: resource.Description, + TargetPath: resource.TargetPath, + Optional: resource.Optional, + }} + } + } + return nil +} + +// ConvertDown implements api.Convertible +func (sink *Task) ConvertDown(ctx context.Context, obj apis.Convertible) error { + switch source := obj.(type) { + case *v1alpha2.Task: + sink.ObjectMeta = source.ObjectMeta + return sink.Spec.ConvertDown(ctx, &source.Spec) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +func (sink *TaskSpec) ConvertDown(ctx context.Context, source *v1alpha2.TaskSpec) error { + sink.Steps = source.Steps + sink.Volumes = source.Volumes + sink.StepTemplate = source.StepTemplate + sink.Sidecars = source.Sidecars + sink.Workspaces = source.Workspaces + sink.Results = source.Results + sink.Params = source.Params + sink.Resources = source.Resources + return nil +} diff --git a/pkg/apis/pipeline/v1alpha1/task_conversion_test.go b/pkg/apis/pipeline/v1alpha1/task_conversion_test.go new file mode 100644 index 00000000000..35a9d971825 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha1/task_conversion_test.go @@ -0,0 +1,321 @@ +/* +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 v1alpha1 + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" + resource "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/apis" +) + +func TestTaskConversionBadType(t *testing.T) { + good, bad := &Task{}, &Pipeline{} + + if err := good.ConvertUp(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } + + if err := good.ConvertDown(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } +} + +func TestTaskConversion(t *testing.T) { + versions := []apis.Convertible{&v1alpha2.Task{}} + + tests := []struct { + name string + in *Task + wantErr bool + }{{ + name: "simple conversion", + in: &Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha2.Step{{Container: corev1.Container{ + Image: "foo", + }}}, + Volumes: []corev1.Volume{{}}, + Params: []v1alpha2.ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + Outputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + }, + }, { + name: "deprecated and non deprecated inputs", + in: &Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + Inputs: &Inputs{ + Resources: []TaskResource{{ResourceDeclaration: ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + wantErr: true, + }, { + name: "deprecated and non deprecated inputs", + in: &Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Params: []v1alpha2.ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + }, + Inputs: &Inputs{ + Params: []ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + }, + }, + }, + wantErr: true, + }, { + name: "deprecated and non deprecated outputs", + in: &Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + Outputs: &Outputs{ + Resources: []TaskResource{{ResourceDeclaration: ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + wantErr: true, + }} + + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := test.in.ConvertUp(context.Background(), ver); err != nil { + if !test.wantErr { + t.Errorf("ConvertUp() = %v", err) + } + return + } + t.Logf("ConvertUp() = %#v", ver) + got := &Task{} + if err := got.ConvertDown(context.Background(), ver); err != nil { + t.Errorf("ConvertDown() = %v", err) + } + t.Logf("ConvertDown() = %#v", got) + if diff := cmp.Diff(test.in, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} + +func TestTaskConversionFromDeprecated(t *testing.T) { + versions := []apis.Convertible{&v1alpha2.Task{}} + tests := []struct { + name string + in *Task + want *Task + badField string + }{{ + name: "inputs params", + in: &Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + Inputs: &Inputs{ + Params: []ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + }, + }, + }, + want: &Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Params: []v1alpha2.ParamSpec{{ + Name: "param-1", + Type: v1alpha2.ParamTypeString, + Description: "My first param", + }}, + }, + }, + }, + }, { + name: "inputs resource", + in: &Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + Inputs: &Inputs{ + Resources: []TaskResource{{ResourceDeclaration: ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + want: &Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + }, + }, { + name: "outputs resource", + in: &Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + Outputs: &Outputs{ + Resources: []TaskResource{{ResourceDeclaration: ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + want: &Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + }, + }, + }} + for _, test := range tests { + for _, version := range versions { + t.Run(test.name, func(t *testing.T) { + ver := version + if err := test.in.ConvertUp(context.Background(), ver); err != nil { + if test.badField != "" { + cce, ok := err.(*CannotConvertError) + if ok && cce.Field == test.badField { + return + } + } + t.Errorf("ConvertUp() = %v", err) + } + t.Logf("ConvertUp() = %#v", ver) + got := &Task{} + if err := got.ConvertDown(context.Background(), ver); err != nil { + t.Errorf("ConvertDown() = %v", err) + } + t.Logf("ConvertDown() = %#v", got) + if diff := cmp.Diff(test.want, got); diff != "" { + t.Errorf("roundtrip (-want, +got) = %v", diff) + } + }) + } + } +} diff --git a/pkg/apis/pipeline/v1alpha1/task_types.go b/pkg/apis/pipeline/v1alpha1/task_types.go index f0675718f62..544e6e0b77c 100644 --- a/pkg/apis/pipeline/v1alpha1/task_types.go +++ b/pkg/apis/pipeline/v1alpha1/task_types.go @@ -17,7 +17,6 @@ limitations under the License. package v1alpha1 import ( - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" @@ -46,6 +45,8 @@ func (t *Task) Copy() TaskInterface { // TaskSpec defines the desired state of Task. type TaskSpec struct { + v1alpha2.TaskSpec `json:",inline"` + // Inputs is an optional set of parameters and resources which must be // supplied by the user when a Task is executed by a TaskRun. // +optional @@ -54,28 +55,6 @@ type TaskSpec struct { // Task is run. // +optional Outputs *Outputs `json:"outputs,omitempty"` - - // Steps are the steps of the build; each step is run sequentially with the - // source mounted into /workspace. - Steps []Step `json:"steps,omitempty"` - - // Volumes is a collection of volumes that are available to mount into the - // steps of the build. - Volumes []corev1.Volume `json:"volumes,omitempty"` - - // StepTemplate can be used as the basis for all step containers within the - // Task, so that the steps inherit settings on the base container. - StepTemplate *corev1.Container `json:"stepTemplate,omitempty"` - - // Sidecars are run alongside the Task's step containers. They begin before - // the steps start and end after the steps complete. - Sidecars []Sidecar `json:"sidecars,omitempty"` - - // Workspaces are the volumes that this Task requires. - Workspaces []WorkspaceDeclaration `json:"workspaces,omitempty"` - - // Results are values that this Task can output - Results []TaskResult `json:"results,omitempty"` } // TaskResult used to describe the results of a task diff --git a/pkg/apis/pipeline/v1alpha1/task_validation.go b/pkg/apis/pipeline/v1alpha1/task_validation.go index 14d3ea69c2e..3209e8aceb6 100644 --- a/pkg/apis/pipeline/v1alpha1/task_validation.go +++ b/pkg/apis/pipeline/v1alpha1/task_validation.go @@ -65,6 +65,20 @@ func (ts *TaskSpec) Validate(ctx context.Context) *apis.FieldError { return err } + if ts.Inputs != nil { + if len(ts.Inputs.Params) > 0 && len(ts.Params) > 0 { + return apis.ErrMultipleOneOf("inputs.params", "params") + } + if ts.Resources != nil && len(ts.Resources.Inputs) > 0 && len(ts.Inputs.Resources) > 0 { + return apis.ErrMultipleOneOf("inputs.resources", "resources.inputs") + } + } + if ts.Outputs != nil { + if ts.Resources != nil && len(ts.Resources.Outputs) > 0 && len(ts.Outputs.Resources) > 0 { + return apis.ErrMultipleOneOf("outputs.resources", "resources.outputs") + } + } + // 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. diff --git a/pkg/apis/pipeline/v1alpha1/task_validation_test.go b/pkg/apis/pipeline/v1alpha1/task_validation_test.go index 32dc449ae3b..b4a37f4e335 100644 --- a/pkg/apis/pipeline/v1alpha1/task_validation_test.go +++ b/pkg/apis/pipeline/v1alpha1/task_validation_test.go @@ -23,6 +23,8 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" + resource "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1" "github.com/tektoncd/pipeline/test/builder" corev1 "k8s.io/api/core/v1" "knative.dev/pkg/apis" @@ -296,11 +298,13 @@ func TestTaskSpecValidate(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ts := &v1alpha1.TaskSpec{ - Inputs: tt.fields.Inputs, - Outputs: tt.fields.Outputs, - Steps: tt.fields.Steps, - StepTemplate: tt.fields.StepTemplate, - Workspaces: tt.fields.Workspaces, + TaskSpec: v1alpha2.TaskSpec{ + Steps: tt.fields.Steps, + StepTemplate: tt.fields.StepTemplate, + Workspaces: tt.fields.Workspaces, + }, + Inputs: tt.fields.Inputs, + Outputs: tt.fields.Outputs, } ctx := context.Background() ts.SetDefaults(ctx) @@ -319,6 +323,9 @@ func TestTaskSpecValidateError(t *testing.T) { Volumes []corev1.Volume StepTemplate *corev1.Container Workspaces []v1alpha1.WorkspaceDeclaration + // v1alpha2 + Params []v1alpha2.ParamSpec + Resources *v1alpha2.TaskResources } tests := []struct { name string @@ -864,16 +871,81 @@ func TestTaskSpecValidateError(t *testing.T) { Message: "workspace mount path \"/workspace/some-workspace\" must be unique", Paths: []string{"workspaces.mountpath"}, }, + }, { + name: "v1alpha2: params and deprecated inputs.params", + fields: fields{ + Steps: validSteps, + Params: []v1alpha2.ParamSpec{{ + Name: "param1", + Type: v1alpha2.ParamTypeString, + }}, + Inputs: &v1alpha1.Inputs{ + Params: []v1alpha1.ParamSpec{{ + Name: "param1", + Type: v1alpha2.ParamTypeString, + }}, + }, + }, + expectedError: apis.FieldError{ + Message: "expected exactly one, got both", + Paths: []string{"inputs.params", "params"}, + }, + }, { + name: "v1alpha2: resources.inputs and deprecated inputs.resource", + fields: fields{ + Steps: validSteps, + Resources: &v1alpha2.TaskResources{ + Inputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + Inputs: &v1alpha1.Inputs{ + Resources: []v1alpha1.TaskResource{{ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "input-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + expectedError: apis.FieldError{ + Message: "expected exactly one, got both", + Paths: []string{"inputs.resources", "resources.inputs"}, + }, + }, { + name: "v1alpha2: resources.outputs and deprecated outputs.resource", + fields: fields{ + Steps: validSteps, + Resources: &v1alpha2.TaskResources{ + Outputs: []v1alpha2.TaskResource{{ResourceDeclaration: v1alpha2.ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ResourceDeclaration: v1alpha1.ResourceDeclaration{ + Name: "output-1", + Type: resource.PipelineResourceTypeGit, + }}}, + }, + }, + expectedError: apis.FieldError{ + Message: "expected exactly one, got both", + Paths: []string{"outputs.resources", "resources.outputs"}, + }, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ts := &v1alpha1.TaskSpec{ - Inputs: tt.fields.Inputs, - Outputs: tt.fields.Outputs, - Steps: tt.fields.Steps, - Volumes: tt.fields.Volumes, - StepTemplate: tt.fields.StepTemplate, - Workspaces: tt.fields.Workspaces, + TaskSpec: v1alpha2.TaskSpec{ + Steps: tt.fields.Steps, + Volumes: tt.fields.Volumes, + StepTemplate: tt.fields.StepTemplate, + Workspaces: tt.fields.Workspaces, + Params: tt.fields.Params, + Resources: tt.fields.Resources, + }, + Inputs: tt.fields.Inputs, + Outputs: tt.fields.Outputs, } ctx := context.Background() ts.SetDefaults(ctx) diff --git a/pkg/apis/pipeline/v1alpha1/taskrun_validation_test.go b/pkg/apis/pipeline/v1alpha1/taskrun_validation_test.go index 557285fe0b2..7ca24ce0739 100644 --- a/pkg/apis/pipeline/v1alpha1/taskrun_validation_test.go +++ b/pkg/apis/pipeline/v1alpha1/taskrun_validation_test.go @@ -23,6 +23,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/test/builder" tb "github.com/tektoncd/pipeline/test/builder" corev1 "k8s.io/api/core/v1" @@ -122,12 +123,12 @@ func TestTaskRunSpec_Invalid(t *testing.T) { TaskRef: &v1alpha1.TaskRef{ Name: "taskrefname", }, - TaskSpec: &v1alpha1.TaskSpec{ + TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "mystep", Image: "myimage", }}}, - }, + }}, }, wantErr: apis.ErrDisallowedFields("spec.taskspec", "spec.taskref"), }, { @@ -142,12 +143,12 @@ func TestTaskRunSpec_Invalid(t *testing.T) { }, { name: "invalid taskspec", spec: v1alpha1.TaskRunSpec{ - TaskSpec: &v1alpha1.TaskSpec{ + TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "invalid-name-with-$weird-char*/%", Image: "myimage", }}}, - }, + }}, }, wantErr: &apis.FieldError{ Message: `invalid value "invalid-name-with-$weird-char*/%"`, @@ -172,23 +173,23 @@ func TestTaskRunSpec_Validate(t *testing.T) { }{{ name: "taskspec without a taskRef", spec: v1alpha1.TaskRunSpec{ - TaskSpec: &v1alpha1.TaskSpec{ + TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "mystep", Image: "myimage", }}}, - }, + }}, }, }, { name: "no timeout", spec: v1alpha1.TaskRunSpec{ Timeout: &metav1.Duration{Duration: 0}, - TaskSpec: &v1alpha1.TaskSpec{ + TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "mystep", Image: "myimage", }}}, - }, + }}, }, }} for _, ts := range tests { diff --git a/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go index 4065c6ae435..6821ae976bf 100644 --- a/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go @@ -87,6 +87,22 @@ 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 *CloudEventDelivery) DeepCopyInto(out *CloudEventDelivery) { *out = *in @@ -1291,6 +1307,7 @@ func (in *TaskRunStatusFields) DeepCopy() *TaskRunStatusFields { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TaskSpec) DeepCopyInto(out *TaskSpec) { *out = *in + in.TaskSpec.DeepCopyInto(&out.TaskSpec) if in.Inputs != nil { in, out := &in.Inputs, &out.Inputs *out = new(Inputs) @@ -1301,42 +1318,6 @@ func (in *TaskSpec) DeepCopyInto(out *TaskSpec) { *out = new(Outputs) (*in).DeepCopyInto(*out) } - if in.Steps != nil { - in, out := &in.Steps, &out.Steps - *out = make([]v1alpha2.Step, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes - *out = make([]v1.Volume, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.StepTemplate != nil { - in, out := &in.StepTemplate, &out.StepTemplate - *out = new(v1.Container) - (*in).DeepCopyInto(*out) - } - if in.Sidecars != nil { - in, out := &in.Sidecars, &out.Sidecars - *out = make([]v1alpha2.Step, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Workspaces != nil { - in, out := &in.Workspaces, &out.Workspaces - *out = make([]v1alpha2.WorkspaceDeclaration, len(*in)) - copy(*out, *in) - } - if in.Results != nil { - in, out := &in.Results, &out.Results - *out = make([]v1alpha2.TaskResult, len(*in)) - copy(*out, *in) - } return } diff --git a/pkg/apis/pipeline/v1alpha2/cluster_task_conversion.go b/pkg/apis/pipeline/v1alpha2/cluster_task_conversion.go new file mode 100644 index 00000000000..c7a96c3c725 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha2/cluster_task_conversion.go @@ -0,0 +1,37 @@ +/* +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. +*/ + +// nolint: golint +package v1alpha2 + +import ( + "context" + "fmt" + + "knative.dev/pkg/apis" +) + +var _ apis.Convertible = (*ClusterTask)(nil) + +// ConvertUp implements api.Convertible +func (source *ClusterTask) ConvertUp(ctx context.Context, sink apis.Convertible) error { + return fmt.Errorf("v1alpha2 is the highest known version, got: %T", sink) +} + +// ConvertDown implements api.Convertible +func (sink *ClusterTask) ConvertDown(ctx context.Context, source apis.Convertible) error { + return fmt.Errorf("v1alpha2 is the highest know version, got: %T", source) +} diff --git a/pkg/apis/pipeline/v1alpha2/cluster_task_conversion_test.go b/pkg/apis/pipeline/v1alpha2/cluster_task_conversion_test.go new file mode 100644 index 00000000000..2c7c0acfc88 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha2/cluster_task_conversion_test.go @@ -0,0 +1,34 @@ +/* +Copyright 2020 The Tetkon 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 ( + "context" + "testing" +) + +func TestClusterTaskConversionBadType(t *testing.T) { + good, bad := &ClusterTask{}, &Pipeline{} + + if err := good.ConvertUp(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } + + if err := good.ConvertDown(context.Background(), bad); err == nil { + t.Errorf("ConvertDown() = %#v, wanted error", good) + } +} diff --git a/pkg/apis/pipeline/v1alpha2/pipeline_conversion.go b/pkg/apis/pipeline/v1alpha2/pipeline_conversion.go new file mode 100644 index 00000000000..658ecdb213c --- /dev/null +++ b/pkg/apis/pipeline/v1alpha2/pipeline_conversion.go @@ -0,0 +1,36 @@ +/* +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. +*/ + +// nolint: golint +package v1alpha2 + +import ( + "context" + "fmt" + + "knative.dev/pkg/apis" +) + +var _ apis.Convertible = (*Pipeline)(nil) + +func (source *Pipeline) ConvertUp(ctx context.Context, sink apis.Convertible) error { + return fmt.Errorf("v1alpha2 is the highest known version, got: %T", sink) +} + +// ConvertDown implements api.Convertible +func (sink *Pipeline) ConvertDown(ctx context.Context, source apis.Convertible) error { + return fmt.Errorf("v1alpha2 is the highest know version, got: %T", source) +} diff --git a/pkg/apis/pipeline/v1alpha2/pipeline_conversion_test.go b/pkg/apis/pipeline/v1alpha2/pipeline_conversion_test.go new file mode 100644 index 00000000000..d24db7ba3a0 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha2/pipeline_conversion_test.go @@ -0,0 +1,34 @@ +/* +Copyright 2020 The Tetkon 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 ( + "context" + "testing" +) + +func TestPipelineConversionBadType(t *testing.T) { + good, bad := &Pipeline{}, &Task{} + + if err := good.ConvertUp(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } + + if err := good.ConvertDown(context.Background(), bad); err == nil { + t.Errorf("ConvertDown() = %#v, wanted error", good) + } +} diff --git a/pkg/apis/pipeline/v1alpha2/pipeline_types.go b/pkg/apis/pipeline/v1alpha2/pipeline_types.go index 51ecca37bbe..d4154c2245f 100644 --- a/pkg/apis/pipeline/v1alpha2/pipeline_types.go +++ b/pkg/apis/pipeline/v1alpha2/pipeline_types.go @@ -36,19 +36,6 @@ type Pipeline struct { // Spec holds the desired state of the Pipeline from the client // +optional Spec PipelineSpec `json:"spec"` - - // Status is deprecated. - // It usually is used to communicate the observed state of the Pipeline from - // the controller, but was unused as there is no controller for Pipeline. - // +optional - Status *PipelineStatus `json:"status,omitempty"` -} - -// PipelineStatus does not contain anything because Pipelines on their own -// do not have a status, they just hold data which is later used by a -// PipelineRun. -// Deprecated -type PipelineStatus struct { } func (p *Pipeline) PipelineMetadata() metav1.ObjectMeta { diff --git a/pkg/apis/pipeline/v1alpha2/task_conversion.go b/pkg/apis/pipeline/v1alpha2/task_conversion.go new file mode 100644 index 00000000000..775a2295165 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha2/task_conversion.go @@ -0,0 +1,37 @@ +/* +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. +*/ + +// nolint: golint +package v1alpha2 + +import ( + "context" + "fmt" + + "knative.dev/pkg/apis" +) + +var _ apis.Convertible = (*Task)(nil) + +// ConvertUp implements api.Convertible +func (source *Task) ConvertUp(ctx context.Context, sink apis.Convertible) error { + return fmt.Errorf("v1alpha2 is the highest known version, got: %T", sink) +} + +// ConvertDown implements api.Convertible +func (sink *Task) ConvertDown(ctx context.Context, source apis.Convertible) error { + return fmt.Errorf("v1alpha2 is the highest know version, got: %T", source) +} diff --git a/pkg/apis/pipeline/v1alpha2/task_conversion_test.go b/pkg/apis/pipeline/v1alpha2/task_conversion_test.go new file mode 100644 index 00000000000..947f795148e --- /dev/null +++ b/pkg/apis/pipeline/v1alpha2/task_conversion_test.go @@ -0,0 +1,34 @@ +/* +Copyright 2020 The Tetkon 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 ( + "context" + "testing" +) + +func TestTaskConversionBadType(t *testing.T) { + good, bad := &Task{}, &Pipeline{} + + if err := good.ConvertUp(context.Background(), bad); err == nil { + t.Errorf("ConvertUp() = %#v, wanted error", bad) + } + + if err := good.ConvertDown(context.Background(), bad); err == nil { + t.Errorf("ConvertDown() = %#v, wanted error", good) + } +} diff --git a/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go index 9f86545b13d..70511c0252b 100644 --- a/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1alpha2/zz_generated.deepcopy.go @@ -270,11 +270,6 @@ func (in *Pipeline) DeepCopyInto(out *Pipeline) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) - if in.Status != nil { - in, out := &in.Status, &out.Status - *out = new(PipelineStatus) - **out = **in - } return } @@ -713,22 +708,6 @@ func (in *PipelineSpec) DeepCopy() *PipelineSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PipelineStatus) DeepCopyInto(out *PipelineStatus) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PipelineStatus. -func (in *PipelineStatus) DeepCopy() *PipelineStatus { - if in == nil { - return nil - } - out := new(PipelineStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PipelineTask) DeepCopyInto(out *PipelineTask) { *out = *in diff --git a/pkg/pod/pod_test.go b/pkg/pod/pod_test.go index 1d2ec383380..942c4a2e700 100644 --- a/pkg/pod/pod_test.go +++ b/pkg/pod/pod_test.go @@ -25,6 +25,7 @@ import ( "github.com/google/go-cmp/cmp" "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/test/names" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" @@ -73,13 +74,13 @@ func TestMakePod(t *testing.T) { wantAnnotations map[string]string }{{ desc: "simple", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. }}}, - }, + }}, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit}, @@ -109,13 +110,13 @@ func TestMakePod(t *testing.T) { }, }, { desc: "with service account", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. }}}, - }, + }}, trs: v1alpha1.TaskRunSpec{ ServiceAccountName: "service-account", }, @@ -163,13 +164,13 @@ func TestMakePod(t *testing.T) { }, }, { desc: "with-pod-template", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. }}}, - }, + }}, trs: v1alpha1.TaskRunSpec{ PodTemplate: &v1alpha1.PodTemplate{ SecurityContext: &corev1.PodSecurityContext{ @@ -231,13 +232,13 @@ func TestMakePod(t *testing.T) { }, }, { desc: "very long step name", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "a-very-very-long-character-step-name-to-trigger-max-len----and-invalid-characters", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. }}}, - }, + }}, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit}, @@ -267,13 +268,13 @@ func TestMakePod(t *testing.T) { }, }, { desc: "step name ends with non alphanumeric", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "ends-with-invalid-%%__$$", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. }}}, - }, + }}, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit}, @@ -303,14 +304,14 @@ func TestMakePod(t *testing.T) { }, }, { desc: "workingDir in workspace", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. WorkingDir: filepath.Join(pipeline.WorkspaceDir, "test"), }}}, - }, + }}, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{{ @@ -349,21 +350,19 @@ func TestMakePod(t *testing.T) { }, }, { desc: "sidecar container", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "primary-name", Image: "primary-image", Command: []string{"cmd"}, // avoid entrypoint lookup. }}}, - Sidecars: []v1alpha1.Sidecar{ - { - Container: corev1.Container{ - Name: "sc-name", - Image: "sidecar-image", - }, + Sidecars: []v1alpha1.Sidecar{{ + Container: corev1.Container{ + Name: "sc-name", + Image: "sidecar-image", }, - }, - }, + }}, + }}, wantAnnotations: map[string]string{}, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, @@ -400,7 +399,7 @@ func TestMakePod(t *testing.T) { }, }, { desc: "sidecar container with script", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "primary-name", Image: "primary-image", @@ -412,9 +411,8 @@ func TestMakePod(t *testing.T) { Image: "sidecar-image", }, Script: "#!/bin/sh\necho hello from sidecar", - }, - }, - }, + }}, + }}, wantAnnotations: map[string]string{}, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, @@ -468,7 +466,7 @@ sidecar-script-heredoc-randomly-generated-mz4c7 }, }, { desc: "resource request", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. @@ -488,7 +486,7 @@ sidecar-script-heredoc-randomly-generated-mz4c7 }, }, }}}, - }, + }}, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit}, @@ -550,7 +548,7 @@ sidecar-script-heredoc-randomly-generated-mz4c7 }, }, { desc: "step with script and stepTemplate", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ StepTemplate: &corev1.Container{ Env: []corev1.EnvVar{{Name: "FOO", Value: "bar"}}, Args: []string{"template", "args"}, @@ -576,7 +574,7 @@ print("Hello from Python")`, Command: []string{"regular", "command"}, }, }}, - }, + }}, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{{ diff --git a/pkg/reconciler/pipelinerun/pipelinerun_test.go b/pkg/reconciler/pipelinerun/pipelinerun_test.go index c25e9c6dd82..702e9cbacbd 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun_test.go +++ b/pkg/reconciler/pipelinerun/pipelinerun_test.go @@ -27,6 +27,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "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/reconciler/pipelinerun/resources" taskrunresources "github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources" ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" @@ -295,11 +296,11 @@ func TestReconcile_PipelineSpecTaskSpec(t *testing.T) { ps := []*v1alpha1.Pipeline{ tb.Pipeline("test-pipeline", "foo", tb.PipelineSpec( - tb.PipelineTask("unit-test-task-spec", "", tb.PipelineTaskSpec(&v1alpha1.TaskSpec{ + tb.PipelineTask("unit-test-task-spec", "", tb.PipelineTaskSpec(&v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "mystep", Image: "myimage"}}}, - })), + }})), ), ), } diff --git a/pkg/reconciler/pipelinerun/resources/conditionresolution.go b/pkg/reconciler/pipelinerun/resources/conditionresolution.go index fbd2191236c..48445928ab7 100644 --- a/pkg/reconciler/pipelinerun/resources/conditionresolution.go +++ b/pkg/reconciler/pipelinerun/resources/conditionresolution.go @@ -22,6 +22,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/pipeline" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" corev1 "k8s.io/api/core/v1" ) @@ -96,7 +97,9 @@ func (rcc *ResolvedConditionCheck) ConditionToTaskSpec() (*v1alpha1.TaskSpec, er } t := &v1alpha1.TaskSpec{ - Steps: []v1alpha1.Step{rcc.Condition.Spec.Check}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{rcc.Condition.Spec.Check}, + }, } t.Inputs = &v1alpha1.Inputs{ diff --git a/pkg/reconciler/pipelinerun/resources/conditionresolution_test.go b/pkg/reconciler/pipelinerun/resources/conditionresolution_test.go index b1822ad4b0c..80aec7f805d 100644 --- a/pkg/reconciler/pipelinerun/resources/conditionresolution_test.go +++ b/pkg/reconciler/pipelinerun/resources/conditionresolution_test.go @@ -22,6 +22,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" tb "github.com/tektoncd/pipeline/test/builder" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -195,10 +196,12 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { tb.ConditionSpecCheck("foo", "ubuntu"), )), want: v1alpha1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "foo", - Image: "ubuntu", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "foo", + Image: "ubuntu", + }}}, + }, Inputs: &v1alpha1.Inputs{}, }, }, { @@ -207,10 +210,12 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { tb.ConditionSpecCheck("", "ubuntu"), )), want: v1alpha1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "condition-check-bar", - Image: "ubuntu", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "condition-check-bar", + Image: "ubuntu", + }}}, + }, Inputs: &v1alpha1.Inputs{}, }, }, { @@ -222,6 +227,13 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { tb.ConditionParamSpec("img", v1alpha1.ParamTypeString), )), want: v1alpha1.TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "$(inputs.params.name)", + Image: "$(inputs.params.img)", + WorkingDir: "$(params.not.replaced)", + }}}, + }, Inputs: &v1alpha1.Inputs{ Params: []v1alpha1.ParamSpec{{ Name: "name", @@ -231,11 +243,6 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { Type: "string", }}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "$(inputs.params.name)", - Image: "$(inputs.params.img)", - WorkingDir: "$(params.not.replaced)", - }}}, }, }, { name: "with-resources", @@ -251,6 +258,13 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { )), }, want: v1alpha1.TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "name", + Image: "ubuntu", + Args: []string{"master"}, + }}}, + }, Inputs: &v1alpha1.Inputs{ Resources: []v1alpha1.TaskResource{{ ResourceDeclaration: v1alpha1.ResourceDeclaration{ @@ -258,11 +272,6 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { Type: "git", }}}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "name", - Image: "ubuntu", - Args: []string{"master"}, - }}}, }, }} diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go index 8469c841f25..acfc06c4cc5 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go @@ -24,6 +24,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" "github.com/tektoncd/pipeline/pkg/reconciler/pipeline/dag" "github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources" tb "github.com/tektoncd/pipeline/test/builder" @@ -91,22 +92,22 @@ var task = &v1alpha1.Task{ ObjectMeta: metav1.ObjectMeta{ Name: "task", }, - Spec: v1alpha1.TaskSpec{ + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "step1", }}}, - }, + }}, } var clustertask = &v1alpha1.ClusterTask{ ObjectMeta: metav1.ObjectMeta{ Name: "clustertask", }, - Spec: v1alpha1.TaskSpec{ + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "step1", }}}, - }, + }}, } var trs = []v1alpha1.TaskRun{{ @@ -457,6 +458,11 @@ var taskWithOptionalResources = &v1alpha1.Task{ Name: "task", }, Spec: v1alpha1.TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "step1", + }}}, + }, Inputs: &v1alpha1.Inputs{ Resources: []v1alpha1.TaskResource{{ResourceDeclaration: v1alpha1.ResourceDeclaration{ Name: "optional-input", @@ -478,9 +484,6 @@ var taskWithOptionalResources = &v1alpha1.Task{ Optional: false, }}}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "step1", - }}}, }, } @@ -1151,11 +1154,11 @@ func TestResolvePipelineRun(t *testing.T) { tb.PipelineTaskOutputResource("output1", "git-resource"), ), tb.PipelineTask("mytask4", "", - tb.PipelineTaskSpec(&v1alpha1.TaskSpec{ + tb.PipelineTaskSpec(&v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "step1", }}}, - })), + }})), )) r := &v1alpha1.PipelineResource{ diff --git a/pkg/reconciler/taskrun/resources/apply_test.go b/pkg/reconciler/taskrun/resources/apply_test.go index c5ff0bef4ed..b0e8dbf339b 100644 --- a/pkg/reconciler/taskrun/resources/apply_test.go +++ b/pkg/reconciler/taskrun/resources/apply_test.go @@ -22,6 +22,7 @@ import ( "github.com/google/go-cmp/cmp" "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/reconciler/taskrun/resources" "github.com/tektoncd/pipeline/test/builder" "github.com/tektoncd/pipeline/test/names" @@ -44,6 +45,121 @@ var ( } simpleTaskSpec = &v1alpha1.TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Sidecars: []v1alpha1.Sidecar{{ + Container: corev1.Container{ + Name: "foo", + Image: "$(inputs.params.myimage)", + Env: []corev1.EnvVar{{ + Name: "foo", + Value: "$(inputs.params.FOO)", + }}, + }, + }}, + StepTemplate: &corev1.Container{ + Env: []corev1.EnvVar{{ + Name: "template-var", + Value: "$(inputs.params.FOO)", + }}, + }, + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "foo", + Image: "$(inputs.params.myimage)", + }}, {Container: corev1.Container{ + Name: "baz", + Image: "bat", + WorkingDir: "$(inputs.resources.workspace.path)", + Args: []string{"$(inputs.resources.workspace.url)"}, + }}, {Container: corev1.Container{ + Name: "qux", + Image: "$(inputs.params.something)", + Args: []string{"$(outputs.resources.imageToUse.url)"}, + }}, {Container: corev1.Container{ + Name: "foo", + Image: "$(inputs.params.myimage)", + }}, {Container: corev1.Container{ + Name: "baz", + Image: "$(inputs.params.somethingelse)", + WorkingDir: "$(inputs.resources.workspace.path)", + Args: []string{"$(inputs.resources.workspace.url)"}, + }}, {Container: corev1.Container{ + Name: "qux", + Image: "quux", + Args: []string{"$(outputs.resources.imageToUse.url)"}, + }}, {Container: corev1.Container{ + Name: "foo", + Image: "busybox:$(inputs.params.FOO)", + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(inputs.params.FOO)", + MountPath: "path/to/$(inputs.params.FOO)", + SubPath: "sub/$(inputs.params.FOO)/path", + }}, + }}, {Container: corev1.Container{ + Name: "foo", + Image: "busybox:$(inputs.params.FOO)", + Env: []corev1.EnvVar{{ + Name: "foo", + Value: "value-$(inputs.params.FOO)", + }, { + Name: "bar", + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: "config-$(inputs.params.FOO)"}, + Key: "config-key-$(inputs.params.FOO)", + }, + }, + }, { + Name: "baz", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{Name: "secret-$(inputs.params.FOO)"}, + Key: "secret-key-$(inputs.params.FOO)", + }, + }, + }}, + EnvFrom: []corev1.EnvFromSource{{ + Prefix: "prefix-0-$(inputs.params.FOO)", + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: "config-$(inputs.params.FOO)"}, + }, + }, { + Prefix: "prefix-1-$(inputs.params.FOO)", + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: "secret-$(inputs.params.FOO)"}, + }, + }}, + }}, {Container: corev1.Container{ + Name: "outputs-resources-path-ab", + Image: "$(outputs.resources.imageToUse-ab.path)", + }}, {Container: corev1.Container{ + Name: "outputs-resources-path-re", + Image: "$(outputs.resources.imageToUse-re.path)", + }}}, + Volumes: []corev1.Volume{{ + Name: "$(inputs.params.FOO)", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(inputs.params.FOO)", + }, + }, + }, + }, { + Name: "some-secret", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "$(inputs.params.FOO)", + }, + }, + }, { + Name: "some-pvc", + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: "$(inputs.params.FOO)", + }, + }, + }}, + }, Inputs: &v1alpha1.Inputs{ Resources: []v1alpha1.TaskResource{{ ResourceDeclaration: v1alpha1.ResourceDeclaration{ @@ -64,122 +180,16 @@ var ( }, }}, }, - Sidecars: []v1alpha1.Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Image: "$(inputs.params.myimage)", - Env: []corev1.EnvVar{{ - Name: "foo", - Value: "$(inputs.params.FOO)", - }}, - }, - }}, - StepTemplate: &corev1.Container{ - Env: []corev1.EnvVar{{ - Name: "template-var", - Value: "$(inputs.params.FOO)", - }}, - }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "foo", - Image: "$(inputs.params.myimage)", - }}, {Container: corev1.Container{ - Name: "baz", - Image: "bat", - WorkingDir: "$(inputs.resources.workspace.path)", - Args: []string{"$(inputs.resources.workspace.url)"}, - }}, {Container: corev1.Container{ - Name: "qux", - Image: "$(inputs.params.something)", - Args: []string{"$(outputs.resources.imageToUse.url)"}, - }}, {Container: corev1.Container{ - Name: "foo", - Image: "$(inputs.params.myimage)", - }}, {Container: corev1.Container{ - Name: "baz", - Image: "$(inputs.params.somethingelse)", - WorkingDir: "$(inputs.resources.workspace.path)", - Args: []string{"$(inputs.resources.workspace.url)"}, - }}, {Container: corev1.Container{ - Name: "qux", - Image: "quux", - Args: []string{"$(outputs.resources.imageToUse.url)"}, - }}, {Container: corev1.Container{ - Name: "foo", - Image: "busybox:$(inputs.params.FOO)", - VolumeMounts: []corev1.VolumeMount{{ - Name: "$(inputs.params.FOO)", - MountPath: "path/to/$(inputs.params.FOO)", - SubPath: "sub/$(inputs.params.FOO)/path", - }}, - }}, {Container: corev1.Container{ - Name: "foo", - Image: "busybox:$(inputs.params.FOO)", - Env: []corev1.EnvVar{{ - Name: "foo", - Value: "value-$(inputs.params.FOO)", - }, { - Name: "bar", - ValueFrom: &corev1.EnvVarSource{ - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "config-$(inputs.params.FOO)"}, - Key: "config-key-$(inputs.params.FOO)", - }, - }, - }, { - Name: "baz", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "secret-$(inputs.params.FOO)"}, - Key: "secret-key-$(inputs.params.FOO)", - }, - }, - }}, - EnvFrom: []corev1.EnvFromSource{{ - Prefix: "prefix-0-$(inputs.params.FOO)", - ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{Name: "config-$(inputs.params.FOO)"}, - }, - }, { - Prefix: "prefix-1-$(inputs.params.FOO)", - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{Name: "secret-$(inputs.params.FOO)"}, - }, - }}, - }}, {Container: corev1.Container{ - Name: "outputs-resources-path-ab", - Image: "$(outputs.resources.imageToUse-ab.path)", - }}, {Container: corev1.Container{ - Name: "outputs-resources-path-re", - Image: "$(outputs.resources.imageToUse-re.path)", - }}}, - Volumes: []corev1.Volume{{ - Name: "$(inputs.params.FOO)", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(inputs.params.FOO)", - }, - }, - }, - }, { - Name: "some-secret", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: "$(inputs.params.FOO)", - }, - }, - }, { - Name: "some-pvc", - VolumeSource: corev1.VolumeSource{ - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: "$(inputs.params.FOO)", - }, - }, - }}, } gcsTaskSpec = &v1alpha1.TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "foobar", + Image: "someImage", + Args: []string{"$(outputs.resources.bucket.path)"}, + }}}, + }, Outputs: &v1alpha1.Outputs{ Resources: []v1alpha1.TaskResource{{ ResourceDeclaration: v1alpha1.ResourceDeclaration{ @@ -187,14 +197,9 @@ var ( }, }}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "foobar", - Image: "someImage", - Args: []string{"$(outputs.resources.bucket.path)"}, - }}}, } - arrayParamTaskSpec = &v1alpha1.TaskSpec{ + arrayParamTaskSpec = &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "simple-image", Image: "some-image", @@ -204,9 +209,9 @@ var ( Command: []string{"echo"}, Args: []string{"first", "second", "$(inputs.params.array-param)", "last"}, }}}, - } + }} - arrayAndStringParamTaskSpec = &v1alpha1.TaskSpec{ + arrayAndStringParamTaskSpec = &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "simple-image", Image: "some-image", @@ -216,9 +221,9 @@ var ( Command: []string{"echo"}, Args: []string{"$(inputs.params.normal-param)", "second", "$(inputs.params.array-param)", "last"}, }}}, - } + }} - multipleArrayParamsTaskSpec = &v1alpha1.TaskSpec{ + multipleArrayParamsTaskSpec = &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "simple-image", Image: "some-image", @@ -228,9 +233,9 @@ var ( Command: []string{"cmd", "$(inputs.params.another-array-param)"}, Args: []string{"first", "second", "$(inputs.params.array-param)", "last"}, }}}, - } + }} - multipleArrayAndStringsParamsTaskSpec = &v1alpha1.TaskSpec{ + multipleArrayAndStringsParamsTaskSpec = &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "simple-image", Image: "image-$(inputs.params.string-param2)", @@ -240,7 +245,7 @@ var ( Command: []string{"cmd", "$(inputs.params.array-param1)"}, Args: []string{"$(inputs.params.array-param2)", "second", "$(inputs.params.array-param1)", "$(inputs.params.string-param1)", "last"}, }}}, - } + }} arrayTaskRun0Elements = &v1alpha1.TaskRun{ Spec: v1alpha1.TaskRunSpec{ @@ -614,7 +619,7 @@ func TestApplyResources(t *testing.T) { func TestApplyWorkspaces(t *testing.T) { names.TestingSeed() - ts := &v1alpha1.TaskSpec{ + ts := &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ StepTemplate: &corev1.Container{ Env: []corev1.EnvVar{{ Name: "template-var", @@ -677,9 +682,8 @@ func TestApplyWorkspaces(t *testing.T) { ClaimName: "$(workspaces.myws.volume)", }, }, - }, - }, - } + }}, + }} want := applyMutation(ts, func(spec *v1alpha1.TaskSpec) { spec.StepTemplate.Env[0].Value = "ws-9l9zj" @@ -726,7 +730,7 @@ func TestApplyWorkspaces(t *testing.T) { func TestTaskResults(t *testing.T) { names.TestingSeed() - ts := &v1alpha1.TaskSpec{ + ts := &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Results: []v1alpha1.TaskResult{{ Name: "current-date-unix-timestamp", Description: "The current date in unix timestamp format", @@ -748,7 +752,7 @@ func TestTaskResults(t *testing.T) { }, Script: "#!/usr/bin/env bash\ndate | tee $(results.current-date-human-readable.path)", }}, - } + }} want := applyMutation(ts, func(spec *v1alpha1.TaskSpec) { spec.Steps[0].Script = "#!/usr/bin/env bash\ndate +%s | tee /tekton/results/current-date-unix-timestamp" spec.Steps[0].Args[0] = "/tekton/results/current-date-unix-timestamp" diff --git a/pkg/reconciler/taskrun/resources/image_exporter_test.go b/pkg/reconciler/taskrun/resources/image_exporter_test.go index a6acd2efe12..e635973e1f9 100644 --- a/pkg/reconciler/taskrun/resources/image_exporter_test.go +++ b/pkg/reconciler/taskrun/resources/image_exporter_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/test/names" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -40,6 +41,11 @@ func TestAddOutputImageDigestExporter(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "step1", + }}}, + }, Inputs: &v1alpha1.Inputs{ Resources: []v1alpha1.TaskResource{{ ResourceDeclaration: v1alpha1.ResourceDeclaration{ @@ -55,9 +61,6 @@ func TestAddOutputImageDigestExporter(t *testing.T) { }, }}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "step1", - }}}, }, }, taskRun: &v1alpha1.TaskRun{ @@ -105,6 +108,13 @@ func TestAddOutputImageDigestExporter(t *testing.T) { Namespace: "marshmallow", }, Spec: v1alpha1.TaskSpec{ + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "step1", + }}, {Container: corev1.Container{ + Name: "step2", + }}}, + }, Inputs: &v1alpha1.Inputs{ Resources: []v1alpha1.TaskResource{{ ResourceDeclaration: v1alpha1.ResourceDeclaration{ @@ -120,11 +130,6 @@ func TestAddOutputImageDigestExporter(t *testing.T) { }, }}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "step1", - }}, {Container: corev1.Container{ - Name: "step2", - }}}, }, }, taskRun: &v1alpha1.TaskRun{ diff --git a/pkg/reconciler/taskrun/resources/input_resource_test.go b/pkg/reconciler/taskrun/resources/input_resource_test.go index 770aaac8410..ba55cc4501d 100644 --- a/pkg/reconciler/taskrun/resources/input_resource_test.go +++ b/pkg/reconciler/taskrun/resources/input_resource_test.go @@ -22,6 +22,7 @@ import ( "github.com/google/go-cmp/cmp" "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" "github.com/tektoncd/pipeline/pkg/logging" "github.com/tektoncd/pipeline/test/names" @@ -359,14 +360,16 @@ func TestAddResourceToTask(t *testing.T) { wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: gitInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "git-source-the-git-9l9zj", - Image: "override-with-git:latest", - Command: []string{"/ko-app/git-init"}, - Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "master", "-path", "/workspace/gitspace"}, - WorkingDir: "/workspace", - Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git"}}, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "git-source-the-git-9l9zj", + Image: "override-with-git:latest", + Command: []string{"/ko-app/git-init"}, + Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "master", "-path", "/workspace/gitspace"}, + WorkingDir: "/workspace", + Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git"}}, + }}}, + }, }, }, { desc: "simple with branch", @@ -395,14 +398,16 @@ func TestAddResourceToTask(t *testing.T) { wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: gitInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "git-source-the-git-with-branch-9l9zj", - Image: "override-with-git:latest", - Command: []string{"/ko-app/git-init"}, - Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/gitspace"}, - WorkingDir: "/workspace", - Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "git-source-the-git-with-branch-9l9zj", + Image: "override-with-git:latest", + Command: []string{"/ko-app/git-init"}, + Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/gitspace"}, + WorkingDir: "/workspace", + Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, + }}}, + }, }, }, { desc: "reuse git input resource and verify order", @@ -438,21 +443,23 @@ func TestAddResourceToTask(t *testing.T) { wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: multipleGitInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "git-source-the-git-with-branch-mz4c7", - Image: "override-with-git:latest", - Command: []string{"/ko-app/git-init"}, - Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/gitspace"}, - WorkingDir: "/workspace", - Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, - }}, {Container: corev1.Container{ - Name: "git-source-the-git-with-branch-9l9zj", - Image: "override-with-git:latest", - Command: []string{"/ko-app/git-init"}, - Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/git-duplicate-space"}, - WorkingDir: "/workspace", - Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "git-source-the-git-with-branch-mz4c7", + Image: "override-with-git:latest", + Command: []string{"/ko-app/git-init"}, + Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/gitspace"}, + WorkingDir: "/workspace", + Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, + }}, {Container: corev1.Container{ + Name: "git-source-the-git-with-branch-9l9zj", + Image: "override-with-git:latest", + Command: []string{"/ko-app/git-init"}, + Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/git-duplicate-space"}, + WorkingDir: "/workspace", + Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, + }}}, + }, }, }, { desc: "set revision to default value 1", @@ -481,14 +488,16 @@ func TestAddResourceToTask(t *testing.T) { wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: gitInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "git-source-the-git-9l9zj", - Image: "override-with-git:latest", - Command: []string{"/ko-app/git-init"}, - Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "master", "-path", "/workspace/gitspace"}, - WorkingDir: "/workspace", - Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git"}}, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "git-source-the-git-9l9zj", + Image: "override-with-git:latest", + Command: []string{"/ko-app/git-init"}, + Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "master", "-path", "/workspace/gitspace"}, + WorkingDir: "/workspace", + Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git"}}, + }}}, + }, }, }, { desc: "set revision to provdided branch", @@ -517,14 +526,16 @@ func TestAddResourceToTask(t *testing.T) { wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: gitInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "git-source-the-git-with-branch-9l9zj", - Image: "override-with-git:latest", - Command: []string{"/ko-app/git-init"}, - Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/gitspace"}, - WorkingDir: "/workspace", - Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "git-source-the-git-with-branch-9l9zj", + Image: "override-with-git:latest", + Command: []string{"/ko-app/git-init"}, + Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/gitspace"}, + WorkingDir: "/workspace", + Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, + }}}, + }, }, }, { desc: "git resource as input from previous task", @@ -555,22 +566,24 @@ func TestAddResourceToTask(t *testing.T) { wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: gitInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "create-dir-gitspace-mz4c7", - Image: "busybox", - Command: []string{"mkdir", "-p", "/workspace/gitspace"}, - }}, {Container: corev1.Container{ - Name: "source-copy-gitspace-9l9zj", - Image: "busybox", - Command: []string{"cp", "-r", "prev-task-path/.", "/workspace/gitspace"}, - VolumeMounts: []corev1.VolumeMount{{MountPath: "/pvc", Name: "pipelinerun-pvc"}}, - }}}, - Volumes: []corev1.Volume{{ - Name: "pipelinerun-pvc", - VolumeSource: corev1.VolumeSource{ - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: "pipelinerun-pvc"}, - }, - }}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "create-dir-gitspace-mz4c7", + Image: "busybox", + Command: []string{"mkdir", "-p", "/workspace/gitspace"}, + }}, {Container: corev1.Container{ + Name: "source-copy-gitspace-9l9zj", + Image: "busybox", + Command: []string{"cp", "-r", "prev-task-path/.", "/workspace/gitspace"}, + VolumeMounts: []corev1.VolumeMount{{MountPath: "/pvc", Name: "pipelinerun-pvc"}}, + }}}, + Volumes: []corev1.Volume{{ + Name: "pipelinerun-pvc", + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: "pipelinerun-pvc"}, + }, + }}, + }, }, }, { desc: "simple with sslVerify false", @@ -599,14 +612,16 @@ func TestAddResourceToTask(t *testing.T) { wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: gitInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "git-source-the-git-with-sslVerify-false-9l9zj", - Image: "override-with-git:latest", - Command: []string{"/ko-app/git-init"}, - Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/gitspace", "-sslVerify=false"}, - WorkingDir: "/workspace", - Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-sslVerify-false"}}, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "git-source-the-git-with-sslVerify-false-9l9zj", + Image: "override-with-git:latest", + Command: []string{"/ko-app/git-init"}, + Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/gitspace", "-sslVerify=false"}, + WorkingDir: "/workspace", + Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-sslVerify-false"}}, + }}}, + }, }, }, { desc: "storage resource as input with target path", @@ -632,23 +647,25 @@ func TestAddResourceToTask(t *testing.T) { wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: gcsInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "create-dir-storage1-9l9zj", - Image: "busybox", - Command: []string{"mkdir", "-p", "/workspace/gcs-dir"}, - }}, { - Script: `#!/usr/bin/env bash + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "create-dir-storage1-9l9zj", + Image: "busybox", + Command: []string{"mkdir", "-p", "/workspace/gcs-dir"}, + }}, { + Script: `#!/usr/bin/env bash if [[ "${GOOGLE_APPLICATION_CREDENTIALS}" != "" ]]; then echo GOOGLE_APPLICATION_CREDENTIALS is set, activating Service Account... gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} fi gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir `, - Container: corev1.Container{ - Name: "fetch-storage1-mz4c7", - Image: "google/cloud-sdk", - }, - }}, + Container: corev1.Container{ + Name: "fetch-storage1-mz4c7", + Image: "google/cloud-sdk", + }, + }}, + }, }, }, { desc: "storage resource as input from previous task", @@ -679,22 +696,24 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: gcsInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "create-dir-workspace-mz4c7", - Image: "busybox", - Command: []string{"mkdir", "-p", "/workspace/gcs-dir"}, - }}, {Container: corev1.Container{ - Name: "source-copy-workspace-9l9zj", - Image: "busybox", - Command: []string{"cp", "-r", "prev-task-path/.", "/workspace/gcs-dir"}, - VolumeMounts: []corev1.VolumeMount{{MountPath: "/pvc", Name: "pipelinerun-pvc"}}, - }}}, - Volumes: []corev1.Volume{{ - Name: "pipelinerun-pvc", - VolumeSource: corev1.VolumeSource{ - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: "pipelinerun-pvc"}, - }, - }}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "create-dir-workspace-mz4c7", + Image: "busybox", + Command: []string{"mkdir", "-p", "/workspace/gcs-dir"}, + }}, {Container: corev1.Container{ + Name: "source-copy-workspace-9l9zj", + Image: "busybox", + Command: []string{"cp", "-r", "prev-task-path/.", "/workspace/gcs-dir"}, + VolumeMounts: []corev1.VolumeMount{{MountPath: "/pvc", Name: "pipelinerun-pvc"}}, + }}}, + Volumes: []corev1.Volume{{ + Name: "pipelinerun-pvc", + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: "pipelinerun-pvc"}, + }, + }}, + }, }, }, { desc: "invalid gcs resource type name", @@ -794,14 +813,16 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: clusterInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "kubeconfig-9l9zj", - Image: "override-with-kubeconfig-writer:latest", - Command: []string{"/ko-app/kubeconfigwriter"}, - Args: []string{ - "-clusterConfig", `{"name":"cluster3","type":"cluster","url":"http://10.10.10.10","revision":"","username":"","password":"","namespace":"namespace1","token":"","Insecure":false,"cadata":"bXktY2EtY2VydAo=","secrets":null}`, - }, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "kubeconfig-9l9zj", + Image: "override-with-kubeconfig-writer:latest", + Command: []string{"/ko-app/kubeconfigwriter"}, + Args: []string{ + "-clusterConfig", `{"name":"cluster3","type":"cluster","url":"http://10.10.10.10","revision":"","username":"","password":"","namespace":"namespace1","token":"","Insecure":false,"cadata":"bXktY2EtY2VydAo=","secrets":null}`, + }, + }}}, + }, }, }, { desc: "cluster resource with secrets", @@ -838,25 +859,27 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: clusterInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "kubeconfig-9l9zj", - Image: "override-with-kubeconfig-writer:latest", - Command: []string{"/ko-app/kubeconfigwriter"}, - Args: []string{ - "-clusterConfig", `{"name":"cluster2","type":"cluster","url":"http://10.10.10.10","revision":"","username":"","password":"","namespace":"","token":"","Insecure":false,"cadata":null,"secrets":[{"fieldName":"cadata","secretKey":"cadatakey","secretName":"secret1"}]}`, - }, - Env: []corev1.EnvVar{{ - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "secret1", + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "kubeconfig-9l9zj", + Image: "override-with-kubeconfig-writer:latest", + Command: []string{"/ko-app/kubeconfigwriter"}, + Args: []string{ + "-clusterConfig", `{"name":"cluster2","type":"cluster","url":"http://10.10.10.10","revision":"","username":"","password":"","namespace":"","token":"","Insecure":false,"cadata":null,"secrets":[{"fieldName":"cadata","secretKey":"cadatakey","secretName":"secret1"}]}`, + }, + Env: []corev1.EnvVar{{ + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "secret1", + }, + Key: "cadatakey", }, - Key: "cadatakey", }, - }, - Name: "CADATA", - }}, - }}}, + Name: "CADATA", + }}, + }}}, + }, }, }, { desc: "optional git input resource", @@ -885,14 +908,16 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: optionalGitInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "git-source-the-git-with-branch-9l9zj", - Image: "override-with-git:latest", - Command: []string{"/ko-app/git-init"}, - Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/gitspace"}, - WorkingDir: "/workspace", - Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "git-source-the-git-with-branch-9l9zj", + Image: "override-with-git:latest", + Command: []string{"/ko-app/git-init"}, + Args: []string{"-url", "https://github.com/grafeas/kritis", "-revision", "branch", "-path", "/workspace/gitspace"}, + WorkingDir: "/workspace", + Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "the-git-with-branch"}}, + }}}, + }, }, }} { t.Run(c.desc, func(t *testing.T) { @@ -999,23 +1024,25 @@ func TestStorageInputResource(t *testing.T) { wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: gcsStorageInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "create-dir-gcs-input-resource-9l9zj", - Image: "busybox", - Command: []string{"mkdir", "-p", "/workspace/gcs-input-resource"}, - }}, { - Script: `#!/usr/bin/env bash + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "create-dir-gcs-input-resource-9l9zj", + Image: "busybox", + Command: []string{"mkdir", "-p", "/workspace/gcs-input-resource"}, + }}, { + Script: `#!/usr/bin/env bash if [[ "${GOOGLE_APPLICATION_CREDENTIALS}" != "" ]]; then echo GOOGLE_APPLICATION_CREDENTIALS is set, activating Service Account... gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} fi gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-input-resource `, - Container: corev1.Container{ - Name: "fetch-gcs-input-resource-mz4c7", - Image: "google/cloud-sdk", - }, - }}, + Container: corev1.Container{ + Name: "fetch-gcs-input-resource-mz4c7", + Image: "google/cloud-sdk", + }, + }}, + }, }, }, { desc: "no inputs", @@ -1065,36 +1092,38 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-input-resource wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: gcsStorageInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "create-dir-storage-gcs-keys-9l9zj", - Image: "busybox", - Command: []string{"mkdir", "-p", "/workspace/gcs-input-resource"}, - }}, { - Script: `#!/usr/bin/env bash + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "create-dir-storage-gcs-keys-9l9zj", + Image: "busybox", + Command: []string{"mkdir", "-p", "/workspace/gcs-input-resource"}, + }}, { + Script: `#!/usr/bin/env bash if [[ "${GOOGLE_APPLICATION_CREDENTIALS}" != "" ]]; then echo GOOGLE_APPLICATION_CREDENTIALS is set, activating Service Account... gcloud auth activate-service-account --key-file=${GOOGLE_APPLICATION_CREDENTIALS} fi gsutil rsync -d -r gs://fake-bucket/rules.zip /workspace/gcs-input-resource `, - Container: corev1.Container{ - Name: "fetch-storage-gcs-keys-mz4c7", - Image: "google/cloud-sdk", - VolumeMounts: []corev1.VolumeMount{ - {Name: "volume-storage-gcs-keys-secret-name", MountPath: "/var/secret/secret-name"}, - }, - Env: []corev1.EnvVar{ - {Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/secret-name/key.json"}, + Container: corev1.Container{ + Name: "fetch-storage-gcs-keys-mz4c7", + Image: "google/cloud-sdk", + VolumeMounts: []corev1.VolumeMount{ + {Name: "volume-storage-gcs-keys-secret-name", MountPath: "/var/secret/secret-name"}, + }, + Env: []corev1.EnvVar{ + {Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/secret-name/key.json"}, + }, }, - }, - }}, - Volumes: []corev1.Volume{{ - Name: "volume-storage-gcs-keys-secret-name", - VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "secret-name"}}, - }, { - Name: "volume-storage-gcs-keys-secret-name2", - VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "secret-name2"}}, - }}, + }}, + Volumes: []corev1.Volume{{ + Name: "volume-storage-gcs-keys-secret-name", + VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "secret-name"}}, + }, { + Name: "volume-storage-gcs-keys-secret-name2", + VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "secret-name2"}}, + }}, + }, }, }, { desc: "optional inputs with no resource spec and no resource ref", @@ -1118,7 +1147,9 @@ gsutil rsync -d -r gs://fake-bucket/rules.zip /workspace/gcs-input-resource wantErr: false, want: &v1alpha1.TaskSpec{ Inputs: optionalStorageInputs, - Steps: nil, + TaskSpec: v1alpha2.TaskSpec{ + Steps: nil, + }, }, }} { t.Run(c.desc, func(t *testing.T) { @@ -1216,19 +1247,21 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }, want: &v1alpha1.TaskSpec{ Inputs: gitInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "artifact-dest-mkdir-gitspace-9l9zj", - Image: "busybox", - Command: []string{"mkdir", "-p", "/workspace/gitspace"}, - }}, {Container: corev1.Container{ - Name: "artifact-copy-from-gitspace-mz4c7", - Image: "google/cloud-sdk", - Command: []string{"gsutil"}, - Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path/*", "/workspace/gitspace"}, - Env: gcsEnv, - VolumeMounts: gcsVolumeMounts, - }}}, - Volumes: gcsVolumes, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "artifact-dest-mkdir-gitspace-9l9zj", + Image: "busybox", + Command: []string{"mkdir", "-p", "/workspace/gitspace"}, + }}, {Container: corev1.Container{ + Name: "artifact-copy-from-gitspace-mz4c7", + Image: "google/cloud-sdk", + Command: []string{"gsutil"}, + Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path/*", "/workspace/gitspace"}, + Env: gcsEnv, + VolumeMounts: gcsVolumeMounts, + }}}, + Volumes: gcsVolumes, + }, }, }, { desc: "storage resource as input from previous task - copy from bucket", @@ -1258,19 +1291,21 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }, want: &v1alpha1.TaskSpec{ Inputs: gcsInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "artifact-dest-mkdir-workspace-mssqb", - Image: "busybox", - Command: []string{"mkdir", "-p", "/workspace/gcs-dir"}, - }}, {Container: corev1.Container{ - Name: "artifact-copy-from-workspace-78c5n", - Image: "google/cloud-sdk", - Command: []string{"gsutil"}, - Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path/*", "/workspace/gcs-dir"}, - Env: gcsEnv, - VolumeMounts: gcsVolumeMounts, - }}}, - Volumes: gcsVolumes, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "artifact-dest-mkdir-workspace-mssqb", + Image: "busybox", + Command: []string{"mkdir", "-p", "/workspace/gcs-dir"}, + }}, {Container: corev1.Container{ + Name: "artifact-copy-from-workspace-78c5n", + Image: "google/cloud-sdk", + Command: []string{"gsutil"}, + Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path/*", "/workspace/gcs-dir"}, + Env: gcsEnv, + VolumeMounts: gcsVolumeMounts, + }}}, + Volumes: gcsVolumes, + }, }, }, { desc: "storage resource with multiple inputs from previous task - copy from bucket", @@ -1308,30 +1343,32 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }, want: &v1alpha1.TaskSpec{ Inputs: multipleGcsInputs, - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "artifact-dest-mkdir-workspace-vr6ds", - Image: "busybox", - Command: []string{"mkdir", "-p", "/workspace/gcs-dir"}, - }}, {Container: corev1.Container{ - Name: "artifact-copy-from-workspace-l22wn", - Image: "google/cloud-sdk", - Command: []string{"gsutil"}, - Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path/*", "/workspace/gcs-dir"}, - Env: gcsEnv, - VolumeMounts: gcsVolumeMounts, - }}, {Container: corev1.Container{ - Name: "artifact-dest-mkdir-workspace2-6nl7g", - Image: "busybox", - Command: []string{"mkdir", "-p", "/workspace/gcs-dir"}, - }}, {Container: corev1.Container{ - Name: "artifact-copy-from-workspace2-j2tds", - Image: "google/cloud-sdk", - Command: []string{"gsutil"}, - Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path2/*", "/workspace/gcs-dir"}, - Env: gcsEnv, - VolumeMounts: gcsVolumeMounts, - }}}, - Volumes: gcsVolumes, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "artifact-dest-mkdir-workspace-vr6ds", + Image: "busybox", + Command: []string{"mkdir", "-p", "/workspace/gcs-dir"}, + }}, {Container: corev1.Container{ + Name: "artifact-copy-from-workspace-l22wn", + Image: "google/cloud-sdk", + Command: []string{"gsutil"}, + Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path/*", "/workspace/gcs-dir"}, + Env: gcsEnv, + VolumeMounts: gcsVolumeMounts, + }}, {Container: corev1.Container{ + Name: "artifact-dest-mkdir-workspace2-6nl7g", + Image: "busybox", + Command: []string{"mkdir", "-p", "/workspace/gcs-dir"}, + }}, {Container: corev1.Container{ + Name: "artifact-copy-from-workspace2-j2tds", + Image: "google/cloud-sdk", + Command: []string{"gsutil"}, + Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path2/*", "/workspace/gcs-dir"}, + Env: gcsEnv, + VolumeMounts: gcsVolumeMounts, + }}}, + Volumes: gcsVolumes, + }, }, }} { t.Run(c.desc, func(t *testing.T) { diff --git a/pkg/reconciler/taskrun/resources/taskresourceresolution_test.go b/pkg/reconciler/taskrun/resources/taskresourceresolution_test.go index 36e387fb3b3..342214c9bc2 100644 --- a/pkg/reconciler/taskrun/resources/taskresourceresolution_test.go +++ b/pkg/reconciler/taskrun/resources/taskresourceresolution_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -75,11 +76,11 @@ func TestResolveTaskRun(t *testing.T) { taskName := "orchestrate" kind := v1alpha1.NamespacedTaskKind - taskSpec := v1alpha1.TaskSpec{ + taskSpec := v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "step1", }}}, - } + }} resources := []*v1alpha1.PipelineResource{{ ObjectMeta: metav1.ObjectMeta{ @@ -197,11 +198,11 @@ func TestResolveTaskRun_missingInput(t *testing.T) { } func TestResolveTaskRun_noResources(t *testing.T) { - taskSpec := v1alpha1.TaskSpec{ + taskSpec := v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "step1", }}}, - } + }} gr := func(n string) (*v1alpha1.PipelineResource, error) { return &v1alpha1.PipelineResource{}, nil } diff --git a/pkg/reconciler/taskrun/resources/taskspec_test.go b/pkg/reconciler/taskrun/resources/taskspec_test.go index e902da2b7d6..9a95ebd7c5d 100644 --- a/pkg/reconciler/taskrun/resources/taskspec_test.go +++ b/pkg/reconciler/taskrun/resources/taskspec_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -30,11 +31,11 @@ func TestGetTaskSpec_Ref(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "orchestrate", }, - Spec: v1alpha1.TaskSpec{ + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "step1", }}}, - }, + }}, } tr := &v1alpha1.TaskRun{ ObjectMeta: metav1.ObjectMeta{ @@ -68,11 +69,11 @@ func TestGetTaskSpec_Embedded(t *testing.T) { Name: "mytaskrun", }, Spec: v1alpha1.TaskRunSpec{ - TaskSpec: &v1alpha1.TaskSpec{ + TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "step1", }}}, - }, + }}, }, } gt := func(n string) (v1alpha1.TaskInterface, error) { return nil, errors.New("shouldn't be called") } diff --git a/pkg/workspace/apply_test.go b/pkg/workspace/apply_test.go index 983f0f4a8c2..3471cb9041c 100644 --- a/pkg/workspace/apply_test.go +++ b/pkg/workspace/apply_test.go @@ -5,6 +5,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/workspace" "github.com/tektoncd/pipeline/test/names" corev1 "k8s.io/api/core/v1" @@ -201,11 +202,11 @@ func TestApply(t *testing.T) { expectedTaskSpec v1alpha1.TaskSpec }{{ name: "binding a single workspace with a PVC", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "custom", }}, - }, + }}, workspaces: []v1alpha1.WorkspaceBinding{{ Name: "custom", PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ @@ -213,7 +214,7 @@ func TestApply(t *testing.T) { }, SubPath: "/foo/bar/baz", }}, - expectedTaskSpec: v1alpha1.TaskSpec{ + expectedTaskSpec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ StepTemplate: &corev1.Container{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-9l9zj", @@ -232,14 +233,14 @@ func TestApply(t *testing.T) { Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "custom", }}, - }, + }}, }, { name: "binding a single workspace with emptyDir", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "custom", }}, - }, + }}, workspaces: []v1alpha1.WorkspaceBinding{{ Name: "custom", EmptyDir: &corev1.EmptyDirVolumeSource{ @@ -247,7 +248,7 @@ func TestApply(t *testing.T) { }, SubPath: "/foo/bar/baz", }}, - expectedTaskSpec: v1alpha1.TaskSpec{ + expectedTaskSpec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ StepTemplate: &corev1.Container{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-mz4c7", @@ -266,10 +267,10 @@ func TestApply(t *testing.T) { Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "custom", }}, - }, + }}, }, { name: "task spec already has volumes and stepTemplate", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ StepTemplate: &corev1.Container{ VolumeMounts: []corev1.VolumeMount{{ Name: "awesome-volume", @@ -285,7 +286,7 @@ func TestApply(t *testing.T) { Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "custom", }}, - }, + }}, workspaces: []v1alpha1.WorkspaceBinding{{ Name: "custom", EmptyDir: &corev1.EmptyDirVolumeSource{ @@ -293,7 +294,7 @@ func TestApply(t *testing.T) { }, SubPath: "/foo/bar/baz", }}, - expectedTaskSpec: v1alpha1.TaskSpec{ + expectedTaskSpec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ StepTemplate: &corev1.Container{ VolumeMounts: []corev1.VolumeMount{{ Name: "awesome-volume", @@ -320,31 +321,31 @@ func TestApply(t *testing.T) { Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "custom", }}, - }, + }}, }, { name: "0 workspace bindings", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{ Container: corev1.Container{ Name: "foo", }}}, - }, + }}, workspaces: []v1alpha1.WorkspaceBinding{}, - expectedTaskSpec: v1alpha1.TaskSpec{ + expectedTaskSpec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{ Container: corev1.Container{ Name: "foo", }}}, - }, + }}, }, { name: "binding multiple workspaces", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "custom", }, { Name: "even-more-custom", }}, - }, + }}, workspaces: []v1alpha1.WorkspaceBinding{{ Name: "custom", PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ @@ -357,7 +358,7 @@ func TestApply(t *testing.T) { ClaimName: "myotherpvc", }, }}, - expectedTaskSpec: v1alpha1.TaskSpec{ + expectedTaskSpec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ StepTemplate: &corev1.Container{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-78c5n", @@ -388,16 +389,16 @@ func TestApply(t *testing.T) { Name: "custom"}, { Name: "even-more-custom", }}, - }, + }}, }, { name: "multiple workspaces binding to the same volume with diff subpaths doesnt duplicate", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "custom", }, { Name: "custom2", }}, - }, + }}, workspaces: []v1alpha1.WorkspaceBinding{{ Name: "custom", PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ @@ -411,7 +412,7 @@ func TestApply(t *testing.T) { }, SubPath: "/very/professional/work/space", }}, - expectedTaskSpec: v1alpha1.TaskSpec{ + expectedTaskSpec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ StepTemplate: &corev1.Container{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-j2tds", @@ -436,22 +437,22 @@ func TestApply(t *testing.T) { }, { Name: "custom2", }}, - }, + }}, }, { name: "non default mount path", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "custom", MountPath: "/my/fancy/mount/path", }}, - }, + }}, workspaces: []v1alpha1.WorkspaceBinding{{ Name: "custom", PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ ClaimName: "mypvc", }, }}, - expectedTaskSpec: v1alpha1.TaskSpec{ + expectedTaskSpec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ StepTemplate: &corev1.Container{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-l22wn", @@ -470,23 +471,23 @@ func TestApply(t *testing.T) { Name: "custom", MountPath: "/my/fancy/mount/path", }}, - }, + }}, }, { name: "readOnly true marks volume mount readOnly", - ts: v1alpha1.TaskSpec{ + ts: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "custom", MountPath: "/my/fancy/mount/path", ReadOnly: true, }}, - }, + }}, workspaces: []v1alpha1.WorkspaceBinding{{ Name: "custom", PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ ClaimName: "mypvc", }, }}, - expectedTaskSpec: v1alpha1.TaskSpec{ + expectedTaskSpec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ StepTemplate: &corev1.Container{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-twkr2", @@ -507,7 +508,7 @@ func TestApply(t *testing.T) { MountPath: "/my/fancy/mount/path", ReadOnly: true, }}, - }, + }}, }} { t.Run(tc.name, func(t *testing.T) { ts, err := workspace.Apply(tc.ts, tc.workspaces) diff --git a/test/builder/pipeline_test.go b/test/builder/pipeline_test.go index 63dfbc0797d..23a739a9430 100644 --- a/test/builder/pipeline_test.go +++ b/test/builder/pipeline_test.go @@ -27,6 +27,7 @@ import ( duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" tb "github.com/tektoncd/pipeline/test/builder" ) @@ -54,11 +55,12 @@ func TestPipeline(t *testing.T) { tb.PipelineTask("never-gonna", "give-you-up", tb.RunAfter("foo"), ), - tb.PipelineTask("foo", "", tb.PipelineTaskSpec(&v1alpha1.TaskSpec{ + tb.PipelineTask("foo", "", tb.PipelineTaskSpec(&v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "step", Image: "myimage", - }}}}, + }}}, + }}, )), tb.PipelineWorkspaceDeclaration("workspace1"), ), @@ -132,13 +134,12 @@ func TestPipeline(t *testing.T) { RunAfter: []string{"foo"}, }, { Name: "foo", - TaskSpec: &v1alpha1.TaskSpec{ + TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Name: "step", Image: "myimage", - }}, - }, - }, + }}}, + }}, }}, Workspaces: []v1alpha1.WorkspacePipelineDeclaration{{ Name: "workspace1", diff --git a/test/builder/task_test.go b/test/builder/task_test.go index 11a5cd96a59..abc3cc81e1f 100644 --- a/test/builder/task_test.go +++ b/test/builder/task_test.go @@ -23,6 +23,7 @@ import ( "github.com/google/go-cmp/cmp" "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" tb "github.com/tektoncd/pipeline/test/builder" corev1 "k8s.io/api/core/v1" @@ -67,14 +68,34 @@ func TestTask(t *testing.T) { expectedTask := &v1alpha1.Task{ ObjectMeta: metav1.ObjectMeta{Name: "test-task", Namespace: "foo"}, Spec: v1alpha1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Name: "mycontainer", - Image: "myimage", - Command: []string{"/mycmd"}, - Args: []string{"--my-other-arg=$(inputs.resources.workspace.url)"}, - }}, {Script: "echo foo", Container: corev1.Container{ - Image: "myimage2", - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Name: "mycontainer", + Image: "myimage", + Command: []string{"/mycmd"}, + Args: []string{"--my-other-arg=$(inputs.resources.workspace.url)"}, + }}, {Script: "echo foo", Container: corev1.Container{ + Image: "myimage2", + }}}, + Volumes: []corev1.Volume{{ + Name: "foo", + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{Path: "/foo/bar"}, + }, + }}, + StepTemplate: &corev1.Container{ + Env: []corev1.EnvVar{{ + Name: "FRUIT", + Value: "BANANA", + }}, + }, + Workspaces: []v1alpha1.WorkspaceDeclaration{{ + Name: "bread", + Description: "kind of bread", + MountPath: "/bread/path", + ReadOnly: false, + }}, + }, Inputs: &v1alpha1.Inputs{ Resources: []v1alpha1.TaskResource{{ ResourceDeclaration: v1alpha1.ResourceDeclaration{ @@ -112,24 +133,6 @@ func TestTask(t *testing.T) { Optional: true, }}}, }, - Volumes: []corev1.Volume{{ - Name: "foo", - VolumeSource: corev1.VolumeSource{ - HostPath: &corev1.HostPathVolumeSource{Path: "/foo/bar"}, - }, - }}, - StepTemplate: &corev1.Container{ - Env: []corev1.EnvVar{{ - Name: "FRUIT", - Value: "BANANA", - }}, - }, - Workspaces: []v1alpha1.WorkspaceDeclaration{{ - Name: "bread", - Description: "kind of bread", - MountPath: "/bread/path", - ReadOnly: false, - }}, }, } if d := cmp.Diff(expectedTask, task); d != "" { @@ -145,13 +148,13 @@ func TestClusterTask(t *testing.T) { )) expectedTask := &v1alpha1.ClusterTask{ ObjectMeta: metav1.ObjectMeta{Name: "test-clustertask"}, - Spec: v1alpha1.TaskSpec{ + Spec: v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Image: "myimage", Command: []string{"/mycmd"}, Args: []string{"--my-other-arg=$(inputs.resources.workspace.url)"}, }}}, - }, + }}, } if d := cmp.Diff(expectedTask, task); d != "" { t.Fatalf("Task diff -want, +got: %v", d) @@ -307,10 +310,12 @@ func TestTaskRunWithTaskSpec(t *testing.T) { }, Spec: v1alpha1.TaskRunSpec{ TaskSpec: &v1alpha1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Image: "image", - Command: []string{"/mycmd"}, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Image: "image", + Command: []string{"/mycmd"}, + }}}, + }, Inputs: &v1alpha1.Inputs{ Resources: []v1alpha1.TaskResource{{ ResourceDeclaration: v1alpha1.ResourceDeclaration{ @@ -351,10 +356,12 @@ func TestTaskRunWithPodTemplate(t *testing.T) { }, Spec: v1alpha1.TaskRunSpec{ TaskSpec: &v1alpha1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ - Image: "image", - Command: []string{"/mycmd"}, - }}}, + TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha1.Step{{Container: corev1.Container{ + Image: "image", + Command: []string{"/mycmd"}, + }}}, + }, Inputs: &v1alpha1.Inputs{ Resources: []v1alpha1.TaskResource{{ ResourceDeclaration: v1alpha1.ResourceDeclaration{ @@ -389,12 +396,12 @@ func TestResolvedTaskResources(t *testing.T) { tb.ResolvedTaskResourcesOutputs("qux", tb.PipelineResource("quux", "quuz")), ) expectedResolvedTaskResources := &resources.ResolvedTaskResources{ - TaskSpec: &v1alpha1.TaskSpec{ + TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{Container: corev1.Container{ Image: "image", Command: []string{"/mycmd"}, }}}, - }, + }}, Inputs: map[string]*v1alpha1.PipelineResource{ "foo": { ObjectMeta: metav1.ObjectMeta{ diff --git a/test/retry_test.go b/test/retry_test.go index 25a5e07d592..e4463163e21 100644 --- a/test/retry_test.go +++ b/test/retry_test.go @@ -23,6 +23,7 @@ import ( "time" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/apis" @@ -47,12 +48,12 @@ func TestTaskRunRetry(t *testing.T) { PipelineSpec: &v1alpha1.PipelineSpec{ Tasks: []v1alpha1.PipelineTask{{ Name: "retry-me", - TaskSpec: &v1alpha1.TaskSpec{ + TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{ Container: corev1.Container{Image: "busybox"}, Script: "exit 1", }}, - }, + }}, Retries: numRetries, }}, }, diff --git a/test/start_time_test.go b/test/start_time_test.go index b370abaefc1..bcbda9d199a 100644 --- a/test/start_time_test.go +++ b/test/start_time_test.go @@ -19,6 +19,7 @@ import ( "time" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha2" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" knativetest "knative.dev/pkg/test" @@ -42,7 +43,7 @@ func TestStartTime(t *testing.T) { Namespace: namespace, }, Spec: v1alpha1.TaskRunSpec{ - TaskSpec: &v1alpha1.TaskSpec{ + TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1alpha2.TaskSpec{ Steps: []v1alpha1.Step{{ Container: corev1.Container{Image: "ubuntu"}, Script: "sleep 10", @@ -59,7 +60,7 @@ func TestStartTime(t *testing.T) { Container: corev1.Container{Image: "ubuntu"}, Script: "sleep 10", }}, - }, + }}, }, }) if err != nil {