diff --git a/pkg/apis/pipeline/v1alpha1/task_conversion_test.go b/pkg/apis/pipeline/v1alpha1/task_conversion_test.go index 35a9d971825..17a1937bf69 100644 --- a/pkg/apis/pipeline/v1alpha1/task_conversion_test.go +++ b/pkg/apis/pipeline/v1alpha1/task_conversion_test.go @@ -106,7 +106,7 @@ func TestTaskConversion(t *testing.T) { }, wantErr: true, }, { - name: "deprecated and non deprecated inputs", + name: "deprecated and non deprecated params", in: &Task{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", diff --git a/pkg/apis/pipeline/v1alpha1/taskrun_conversion.go b/pkg/apis/pipeline/v1alpha1/taskrun_conversion.go new file mode 100644 index 00000000000..23b91eed756 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha1/taskrun_conversion.go @@ -0,0 +1,147 @@ +/* +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 = (*TaskRun)(nil) + +// ConvertUp implements api.Convertible +func (source *TaskRun) ConvertUp(ctx context.Context, obj apis.Convertible) error { + switch sink := obj.(type) { + case *v1alpha2.TaskRun: + sink.ObjectMeta = source.ObjectMeta + if err := source.Spec.ConvertUp(ctx, &sink.Spec); err != nil { + return err + } + sink.Status = source.Status + return nil + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +func (source *TaskRunSpec) ConvertUp(ctx context.Context, sink *v1alpha2.TaskRunSpec) error { + sink.ServiceAccountName = source.ServiceAccountName + 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.Status = source.Status + sink.Timeout = source.Timeout + sink.PodTemplate = source.PodTemplate + sink.Workspaces = source.Workspaces + sink.LimitRangeName = source.LimitRangeName + sink.Params = source.Params + sink.Resources = source.Resources + // Deprecated fields + 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.Param, 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.TaskRunResources{} + } + 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.TaskResourceBinding, len(source.Inputs.Resources)) + for i, resource := range source.Inputs.Resources { + sink.Resources.Inputs[i] = v1alpha2.TaskResourceBinding{ + PipelineResourceBinding: v1alpha2.PipelineResourceBinding{ + Name: resource.Name, + ResourceRef: resource.ResourceRef, + ResourceSpec: resource.ResourceSpec, + }, + Paths: resource.Paths, + } + } + } + if len(source.Outputs.Resources) > 0 { + if sink.Resources == nil { + sink.Resources = &v1alpha2.TaskRunResources{} + } + 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.TaskResourceBinding, len(source.Outputs.Resources)) + for i, resource := range source.Outputs.Resources { + sink.Resources.Outputs[i] = v1alpha2.TaskResourceBinding{ + PipelineResourceBinding: v1alpha2.PipelineResourceBinding{ + Name: resource.Name, + ResourceRef: resource.ResourceRef, + ResourceSpec: resource.ResourceSpec, + }, + Paths: resource.Paths, + } + } + } + return nil +} + +// ConvertDown implements api.Convertible +func (sink *TaskRun) ConvertDown(ctx context.Context, obj apis.Convertible) error { + switch source := obj.(type) { + case *v1alpha2.TaskRun: + sink.ObjectMeta = source.ObjectMeta + if err := sink.Spec.ConvertDown(ctx, &source.Spec); err != nil { + return err + } + sink.Status = source.Status + return nil + default: + return fmt.Errorf("unknown version, got: %T", sink) + } +} + +func (sink *TaskRunSpec) ConvertDown(ctx context.Context, source *v1alpha2.TaskRunSpec) error { + sink.ServiceAccountName = source.ServiceAccountName + sink.TaskRef = source.TaskRef + if source.TaskSpec != nil { + sink.TaskSpec = &TaskSpec{} + if err := sink.TaskSpec.ConvertDown(ctx, source.TaskSpec); err != nil { + return err + } + } + sink.Status = source.Status + sink.Timeout = source.Timeout + sink.PodTemplate = source.PodTemplate + sink.Workspaces = source.Workspaces + sink.LimitRangeName = source.LimitRangeName + sink.Params = source.Params + sink.Resources = source.Resources + return nil +} diff --git a/pkg/apis/pipeline/v1alpha1/taskrun_conversion_test.go b/pkg/apis/pipeline/v1alpha1/taskrun_conversion_test.go new file mode 100644 index 00000000000..5a7668844a3 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha1/taskrun_conversion_test.go @@ -0,0 +1,445 @@ +/* +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" + "time" + + "github.com/google/go-cmp/cmp" + "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" +) + +func TestTaskRunConversionBadType(t *testing.T) { + good, bad := &TaskRun{}, &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 TestTaskRunConversion(t *testing.T) { + versions := []apis.Convertible{&v1alpha2.TaskRun{}} + + tests := []struct { + name string + in *TaskRun + wantErr bool + }{{ + name: "simple conversion taskref", + in: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + TaskRef: &TaskRef{ + Name: "task", + }, + ServiceAccountName: "sa", + Timeout: &metav1.Duration{Duration: 1 * time.Minute}, + PodTemplate: &PodTemplate{ + NodeSelector: map[string]string{"foo": "bar"}, + }, + Workspaces: []WorkspaceBinding{{ + Name: "w1", + SubPath: "foo", + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }}, + LimitRangeName: "foo", + Params: []Param{{ + Name: "p1", + Value: v1alpha2.ArrayOrString{StringVal: "baz"}, + }}, + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha2.TaskResourceBinding{{ + PipelineResourceBinding: v1alpha2.PipelineResourceBinding{ + Name: "i1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r1"}, + }, + Paths: []string{"foo", "bar"}, + }}, + Outputs: []v1alpha2.TaskResourceBinding{{ + PipelineResourceBinding: v1alpha2.PipelineResourceBinding{ + Name: "o1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r2"}, + }, + }}, + }, + }, + Status: TaskRunStatus{ + TaskRunStatusFields: TaskRunStatusFields{ + PodName: "foo", + StartTime: &metav1.Time{Time: time.Now().Add(-4 * time.Minute)}, + CompletionTime: &metav1.Time{Time: time.Now().Add(-1 * time.Minute)}, + Steps: []StepState{{ + Name: "s1", + }}, + }, + }, + }, + }, { + name: "simple conversion taskspec", + in: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + TaskSpec: &TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha2.Step{{Container: corev1.Container{ + Image: "foo", + }}}, + }}, + ServiceAccountName: "sa", + Timeout: &metav1.Duration{Duration: 1 * time.Minute}, + PodTemplate: &PodTemplate{ + NodeSelector: map[string]string{"foo": "bar"}, + }, + Workspaces: []WorkspaceBinding{{ + Name: "w1", + SubPath: "foo", + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }}, + LimitRangeName: "foo", + Params: []Param{{ + Name: "p1", + Value: v1alpha2.ArrayOrString{StringVal: "baz"}, + }}, + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha2.TaskResourceBinding{{ + PipelineResourceBinding: v1alpha2.PipelineResourceBinding{ + Name: "i1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r1"}, + }, + Paths: []string{"foo", "bar"}, + }}, + Outputs: []v1alpha2.TaskResourceBinding{{ + PipelineResourceBinding: v1alpha2.PipelineResourceBinding{ + Name: "o1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r2"}, + }, + }}, + }, + }, + }, + }, { + name: "deprecated and non deprecated params", + in: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + TaskSpec: &TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha2.Step{{Container: corev1.Container{ + Image: "foo", + }}}, + }}, + ServiceAccountName: "sa", + Timeout: &metav1.Duration{Duration: 1 * time.Minute}, + PodTemplate: &PodTemplate{ + NodeSelector: map[string]string{"foo": "bar"}, + }, + Workspaces: []WorkspaceBinding{{ + Name: "w1", + SubPath: "foo", + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }}, + LimitRangeName: "foo", + Params: []Param{{ + Name: "p1", + Value: v1alpha2.ArrayOrString{StringVal: "baz"}, + }}, + Inputs: TaskRunInputs{ + Params: []Param{{ + Name: "p2", + Value: v1alpha2.ArrayOrString{StringVal: "bar"}}, + }, + }, + }, + }, + wantErr: true, + }, { + name: "deprecated and non deprecated inputs", + in: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + TaskSpec: &TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha2.Step{{Container: corev1.Container{ + Image: "foo", + }}}, + }}, + ServiceAccountName: "sa", + Timeout: &metav1.Duration{Duration: 1 * time.Minute}, + PodTemplate: &PodTemplate{ + NodeSelector: map[string]string{"foo": "bar"}, + }, + Workspaces: []WorkspaceBinding{{ + Name: "w1", + SubPath: "foo", + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }}, + LimitRangeName: "foo", + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha2.TaskResourceBinding{{ + PipelineResourceBinding: v1alpha2.PipelineResourceBinding{ + Name: "i1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r1"}, + }, + Paths: []string{"foo", "bar"}, + }}, + }, + Inputs: TaskRunInputs{ + Resources: []TaskResourceBinding{{ + PipelineResourceBinding: PipelineResourceBinding{ + Name: "i1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r1"}, + }, + Paths: []string{"foo", "bar"}, + }}, + }, + }, + }, + wantErr: true, + }, { + name: "deprecated and non deprecated outputs", + in: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + TaskSpec: &TaskSpec{TaskSpec: v1alpha2.TaskSpec{ + Steps: []v1alpha2.Step{{Container: corev1.Container{ + Image: "foo", + }}}, + }}, + ServiceAccountName: "sa", + Timeout: &metav1.Duration{Duration: 1 * time.Minute}, + PodTemplate: &PodTemplate{ + NodeSelector: map[string]string{"foo": "bar"}, + }, + Workspaces: []WorkspaceBinding{{ + Name: "w1", + SubPath: "foo", + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }}, + LimitRangeName: "foo", + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha2.TaskResourceBinding{{ + PipelineResourceBinding: v1alpha2.PipelineResourceBinding{ + Name: "o1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r1"}, + }, + Paths: []string{"foo", "bar"}, + }}, + }, + Outputs: TaskRunOutputs{ + Resources: []TaskResourceBinding{{ + PipelineResourceBinding: PipelineResourceBinding{ + Name: "o1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r1"}, + }, + Paths: []string{"foo", "bar"}, + }}, + }, + }, + }, + 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 := &TaskRun{} + 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 TestTaskRunConversionFromDeprecated(t *testing.T) { + versions := []apis.Convertible{&v1alpha2.TaskRun{}} + tests := []struct { + name string + in *TaskRun + want *TaskRun + badField string + }{{ + name: "inputs params", + in: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + Inputs: TaskRunInputs{ + Params: []Param{{ + Name: "p2", + Value: v1alpha2.ArrayOrString{StringVal: "bar"}}, + }, + }, + }, + }, + want: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + Params: []Param{{ + Name: "p2", + Value: v1alpha2.ArrayOrString{StringVal: "bar"}}, + }, + }, + }, + }, { + name: "inputs resource", + in: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + Inputs: TaskRunInputs{ + Resources: []TaskResourceBinding{{ + PipelineResourceBinding: PipelineResourceBinding{ + Name: "i1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r1"}, + }, + Paths: []string{"foo", "bar"}, + }}, + }, + }, + }, + want: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + Resources: &v1alpha2.TaskRunResources{ + Inputs: []v1alpha2.TaskResourceBinding{{ + PipelineResourceBinding: v1alpha2.PipelineResourceBinding{ + Name: "i1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r1"}, + }, + Paths: []string{"foo", "bar"}, + }}, + }, + }, + }, + }, { + name: "outputs resource", + in: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + Outputs: TaskRunOutputs{ + Resources: []TaskResourceBinding{{ + PipelineResourceBinding: PipelineResourceBinding{ + Name: "o1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r1"}, + }, + Paths: []string{"foo", "bar"}, + }}, + }, + }, + }, + want: &TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + Generation: 1, + }, + Spec: TaskRunSpec{ + Resources: &v1alpha2.TaskRunResources{ + Outputs: []v1alpha2.TaskResourceBinding{{ + PipelineResourceBinding: v1alpha2.PipelineResourceBinding{ + Name: "o1", + ResourceRef: &v1alpha2.PipelineResourceRef{Name: "r1"}, + }, + Paths: []string{"foo", "bar"}, + }}, + }, + }, + }, + }} + 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 := &TaskRun{} + 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/taskrun_types.go b/pkg/apis/pipeline/v1alpha1/taskrun_types.go index cd4677a8b85..67e61f1f2c0 100644 --- a/pkg/apis/pipeline/v1alpha1/taskrun_types.go +++ b/pkg/apis/pipeline/v1alpha1/taskrun_types.go @@ -18,22 +18,16 @@ package v1alpha1 import ( "fmt" - "time" "github.com/tektoncd/pipeline/pkg/apis/pipeline" "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" - duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1" ) // TaskRunSpec defines the desired state of TaskRun type TaskRunSpec struct { - // +optional - Inputs TaskRunInputs `json:"inputs,omitempty"` - // +optional - Outputs TaskRunOutputs `json:"outputs,omitempty"` // +optional ServiceAccountName string `json:"serviceAccountName"` // no more than one of the TaskRef and TaskSpec may be specified. @@ -60,6 +54,18 @@ type TaskRunSpec struct { // container requests can be used by containers of TaskRun // +optional LimitRangeName string `json:"limitRangeName"` + + // From v1alpha2 + // +optional + Params []Param `json:"params,omitempty"` + // +optional + Resources *v1alpha2.TaskRunResources `json:"resources,omitempty"` + + // Deprecated + // +optional + Inputs TaskRunInputs `json:"inputs,omitempty"` + // +optional + Outputs TaskRunOutputs `json:"outputs,omitempty"` } // TaskRunSpecStatus defines the taskrun spec status the user can provide @@ -96,138 +102,43 @@ type TaskRunOutputs struct { Resources []TaskResourceBinding `json:"resources,omitempty"` } -var taskRunCondSet = apis.NewBatchConditionSet() - // TaskRunStatus defines the observed state of TaskRun -type TaskRunStatus struct { - duckv1beta1.Status `json:",inline"` - - // TaskRunStatusFields inlines the status fields. - TaskRunStatusFields `json:",inline"` -} +type TaskRunStatus = v1alpha2.TaskRunStatus // TaskRunStatusFields holds the fields of TaskRun's status. This is defined // separately and inlined so that other types can readily consume these fields // via duck typing. -type TaskRunStatusFields struct { - // PodName is the name of the pod responsible for executing this task's steps. - PodName string `json:"podName"` - - // StartTime is the time the build is actually started. - // +optional - StartTime *metav1.Time `json:"startTime,omitempty"` - - // CompletionTime is the time the build completed. - // +optional - CompletionTime *metav1.Time `json:"completionTime,omitempty"` - - // Steps describes the state of each build step container. - // +optional - Steps []StepState `json:"steps,omitempty"` - - // CloudEvents describe the state of each cloud event requested via a - // CloudEventResource. - // +optional - CloudEvents []CloudEventDelivery `json:"cloudEvents,omitempty"` - - // RetriesStatus contains the history of TaskRunStatus in case of a retry in order to keep record of failures. - // All TaskRunStatus stored in RetriesStatus will have no date within the RetriesStatus as is redundant. - // +optional - RetriesStatus []TaskRunStatus `json:"retriesStatus,omitempty"` - - // Results from Resources built during the taskRun. currently includes - // the digest of build container images - // +optional - ResourcesResult []PipelineResourceResult `json:"resourcesResult,omitempty"` - - // TaskRunResults are the list of results written out by the task's containers - // +optional - TaskRunResults []TaskRunResult `json:"taskResults,omitempty"` - - // The list has one entry per sidecar in the manifest. Each entry is - // represents the imageid of the corresponding sidecar. - Sidecars []SidecarState `json:"sidecars,omitempty"` -} +type TaskRunStatusFields = v1alpha2.TaskRunStatusFields // TaskRunResult used to describe the results of a task -type TaskRunResult struct { - // Name the given name - Name string `json:"name"` - - // Value the given value of the result - Value string `json:"value"` -} - -// GetCondition returns the Condition matching the given type. -func (tr *TaskRunStatus) GetCondition(t apis.ConditionType) *apis.Condition { - return taskRunCondSet.Manage(tr).GetCondition(t) -} - -// InitializeConditions will set all conditions in taskRunCondSet to unknown for the TaskRun -// and set the started time to the current time -func (tr *TaskRunStatus) InitializeConditions() { - if tr.StartTime.IsZero() { - tr.StartTime = &metav1.Time{Time: time.Now()} - } - taskRunCondSet.Manage(tr).InitializeConditions() -} - -// SetCondition sets the condition, unsetting previous conditions with the same -// type as necessary. -func (tr *TaskRunStatus) SetCondition(newCond *apis.Condition) { - if newCond != nil { - taskRunCondSet.Manage(tr).SetCondition(*newCond) - } -} +type TaskRunResult = v1alpha2.TaskRunResult // StepState reports the results of running a step in the Task. -type StepState struct { - corev1.ContainerState - Name string `json:"name,omitempty"` - ContainerName string `json:"container,omitempty"` - ImageID string `json:"imageID,omitempty"` -} +type StepState = v1alpha2.StepState // SidecarState reports the results of sidecar in the Task. -type SidecarState struct { - Name string `json:"name,omitempty"` - ImageID string `json:"imageID,omitempty"` -} +type SidecarState = v1alpha2.SidecarState // CloudEventDelivery is the target of a cloud event along with the state of // delivery. -type CloudEventDelivery struct { - // Target points to an addressable - Target string `json:"target,omitempty"` - Status CloudEventDeliveryState `json:"status,omitempty"` -} +type CloudEventDelivery = v1alpha2.CloudEventDelivery // CloudEventCondition is a string that represents the condition of the event. -type CloudEventCondition string +type CloudEventCondition = v1alpha2.CloudEventCondition const ( // CloudEventConditionUnknown means that the condition for the event to be // triggered was not met yet, or we don't know the state yet. - CloudEventConditionUnknown CloudEventCondition = "Unknown" + CloudEventConditionUnknown CloudEventCondition = v1alpha2.CloudEventConditionUnknown // CloudEventConditionSent means that the event was sent successfully - CloudEventConditionSent CloudEventCondition = "Sent" + CloudEventConditionSent CloudEventCondition = v1alpha2.CloudEventConditionSent // CloudEventConditionFailed means that there was one or more attempts to // send the event, and none was successful so far. - CloudEventConditionFailed CloudEventCondition = "Failed" + CloudEventConditionFailed CloudEventCondition = v1alpha2.CloudEventConditionFailed ) // CloudEventDeliveryState reports the state of a cloud event to be sent. -type CloudEventDeliveryState struct { - // Current status - Condition CloudEventCondition `json:"condition,omitempty"` - // SentAt is the time at which the last attempt to send the event was made - // +optional - SentAt *metav1.Time `json:"sentAt,omitempty"` - // Error is the text of error (if any) - Error string `json:"message"` - // RetryCount is the number of attempts of sending the cloud event - RetryCount int32 `json:"retryCount"` -} +type CloudEventDeliveryState = v1alpha2.CloudEventDeliveryState // +genclient // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go index 6821ae976bf..c62d827ba0a 100644 --- a/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1alpha1/zz_generated.deepcopy.go @@ -103,43 +103,6 @@ func (in *CannotConvertError) DeepCopy() *CannotConvertError { 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 - in.Status.DeepCopyInto(&out.Status) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudEventDelivery. -func (in *CloudEventDelivery) DeepCopy() *CloudEventDelivery { - if in == nil { - return nil - } - out := new(CloudEventDelivery) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *CloudEventDeliveryState) DeepCopyInto(out *CloudEventDeliveryState) { - *out = *in - if in.SentAt != nil { - in, out := &in.SentAt, &out.SentAt - *out = (*in).DeepCopy() - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudEventDeliveryState. -func (in *CloudEventDeliveryState) DeepCopy() *CloudEventDeliveryState { - if in == nil { - return nil - } - out := new(CloudEventDeliveryState) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CloudEventResource) DeepCopyInto(out *CloudEventResource) { *out = *in @@ -734,7 +697,7 @@ func (in *PipelineRunTaskRunStatus) DeepCopyInto(out *PipelineRunTaskRunStatus) *out = *in if in.Status != nil { in, out := &in.Status, &out.Status - *out = new(TaskRunStatus) + *out = new(v1alpha2.TaskRunStatus) (*in).DeepCopyInto(*out) } if in.ConditionChecks != nil { @@ -919,39 +882,6 @@ func (in *PullRequestResource) DeepCopy() *PullRequestResource { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *SidecarState) DeepCopyInto(out *SidecarState) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SidecarState. -func (in *SidecarState) DeepCopy() *SidecarState { - if in == nil { - return nil - } - out := new(SidecarState) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *StepState) DeepCopyInto(out *StepState) { - *out = *in - in.ContainerState.DeepCopyInto(&out.ContainerState) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepState. -func (in *StepState) DeepCopy() *StepState { - if in == nil { - return nil - } - out := new(StepState) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Task) DeepCopyInto(out *Task) { *out = *in @@ -1165,27 +1095,9 @@ func (in *TaskRunOutputs) DeepCopy() *TaskRunOutputs { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TaskRunResult) DeepCopyInto(out *TaskRunResult) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TaskRunResult. -func (in *TaskRunResult) DeepCopy() *TaskRunResult { - if in == nil { - return nil - } - out := new(TaskRunResult) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TaskRunSpec) DeepCopyInto(out *TaskRunSpec) { *out = *in - in.Inputs.DeepCopyInto(&out.Inputs) - in.Outputs.DeepCopyInto(&out.Outputs) if in.TaskRef != nil { in, out := &in.TaskRef, &out.TaskRef *out = new(v1alpha2.TaskRef) @@ -1213,93 +1125,29 @@ func (in *TaskRunSpec) DeepCopyInto(out *TaskRunSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TaskRunSpec. -func (in *TaskRunSpec) DeepCopy() *TaskRunSpec { - if in == nil { - return nil - } - out := new(TaskRunSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TaskRunStatus) DeepCopyInto(out *TaskRunStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) - in.TaskRunStatusFields.DeepCopyInto(&out.TaskRunStatusFields) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TaskRunStatus. -func (in *TaskRunStatus) DeepCopy() *TaskRunStatus { - if in == nil { - return nil - } - out := new(TaskRunStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TaskRunStatusFields) DeepCopyInto(out *TaskRunStatusFields) { - *out = *in - if in.StartTime != nil { - in, out := &in.StartTime, &out.StartTime - *out = (*in).DeepCopy() - } - if in.CompletionTime != nil { - in, out := &in.CompletionTime, &out.CompletionTime - *out = (*in).DeepCopy() - } - if in.Steps != nil { - in, out := &in.Steps, &out.Steps - *out = make([]StepState, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.CloudEvents != nil { - in, out := &in.CloudEvents, &out.CloudEvents - *out = make([]CloudEventDelivery, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.RetriesStatus != nil { - in, out := &in.RetriesStatus, &out.RetriesStatus - *out = make([]TaskRunStatus, len(*in)) + if in.Params != nil { + in, out := &in.Params, &out.Params + *out = make([]v1alpha2.Param, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.ResourcesResult != nil { - in, out := &in.ResourcesResult, &out.ResourcesResult - *out = make([]v1alpha2.PipelineResourceResult, len(*in)) - copy(*out, *in) - } - if in.TaskRunResults != nil { - in, out := &in.TaskRunResults, &out.TaskRunResults - *out = make([]TaskRunResult, len(*in)) - copy(*out, *in) - } - if in.Sidecars != nil { - in, out := &in.Sidecars, &out.Sidecars - *out = make([]SidecarState, len(*in)) - copy(*out, *in) + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1alpha2.TaskRunResources) + (*in).DeepCopyInto(*out) } + in.Inputs.DeepCopyInto(&out.Inputs) + in.Outputs.DeepCopyInto(&out.Outputs) return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TaskRunStatusFields. -func (in *TaskRunStatusFields) DeepCopy() *TaskRunStatusFields { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TaskRunSpec. +func (in *TaskRunSpec) DeepCopy() *TaskRunSpec { if in == nil { return nil } - out := new(TaskRunStatusFields) + out := new(TaskRunSpec) in.DeepCopyInto(out) return out } diff --git a/pkg/apis/pipeline/v1alpha2/taskrun_conversion.go b/pkg/apis/pipeline/v1alpha2/taskrun_conversion.go new file mode 100644 index 00000000000..c02993167de --- /dev/null +++ b/pkg/apis/pipeline/v1alpha2/taskrun_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 = (*TaskRun)(nil) + +// ConvertUp implements api.Convertible +func (source *TaskRun) 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 *TaskRun) 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/taskrun_conversion_test.go b/pkg/apis/pipeline/v1alpha2/taskrun_conversion_test.go new file mode 100644 index 00000000000..01fa6ea729f --- /dev/null +++ b/pkg/apis/pipeline/v1alpha2/taskrun_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 TestTaskRunConversionBadType(t *testing.T) { + good, bad := &TaskRun{}, &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) + } +}