From 824108b0b3bb07399a429e0f8786015ee680ef8f Mon Sep 17 00:00:00 2001 From: Lee Bernick Date: Tue, 19 Apr 2022 15:19:23 -0400 Subject: [PATCH] Add Tekton-owned Step, StepTemplate, and Sidecar This commit copies the Container struct from Kubernetes into Tekton into the existing structs Task.Step.Container, Task.Sidecar.Container, and Task.StepTemplate. This change breaks the Tekton Go libraries, but does not require any changes to the yaml that users provide. This should not change anything for users who do not use the Go libraries. The reason for this change is to have more control over our Task API. For example, we may want to modify the Container fields we support, or change fields to string types to allow them to be parameterized. This commit is the first step towards being able to make changes to parts of the Task API embedded in Container. --- go.mod | 2 +- go.sum | 3 +- .../v1alpha1/cluster_task_conversion_test.go | 4 +- .../v1alpha1/condition_validation_test.go | 23 +- .../v1alpha1/container_replacements.go | 3 +- .../v1alpha1/container_replacements_test.go | 8 +- .../v1alpha1/pipeline_conversion_test.go | 9 +- .../v1alpha1/pipeline_validation_test.go | 9 +- .../v1alpha1/pipelinerun_conversion_test.go | 4 +- .../pipeline/v1alpha1/resource_types_test.go | 26 +- .../pipeline/v1alpha1/step_replacements.go | 2 +- .../v1alpha1/step_replacements_test.go | 136 ++-- .../pipeline/v1alpha1/task_conversion_test.go | 4 +- pkg/apis/pipeline/v1alpha1/task_types.go | 3 + pkg/apis/pipeline/v1alpha1/task_validation.go | 2 +- .../pipeline/v1alpha1/task_validation_test.go | 148 ++-- .../v1alpha1/taskrun_conversion_test.go | 16 +- .../v1alpha1/taskrun_validation_test.go | 22 +- .../v1beta1/container_replacements.go | 63 +- pkg/apis/pipeline/v1beta1/container_types.go | 686 ++++++++++++++++++ pkg/apis/pipeline/v1beta1/merge.go | 17 +- pkg/apis/pipeline/v1beta1/merge_test.go | 304 ++++---- .../pipeline/v1beta1/openapi_generated.go | 313 +++++++- .../v1beta1/pipeline_validation_test.go | 4 +- .../v1beta1/pipelinerun_validation_test.go | 10 +- .../pipeline/v1beta1/resource_types_test.go | 29 +- .../pipeline/v1beta1/sidecar_replacements.go | 2 +- .../v1beta1/sidecar_replacements_test.go | 136 ++-- .../pipeline/v1beta1/step_replacements.go | 2 +- .../v1beta1/step_replacements_test.go | 136 ++-- pkg/apis/pipeline/v1beta1/swagger.json | 178 ++++- pkg/apis/pipeline/v1beta1/task_types.go | 58 +- pkg/apis/pipeline/v1beta1/task_validation.go | 2 +- .../pipeline/v1beta1/task_validation_test.go | 258 +++---- .../v1beta1/taskrun_validation_test.go | 26 +- .../pipeline/v1beta1/zz_generated.deepcopy.go | 221 +++++- .../v1alpha1/cluster/cluster_resource.go | 4 +- .../v1alpha1/cluster/cluster_resource_test.go | 38 +- .../resource/v1alpha1/git/git_resource.go | 22 +- .../v1alpha1/git/git_resource_test.go | 22 +- .../pullrequest/pull_request_resource.go | 4 +- .../pullrequest/pull_request_resource_test.go | 16 +- .../v1alpha1/storage/artifact_bucket.go | 10 +- .../v1alpha1/storage/artifact_bucket_test.go | 10 +- .../resource/v1alpha1/storage/artifact_pvc.go | 10 +- .../v1alpha1/storage/artifact_pvc_test.go | 14 +- pkg/apis/resource/v1alpha1/storage/gcs.go | 16 +- .../resource/v1alpha1/storage/gcs_test.go | 76 +- pkg/apis/resource/v1alpha1/storage/storage.go | 4 +- pkg/pod/pod_test.go | 256 +++---- pkg/pod/script.go | 13 +- pkg/pod/script_test.go | 124 ++-- .../pipelinerun/pipelinerun_test.go | 14 +- .../resources/conditionresolution_test.go | 54 +- .../resources/pipelinerunresolution_test.go | 16 +- .../resources/pipelinerunstate_test.go | 4 +- pkg/reconciler/taskrun/resources/apply.go | 5 +- .../taskrun/resources/apply_test.go | 246 +++---- .../taskrun/resources/image_exporter.go | 5 +- .../taskrun/resources/image_exporter_test.go | 25 +- .../taskrun/resources/input_resource_test.go | 170 ++--- .../taskrun/resources/output_resource_test.go | 160 ++-- .../taskrun/resources/taskref_test.go | 28 +- .../resources/taskresourceresolution_test.go | 9 +- .../taskrun/resources/taskspec_test.go | 9 +- pkg/reconciler/taskrun/taskrun_test.go | 104 ++- .../taskrun/validate_resources_test.go | 35 +- pkg/workspace/apply.go | 2 +- pkg/workspace/apply_test.go | 192 +++-- .../Azure/azure-sdk-for-go/version/version.go | 2 +- vendor/modules.txt | 2 +- 71 files changed, 2764 insertions(+), 1826 deletions(-) create mode 100644 pkg/apis/pipeline/v1beta1/container_types.go diff --git a/go.mod b/go.mod index 86d8ed93883..f4949d05000 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( cloud.google.com/go/compute v1.5.0 // indirect contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect contrib.go.opencensus.io/exporter/prometheus v0.4.0 // indirect - github.com/Azure/azure-sdk-for-go v62.0.0+incompatible // indirect + github.com/Azure/azure-sdk-for-go v63.3.0+incompatible // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.24 // indirect github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect diff --git a/go.sum b/go.sum index 3c2667b9c53..633143c9972 100644 --- a/go.sum +++ b/go.sum @@ -73,8 +73,9 @@ github.com/Antonboom/errname v0.1.5/go.mod h1:DugbBstvPFQbv/5uLcRRzfrNqKE9tVdVCq github.com/Antonboom/nilnil v0.1.0/go.mod h1:PhHLvRPSghY5Y7mX4TW+BHZQYo1A8flE5H20D3IPZBo= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v46.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v62.0.0+incompatible h1:8N2k27SYtc12qj5nTsuFMFJPZn5CGmgMWqTy4y9I7Jw= github.com/Azure/azure-sdk-for-go v62.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v63.3.0+incompatible h1:INepVujzUrmArRZjDLHbtER+FkvCoEwyRCXGqOlmDII= +github.com/Azure/azure-sdk-for-go v63.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= diff --git a/pkg/apis/pipeline/v1alpha1/cluster_task_conversion_test.go b/pkg/apis/pipeline/v1alpha1/cluster_task_conversion_test.go index 0708802e6fe..a66207c243b 100644 --- a/pkg/apis/pipeline/v1alpha1/cluster_task_conversion_test.go +++ b/pkg/apis/pipeline/v1alpha1/cluster_task_conversion_test.go @@ -58,9 +58,9 @@ func TestClusterTaskConversion(t *testing.T) { }, Spec: TaskSpec{ TaskSpec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "foo", - }}}, + }}, Volumes: []corev1.Volume{{}}, Params: []v1beta1.ParamSpec{{ Name: "param-1", diff --git a/pkg/apis/pipeline/v1alpha1/condition_validation_test.go b/pkg/apis/pipeline/v1alpha1/condition_validation_test.go index 2a1a0e80830..e5ada37a96e 100644 --- a/pkg/apis/pipeline/v1alpha1/condition_validation_test.go +++ b/pkg/apis/pipeline/v1alpha1/condition_validation_test.go @@ -24,7 +24,6 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" "github.com/tektoncd/pipeline/test/diff" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/apis" ) @@ -33,10 +32,10 @@ func TestCondition_Validate(t *testing.T) { c := v1alpha1.Condition{ ObjectMeta: metav1.ObjectMeta{Name: "condname"}, Spec: v1alpha1.ConditionSpec{ - Check: v1alpha1.Step{Container: corev1.Container{ + Check: v1alpha1.Step{ Name: "cname", Image: "ubuntu", - }}, + }, Params: []v1alpha1.ParamSpec{{ Name: "paramname", Type: v1alpha1.ParamTypeString, @@ -67,9 +66,9 @@ func TestCondition_Invalid(t *testing.T) { cond: &v1alpha1.Condition{ ObjectMeta: metav1.ObjectMeta{Name: "condname"}, Spec: v1alpha1.ConditionSpec{ - Check: v1alpha1.Step{Container: corev1.Container{ + Check: v1alpha1.Step{ Image: "", - }}, + }, }, }, expectedError: apis.FieldError{ @@ -82,11 +81,9 @@ func TestCondition_Invalid(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "condname"}, Spec: v1alpha1.ConditionSpec{ Check: v1alpha1.Step{ - Container: corev1.Container{ - Image: "image", - Command: []string{"exit", "0"}, - }, - Script: "echo foo", + Image: "image", + Command: []string{"exit", "0"}, + Script: "echo foo", }, }, }, @@ -100,10 +97,8 @@ func TestCondition_Invalid(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "condname"}, Spec: v1alpha1.ConditionSpec{ Check: v1alpha1.Step{ - Container: corev1.Container{ - Name: "Cname", - Image: "image", - }, + Name: "Cname", + Image: "image", }, }, }, diff --git a/pkg/apis/pipeline/v1alpha1/container_replacements.go b/pkg/apis/pipeline/v1alpha1/container_replacements.go index 63606afc6ac..04541934450 100644 --- a/pkg/apis/pipeline/v1alpha1/container_replacements.go +++ b/pkg/apis/pipeline/v1alpha1/container_replacements.go @@ -18,12 +18,11 @@ package v1alpha1 import ( "github.com/tektoncd/pipeline/pkg/substitution" - corev1 "k8s.io/api/core/v1" ) // ApplyContainerReplacements replaces ${...} expressions in the container's name, image, args, env, command, workingDir, // and volumes. -func ApplyContainerReplacements(step *corev1.Container, stringReplacements map[string]string, arrayReplacements map[string][]string) { +func ApplyContainerReplacements(step *Step, stringReplacements map[string]string, arrayReplacements map[string][]string) { step.Name = substitution.ApplyReplacements(step.Name, stringReplacements) step.Image = substitution.ApplyReplacements(step.Image, stringReplacements) diff --git a/pkg/apis/pipeline/v1alpha1/container_replacements_test.go b/pkg/apis/pipeline/v1alpha1/container_replacements_test.go index ce84bf3a738..0f2cc766f36 100644 --- a/pkg/apis/pipeline/v1alpha1/container_replacements_test.go +++ b/pkg/apis/pipeline/v1alpha1/container_replacements_test.go @@ -34,7 +34,7 @@ func TestApplyContainerReplacements(t *testing.T) { "array.replace.me": {"val1", "val2"}, } - s := corev1.Container{ + s := v1alpha1.Step{ Name: "$(replace.me)", Image: "$(replace.me)", Command: []string{"$(array.replace.me)"}, @@ -77,7 +77,7 @@ func TestApplyContainerReplacements(t *testing.T) { }}, } - expected := corev1.Container{ + expected := v1alpha1.Step{ Name: "replaced!", Image: "replaced!", Command: []string{"val1", "val2"}, @@ -127,7 +127,7 @@ func TestApplyContainerReplacements(t *testing.T) { } func TestApplyContainerReplacements_NotDefined(t *testing.T) { - s := corev1.Container{ + s := v1alpha1.Step{ Name: "$(params.not.defined)", } replacements := map[string]string{ @@ -138,7 +138,7 @@ func TestApplyContainerReplacements_NotDefined(t *testing.T) { "array.replace.me": {"val1", "val2"}, } - expected := corev1.Container{ + expected := v1alpha1.Step{ Name: "$(params.not.defined)", } v1alpha1.ApplyContainerReplacements(&s, replacements, arrayReplacements) diff --git a/pkg/apis/pipeline/v1alpha1/pipeline_conversion_test.go b/pkg/apis/pipeline/v1alpha1/pipeline_conversion_test.go index 2789f5b6e31..8f34514fc05 100644 --- a/pkg/apis/pipeline/v1alpha1/pipeline_conversion_test.go +++ b/pkg/apis/pipeline/v1alpha1/pipeline_conversion_test.go @@ -25,7 +25,6 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" resource "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1" "github.com/tektoncd/pipeline/test/diff" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/apis" ) @@ -105,9 +104,9 @@ func TestPipelineConversion_Success(t *testing.T) { }, { Name: "task2", TaskSpec: &TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "foo", - }}}, + }}, }}, RunAfter: []string{"task1"}, }}, @@ -162,9 +161,9 @@ func TestPipelineConversion_Failure(t *testing.T) { Name: "task2", TaskSpec: &TaskSpec{ TaskSpec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "foo", - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: []v1beta1.TaskResource{{ResourceDeclaration: v1beta1.ResourceDeclaration{ Name: "input-1", diff --git a/pkg/apis/pipeline/v1alpha1/pipeline_validation_test.go b/pkg/apis/pipeline/v1alpha1/pipeline_validation_test.go index eb21c86cc23..404a24600ed 100644 --- a/pkg/apis/pipeline/v1alpha1/pipeline_validation_test.go +++ b/pkg/apis/pipeline/v1alpha1/pipeline_validation_test.go @@ -23,7 +23,6 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -157,10 +156,10 @@ func TestPipeline_Validate(t *testing.T) { Name: "foo", TaskRef: &v1alpha1.TaskRef{Name: "foo-task"}, TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "foo", Image: "bar", - }}}, + }}, }}, }}, }, @@ -186,10 +185,10 @@ func TestPipeline_Validate(t *testing.T) { Tasks: []v1alpha1.PipelineTask{{ Name: "foo", TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "foo", Image: "bar", - }}}, + }}, }}, }}, }, diff --git a/pkg/apis/pipeline/v1alpha1/pipelinerun_conversion_test.go b/pkg/apis/pipeline/v1alpha1/pipelinerun_conversion_test.go index 67c083bfe16..2e059f57898 100644 --- a/pkg/apis/pipeline/v1alpha1/pipelinerun_conversion_test.go +++ b/pkg/apis/pipeline/v1alpha1/pipelinerun_conversion_test.go @@ -113,9 +113,9 @@ func TestPipelineRunConversion(t *testing.T) { }, { Name: "task2", TaskSpec: &TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "foo", - }}}, + }}, }}, RunAfter: []string{"task1"}, }}, diff --git a/pkg/apis/pipeline/v1alpha1/resource_types_test.go b/pkg/apis/pipeline/v1alpha1/resource_types_test.go index 52a55c2ee18..3ccb8a0864f 100644 --- a/pkg/apis/pipeline/v1alpha1/resource_types_test.go +++ b/pkg/apis/pipeline/v1alpha1/resource_types_test.go @@ -24,13 +24,13 @@ import ( ) var ( - prependStep = corev1.Container{ + prependStep = v1alpha1.Step{ Name: "prepend-step", Image: "dummy", Command: []string{"doit"}, Args: []string{"stuff", "things"}, } - appendStep = corev1.Container{ + appendStep = v1alpha1.Step{ Name: "append-step", Image: "dummy", Command: []string{"doit"}, @@ -47,15 +47,11 @@ var ( type TestTaskModifier struct{} func (tm *TestTaskModifier) GetStepsToPrepend() []v1alpha1.Step { - return []v1alpha1.Step{{ - Container: prependStep, - }} + return []v1alpha1.Step{prependStep} } func (tm *TestTaskModifier) GetStepsToAppend() []v1alpha1.Step { - return []v1alpha1.Step{{ - Container: appendStep, - }} + return []v1alpha1.Step{appendStep} } func (tm *TestTaskModifier) GetVolumes() []corev1.Volume { @@ -84,11 +80,7 @@ func TestApplyTaskModifier(t *testing.T) { } expectedTaskSpec := v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{ - Container: prependStep, - }, { - Container: appendStep, - }}, + Steps: []v1alpha1.Step{prependStep, appendStep}, Volumes: []corev1.Volume{ volume, }, @@ -108,22 +100,22 @@ func TestApplyTaskModifier_AlreadyAdded(t *testing.T) { }{{ name: "prepend already added", ts: v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: prependStep}}, + Steps: []v1alpha1.Step{prependStep}, }}, }, { name: "append already added", ts: v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: appendStep}}, + Steps: []v1alpha1.Step{appendStep}, }}, }, { name: "both steps already added", ts: v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: prependStep}, {Container: appendStep}}, + Steps: []v1alpha1.Step{prependStep, appendStep}, }}, }, { name: "both steps already added reverse order", ts: v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: appendStep}, {Container: prependStep}}, + Steps: []v1alpha1.Step{appendStep, prependStep}, }}, }, { name: "volume with same name but diff content already added", diff --git a/pkg/apis/pipeline/v1alpha1/step_replacements.go b/pkg/apis/pipeline/v1alpha1/step_replacements.go index 5a484579ec5..15f9b9ade20 100644 --- a/pkg/apis/pipeline/v1alpha1/step_replacements.go +++ b/pkg/apis/pipeline/v1alpha1/step_replacements.go @@ -23,5 +23,5 @@ import ( // ApplyStepReplacements applies variable interpolation on a Step. func ApplyStepReplacements(step *Step, stringReplacements map[string]string, arrayReplacements map[string][]string) { step.Script = substitution.ApplyReplacements(step.Script, stringReplacements) - ApplyContainerReplacements(&step.Container, stringReplacements, arrayReplacements) + ApplyContainerReplacements(step, stringReplacements, arrayReplacements) } diff --git a/pkg/apis/pipeline/v1alpha1/step_replacements_test.go b/pkg/apis/pipeline/v1alpha1/step_replacements_test.go index 70618685b50..633c09a0db5 100644 --- a/pkg/apis/pipeline/v1alpha1/step_replacements_test.go +++ b/pkg/apis/pipeline/v1alpha1/step_replacements_test.go @@ -35,95 +35,91 @@ func TestApplyStepReplacements(t *testing.T) { } s := v1alpha1.Step{ - Script: "$(replace.me)", - Container: corev1.Container{ - Name: "$(replace.me)", - Image: "$(replace.me)", - Command: []string{"$(array.replace.me)"}, - Args: []string{"$(array.replace.me)"}, - WorkingDir: "$(replace.me)", - EnvFrom: []corev1.EnvFromSource{{ - ConfigMapRef: &corev1.ConfigMapEnvSource{ + Script: "$(replace.me)", + Name: "$(replace.me)", + Image: "$(replace.me)", + Command: []string{"$(array.replace.me)"}, + Args: []string{"$(array.replace.me)"}, + WorkingDir: "$(replace.me)", + EnvFrom: []corev1.EnvFromSource{{ + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(replace.me)", + }, + }, + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(replace.me)", + }, + }, + }}, + Env: []corev1.EnvVar{{ + Name: "not_me", + Value: "$(replace.me)", + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "$(replace.me)", }, + Key: "$(replace.me)", }, - SecretRef: &corev1.SecretEnvSource{ + SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "$(replace.me)", }, + Key: "$(replace.me)", }, - }}, - Env: []corev1.EnvVar{{ - Name: "not_me", - Value: "$(replace.me)", - ValueFrom: &corev1.EnvVarSource{ - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(replace.me)", - }, - Key: "$(replace.me)", - }, - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(replace.me)", - }, - Key: "$(replace.me)", - }, - }, - }}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "$(replace.me)", - MountPath: "$(replace.me)", - SubPath: "$(replace.me)", - }}, - }, + }, + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(replace.me)", + MountPath: "$(replace.me)", + SubPath: "$(replace.me)", + }}, } expected := v1alpha1.Step{ - Script: "replaced!", - Container: corev1.Container{ - Name: "replaced!", - Image: "replaced!", - Command: []string{"val1", "val2"}, - Args: []string{"val1", "val2"}, - WorkingDir: "replaced!", - EnvFrom: []corev1.EnvFromSource{{ - ConfigMapRef: &corev1.ConfigMapEnvSource{ + Script: "replaced!", + Name: "replaced!", + Image: "replaced!", + Command: []string{"val1", "val2"}, + Args: []string{"val1", "val2"}, + WorkingDir: "replaced!", + EnvFrom: []corev1.EnvFromSource{{ + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "replaced!", + }, + }, + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "replaced!", + }, + }, + }}, + Env: []corev1.EnvVar{{ + Name: "not_me", + Value: "replaced!", + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "replaced!", }, + Key: "replaced!", }, - SecretRef: &corev1.SecretEnvSource{ + SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "replaced!", }, + Key: "replaced!", }, - }}, - Env: []corev1.EnvVar{{ - Name: "not_me", - Value: "replaced!", - ValueFrom: &corev1.EnvVarSource{ - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "replaced!", - }, - Key: "replaced!", - }, - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "replaced!", - }, - Key: "replaced!", - }, - }, - }}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "replaced!", - MountPath: "replaced!", - SubPath: "replaced!", - }}, - }, + }, + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "replaced!", + MountPath: "replaced!", + SubPath: "replaced!", + }}, } v1alpha1.ApplyStepReplacements(&s, replacements, arrayReplacements) if d := cmp.Diff(s, expected); d != "" { diff --git a/pkg/apis/pipeline/v1alpha1/task_conversion_test.go b/pkg/apis/pipeline/v1alpha1/task_conversion_test.go index a9b13685828..d20edf4118a 100644 --- a/pkg/apis/pipeline/v1alpha1/task_conversion_test.go +++ b/pkg/apis/pipeline/v1alpha1/task_conversion_test.go @@ -59,9 +59,9 @@ func TestTaskConversion(t *testing.T) { Spec: TaskSpec{ TaskSpec: v1beta1.TaskSpec{ Description: "test", - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "foo", - }}}, + }}, Volumes: []corev1.Volume{{}}, Params: []v1beta1.ParamSpec{{ Name: "param-1", diff --git a/pkg/apis/pipeline/v1alpha1/task_types.go b/pkg/apis/pipeline/v1alpha1/task_types.go index 1121e93c787..2c4180b5796 100644 --- a/pkg/apis/pipeline/v1alpha1/task_types.go +++ b/pkg/apis/pipeline/v1alpha1/task_types.go @@ -70,6 +70,9 @@ type Step = v1beta1.Step // Sidecar has nearly the same data structure as Step, consisting of a Container and an optional Script, but does not have the ability to timeout. type Sidecar = v1beta1.Sidecar +// StepTemplate is a template for a Step +type StepTemplate = v1beta1.StepTemplate + // +genclient // +genclient:noStatus // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object diff --git a/pkg/apis/pipeline/v1alpha1/task_validation.go b/pkg/apis/pipeline/v1alpha1/task_validation.go index 94a13a69185..6366a75d7bd 100644 --- a/pkg/apis/pipeline/v1alpha1/task_validation.go +++ b/pkg/apis/pipeline/v1alpha1/task_validation.go @@ -148,7 +148,7 @@ func (ts *TaskSpec) Validate(ctx context.Context) *apis.FieldError { // validateDeclaredWorkspaces will make sure that the declared workspaces do not try to use // a mount path which conflicts with any other declared workspaces, with the explicitly // declared volume mounts, or with the stepTemplate. The names must also be unique. -func validateDeclaredWorkspaces(workspaces []WorkspaceDeclaration, steps []Step, stepTemplate *corev1.Container) *apis.FieldError { +func validateDeclaredWorkspaces(workspaces []WorkspaceDeclaration, steps []Step, stepTemplate *StepTemplate) *apis.FieldError { mountPaths := sets.NewString() for _, step := range steps { for _, vm := range step.VolumeMounts { diff --git a/pkg/apis/pipeline/v1alpha1/task_validation_test.go b/pkg/apis/pipeline/v1alpha1/task_validation_test.go index b7459b85d8b..febb2de3343 100644 --- a/pkg/apis/pipeline/v1alpha1/task_validation_test.go +++ b/pkg/apis/pipeline/v1alpha1/task_validation_test.go @@ -67,22 +67,22 @@ var requiredResource = v1alpha1.TaskResource{ }, } -var validSteps = []v1alpha1.Step{{Container: corev1.Container{ +var validSteps = []v1alpha1.Step{{ Name: "mystep", Image: "myimage", -}}} +}} -var invalidSteps = []v1alpha1.Step{{Container: corev1.Container{ +var invalidSteps = []v1alpha1.Step{{ Name: "replaceImage", Image: "myimage", -}}} +}} func TestTaskSpecValidate(t *testing.T) { type fields struct { Inputs *v1alpha1.Inputs Outputs *v1alpha1.Outputs Steps []v1alpha1.Step - StepTemplate *corev1.Container + StepTemplate *v1alpha1.StepTemplate Workspaces []v1alpha1.WorkspaceDeclaration } tests := []struct { @@ -91,11 +91,11 @@ func TestTaskSpecValidate(t *testing.T) { }{{ name: "unnamed steps", fields: fields{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Image: "myimage", - }}, {Container: corev1.Container{ + }, { Image: "myotherimage", - }}}, + }}, }, }, { name: "valid inputs (type implied)", @@ -206,12 +206,12 @@ func TestTaskSpecValidate(t *testing.T) { Outputs: &v1alpha1.Outputs{ Resources: []v1alpha1.TaskResource{validResource}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "$(inputs.resources.source.url)", Args: []string{"--flag=$(inputs.params.baz) && $(input.params.foo-is-baz)"}, WorkingDir: "/foo/bar/$(outputs.resources.source)", - }}}, + }}, }, }, { name: "valid array template variable", @@ -229,13 +229,13 @@ func TestTaskSpecValidate(t *testing.T) { Outputs: &v1alpha1.Outputs{ Resources: []v1alpha1.TaskResource{validResource}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "$(inputs.resources.source.url)", Command: []string{"$(inputs.params.foo-is-baz)"}, Args: []string{"$(inputs.params.baz)", "middle string", "$(input.params.foo-is-baz)"}, WorkingDir: "/foo/bar/$(outputs.resources.source)", - }}}, + }}, }, }, { name: "valid star array template variable", @@ -253,32 +253,32 @@ func TestTaskSpecValidate(t *testing.T) { Outputs: &v1alpha1.Outputs{ Resources: []v1alpha1.TaskResource{validResource}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "$(inputs.resources.source.url)", Command: []string{"$(inputs.params.foo-is-baz)"}, Args: []string{"$(inputs.params.baz[*])", "middle string", "$(input.params.foo-is-baz[*])"}, WorkingDir: "/foo/bar/$(outputs.resources.source)", - }}}, + }}, }, }, { name: "valid legacy credential helper (creds-init) path variable", fields: fields{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "echo", Args: []string{"$(credentials.path)"}, - }}}, + }}, }, }, { name: "step template included in validation", fields: fields{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "astep", Command: []string{"echo"}, Args: []string{"hello"}, - }}}, - StepTemplate: &corev1.Container{ + }}, + StepTemplate: &v1alpha1.StepTemplate{ Image: "some-image", }, }, @@ -286,9 +286,7 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid step with script", fields: fields{ Steps: []v1alpha1.Step{{ - Container: corev1.Container{ - Image: "my-image", - }, + Image: "my-image", Script: ` #!/usr/bin/env bash hello world`, @@ -298,10 +296,8 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid step with script and args", fields: fields{ Steps: []v1alpha1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, Script: ` #!/usr/bin/env bash hello $1`, @@ -310,22 +306,20 @@ func TestTaskSpecValidate(t *testing.T) { }, { name: "valid step with volumeMount under /tekton/home", fields: fields{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Image: "myimage", VolumeMounts: []corev1.VolumeMount{{ Name: "foo", MountPath: "/tekton/home", }}, - }}}, + }}, }, }, { name: "valid workspace", fields: fields{ Steps: []v1alpha1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, }}, Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "foo-workspace", @@ -360,7 +354,7 @@ func TestTaskSpecValidateError(t *testing.T) { Outputs *v1alpha1.Outputs Steps []v1alpha1.Step Volumes []corev1.Volume - StepTemplate *corev1.Container + StepTemplate *v1alpha1.StepTemplate Workspaces []v1alpha1.WorkspaceDeclaration // v1beta1 Params []v1beta1.ParamSpec @@ -566,11 +560,11 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "inexistent input param variable", fields: fields{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "myimage", Args: []string{"--flag=$(inputs.params.inexistent)"}, - }}}, + }}, }, expectedError: apis.FieldError{ Message: `non-existent variable in "--flag=$(inputs.params.inexistent)" for step arg[0]`, @@ -592,13 +586,13 @@ func TestTaskSpecValidateError(t *testing.T) { Outputs: &v1alpha1.Outputs{ Resources: []v1alpha1.TaskResource{validResource}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "$(inputs.params.baz)", Command: []string{"$(inputs.params.foo-is-baz)"}, Args: []string{"$(inputs.params.baz)", "middle string", "$(input.resources.foo.url)"}, WorkingDir: "/foo/bar/$(outputs.resources.source)", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable type invalid in "$(inputs.params.baz)" for step image`, @@ -620,13 +614,13 @@ func TestTaskSpecValidateError(t *testing.T) { Outputs: &v1alpha1.Outputs{ Resources: []v1alpha1.TaskResource{validResource}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "$(inputs.params.baz[*])", Command: []string{"$(inputs.params.foo-is-baz)"}, Args: []string{"$(inputs.params.baz)", "middle string", "$(input.resources.foo.url)"}, WorkingDir: "/foo/bar/$(outputs.resources.source)", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable type invalid in "$(inputs.params.baz[*])" for step image`, @@ -648,13 +642,13 @@ func TestTaskSpecValidateError(t *testing.T) { Outputs: &v1alpha1.Outputs{ Resources: []v1alpha1.TaskResource{validResource}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "someimage", Command: []string{"$(inputs.params.foo-is-baz)"}, Args: []string{"not isolated: $(inputs.params.baz)", "middle string", "$(input.resources.foo.url)"}, WorkingDir: "/foo/bar/$(outputs.resources.source)", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable is not properly isolated in "not isolated: $(inputs.params.baz)" for step arg[0]`, @@ -676,13 +670,13 @@ func TestTaskSpecValidateError(t *testing.T) { Outputs: &v1alpha1.Outputs{ Resources: []v1alpha1.TaskResource{validResource}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "someimage", Command: []string{"$(inputs.params.foo-is-baz)"}, Args: []string{"not isolated: $(inputs.params.baz[*])", "middle string", "$(input.resources.foo.url)"}, WorkingDir: "/foo/bar/$(outputs.resources.source)", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable is not properly isolated in "not isolated: $(inputs.params.baz[*])" for step arg[0]`, @@ -691,10 +685,10 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "inexistent input resource variable", fields: fields{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "myimage:$(inputs.resources.inputs)", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `non-existent variable in "myimage:$(inputs.resources.inputs)" for step image`, @@ -722,13 +716,13 @@ func TestTaskSpecValidateError(t *testing.T) { Outputs: &v1alpha1.Outputs{ Resources: []v1alpha1.TaskResource{validResource}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "someimage", Command: []string{"$(inputs.params.foo-is-baz)"}, Args: []string{"not isolated: $(inputs.params.baz)", "middle string", "$(input.resources.foo.url)"}, WorkingDir: "/foo/bar/$(outputs.resources.source)", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable is not properly isolated in "not isolated: $(inputs.params.baz)" for step arg[0]`, @@ -737,10 +731,10 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "inexistent input resource variable", fields: fields{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "myimage:$(inputs.resources.inputs)", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `non-existent variable in "myimage:$(inputs.resources.inputs)" for step image`, @@ -749,11 +743,11 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "inexistent output param variable", fields: fields{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "myimage", WorkingDir: "/foo/bar/$(outputs.resources.inexistent)", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `non-existent variable in "/foo/bar/$(outputs.resources.inexistent)" for step workingDir`, @@ -772,11 +766,11 @@ func TestTaskSpecValidateError(t *testing.T) { }, }}, }, - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "myimage", Args: []string{"$(inputs.params.foo) && $(inputs.params.inexistent)"}, - }}}, + }}, }, expectedError: apis.FieldError{ Message: `non-existent variable in "$(inputs.params.foo) && $(inputs.params.inexistent)" for step arg[0]`, @@ -800,11 +794,9 @@ func TestTaskSpecValidateError(t *testing.T) { name: "step with script and command", fields: fields{ Steps: []v1alpha1.Step{{ - Container: corev1.Container{ - Image: "myimage", - Command: []string{"command"}, - }, - Script: "script", + Image: "myimage", + Command: []string{"command"}, + Script: "script", }}, }, expectedError: apis.FieldError{ @@ -814,13 +806,13 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "step volume mounts under /tekton/", fields: fields{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Image: "myimage", VolumeMounts: []corev1.VolumeMount{{ Name: "foo", MountPath: "/tekton/foo", }}, - }}}, + }}, }, expectedError: apis.FieldError{ Message: `step 0 volumeMount cannot be mounted under /tekton/ (volumeMount "foo" mounted at "/tekton/foo")`, @@ -829,13 +821,13 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "step volume mount name starts with tekton-internal-", fields: fields{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Image: "myimage", VolumeMounts: []corev1.VolumeMount{{ Name: "tekton-internal-foo", MountPath: "/this/is/fine", }}, - }}}, + }}, }, expectedError: apis.FieldError{ Message: `step 0 volumeMount name "tekton-internal-foo" cannot start with "tekton-internal-"`, @@ -875,14 +867,12 @@ func TestTaskSpecValidateError(t *testing.T) { name: "workspace mount path already in volumeMounts", fields: fields{ Steps: []v1alpha1.Step{{ - Container: corev1.Container{ - Image: "myimage", - Command: []string{"command"}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "my-mount", - MountPath: "/foo", - }}, - }, + Image: "myimage", + Command: []string{"command"}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "my-mount", + MountPath: "/foo", + }}, }}, Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "some-workspace", @@ -897,14 +887,12 @@ func TestTaskSpecValidateError(t *testing.T) { name: "workspace default mount path already in volumeMounts", fields: fields{ Steps: []v1alpha1.Step{{ - Container: corev1.Container{ - Image: "myimage", - Command: []string{"command"}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "my-mount", - MountPath: "/workspace/some-workspace/", - }}, - }, + Image: "myimage", + Command: []string{"command"}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "my-mount", + MountPath: "/workspace/some-workspace/", + }}, }}, Workspaces: []v1alpha1.WorkspaceDeclaration{{ Name: "some-workspace", @@ -917,7 +905,7 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "workspace mount path already in stepTemplate", fields: fields{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1alpha1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "my-mount", MountPath: "/foo", @@ -936,7 +924,7 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "workspace default mount path already in stepTemplate", fields: fields{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1alpha1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "my-mount", MountPath: "/workspace/some-workspace", diff --git a/pkg/apis/pipeline/v1alpha1/taskrun_conversion_test.go b/pkg/apis/pipeline/v1alpha1/taskrun_conversion_test.go index 80741b0cf99..9e0397940be 100644 --- a/pkg/apis/pipeline/v1alpha1/taskrun_conversion_test.go +++ b/pkg/apis/pipeline/v1alpha1/taskrun_conversion_test.go @@ -111,9 +111,9 @@ func TestTaskRunConversion(t *testing.T) { }, Spec: TaskRunSpec{ TaskSpec: &TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "foo", - }}}, + }}, }}, ServiceAccountName: "sa", Timeout: &metav1.Duration{Duration: 1 * time.Minute}, @@ -156,9 +156,9 @@ func TestTaskRunConversion(t *testing.T) { }, Spec: TaskRunSpec{ TaskSpec: &TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "foo", - }}}, + }}, }}, ServiceAccountName: "sa", Timeout: &metav1.Duration{Duration: 1 * time.Minute}, @@ -193,9 +193,9 @@ func TestTaskRunConversion(t *testing.T) { }, Spec: TaskRunSpec{ TaskSpec: &TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "foo", - }}}, + }}, }}, ServiceAccountName: "sa", Timeout: &metav1.Duration{Duration: 1 * time.Minute}, @@ -238,9 +238,9 @@ func TestTaskRunConversion(t *testing.T) { }, Spec: TaskRunSpec{ TaskSpec: &TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "foo", - }}}, + }}, }}, ServiceAccountName: "sa", Timeout: &metav1.Duration{Duration: 1 * time.Minute}, diff --git a/pkg/apis/pipeline/v1alpha1/taskrun_validation_test.go b/pkg/apis/pipeline/v1alpha1/taskrun_validation_test.go index b5f20e71c3d..86404ae7b5e 100644 --- a/pkg/apis/pipeline/v1alpha1/taskrun_validation_test.go +++ b/pkg/apis/pipeline/v1alpha1/taskrun_validation_test.go @@ -164,10 +164,10 @@ func TestTaskRunSpec_Invalid(t *testing.T) { Name: "taskrefname", }, TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "myimage", - }}}, + }}, }}, }, wantErr: apis.ErrDisallowedFields("spec.taskspec", "spec.taskref"), @@ -184,10 +184,10 @@ func TestTaskRunSpec_Invalid(t *testing.T) { name: "invalid taskspec", spec: v1alpha1.TaskRunSpec{ TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "invalid-name-with-$weird-char*/%", Image: "myimage", - }}}, + }}, }}, }, wantErr: &apis.FieldError{ @@ -214,10 +214,10 @@ func TestTaskRunSpec_Validate(t *testing.T) { name: "taskspec without a taskRef", spec: v1alpha1.TaskRunSpec{ TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "myimage", - }}}, + }}, }}, }, }, { @@ -225,10 +225,10 @@ func TestTaskRunSpec_Validate(t *testing.T) { spec: v1alpha1.TaskRunSpec{ Timeout: &metav1.Duration{Duration: 0}, TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ - Steps: []v1alpha1.Step{{Container: corev1.Container{ + Steps: []v1alpha1.Step{{ Name: "mystep", Image: "myimage", - }}}, + }}, }}, }, }, { @@ -236,10 +236,8 @@ func TestTaskRunSpec_Validate(t *testing.T) { spec: v1alpha1.TaskRunSpec{ TaskSpec: &v1alpha1.TaskSpec{TaskSpec: v1beta1.TaskSpec{ Steps: []v1alpha1.Step{{ - Container: corev1.Container{ - Name: "mystep", - Image: "myimage", - }, + Name: "mystep", + Image: "myimage", Script: `echo "creds-init writes to $(credentials.path)"`, }}, }}, diff --git a/pkg/apis/pipeline/v1beta1/container_replacements.go b/pkg/apis/pipeline/v1beta1/container_replacements.go index 30af4e11e8c..5274507f772 100644 --- a/pkg/apis/pipeline/v1beta1/container_replacements.go +++ b/pkg/apis/pipeline/v1beta1/container_replacements.go @@ -21,54 +21,67 @@ import ( corev1 "k8s.io/api/core/v1" ) -// applyContainerReplacements applies variable interpolation on a Container (subset of a Step). -func applyContainerReplacements(step *corev1.Container, stringReplacements map[string]string, arrayReplacements map[string][]string) { - step.Name = substitution.ApplyReplacements(step.Name, stringReplacements) - step.Image = substitution.ApplyReplacements(step.Image, stringReplacements) - step.ImagePullPolicy = corev1.PullPolicy(substitution.ApplyReplacements(string(step.ImagePullPolicy), stringReplacements)) +// applyStepReplacements returns a StepContainer with variable interpolation applied. +func applyStepReplacements(step *Step, stringReplacements map[string]string, arrayReplacements map[string][]string) { + c := step.ToK8sContainer() + applyContainerReplacements(c, stringReplacements, arrayReplacements) + step.SetContainerFields(*c) +} + +// applySidecarReplacements returns a SidecarContainer with variable interpolation applied. +func applySidecarReplacements(sidecar *Sidecar, stringReplacements map[string]string, arrayReplacements map[string][]string) { + c := sidecar.ToK8sContainer() + applyContainerReplacements(c, stringReplacements, arrayReplacements) + sidecar.SetContainerFields(*c) +} + +func applyContainerReplacements(c *corev1.Container, stringReplacements map[string]string, arrayReplacements map[string][]string) { + c.Name = substitution.ApplyReplacements(c.Name, stringReplacements) + c.Image = substitution.ApplyReplacements(c.Image, stringReplacements) + c.ImagePullPolicy = corev1.PullPolicy(substitution.ApplyReplacements(string(c.ImagePullPolicy), stringReplacements)) // Use ApplyArrayReplacements here, as additional args may be added via an array parameter. var newArgs []string - for _, a := range step.Args { + for _, a := range c.Args { newArgs = append(newArgs, substitution.ApplyArrayReplacements(a, stringReplacements, arrayReplacements)...) } - step.Args = newArgs + c.Args = newArgs - for ie, e := range step.Env { - step.Env[ie].Value = substitution.ApplyReplacements(e.Value, stringReplacements) - if step.Env[ie].ValueFrom != nil { + for ie, e := range c.Env { + c.Env[ie].Value = substitution.ApplyReplacements(e.Value, stringReplacements) + if c.Env[ie].ValueFrom != nil { if e.ValueFrom.SecretKeyRef != nil { - step.Env[ie].ValueFrom.SecretKeyRef.LocalObjectReference.Name = substitution.ApplyReplacements(e.ValueFrom.SecretKeyRef.LocalObjectReference.Name, stringReplacements) - step.Env[ie].ValueFrom.SecretKeyRef.Key = substitution.ApplyReplacements(e.ValueFrom.SecretKeyRef.Key, stringReplacements) + c.Env[ie].ValueFrom.SecretKeyRef.LocalObjectReference.Name = substitution.ApplyReplacements(e.ValueFrom.SecretKeyRef.LocalObjectReference.Name, stringReplacements) + c.Env[ie].ValueFrom.SecretKeyRef.Key = substitution.ApplyReplacements(e.ValueFrom.SecretKeyRef.Key, stringReplacements) } if e.ValueFrom.ConfigMapKeyRef != nil { - step.Env[ie].ValueFrom.ConfigMapKeyRef.LocalObjectReference.Name = substitution.ApplyReplacements(e.ValueFrom.ConfigMapKeyRef.LocalObjectReference.Name, stringReplacements) - step.Env[ie].ValueFrom.ConfigMapKeyRef.Key = substitution.ApplyReplacements(e.ValueFrom.ConfigMapKeyRef.Key, stringReplacements) + c.Env[ie].ValueFrom.ConfigMapKeyRef.LocalObjectReference.Name = substitution.ApplyReplacements(e.ValueFrom.ConfigMapKeyRef.LocalObjectReference.Name, stringReplacements) + c.Env[ie].ValueFrom.ConfigMapKeyRef.Key = substitution.ApplyReplacements(e.ValueFrom.ConfigMapKeyRef.Key, stringReplacements) } } } - for ie, e := range step.EnvFrom { - step.EnvFrom[ie].Prefix = substitution.ApplyReplacements(e.Prefix, stringReplacements) + for ie, e := range c.EnvFrom { + c.EnvFrom[ie].Prefix = substitution.ApplyReplacements(e.Prefix, stringReplacements) if e.ConfigMapRef != nil { - step.EnvFrom[ie].ConfigMapRef.LocalObjectReference.Name = substitution.ApplyReplacements(e.ConfigMapRef.LocalObjectReference.Name, stringReplacements) + c.EnvFrom[ie].ConfigMapRef.LocalObjectReference.Name = substitution.ApplyReplacements(e.ConfigMapRef.LocalObjectReference.Name, stringReplacements) } if e.SecretRef != nil { - step.EnvFrom[ie].SecretRef.LocalObjectReference.Name = substitution.ApplyReplacements(e.SecretRef.LocalObjectReference.Name, stringReplacements) + c.EnvFrom[ie].SecretRef.LocalObjectReference.Name = substitution.ApplyReplacements(e.SecretRef.LocalObjectReference.Name, stringReplacements) } } - step.WorkingDir = substitution.ApplyReplacements(step.WorkingDir, stringReplacements) + c.WorkingDir = substitution.ApplyReplacements(c.WorkingDir, stringReplacements) // Use ApplyArrayReplacements here, as additional commands may be added via an array parameter. var newCommand []string - for _, c := range step.Command { + for _, c := range c.Command { newCommand = append(newCommand, substitution.ApplyArrayReplacements(c, stringReplacements, arrayReplacements)...) } - step.Command = newCommand + c.Command = newCommand - for iv, v := range step.VolumeMounts { - step.VolumeMounts[iv].Name = substitution.ApplyReplacements(v.Name, stringReplacements) - step.VolumeMounts[iv].MountPath = substitution.ApplyReplacements(v.MountPath, stringReplacements) - step.VolumeMounts[iv].SubPath = substitution.ApplyReplacements(v.SubPath, stringReplacements) + for iv, v := range c.VolumeMounts { + c.VolumeMounts[iv].Name = substitution.ApplyReplacements(v.Name, stringReplacements) + c.VolumeMounts[iv].MountPath = substitution.ApplyReplacements(v.MountPath, stringReplacements) + c.VolumeMounts[iv].SubPath = substitution.ApplyReplacements(v.SubPath, stringReplacements) } } diff --git a/pkg/apis/pipeline/v1beta1/container_types.go b/pkg/apis/pipeline/v1beta1/container_types.go new file mode 100644 index 00000000000..1c96476835f --- /dev/null +++ b/pkg/apis/pipeline/v1beta1/container_types.go @@ -0,0 +1,686 @@ +package v1beta1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Step runs a subcomponent of a Task +type Step struct { + + // Name of the container specified as a DNS_LABEL. + // Each container in a pod must have a unique name (DNS_LABEL). + // Cannot be updated. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + // Docker image name. + // More info: https://kubernetes.io/docs/concepts/containers/images + // This field is optional to allow higher level config management to default or override + // container images in workload controllers like Deployments and StatefulSets. + // +optional + Image string `json:"image,omitempty" protobuf:"bytes,2,opt,name=image"` + // Entrypoint array. Not executed within a shell. + // The docker image's ENTRYPOINT is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + // produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + // of whether the variable exists or not. Cannot be updated. + // More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + // +optional + // +listType=atomic + Command []string `json:"command,omitempty" protobuf:"bytes,3,rep,name=command"` + // Arguments to the entrypoint. + // The docker image's CMD is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + // produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + // of whether the variable exists or not. Cannot be updated. + // More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + // +optional + // +listType=atomic + Args []string `json:"args,omitempty" protobuf:"bytes,4,rep,name=args"` + // Container's working directory. + // If not specified, the container runtime's default will be used, which + // might be configured in the container image. + // Cannot be updated. + // +optional + WorkingDir string `json:"workingDir,omitempty" protobuf:"bytes,5,opt,name=workingDir"` + // List of ports to expose from the container. Exposing a port here gives + // the system additional information about the network connections a + // container uses, but is primarily informational. Not specifying a port here + // DOES NOT prevent that port from being exposed. Any port which is + // listening on the default "0.0.0.0" address inside a container will be + // accessible from the network. + // Cannot be updated. + // +optional + // +patchMergeKey=containerPort + // +patchStrategy=merge + // +listType=map + // +listMapKey=containerPort + // +listMapKey=protocol + Ports []corev1.ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"` + // List of sources to populate environment variables in the container. + // The keys defined within a source must be a C_IDENTIFIER. All invalid keys + // will be reported as an event when the container is starting. When a key exists in multiple + // sources, the value associated with the last source will take precedence. + // Values defined by an Env with a duplicate key will take precedence. + // Cannot be updated. + // +optional + // +listType=atomic + EnvFrom []corev1.EnvFromSource `json:"envFrom,omitempty" protobuf:"bytes,19,rep,name=envFrom"` + // List of environment variables to set in the container. + // Cannot be updated. + // +optional + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=atomic + Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + // Compute Resources required by this container. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + // +optional + Resources corev1.ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"` + // Pod volumes to mount into the container's filesystem. + // Cannot be updated. + // +optional + // +patchMergeKey=mountPath + // +patchStrategy=merge + // +listType=atomic + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"` + // volumeDevices is the list of block devices to be used by the container. + // +patchMergeKey=devicePath + // +patchStrategy=merge + // +optional + // +listType=atomic + VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchStrategy:"merge" patchMergeKey:"devicePath" protobuf:"bytes,21,rep,name=volumeDevices"` + // Periodic probe of container liveness. + // Container will be restarted if the probe fails. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional + LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty" protobuf:"bytes,10,opt,name=livenessProbe"` + // Periodic probe of container service readiness. + // Container will be removed from service endpoints if the probe fails. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional + ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"` + // StartupProbe indicates that the Pod has successfully initialized. + // If specified, no other probes are executed until this completes successfully. + // If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + // This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + // when it might take a long time to load data or warm a cache, than during steady-state operation. + // This cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional + StartupProbe *corev1.Probe `json:"startupProbe,omitempty" protobuf:"bytes,22,opt,name=startupProbe"` + // Actions that the management system should take in response to container lifecycle events. + // Cannot be updated. + // +optional + Lifecycle *corev1.Lifecycle `json:"lifecycle,omitempty" protobuf:"bytes,12,opt,name=lifecycle"` + // Optional: Path at which the file to which the container's termination message + // will be written is mounted into the container's filesystem. + // Message written is intended to be brief final status, such as an assertion failure message. + // Will be truncated by the node if greater than 4096 bytes. The total message length across + // all containers will be limited to 12kb. + // Defaults to /dev/termination-log. + // Cannot be updated. + // +optional + TerminationMessagePath string `json:"terminationMessagePath,omitempty" protobuf:"bytes,13,opt,name=terminationMessagePath"` + // Indicate how the termination message should be populated. File will use the contents of + // terminationMessagePath to populate the container status message on both success and failure. + // FallbackToLogsOnError will use the last chunk of container log output if the termination + // message file is empty and the container exited with an error. + // The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + // Defaults to File. + // Cannot be updated. + // +optional + TerminationMessagePolicy corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty" protobuf:"bytes,20,opt,name=terminationMessagePolicy,casttype=TerminationMessagePolicy"` + // Image pull policy. + // One of Always, Never, IfNotPresent. + // Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + // +optional + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty" protobuf:"bytes,14,opt,name=imagePullPolicy,casttype=PullPolicy"` + // SecurityContext defines the security options the container should be run with. + // If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + // More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + // +optional + SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty" protobuf:"bytes,15,opt,name=securityContext"` + + // Variables for interactive containers, these have very specialized use-cases (e.g. debugging) + // and shouldn't be used for general purpose containers. + + // Whether this container should allocate a buffer for stdin in the container runtime. If this + // is not set, reads from stdin in the container will always result in EOF. + // Default is false. + // +optional + Stdin bool `json:"stdin,omitempty" protobuf:"varint,16,opt,name=stdin"` + // Whether the container runtime should close the stdin channel after it has been opened by + // a single attach. When stdin is true the stdin stream will remain open across multiple attach + // sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + // first client attaches to stdin, and then remains open and accepts data until the client disconnects, + // at which time stdin is closed and remains closed until the container is restarted. If this + // flag is false, a container processes that reads from stdin will never receive an EOF. + // Default is false + // +optional + StdinOnce bool `json:"stdinOnce,omitempty" protobuf:"varint,17,opt,name=stdinOnce"` + // Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + // Default is false. + // +optional + TTY bool `json:"tty,omitempty" protobuf:"varint,18,opt,name=tty"` + + // Script is the contents of an executable file to execute. + // + // If Script is not empty, the Step cannot have an Command and the Args will be passed to the Script. + // +optional + Script string `json:"script,omitempty"` + + // Timeout is the time after which the step times out. Defaults to never. + // Refer to Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration + // +optional + Timeout *metav1.Duration `json:"timeout,omitempty"` + + // This is an alpha field. You must set the "enable-api-fields" feature flag to "alpha" + // for this field to be supported. + // + // Workspaces is a list of workspaces from the Task that this Step wants + // exclusive access to. Adding a workspace to this list means that any + // other Step or Sidecar that does not also request this Workspace will + // not have access to it. + // +optional + // +listType=atomic + Workspaces []WorkspaceUsage `json:"workspaces,omitempty"` + + // OnError defines the exiting behavior of a container on error + // can be set to [ continue | stopAndFail ] + // stopAndFail indicates exit the taskRun if the container exits with non-zero exit code + // continue indicates continue executing the rest of the steps irrespective of the container exit code + OnError string `json:"onError,omitempty"` +} + +// ToK8sContainer converts the Step to a Kubernetes Container struct +func (s *Step) ToK8sContainer() *corev1.Container { + return &corev1.Container{ + Name: s.Name, + Image: s.Image, + Command: s.Command, + Args: s.Args, + WorkingDir: s.WorkingDir, + Ports: s.Ports, + EnvFrom: s.EnvFrom, + Env: s.Env, + Resources: s.Resources, + VolumeMounts: s.VolumeMounts, + VolumeDevices: s.VolumeDevices, + LivenessProbe: s.LivenessProbe, + ReadinessProbe: s.ReadinessProbe, + StartupProbe: s.StartupProbe, + Lifecycle: s.Lifecycle, + TerminationMessagePath: s.TerminationMessagePath, + ImagePullPolicy: s.ImagePullPolicy, + SecurityContext: s.SecurityContext, + Stdin: s.Stdin, + StdinOnce: s.StdinOnce, + TTY: s.TTY, + } +} + +// SetContainerFields sets the fields of the Step to the values of the corresponding fields in the Container +func (s *Step) SetContainerFields(c corev1.Container) { + s.Name = c.Name + s.Image = c.Image + s.Command = c.Command + s.Args = c.Args + s.WorkingDir = c.WorkingDir + s.Ports = c.Ports + s.EnvFrom = c.EnvFrom + s.Env = c.Env + s.Resources = c.Resources + s.VolumeMounts = c.VolumeMounts + s.VolumeDevices = c.VolumeDevices + s.LivenessProbe = c.LivenessProbe + s.ReadinessProbe = c.ReadinessProbe + s.StartupProbe = c.StartupProbe + s.Lifecycle = c.Lifecycle + s.TerminationMessagePath = c.TerminationMessagePath + s.ImagePullPolicy = c.ImagePullPolicy + s.SecurityContext = c.SecurityContext + s.Stdin = c.Stdin + s.StdinOnce = c.StdinOnce + s.TTY = c.TTY +} + +// StepTemplate is a template for a Step +type StepTemplate struct { + + // Name of the container specified as a DNS_LABEL. + // Each container in a pod must have a unique name (DNS_LABEL). + // Cannot be updated. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + // Docker image name. + // More info: https://kubernetes.io/docs/concepts/containers/images + // This field is optional to allow higher level config management to default or override + // container images in workload controllers like Deployments and StatefulSets. + // +optional + Image string `json:"image,omitempty" protobuf:"bytes,2,opt,name=image"` + // Entrypoint array. Not executed within a shell. + // The docker image's ENTRYPOINT is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + // produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + // of whether the variable exists or not. Cannot be updated. + // More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + // +optional + // +listType=atomic + Command []string `json:"command,omitempty" protobuf:"bytes,3,rep,name=command"` + // Arguments to the entrypoint. + // The docker image's CMD is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + // produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + // of whether the variable exists or not. Cannot be updated. + // More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + // +optional + // +listType=atomic + Args []string `json:"args,omitempty" protobuf:"bytes,4,rep,name=args"` + // Container's working directory. + // If not specified, the container runtime's default will be used, which + // might be configured in the container image. + // Cannot be updated. + // +optional + WorkingDir string `json:"workingDir,omitempty" protobuf:"bytes,5,opt,name=workingDir"` + // List of ports to expose from the container. Exposing a port here gives + // the system additional information about the network connections a + // container uses, but is primarily informational. Not specifying a port here + // DOES NOT prevent that port from being exposed. Any port which is + // listening on the default "0.0.0.0" address inside a container will be + // accessible from the network. + // Cannot be updated. + // +optional + // +patchMergeKey=containerPort + // +patchStrategy=merge + // +listType=map + // +listMapKey=containerPort + // +listMapKey=protocol + Ports []corev1.ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"` + // List of sources to populate environment variables in the container. + // The keys defined within a source must be a C_IDENTIFIER. All invalid keys + // will be reported as an event when the container is starting. When a key exists in multiple + // sources, the value associated with the last source will take precedence. + // Values defined by an Env with a duplicate key will take precedence. + // Cannot be updated. + // +optional + // +listType=atomic + EnvFrom []corev1.EnvFromSource `json:"envFrom,omitempty" protobuf:"bytes,19,rep,name=envFrom"` + // List of environment variables to set in the container. + // Cannot be updated. + // +optional + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=atomic + Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + // Compute Resources required by this container. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + // +optional + Resources corev1.ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"` + // Pod volumes to mount into the container's filesystem. + // Cannot be updated. + // +optional + // +patchMergeKey=mountPath + // +patchStrategy=merge + // +listType=atomic + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"` + // volumeDevices is the list of block devices to be used by the container. + // +patchMergeKey=devicePath + // +patchStrategy=merge + // +optional + // +listType=atomic + VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchStrategy:"merge" patchMergeKey:"devicePath" protobuf:"bytes,21,rep,name=volumeDevices"` + // Periodic probe of container liveness. + // Container will be restarted if the probe fails. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional + LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty" protobuf:"bytes,10,opt,name=livenessProbe"` + // Periodic probe of container service readiness. + // Container will be removed from service endpoints if the probe fails. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional + ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"` + // StartupProbe indicates that the Pod has successfully initialized. + // If specified, no other probes are executed until this completes successfully. + // If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + // This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + // when it might take a long time to load data or warm a cache, than during steady-state operation. + // This cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional + StartupProbe *corev1.Probe `json:"startupProbe,omitempty" protobuf:"bytes,22,opt,name=startupProbe"` + // Actions that the management system should take in response to container lifecycle events. + // Cannot be updated. + // +optional + Lifecycle *corev1.Lifecycle `json:"lifecycle,omitempty" protobuf:"bytes,12,opt,name=lifecycle"` + // Optional: Path at which the file to which the container's termination message + // will be written is mounted into the container's filesystem. + // Message written is intended to be brief final status, such as an assertion failure message. + // Will be truncated by the node if greater than 4096 bytes. The total message length across + // all containers will be limited to 12kb. + // Defaults to /dev/termination-log. + // Cannot be updated. + // +optional + TerminationMessagePath string `json:"terminationMessagePath,omitempty" protobuf:"bytes,13,opt,name=terminationMessagePath"` + // Indicate how the termination message should be populated. File will use the contents of + // terminationMessagePath to populate the container status message on both success and failure. + // FallbackToLogsOnError will use the last chunk of container log output if the termination + // message file is empty and the container exited with an error. + // The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + // Defaults to File. + // Cannot be updated. + // +optional + TerminationMessagePolicy corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty" protobuf:"bytes,20,opt,name=terminationMessagePolicy,casttype=TerminationMessagePolicy"` + // Image pull policy. + // One of Always, Never, IfNotPresent. + // Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + // +optional + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty" protobuf:"bytes,14,opt,name=imagePullPolicy,casttype=PullPolicy"` + // SecurityContext defines the security options the container should be run with. + // If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + // More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + // +optional + SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty" protobuf:"bytes,15,opt,name=securityContext"` + + // Variables for interactive containers, these have very specialized use-cases (e.g. debugging) + // and shouldn't be used for general purpose containers. + + // Whether this container should allocate a buffer for stdin in the container runtime. If this + // is not set, reads from stdin in the container will always result in EOF. + // Default is false. + // +optional + Stdin bool `json:"stdin,omitempty" protobuf:"varint,16,opt,name=stdin"` + // Whether the container runtime should close the stdin channel after it has been opened by + // a single attach. When stdin is true the stdin stream will remain open across multiple attach + // sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + // first client attaches to stdin, and then remains open and accepts data until the client disconnects, + // at which time stdin is closed and remains closed until the container is restarted. If this + // flag is false, a container processes that reads from stdin will never receive an EOF. + // Default is false + // +optional + StdinOnce bool `json:"stdinOnce,omitempty" protobuf:"varint,17,opt,name=stdinOnce"` + // Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + // Default is false. + // +optional + TTY bool `json:"tty,omitempty" protobuf:"varint,18,opt,name=tty"` +} + +// ToK8sContainer converts the StepTemplate to a Kubernetes Container struct +func (s *StepTemplate) ToK8sContainer() *corev1.Container { + return &corev1.Container{ + Name: s.Name, + Image: s.Image, + Command: s.Command, + Args: s.Args, + WorkingDir: s.WorkingDir, + Ports: s.Ports, + EnvFrom: s.EnvFrom, + Env: s.Env, + Resources: s.Resources, + VolumeMounts: s.VolumeMounts, + VolumeDevices: s.VolumeDevices, + LivenessProbe: s.LivenessProbe, + ReadinessProbe: s.ReadinessProbe, + StartupProbe: s.StartupProbe, + Lifecycle: s.Lifecycle, + TerminationMessagePath: s.TerminationMessagePath, + ImagePullPolicy: s.ImagePullPolicy, + SecurityContext: s.SecurityContext, + Stdin: s.Stdin, + StdinOnce: s.StdinOnce, + TTY: s.TTY, + } +} + +// Sidecar has nearly the same data structure as Step but does not have the ability to timeout. +type Sidecar struct { + + // Name of the container specified as a DNS_LABEL. + // Each container in a pod must have a unique name (DNS_LABEL). + // Cannot be updated. + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + // Docker image name. + // More info: https://kubernetes.io/docs/concepts/containers/images + // This field is optional to allow higher level config management to default or override + // container images in workload controllers like Deployments and StatefulSets. + // +optional + Image string `json:"image,omitempty" protobuf:"bytes,2,opt,name=image"` + // Entrypoint array. Not executed within a shell. + // The docker image's ENTRYPOINT is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + // produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + // of whether the variable exists or not. Cannot be updated. + // More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + // +optional + // +listType=atomic + Command []string `json:"command,omitempty" protobuf:"bytes,3,rep,name=command"` + // Arguments to the entrypoint. + // The docker image's CMD is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + // produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + // of whether the variable exists or not. Cannot be updated. + // More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + // +optional + // +listType=atomic + Args []string `json:"args,omitempty" protobuf:"bytes,4,rep,name=args"` + // Container's working directory. + // If not specified, the container runtime's default will be used, which + // might be configured in the container image. + // Cannot be updated. + // +optional + WorkingDir string `json:"workingDir,omitempty" protobuf:"bytes,5,opt,name=workingDir"` + // List of ports to expose from the container. Exposing a port here gives + // the system additional information about the network connections a + // container uses, but is primarily informational. Not specifying a port here + // DOES NOT prevent that port from being exposed. Any port which is + // listening on the default "0.0.0.0" address inside a container will be + // accessible from the network. + // Cannot be updated. + // +optional + // +patchMergeKey=containerPort + // +patchStrategy=merge + // +listType=map + // +listMapKey=containerPort + // +listMapKey=protocol + Ports []corev1.ContainerPort `json:"ports,omitempty" patchStrategy:"merge" patchMergeKey:"containerPort" protobuf:"bytes,6,rep,name=ports"` + // List of sources to populate environment variables in the container. + // The keys defined within a source must be a C_IDENTIFIER. All invalid keys + // will be reported as an event when the container is starting. When a key exists in multiple + // sources, the value associated with the last source will take precedence. + // Values defined by an Env with a duplicate key will take precedence. + // Cannot be updated. + // +optional + // +listType=atomic + EnvFrom []corev1.EnvFromSource `json:"envFrom,omitempty" protobuf:"bytes,19,rep,name=envFrom"` + // List of environment variables to set in the container. + // Cannot be updated. + // +optional + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=atomic + Env []corev1.EnvVar `json:"env,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,7,rep,name=env"` + // Compute Resources required by this container. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + // +optional + Resources corev1.ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"` + // Pod volumes to mount into the container's filesystem. + // Cannot be updated. + // +optional + // +patchMergeKey=mountPath + // +patchStrategy=merge + // +listType=atomic + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchStrategy:"merge" patchMergeKey:"mountPath" protobuf:"bytes,9,rep,name=volumeMounts"` + // volumeDevices is the list of block devices to be used by the container. + // +patchMergeKey=devicePath + // +patchStrategy=merge + // +optional + // +listType=atomic + VolumeDevices []corev1.VolumeDevice `json:"volumeDevices,omitempty" patchStrategy:"merge" patchMergeKey:"devicePath" protobuf:"bytes,21,rep,name=volumeDevices"` + // Periodic probe of container liveness. + // Container will be restarted if the probe fails. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional + LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty" protobuf:"bytes,10,opt,name=livenessProbe"` + // Periodic probe of container service readiness. + // Container will be removed from service endpoints if the probe fails. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional + ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"` + // StartupProbe indicates that the Pod has successfully initialized. + // If specified, no other probes are executed until this completes successfully. + // If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + // This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + // when it might take a long time to load data or warm a cache, than during steady-state operation. + // This cannot be updated. + // More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + // +optional + StartupProbe *corev1.Probe `json:"startupProbe,omitempty" protobuf:"bytes,22,opt,name=startupProbe"` + // Actions that the management system should take in response to container lifecycle events. + // Cannot be updated. + // +optional + Lifecycle *corev1.Lifecycle `json:"lifecycle,omitempty" protobuf:"bytes,12,opt,name=lifecycle"` + // Optional: Path at which the file to which the container's termination message + // will be written is mounted into the container's filesystem. + // Message written is intended to be brief final status, such as an assertion failure message. + // Will be truncated by the node if greater than 4096 bytes. The total message length across + // all containers will be limited to 12kb. + // Defaults to /dev/termination-log. + // Cannot be updated. + // +optional + TerminationMessagePath string `json:"terminationMessagePath,omitempty" protobuf:"bytes,13,opt,name=terminationMessagePath"` + // Indicate how the termination message should be populated. File will use the contents of + // terminationMessagePath to populate the container status message on both success and failure. + // FallbackToLogsOnError will use the last chunk of container log output if the termination + // message file is empty and the container exited with an error. + // The log output is limited to 2048 bytes or 80 lines, whichever is smaller. + // Defaults to File. + // Cannot be updated. + // +optional + TerminationMessagePolicy corev1.TerminationMessagePolicy `json:"terminationMessagePolicy,omitempty" protobuf:"bytes,20,opt,name=terminationMessagePolicy,casttype=TerminationMessagePolicy"` + // Image pull policy. + // One of Always, Never, IfNotPresent. + // Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. + // Cannot be updated. + // More info: https://kubernetes.io/docs/concepts/containers/images#updating-images + // +optional + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty" protobuf:"bytes,14,opt,name=imagePullPolicy,casttype=PullPolicy"` + // SecurityContext defines the security options the container should be run with. + // If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + // More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + // +optional + SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty" protobuf:"bytes,15,opt,name=securityContext"` + + // Variables for interactive containers, these have very specialized use-cases (e.g. debugging) + // and shouldn't be used for general purpose containers. + + // Whether this container should allocate a buffer for stdin in the container runtime. If this + // is not set, reads from stdin in the container will always result in EOF. + // Default is false. + // +optional + Stdin bool `json:"stdin,omitempty" protobuf:"varint,16,opt,name=stdin"` + // Whether the container runtime should close the stdin channel after it has been opened by + // a single attach. When stdin is true the stdin stream will remain open across multiple attach + // sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the + // first client attaches to stdin, and then remains open and accepts data until the client disconnects, + // at which time stdin is closed and remains closed until the container is restarted. If this + // flag is false, a container processes that reads from stdin will never receive an EOF. + // Default is false + // +optional + StdinOnce bool `json:"stdinOnce,omitempty" protobuf:"varint,17,opt,name=stdinOnce"` + // Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. + // Default is false. + // +optional + TTY bool `json:"tty,omitempty" protobuf:"varint,18,opt,name=tty"` + + // Script is the contents of an executable file to execute. + // + // If Script is not empty, the Step cannot have an Command or Args. + // +optional + Script string `json:"script,omitempty"` + + // This is an alpha field. You must set the "enable-api-fields" feature flag to "alpha" + // for this field to be supported. + // + // Workspaces is a list of workspaces from the Task that this Sidecar wants + // exclusive access to. Adding a workspace to this list means that any + // other Step or Sidecar that does not also request this Workspace will + // not have access to it. + // +optional + // +listType=atomic + Workspaces []WorkspaceUsage `json:"workspaces,omitempty"` +} + +// ToK8sContainer converts the Sidecar to a Kubernetes Container struct +func (s *Sidecar) ToK8sContainer() *corev1.Container { + return &corev1.Container{ + Name: s.Name, + Image: s.Image, + Command: s.Command, + Args: s.Args, + WorkingDir: s.WorkingDir, + Ports: s.Ports, + EnvFrom: s.EnvFrom, + Env: s.Env, + Resources: s.Resources, + VolumeMounts: s.VolumeMounts, + VolumeDevices: s.VolumeDevices, + LivenessProbe: s.LivenessProbe, + ReadinessProbe: s.ReadinessProbe, + StartupProbe: s.StartupProbe, + Lifecycle: s.Lifecycle, + TerminationMessagePath: s.TerminationMessagePath, + ImagePullPolicy: s.ImagePullPolicy, + SecurityContext: s.SecurityContext, + Stdin: s.Stdin, + StdinOnce: s.StdinOnce, + TTY: s.TTY, + } +} + +// SetContainerFields sets the fields of the Sidecar to the values of the corresponding fields in the Container +func (s *Sidecar) SetContainerFields(c corev1.Container) { + s.Name = c.Name + s.Image = c.Image + s.Command = c.Command + s.Args = c.Args + s.WorkingDir = c.WorkingDir + s.Ports = c.Ports + s.EnvFrom = c.EnvFrom + s.Env = c.Env + s.Resources = c.Resources + s.VolumeMounts = c.VolumeMounts + s.VolumeDevices = c.VolumeDevices + s.LivenessProbe = c.LivenessProbe + s.ReadinessProbe = c.ReadinessProbe + s.StartupProbe = c.StartupProbe + s.Lifecycle = c.Lifecycle + s.TerminationMessagePath = c.TerminationMessagePath + s.ImagePullPolicy = c.ImagePullPolicy + s.SecurityContext = c.SecurityContext + s.Stdin = c.Stdin + s.StdinOnce = c.StdinOnce + s.TTY = c.TTY +} diff --git a/pkg/apis/pipeline/v1beta1/merge.go b/pkg/apis/pipeline/v1beta1/merge.go index f200c99e3ea..deced8e6675 100644 --- a/pkg/apis/pipeline/v1beta1/merge.go +++ b/pkg/apis/pipeline/v1beta1/merge.go @@ -19,6 +19,7 @@ package v1beta1 import ( "encoding/json" + corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/strategicpatch" ) @@ -35,19 +36,19 @@ type mergeData struct { // MergeStepsWithStepTemplate takes a possibly nil container template and a // list of steps, merging each of the steps with the container template, if // it's not nil, and returning the resulting list. -func MergeStepsWithStepTemplate(template *v1.Container, steps []Step) ([]Step, error) { +func MergeStepsWithStepTemplate(template *StepTemplate, steps []Step) ([]Step, error) { if template == nil { return steps, nil } - md, err := getMergeData(template, &v1.Container{}) + md, err := getMergeData(template.ToK8sContainer(), &corev1.Container{}) if err != nil { return nil, err } for i, s := range steps { - merged := v1.Container{} - err := mergeObjWithTemplateBytes(md, &s.Container, &merged) + merged := corev1.Container{} + err := mergeObjWithTemplateBytes(md, s.ToK8sContainer(), &merged) if err != nil { return nil, err } @@ -58,7 +59,9 @@ func MergeStepsWithStepTemplate(template *v1.Container, steps []Step) ([]Step, e } // Pass through original step Script, for later conversion. - steps[i] = Step{Container: merged, Script: s.Script, OnError: s.OnError, Timeout: s.Timeout} + newStep := Step{Script: s.Script, OnError: s.OnError, Timeout: s.Timeout} + newStep.SetContainerFields(merged) + steps[i] = newStep } return steps, nil } @@ -81,7 +84,7 @@ func MergeStepsWithOverrides(steps []Step, overrides []TaskRunStepOverride) ([]S if err != nil { return nil, err } - steps[i].Container.Resources = merged + steps[i].Resources = merged } return steps, nil } @@ -107,7 +110,7 @@ func MergeSidecarsWithOverrides(sidecars []Sidecar, overrides []TaskRunSidecarOv if err != nil { return nil, err } - sidecars[i].Container.Resources = merged + sidecars[i].Resources = merged } return sidecars, nil } diff --git a/pkg/apis/pipeline/v1beta1/merge_test.go b/pkg/apis/pipeline/v1beta1/merge_test.go index 32814550f8a..038089579eb 100644 --- a/pkg/apis/pipeline/v1beta1/merge_test.go +++ b/pkg/apis/pipeline/v1beta1/merge_test.go @@ -32,49 +32,49 @@ func TestMergeStepsWithStepTemplate(t *testing.T) { for _, tc := range []struct { name string - template *corev1.Container + template *StepTemplate steps []Step expected []Step }{{ name: "nil-template", template: nil, steps: []Step{{ - Container: corev1.Container{Image: "some-image"}, - OnError: "foo", + Image: "some-image", + OnError: "foo", }}, expected: []Step{{ - Container: corev1.Container{Image: "some-image"}, - OnError: "foo", + Image: "some-image", + OnError: "foo", }}, }, { name: "not-overlapping", - template: &corev1.Container{ + template: &StepTemplate{ Command: []string{"/somecmd"}, }, steps: []Step{{ - Container: corev1.Container{Image: "some-image"}, - OnError: "foo", + Image: "some-image", + OnError: "foo", }}, expected: []Step{{ - Container: corev1.Container{Command: []string{"/somecmd"}, Image: "some-image"}, - OnError: "foo", + Command: []string{"/somecmd"}, Image: "some-image", + OnError: "foo", }}, }, { name: "overwriting-one-field", - template: &corev1.Container{ + template: &StepTemplate{ Image: "some-image", Command: []string{"/somecmd"}, }, - steps: []Step{{Container: corev1.Container{ + steps: []Step{{ Image: "some-other-image", - }}}, - expected: []Step{{Container: corev1.Container{ + }}, + expected: []Step{{ Command: []string{"/somecmd"}, Image: "some-other-image", - }}}, + }}, }, { name: "merge-and-overwrite-slice", - template: &corev1.Container{ + template: &StepTemplate{ Env: []corev1.EnvVar{{ Name: "KEEP_THIS", Value: "A_VALUE", @@ -83,7 +83,7 @@ func TestMergeStepsWithStepTemplate(t *testing.T) { Value: "ORIGINAL_VALUE", }}, }, - steps: []Step{{Container: corev1.Container{ + steps: []Step{{ Env: []corev1.EnvVar{{ Name: "NEW_KEY", Value: "A_VALUE", @@ -91,8 +91,8 @@ func TestMergeStepsWithStepTemplate(t *testing.T) { Name: "SOME_KEY", Value: "NEW_VALUE", }}, - }}}, - expected: []Step{{Container: corev1.Container{ + }}, + expected: []Step{{ Env: []corev1.EnvVar{{ Name: "NEW_KEY", Value: "A_VALUE", @@ -103,7 +103,7 @@ func TestMergeStepsWithStepTemplate(t *testing.T) { Name: "SOME_KEY", Value: "NEW_VALUE", }}, - }}}, + }}, }} { t.Run(tc.name, func(t *testing.T) { result, err := MergeStepsWithStepTemplate(tc.template, tc.steps) @@ -127,36 +127,28 @@ func TestMergeStepOverrides(t *testing.T) { }{{ name: "no overrides", steps: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, }, }}, want: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, }, }}, }, { name: "not all steps overridden", steps: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, }, }, { - Container: corev1.Container{ - Name: "bar", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - }, + Name: "bar", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, }, }}, stepOverrides: []TaskRunStepOverride{{ @@ -166,30 +158,24 @@ func TestMergeStepOverrides(t *testing.T) { }, }}, want: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, }, }, { - Container: corev1.Container{ - Name: "bar", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "bar", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, }, { name: "override memory but not CPU", steps: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse("1Gi"), - corev1.ResourceCPU: resource.MustParse("100m"), - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1Gi"), + corev1.ResourceCPU: resource.MustParse("100m"), }, }, }}, @@ -200,25 +186,21 @@ func TestMergeStepOverrides(t *testing.T) { }, }}, want: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("100m"), - corev1.ResourceMemory: resource.MustParse("2Gi"), - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("100m"), + corev1.ResourceMemory: resource.MustParse("2Gi"), }, }, }}, }, { name: "override request but not limit", steps: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, stepOverrides: []TaskRunStepOverride{{ @@ -228,23 +210,19 @@ func TestMergeStepOverrides(t *testing.T) { }, }}, want: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1.5Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1.5Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, }, { name: "override request and limit", steps: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, stepOverrides: []TaskRunStepOverride{{ @@ -255,12 +233,10 @@ func TestMergeStepOverrides(t *testing.T) { }, }}, want: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1.5Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("3Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1.5Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("3Gi")}, }, }}, }, { @@ -268,12 +244,10 @@ func TestMergeStepOverrides(t *testing.T) { // instead, we let k8s reject the resulting pod. name: "new request > old limit", steps: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, stepOverrides: []TaskRunStepOverride{{ @@ -283,12 +257,10 @@ func TestMergeStepOverrides(t *testing.T) { }, }}, want: []Step{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("3Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("3Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, }} @@ -314,36 +286,28 @@ func TestMergeSidecarOverrides(t *testing.T) { }{{ name: "no overrides", sidecars: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, }, }}, want: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, }, }}, }, { name: "not all sidecars overridden", sidecars: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, }, }, { - Container: corev1.Container{ - Name: "bar", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - }, + Name: "bar", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, }, }}, sidecarOverrides: []TaskRunSidecarOverride{{ @@ -353,30 +317,24 @@ func TestMergeSidecarOverrides(t *testing.T) { }, }}, want: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, }, }, { - Container: corev1.Container{ - Name: "bar", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "bar", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, }, { name: "override memory but not CPU", sidecars: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceMemory: resource.MustParse("1Gi"), - corev1.ResourceCPU: resource.MustParse("100m"), - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceMemory: resource.MustParse("1Gi"), + corev1.ResourceCPU: resource.MustParse("100m"), }, }, }}, @@ -387,25 +345,21 @@ func TestMergeSidecarOverrides(t *testing.T) { }, }}, want: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("100m"), - corev1.ResourceMemory: resource.MustParse("2Gi"), - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("100m"), + corev1.ResourceMemory: resource.MustParse("2Gi"), }, }, }}, }, { name: "override request but not limit", sidecars: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, sidecarOverrides: []TaskRunSidecarOverride{{ @@ -415,23 +369,19 @@ func TestMergeSidecarOverrides(t *testing.T) { }, }}, want: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1.5Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1.5Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, }, { name: "override request and limit", sidecars: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, sidecarOverrides: []TaskRunSidecarOverride{{ @@ -442,12 +392,10 @@ func TestMergeSidecarOverrides(t *testing.T) { }, }}, want: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1.5Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("3Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1.5Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("3Gi")}, }, }}, }, { @@ -455,12 +403,10 @@ func TestMergeSidecarOverrides(t *testing.T) { // instead, we let k8s reject the resulting pod. name: "new request > old limit", sidecars: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("1Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, sidecarOverrides: []TaskRunSidecarOverride{{ @@ -470,12 +416,10 @@ func TestMergeSidecarOverrides(t *testing.T) { }, }}, want: []Sidecar{{ - Container: corev1.Container{ - Name: "foo", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("3Gi")}, - Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, - }, + Name: "foo", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("3Gi")}, + Limits: corev1.ResourceList{corev1.ResourceMemory: resource.MustParse("2Gi")}, }, }}, }} diff --git a/pkg/apis/pipeline/v1beta1/openapi_generated.go b/pkg/apis/pipeline/v1beta1/openapi_generated.go index 232fcbbe03f..a5ce2b5af39 100644 --- a/pkg/apis/pipeline/v1beta1/openapi_generated.go +++ b/pkg/apis/pipeline/v1beta1/openapi_generated.go @@ -83,6 +83,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SkippedTask": schema_pkg_apis_pipeline_v1beta1_SkippedTask(ref), "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step": schema_pkg_apis_pipeline_v1beta1_Step(ref), "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepState": schema_pkg_apis_pipeline_v1beta1_StepState(ref), + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepTemplate": schema_pkg_apis_pipeline_v1beta1_StepTemplate(ref), "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Task": schema_pkg_apis_pipeline_v1beta1_Task(ref), "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskList": schema_pkg_apis_pipeline_v1beta1_TaskList(ref), "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskRef": schema_pkg_apis_pipeline_v1beta1_TaskRef(ref), @@ -935,7 +936,7 @@ func schema_pkg_apis_pipeline_v1beta1_EmbeddedTask(ref common.ReferenceCallback) "stepTemplate": { SchemaProps: spec.SchemaProps{ Description: "StepTemplate can be used as the basis for all step containers within the Task, so that the steps inherit settings on the base container.", - Ref: ref("k8s.io/api/core/v1.Container"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepTemplate"), }, }, "sidecars": { @@ -999,7 +1000,7 @@ func schema_pkg_apis_pipeline_v1beta1_EmbeddedTask(ref common.ReferenceCallback) }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamSpec", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTaskMetadata", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Sidecar", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResources", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceDeclaration", "k8s.io/api/core/v1.Container", "k8s.io/api/core/v1.Volume", "k8s.io/apimachinery/pkg/runtime.RawExtension"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamSpec", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineTaskMetadata", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Sidecar", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepTemplate", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResources", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceDeclaration", "k8s.io/api/core/v1.Volume", "k8s.io/apimachinery/pkg/runtime.RawExtension"}, } } @@ -2996,7 +2997,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "Sidecar has nearly the same data structure as Step, consisting of a Container and an optional Script, but does not have the ability to timeout.", + Description: "Sidecar has nearly the same data structure as Step but does not have the ability to timeout.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "name": { @@ -3015,6 +3016,11 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm }, }, "command": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, SchemaProps: spec.SchemaProps{ Description: "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", Type: []string{"array"}, @@ -3030,6 +3036,11 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm }, }, "args": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, SchemaProps: spec.SchemaProps{ Description: "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", Type: []string{"array"}, @@ -3077,6 +3088,11 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm }, }, "envFrom": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, SchemaProps: spec.SchemaProps{ Description: "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", Type: []string{"array"}, @@ -3093,6 +3109,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm "env": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "name", "x-kubernetes-patch-strategy": "merge", }, @@ -3120,6 +3137,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm "volumeMounts": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "mountPath", "x-kubernetes-patch-strategy": "merge", }, @@ -3140,6 +3158,7 @@ func schema_pkg_apis_pipeline_v1beta1_Sidecar(ref common.ReferenceCallback) comm "volumeDevices": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "devicePath", "x-kubernetes-patch-strategy": "merge", }, @@ -3362,7 +3381,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "Step embeds the Container type, which allows it to include fields not provided by Container.", + Description: "Step runs a subcomponent of a Task", Type: []string{"object"}, Properties: map[string]spec.Schema{ "name": { @@ -3381,6 +3400,11 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. }, }, "command": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, SchemaProps: spec.SchemaProps{ Description: "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", Type: []string{"array"}, @@ -3396,6 +3420,11 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. }, }, "args": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, SchemaProps: spec.SchemaProps{ Description: "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", Type: []string{"array"}, @@ -3443,6 +3472,11 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. }, }, "envFrom": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, SchemaProps: spec.SchemaProps{ Description: "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", Type: []string{"array"}, @@ -3459,6 +3493,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. "env": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "name", "x-kubernetes-patch-strategy": "merge", }, @@ -3486,6 +3521,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. "volumeMounts": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "mountPath", "x-kubernetes-patch-strategy": "merge", }, @@ -3506,6 +3542,7 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. "volumeDevices": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "devicePath", "x-kubernetes-patch-strategy": "merge", }, @@ -3694,6 +3731,270 @@ func schema_pkg_apis_pipeline_v1beta1_StepState(ref common.ReferenceCallback) co } } +func schema_pkg_apis_pipeline_v1beta1_StepTemplate(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "StepTemplate is a template for a Step", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "image": { + SchemaProps: spec.SchemaProps{ + Description: "Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.", + Type: []string{"string"}, + Format: "", + }, + }, + "command": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "args": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "workingDir": { + SchemaProps: spec.SchemaProps{ + Description: "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", + Type: []string{"string"}, + Format: "", + }, + }, + "ports": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "containerPort", + "protocol", + }, + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "containerPort", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.ContainerPort"), + }, + }, + }, + }, + }, + "envFrom": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.EnvFromSource"), + }, + }, + }, + }, + }, + "env": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "List of environment variables to set in the container. Cannot be updated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.EnvVar"), + }, + }, + }, + }, + }, + "resources": { + SchemaProps: spec.SchemaProps{ + Description: "Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.ResourceRequirements"), + }, + }, + "volumeMounts": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "mountPath", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Pod volumes to mount into the container's filesystem. Cannot be updated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.VolumeMount"), + }, + }, + }, + }, + }, + "volumeDevices": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "devicePath", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "volumeDevices is the list of block devices to be used by the container.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.VolumeDevice"), + }, + }, + }, + }, + }, + "livenessProbe": { + SchemaProps: spec.SchemaProps{ + Description: "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + Ref: ref("k8s.io/api/core/v1.Probe"), + }, + }, + "readinessProbe": { + SchemaProps: spec.SchemaProps{ + Description: "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + Ref: ref("k8s.io/api/core/v1.Probe"), + }, + }, + "startupProbe": { + SchemaProps: spec.SchemaProps{ + Description: "StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + Ref: ref("k8s.io/api/core/v1.Probe"), + }, + }, + "lifecycle": { + SchemaProps: spec.SchemaProps{ + Description: "Actions that the management system should take in response to container lifecycle events. Cannot be updated.", + Ref: ref("k8s.io/api/core/v1.Lifecycle"), + }, + }, + "terminationMessagePath": { + SchemaProps: spec.SchemaProps{ + Description: "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", + Type: []string{"string"}, + Format: "", + }, + }, + "terminationMessagePolicy": { + SchemaProps: spec.SchemaProps{ + Description: "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", + Type: []string{"string"}, + Format: "", + }, + }, + "imagePullPolicy": { + SchemaProps: spec.SchemaProps{ + Description: "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images", + Type: []string{"string"}, + Format: "", + }, + }, + "securityContext": { + SchemaProps: spec.SchemaProps{ + Description: "SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", + Ref: ref("k8s.io/api/core/v1.SecurityContext"), + }, + }, + "stdin": { + SchemaProps: spec.SchemaProps{ + Description: "Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "stdinOnce": { + SchemaProps: spec.SchemaProps{ + Description: "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false", + Type: []string{"boolean"}, + Format: "", + }, + }, + "tty": { + SchemaProps: spec.SchemaProps{ + Description: "Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.", + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"name"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/core/v1.ContainerPort", "k8s.io/api/core/v1.EnvFromSource", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.Lifecycle", "k8s.io/api/core/v1.Probe", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeDevice", "k8s.io/api/core/v1.VolumeMount"}, + } +} + func schema_pkg_apis_pipeline_v1beta1_Task(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -4957,7 +5258,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskSpec(ref common.ReferenceCallback) com "stepTemplate": { SchemaProps: spec.SchemaProps{ Description: "StepTemplate can be used as the basis for all step containers within the Task, so that the steps inherit settings on the base container.", - Ref: ref("k8s.io/api/core/v1.Container"), + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepTemplate"), }, }, "sidecars": { @@ -5021,7 +5322,7 @@ func schema_pkg_apis_pipeline_v1beta1_TaskSpec(ref common.ReferenceCallback) com }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamSpec", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Sidecar", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResources", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceDeclaration", "k8s.io/api/core/v1.Container", "k8s.io/api/core/v1.Volume"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.ParamSpec", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Sidecar", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepTemplate", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResources", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.TaskResult", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceDeclaration", "k8s.io/api/core/v1.Volume"}, } } diff --git a/pkg/apis/pipeline/v1beta1/pipeline_validation_test.go b/pkg/apis/pipeline/v1beta1/pipeline_validation_test.go index b618ec50292..6a6e27bccac 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_validation_test.go @@ -1153,7 +1153,7 @@ func TestValidateParamResults_Success(t *testing.T) { Name: "output", }}, Steps: []Step{{ - Container: corev1.Container{Name: "foo", Image: "bar"}, + Name: "foo", Image: "bar", }}, }}, Name: "a-task", @@ -3078,7 +3078,7 @@ func Test_validateResultsFromMatrixedPipelineTasksNotConsumed(t *testing.T) { func getTaskSpec() TaskSpec { return TaskSpec{ Steps: []Step{{ - Container: corev1.Container{Name: "foo", Image: "bar"}, + Name: "foo", Image: "bar", }}, } } diff --git a/pkg/apis/pipeline/v1beta1/pipelinerun_validation_test.go b/pkg/apis/pipeline/v1beta1/pipelinerun_validation_test.go index 9564213391e..c9ae415cc57 100644 --- a/pkg/apis/pipeline/v1beta1/pipelinerun_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/pipelinerun_validation_test.go @@ -230,12 +230,10 @@ func TestPipelineRun_Validate(t *testing.T) { Type: v1beta1.ParamTypeArray, }}, Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "echo", - Image: "ubuntu", - Command: []string{"echo"}, - Args: []string{"$(params.task-words[*])"}, - }, + Name: "echo", + Image: "ubuntu", + Command: []string{"echo"}, + Args: []string{"$(params.task-words[*])"}, }}, }}, }}, diff --git a/pkg/apis/pipeline/v1beta1/resource_types_test.go b/pkg/apis/pipeline/v1beta1/resource_types_test.go index ef481daa87d..a8f54dfb2a3 100644 --- a/pkg/apis/pipeline/v1beta1/resource_types_test.go +++ b/pkg/apis/pipeline/v1beta1/resource_types_test.go @@ -24,13 +24,13 @@ import ( ) var ( - prependStep = corev1.Container{ + prependStep = v1beta1.Step{ Name: "prepend-step", Image: "dummy", Command: []string{"doit"}, Args: []string{"stuff", "things"}, } - appendStep = corev1.Container{ + appendStep = v1beta1.Step{ Name: "append-step", Image: "dummy", Command: []string{"doit"}, @@ -47,15 +47,11 @@ var ( type TestTaskModifier struct{} func (tm *TestTaskModifier) GetStepsToPrepend() []v1beta1.Step { - return []v1beta1.Step{{ - Container: prependStep, - }} + return []v1beta1.Step{prependStep} } func (tm *TestTaskModifier) GetStepsToAppend() []v1beta1.Step { - return []v1beta1.Step{{ - Container: appendStep, - }} + return []v1beta1.Step{appendStep} } func (tm *TestTaskModifier) GetVolumes() []corev1.Volume { @@ -84,11 +80,10 @@ func TestApplyTaskModifier(t *testing.T) { } expectedTaskSpec := v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{ - Container: prependStep, - }, { - Container: appendStep, - }}, + Steps: []v1beta1.Step{ + prependStep, + appendStep, + }, Volumes: []corev1.Volume{ volume, }, @@ -108,22 +103,22 @@ func TestApplyTaskModifier_AlreadyAdded(t *testing.T) { }{{ name: "prepend already added", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: prependStep}}, + Steps: []v1beta1.Step{prependStep}, }, }, { name: "append already added", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: appendStep}}, + Steps: []v1beta1.Step{appendStep}, }, }, { name: "both steps already added", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: prependStep}, {Container: appendStep}}, + Steps: []v1beta1.Step{prependStep, appendStep}, }, }, { name: "both steps already added reverse order", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: appendStep}, {Container: prependStep}}, + Steps: []v1beta1.Step{appendStep, prependStep}, }, }, { name: "volume with same name but diff content already added", diff --git a/pkg/apis/pipeline/v1beta1/sidecar_replacements.go b/pkg/apis/pipeline/v1beta1/sidecar_replacements.go index bf41f463383..a331936cd4b 100644 --- a/pkg/apis/pipeline/v1beta1/sidecar_replacements.go +++ b/pkg/apis/pipeline/v1beta1/sidecar_replacements.go @@ -23,5 +23,5 @@ import ( // ApplySidecarReplacements applies variable interpolation on a Sidecar. func ApplySidecarReplacements(sidecar *Sidecar, stringReplacements map[string]string, arrayReplacements map[string][]string) { sidecar.Script = substitution.ApplyReplacements(sidecar.Script, stringReplacements) - applyContainerReplacements(&sidecar.Container, stringReplacements, arrayReplacements) + applySidecarReplacements(sidecar, stringReplacements, arrayReplacements) } diff --git a/pkg/apis/pipeline/v1beta1/sidecar_replacements_test.go b/pkg/apis/pipeline/v1beta1/sidecar_replacements_test.go index bca75facff7..e2ce2adf861 100644 --- a/pkg/apis/pipeline/v1beta1/sidecar_replacements_test.go +++ b/pkg/apis/pipeline/v1beta1/sidecar_replacements_test.go @@ -34,95 +34,91 @@ func TestApplySidecarReplacements(t *testing.T) { } s := v1beta1.Sidecar{ - Script: "$(replace.me)", - Container: corev1.Container{ - Name: "$(replace.me)", - Image: "$(replace.me)", - Command: []string{"$(array.replace.me)"}, - Args: []string{"$(array.replace.me)"}, - WorkingDir: "$(replace.me)", - EnvFrom: []corev1.EnvFromSource{{ - ConfigMapRef: &corev1.ConfigMapEnvSource{ + Script: "$(replace.me)", + Name: "$(replace.me)", + Image: "$(replace.me)", + Command: []string{"$(array.replace.me)"}, + Args: []string{"$(array.replace.me)"}, + WorkingDir: "$(replace.me)", + EnvFrom: []corev1.EnvFromSource{{ + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(replace.me)", + }, + }, + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(replace.me)", + }, + }, + }}, + Env: []corev1.EnvVar{{ + Name: "not_me", + Value: "$(replace.me)", + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "$(replace.me)", }, + Key: "$(replace.me)", }, - SecretRef: &corev1.SecretEnvSource{ + SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "$(replace.me)", }, + Key: "$(replace.me)", }, - }}, - Env: []corev1.EnvVar{{ - Name: "not_me", - Value: "$(replace.me)", - ValueFrom: &corev1.EnvVarSource{ - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(replace.me)", - }, - Key: "$(replace.me)", - }, - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(replace.me)", - }, - Key: "$(replace.me)", - }, - }, - }}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "$(replace.me)", - MountPath: "$(replace.me)", - SubPath: "$(replace.me)", - }}, - }, + }, + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(replace.me)", + MountPath: "$(replace.me)", + SubPath: "$(replace.me)", + }}, } expected := v1beta1.Sidecar{ - Script: "replaced!", - Container: corev1.Container{ - Name: "replaced!", - Image: "replaced!", - Command: []string{"val1", "val2"}, - Args: []string{"val1", "val2"}, - WorkingDir: "replaced!", - EnvFrom: []corev1.EnvFromSource{{ - ConfigMapRef: &corev1.ConfigMapEnvSource{ + Script: "replaced!", + Name: "replaced!", + Image: "replaced!", + Command: []string{"val1", "val2"}, + Args: []string{"val1", "val2"}, + WorkingDir: "replaced!", + EnvFrom: []corev1.EnvFromSource{{ + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "replaced!", + }, + }, + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "replaced!", + }, + }, + }}, + Env: []corev1.EnvVar{{ + Name: "not_me", + Value: "replaced!", + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "replaced!", }, + Key: "replaced!", }, - SecretRef: &corev1.SecretEnvSource{ + SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "replaced!", }, + Key: "replaced!", }, - }}, - Env: []corev1.EnvVar{{ - Name: "not_me", - Value: "replaced!", - ValueFrom: &corev1.EnvVarSource{ - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "replaced!", - }, - Key: "replaced!", - }, - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "replaced!", - }, - Key: "replaced!", - }, - }, - }}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "replaced!", - MountPath: "replaced!", - SubPath: "replaced!", - }}, - }, + }, + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "replaced!", + MountPath: "replaced!", + SubPath: "replaced!", + }}, } v1beta1.ApplySidecarReplacements(&s, replacements, arrayReplacements) if d := cmp.Diff(s, expected); d != "" { diff --git a/pkg/apis/pipeline/v1beta1/step_replacements.go b/pkg/apis/pipeline/v1beta1/step_replacements.go index 66ef5e3a7f6..b39466837c5 100644 --- a/pkg/apis/pipeline/v1beta1/step_replacements.go +++ b/pkg/apis/pipeline/v1beta1/step_replacements.go @@ -23,5 +23,5 @@ import ( // ApplyStepReplacements applies variable interpolation on a Step. func ApplyStepReplacements(step *Step, stringReplacements map[string]string, arrayReplacements map[string][]string) { step.Script = substitution.ApplyReplacements(step.Script, stringReplacements) - applyContainerReplacements(&step.Container, stringReplacements, arrayReplacements) + applyStepReplacements(step, stringReplacements, arrayReplacements) } diff --git a/pkg/apis/pipeline/v1beta1/step_replacements_test.go b/pkg/apis/pipeline/v1beta1/step_replacements_test.go index 8f03671e430..89177189f70 100644 --- a/pkg/apis/pipeline/v1beta1/step_replacements_test.go +++ b/pkg/apis/pipeline/v1beta1/step_replacements_test.go @@ -34,95 +34,91 @@ func TestApplyStepReplacements(t *testing.T) { } s := v1beta1.Step{ - Script: "$(replace.me)", - Container: corev1.Container{ - Name: "$(replace.me)", - Image: "$(replace.me)", - Command: []string{"$(array.replace.me)"}, - Args: []string{"$(array.replace.me)"}, - WorkingDir: "$(replace.me)", - EnvFrom: []corev1.EnvFromSource{{ - ConfigMapRef: &corev1.ConfigMapEnvSource{ + Script: "$(replace.me)", + Name: "$(replace.me)", + Image: "$(replace.me)", + Command: []string{"$(array.replace.me)"}, + Args: []string{"$(array.replace.me)"}, + WorkingDir: "$(replace.me)", + EnvFrom: []corev1.EnvFromSource{{ + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(replace.me)", + }, + }, + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "$(replace.me)", + }, + }, + }}, + Env: []corev1.EnvVar{{ + Name: "not_me", + Value: "$(replace.me)", + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "$(replace.me)", }, + Key: "$(replace.me)", }, - SecretRef: &corev1.SecretEnvSource{ + SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "$(replace.me)", }, + Key: "$(replace.me)", }, - }}, - Env: []corev1.EnvVar{{ - Name: "not_me", - Value: "$(replace.me)", - ValueFrom: &corev1.EnvVarSource{ - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(replace.me)", - }, - Key: "$(replace.me)", - }, - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "$(replace.me)", - }, - Key: "$(replace.me)", - }, - }, - }}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "$(replace.me)", - MountPath: "$(replace.me)", - SubPath: "$(replace.me)", - }}, - }, + }, + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(replace.me)", + MountPath: "$(replace.me)", + SubPath: "$(replace.me)", + }}, } expected := v1beta1.Step{ - Script: "replaced!", - Container: corev1.Container{ - Name: "replaced!", - Image: "replaced!", - Command: []string{"val1", "val2"}, - Args: []string{"val1", "val2"}, - WorkingDir: "replaced!", - EnvFrom: []corev1.EnvFromSource{{ - ConfigMapRef: &corev1.ConfigMapEnvSource{ + Script: "replaced!", + Name: "replaced!", + Image: "replaced!", + Command: []string{"val1", "val2"}, + Args: []string{"val1", "val2"}, + WorkingDir: "replaced!", + EnvFrom: []corev1.EnvFromSource{{ + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "replaced!", + }, + }, + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "replaced!", + }, + }, + }}, + Env: []corev1.EnvVar{{ + Name: "not_me", + Value: "replaced!", + ValueFrom: &corev1.EnvVarSource{ + ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "replaced!", }, + Key: "replaced!", }, - SecretRef: &corev1.SecretEnvSource{ + SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ Name: "replaced!", }, + Key: "replaced!", }, - }}, - Env: []corev1.EnvVar{{ - Name: "not_me", - Value: "replaced!", - ValueFrom: &corev1.EnvVarSource{ - ConfigMapKeyRef: &corev1.ConfigMapKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "replaced!", - }, - Key: "replaced!", - }, - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "replaced!", - }, - Key: "replaced!", - }, - }, - }}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "replaced!", - MountPath: "replaced!", - SubPath: "replaced!", - }}, - }, + }, + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "replaced!", + MountPath: "replaced!", + SubPath: "replaced!", + }}, } v1beta1.ApplyStepReplacements(&s, replacements, arrayReplacements) if d := cmp.Diff(s, expected); d != "" { diff --git a/pkg/apis/pipeline/v1beta1/swagger.json b/pkg/apis/pipeline/v1beta1/swagger.json index 794007f7b02..f16198131d1 100644 --- a/pkg/apis/pipeline/v1beta1/swagger.json +++ b/pkg/apis/pipeline/v1beta1/swagger.json @@ -616,7 +616,7 @@ }, "stepTemplate": { "description": "StepTemplate can be used as the basis for all step containers within the Task, so that the steps inherit settings on the base container.", - "$ref": "#/definitions/v1.Container" + "$ref": "#/definitions/v1beta1.StepTemplate" }, "steps": { "description": "Steps are the steps of the build; each step is run sequentially with the source mounted into /workspace.", @@ -1700,7 +1700,7 @@ } }, "v1beta1.Sidecar": { - "description": "Sidecar has nearly the same data structure as Step, consisting of a Container and an optional Script, but does not have the ability to timeout.", + "description": "Sidecar has nearly the same data structure as Step but does not have the ability to timeout.", "type": "object", "required": [ "name" @@ -1712,7 +1712,8 @@ "items": { "type": "string", "default": "" - } + }, + "x-kubernetes-list-type": "atomic" }, "command": { "description": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", @@ -1720,7 +1721,8 @@ "items": { "type": "string", "default": "" - } + }, + "x-kubernetes-list-type": "atomic" }, "env": { "description": "List of environment variables to set in the container. Cannot be updated.", @@ -1729,6 +1731,7 @@ "default": {}, "$ref": "#/definitions/v1.EnvVar" }, + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "name", "x-kubernetes-patch-strategy": "merge" }, @@ -1738,7 +1741,8 @@ "items": { "default": {}, "$ref": "#/definitions/v1.EnvFromSource" - } + }, + "x-kubernetes-list-type": "atomic" }, "image": { "description": "Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.", @@ -1824,6 +1828,7 @@ "default": {}, "$ref": "#/definitions/v1.VolumeDevice" }, + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "devicePath", "x-kubernetes-patch-strategy": "merge" }, @@ -1834,6 +1839,7 @@ "default": {}, "$ref": "#/definitions/v1.VolumeMount" }, + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "mountPath", "x-kubernetes-patch-strategy": "merge" }, @@ -1903,7 +1909,7 @@ } }, "v1beta1.Step": { - "description": "Step embeds the Container type, which allows it to include fields not provided by Container.", + "description": "Step runs a subcomponent of a Task", "type": "object", "required": [ "name" @@ -1915,7 +1921,8 @@ "items": { "type": "string", "default": "" - } + }, + "x-kubernetes-list-type": "atomic" }, "command": { "description": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", @@ -1923,7 +1930,8 @@ "items": { "type": "string", "default": "" - } + }, + "x-kubernetes-list-type": "atomic" }, "env": { "description": "List of environment variables to set in the container. Cannot be updated.", @@ -1932,6 +1940,7 @@ "default": {}, "$ref": "#/definitions/v1.EnvVar" }, + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "name", "x-kubernetes-patch-strategy": "merge" }, @@ -1941,7 +1950,8 @@ "items": { "default": {}, "$ref": "#/definitions/v1.EnvFromSource" - } + }, + "x-kubernetes-list-type": "atomic" }, "image": { "description": "Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.", @@ -2035,6 +2045,7 @@ "default": {}, "$ref": "#/definitions/v1.VolumeDevice" }, + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "devicePath", "x-kubernetes-patch-strategy": "merge" }, @@ -2045,6 +2056,7 @@ "default": {}, "$ref": "#/definitions/v1.VolumeMount" }, + "x-kubernetes-list-type": "atomic", "x-kubernetes-patch-merge-key": "mountPath", "x-kubernetes-patch-strategy": "merge" }, @@ -2090,6 +2102,152 @@ } } }, + "v1beta1.StepTemplate": { + "description": "StepTemplate is a template for a Step", + "type": "object", + "required": [ + "name" + ], + "properties": { + "args": { + "description": "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + "type": "array", + "items": { + "type": "string", + "default": "" + }, + "x-kubernetes-list-type": "atomic" + }, + "command": { + "description": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + "type": "array", + "items": { + "type": "string", + "default": "" + }, + "x-kubernetes-list-type": "atomic" + }, + "env": { + "description": "List of environment variables to set in the container. Cannot be updated.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.EnvVar" + }, + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge" + }, + "envFrom": { + "description": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.EnvFromSource" + }, + "x-kubernetes-list-type": "atomic" + }, + "image": { + "description": "Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.", + "type": "string" + }, + "imagePullPolicy": { + "description": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images", + "type": "string" + }, + "lifecycle": { + "description": "Actions that the management system should take in response to container lifecycle events. Cannot be updated.", + "$ref": "#/definitions/v1.Lifecycle" + }, + "livenessProbe": { + "description": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + "$ref": "#/definitions/v1.Probe" + }, + "name": { + "description": "Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.", + "type": "string", + "default": "" + }, + "ports": { + "description": "List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.ContainerPort" + }, + "x-kubernetes-list-map-keys": [ + "containerPort", + "protocol" + ], + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "containerPort", + "x-kubernetes-patch-strategy": "merge" + }, + "readinessProbe": { + "description": "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + "$ref": "#/definitions/v1.Probe" + }, + "resources": { + "description": "Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "default": {}, + "$ref": "#/definitions/v1.ResourceRequirements" + }, + "securityContext": { + "description": "SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/", + "$ref": "#/definitions/v1.SecurityContext" + }, + "startupProbe": { + "description": "StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + "$ref": "#/definitions/v1.Probe" + }, + "stdin": { + "description": "Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.", + "type": "boolean" + }, + "stdinOnce": { + "description": "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false", + "type": "boolean" + }, + "terminationMessagePath": { + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", + "type": "string" + }, + "terminationMessagePolicy": { + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", + "type": "string" + }, + "tty": { + "description": "Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.", + "type": "boolean" + }, + "volumeDevices": { + "description": "volumeDevices is the list of block devices to be used by the container.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.VolumeDevice" + }, + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "devicePath", + "x-kubernetes-patch-strategy": "merge" + }, + "volumeMounts": { + "description": "Pod volumes to mount into the container's filesystem. Cannot be updated.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.VolumeMount" + }, + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "mountPath", + "x-kubernetes-patch-strategy": "merge" + }, + "workingDir": { + "description": "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", + "type": "string" + } + } + }, "v1beta1.Task": { "description": "Task represents a collection of sequential steps that are run as part of a Pipeline using a set of inputs and producing a set of outputs. Tasks execute when TaskRuns are created that provide the input parameters and resources and output resources the Task requires.", "type": "object", @@ -2755,7 +2913,7 @@ }, "stepTemplate": { "description": "StepTemplate can be used as the basis for all step containers within the Task, so that the steps inherit settings on the base container.", - "$ref": "#/definitions/v1.Container" + "$ref": "#/definitions/v1beta1.StepTemplate" }, "steps": { "description": "Steps are the steps of the build; each step is run sequentially with the source mounted into /workspace.", diff --git a/pkg/apis/pipeline/v1beta1/task_types.go b/pkg/apis/pipeline/v1beta1/task_types.go index 7a218754193..c0d168b0a77 100644 --- a/pkg/apis/pipeline/v1beta1/task_types.go +++ b/pkg/apis/pipeline/v1beta1/task_types.go @@ -110,7 +110,7 @@ type TaskSpec struct { // 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"` + StepTemplate *StepTemplate `json:"stepTemplate,omitempty"` // Sidecars are run alongside the Task's step containers. They begin before // the steps start and end after the steps complete. @@ -126,62 +126,6 @@ type TaskSpec struct { Results []TaskResult `json:"results,omitempty"` } -// Step embeds the Container type, which allows it to include fields not -// provided by Container. -type Step struct { - corev1.Container `json:",inline"` - - // Script is the contents of an executable file to execute. - // - // If Script is not empty, the Step cannot have an Command and the Args will be passed to the Script. - // +optional - Script string `json:"script,omitempty"` - - // Timeout is the time after which the step times out. Defaults to never. - // Refer to Go's ParseDuration documentation for expected format: https://golang.org/pkg/time/#ParseDuration - // +optional - Timeout *metav1.Duration `json:"timeout,omitempty"` - - // This is an alpha field. You must set the "enable-api-fields" feature flag to "alpha" - // for this field to be supported. - // - // Workspaces is a list of workspaces from the Task that this Step wants - // exclusive access to. Adding a workspace to this list means that any - // other Step or Sidecar that does not also request this Workspace will - // not have access to it. - // +optional - // +listType=atomic - Workspaces []WorkspaceUsage `json:"workspaces,omitempty"` - - // OnError defines the exiting behavior of a container on error - // can be set to [ continue | stopAndFail ] - // stopAndFail indicates exit the taskRun if the container exits with non-zero exit code - // continue indicates continue executing the rest of the steps irrespective of the container exit code - OnError string `json:"onError,omitempty"` -} - -// Sidecar has nearly the same data structure as Step, consisting of a Container and an optional Script, but does not have the ability to timeout. -type Sidecar struct { - corev1.Container `json:",inline"` - - // Script is the contents of an executable file to execute. - // - // If Script is not empty, the Step cannot have an Command or Args. - // +optional - Script string `json:"script,omitempty"` - - // This is an alpha field. You must set the "enable-api-fields" feature flag to "alpha" - // for this field to be supported. - // - // Workspaces is a list of workspaces from the Task that this Sidecar wants - // exclusive access to. Adding a workspace to this list means that any - // other Step or Sidecar that does not also request this Workspace will - // not have access to it. - // +optional - // +listType=atomic - Workspaces []WorkspaceUsage `json:"workspaces,omitempty"` -} - // TaskList contains a list of Task // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type TaskList struct { diff --git a/pkg/apis/pipeline/v1beta1/task_validation.go b/pkg/apis/pipeline/v1beta1/task_validation.go index 2a9435fd0b6..35383626013 100644 --- a/pkg/apis/pipeline/v1beta1/task_validation.go +++ b/pkg/apis/pipeline/v1beta1/task_validation.go @@ -79,7 +79,7 @@ func validateResults(ctx context.Context, results []TaskResult) (errs *apis.Fiel // a mount path which conflicts with any other declared workspaces, with the explicitly // declared volume mounts, or with the stepTemplate. The names must also be unique. -func validateDeclaredWorkspaces(workspaces []WorkspaceDeclaration, steps []Step, stepTemplate *corev1.Container) (errs *apis.FieldError) { +func validateDeclaredWorkspaces(workspaces []WorkspaceDeclaration, steps []Step, stepTemplate *StepTemplate) (errs *apis.FieldError) { mountPaths := sets.NewString() for _, step := range steps { for _, vm := range step.VolumeMounts { diff --git a/pkg/apis/pipeline/v1beta1/task_validation_test.go b/pkg/apis/pipeline/v1beta1/task_validation_test.go index 6cb3391e71b..beb660a631d 100644 --- a/pkg/apis/pipeline/v1beta1/task_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/task_validation_test.go @@ -46,15 +46,15 @@ var invalidResource = v1beta1.TaskResource{ }, } -var validSteps = []v1beta1.Step{{Container: corev1.Container{ +var validSteps = []v1beta1.Step{{ Name: "mystep", Image: "myimage", -}}} +}} -var invalidSteps = []v1beta1.Step{{Container: corev1.Container{ +var invalidSteps = []v1beta1.Step{{ Name: "replaceImage", Image: "myimage", -}}} +}} func TestTaskValidate(t *testing.T) { tests := []struct { @@ -87,7 +87,7 @@ func TestTaskSpecValidate(t *testing.T) { Params []v1beta1.ParamSpec Resources *v1beta1.TaskResources Steps []v1beta1.Step - StepTemplate *corev1.Container + StepTemplate *v1beta1.StepTemplate Workspaces []v1beta1.WorkspaceDeclaration Results []v1beta1.TaskResult } @@ -97,11 +97,11 @@ func TestTaskSpecValidate(t *testing.T) { }{{ name: "unnamed steps", fields: fields{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "myimage", - }}, {Container: corev1.Container{ + }, { Image: "myotherimage", - }}}, + }}, }, }, { name: "valid input resources", @@ -148,12 +148,12 @@ func TestTaskSpecValidate(t *testing.T) { }, { Name: "foo-is-baz", }}, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "url", Args: []string{"--flag=$(params.baz) && $(params.foo-is-baz)"}, WorkingDir: "/foo/bar/src/", - }}}, + }}, }, }, { name: "valid array template variable", @@ -165,13 +165,13 @@ func TestTaskSpecValidate(t *testing.T) { Name: "foo-is-baz", Type: v1beta1.ParamTypeArray, }}, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "myimage", Command: []string{"$(params.foo-is-baz)"}, Args: []string{"$(params.baz)", "middle string", "$(params.foo-is-baz)"}, WorkingDir: "/foo/bar/src/", - }}}, + }}, }, }, { name: "valid star array template variable", @@ -183,32 +183,32 @@ func TestTaskSpecValidate(t *testing.T) { Name: "foo-is-baz", Type: v1beta1.ParamTypeArray, }}, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "myimage", Command: []string{"$(params.foo-is-baz)"}, Args: []string{"$(params.baz[*])", "middle string", "$(params.foo-is-baz[*])"}, WorkingDir: "/foo/bar/src/", - }}}, + }}, }, }, { name: "valid path variable for legacy credential helper (aka creds-init)", fields: fields{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "echo", Args: []string{"$(credentials.path)"}, - }}}, + }}, }, }, { name: "step template included in validation", fields: fields{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "astep", Command: []string{"echo"}, Args: []string{"hello"}, - }}}, - StepTemplate: &corev1.Container{ + }}, + StepTemplate: &v1beta1.StepTemplate{ Image: "some-image", }, }, @@ -216,9 +216,7 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid step with script", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - }, + Image: "my-image", Script: ` #!/usr/bin/env bash hello world`, @@ -233,9 +231,7 @@ func TestTaskSpecValidate(t *testing.T) { Name: "foo-is-baz", }}, Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - }, + Image: "my-image", Script: ` #!/usr/bin/env bash hello $(params.baz)`, @@ -245,10 +241,8 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid step with script and args", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, Script: ` #!/usr/bin/env bash hello $1`, @@ -257,22 +251,20 @@ func TestTaskSpecValidate(t *testing.T) { }, { name: "valid step with volumeMount under /tekton/home", fields: fields{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "myimage", VolumeMounts: []corev1.VolumeMount{{ Name: "foo", MountPath: "/tekton/home", }}, - }}}, + }}, }, }, { name: "valid workspace", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, }}, Workspaces: []v1beta1.WorkspaceDeclaration{{ Name: "foo-workspace", @@ -284,10 +276,8 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid result", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, }}, Results: []v1beta1.TaskResult{{ Name: "MY-RESULT", @@ -298,10 +288,8 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid result type", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, }}, Results: []v1beta1.TaskResult{{ Name: "MY-RESULT", @@ -313,10 +301,8 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid task name context", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, Script: ` #!/usr/bin/env bash hello "$(context.task.name)"`, @@ -326,10 +312,8 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid task retry count context", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, Script: ` #!/usr/bin/env bash retry count "$(context.task.retry-count)"`, @@ -339,10 +323,8 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid taskrun name context", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, Script: ` #!/usr/bin/env bash hello "$(context.taskRun.name)"`, @@ -352,10 +334,8 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid taskrun uid context", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, Script: ` #!/usr/bin/env bash hello "$(context.taskRun.uid)"`, @@ -365,10 +345,8 @@ func TestTaskSpecValidate(t *testing.T) { name: "valid context", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, Script: ` #!/usr/bin/env bash hello "$(context.taskRun.namespace)"`, @@ -400,7 +378,7 @@ func TestTaskSpecValidateError(t *testing.T) { Resources *v1beta1.TaskResources Steps []v1beta1.Step Volumes []corev1.Volume - StepTemplate *corev1.Container + StepTemplate *v1beta1.StepTemplate Workspaces []v1beta1.WorkspaceDeclaration Results []v1beta1.TaskResult } @@ -580,11 +558,11 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "inexistent param variable", fields: fields{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "myimage", Args: []string{"--flag=$(params.inexistent)"}, - }}}, + }}, }, expectedError: apis.FieldError{ Message: `non-existent variable in "--flag=$(params.inexistent)"`, @@ -600,13 +578,13 @@ func TestTaskSpecValidateError(t *testing.T) { Name: "foo-is-baz", Type: v1beta1.ParamTypeArray, }}, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "$(params.baz)", Command: []string{"$(params.foo-is-baz)"}, Args: []string{"$(params.baz)", "middle string", "url"}, WorkingDir: "/foo/bar/src/", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable type invalid in "$(params.baz)"`, @@ -622,13 +600,13 @@ func TestTaskSpecValidateError(t *testing.T) { Name: "foo-is-baz", Type: v1beta1.ParamTypeArray, }}, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "$(params.baz[*])", Command: []string{"$(params.foo-is-baz)"}, Args: []string{"$(params.baz)", "middle string", "url"}, WorkingDir: "/foo/bar/src/", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable type invalid in "$(params.baz[*])"`, @@ -646,12 +624,10 @@ func TestTaskSpecValidateError(t *testing.T) { }}, Steps: []v1beta1.Step{ { - Script: "$(params.baz[*])", - Container: corev1.Container{ - Name: "mystep", - Image: "my-image", - WorkingDir: "/foo/bar/src/", - }, + Script: "$(params.baz[*])", + Name: "mystep", + Image: "my-image", + WorkingDir: "/foo/bar/src/", }}, }, expectedError: apis.FieldError{ @@ -668,13 +644,13 @@ func TestTaskSpecValidateError(t *testing.T) { Name: "foo-is-baz", Type: v1beta1.ParamTypeArray, }}, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "someimage", Command: []string{"$(params.foo-is-baz)"}, Args: []string{"not isolated: $(params.baz)", "middle string", "url"}, WorkingDir: "/foo/bar/src/", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable is not properly isolated in "not isolated: $(params.baz)"`, @@ -690,13 +666,13 @@ func TestTaskSpecValidateError(t *testing.T) { Name: "foo-is-baz", Type: v1beta1.ParamTypeArray, }}, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "someimage", Command: []string{"$(params.foo-is-baz)"}, Args: []string{"not isolated: $(params.baz[*])", "middle string", "url"}, WorkingDir: "/foo/bar/src/", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable is not properly isolated in "not isolated: $(params.baz[*])"`, @@ -712,13 +688,13 @@ func TestTaskSpecValidateError(t *testing.T) { Name: "foo-is-baz", Default: v1beta1.NewArrayOrString("implied", "array", "type"), }}, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "someimage", Command: []string{"$(params.foo-is-baz)"}, Args: []string{"not isolated: $(params.baz)", "middle string", "url"}, WorkingDir: "/foo/bar/src/", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable is not properly isolated in "not isolated: $(params.baz)"`, @@ -734,13 +710,13 @@ func TestTaskSpecValidateError(t *testing.T) { Name: "foo-is-baz", Default: v1beta1.NewArrayOrString("implied", "array", "type"), }}, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "someimage", Command: []string{"$(params.foo-is-baz)"}, Args: []string{"not isolated: $(params.baz[*])", "middle string", "url"}, WorkingDir: "/foo/bar/src/", - }}}, + }}, }, expectedError: apis.FieldError{ Message: `variable is not properly isolated in "not isolated: $(params.baz[*])"`, @@ -756,13 +732,13 @@ func TestTaskSpecValidateError(t *testing.T) { Default: v1beta1.NewArrayOrString("default"), }, }, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "myimage", VolumeMounts: []corev1.VolumeMount{{ Name: "$(params.inexistent)-foo", }}, - }}}, + }}, }, expectedError: apis.FieldError{ Message: `non-existent variable in "$(params.inexistent)-foo"`, @@ -776,11 +752,11 @@ func TestTaskSpecValidateError(t *testing.T) { Description: "param", Default: v1beta1.NewArrayOrString("default"), }}, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "myimage", Args: []string{"$(params.foo) && $(params.inexistent)"}, - }}}, + }}, }, expectedError: apis.FieldError{ Message: `non-existent variable in "$(params.foo) && $(params.inexistent)"`, @@ -804,11 +780,9 @@ func TestTaskSpecValidateError(t *testing.T) { name: "step with script and command", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "myimage", - Command: []string{"command"}, - }, - Script: "script", + Image: "myimage", + Command: []string{"command"}, + Script: "script", }}, }, expectedError: apis.FieldError{ @@ -818,13 +792,13 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "step volume mounts under /tekton/", fields: fields{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "myimage", VolumeMounts: []corev1.VolumeMount{{ Name: "foo", MountPath: "/tekton/foo", }}, - }}}, + }}, }, expectedError: apis.FieldError{ Message: `volumeMount cannot be mounted under /tekton/ (volumeMount "foo" mounted at "/tekton/foo")`, @@ -833,13 +807,13 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "step volume mount name starts with tekton-internal-", fields: fields{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "myimage", VolumeMounts: []corev1.VolumeMount{{ Name: "tekton-internal-foo", MountPath: "/this/is/fine", }}, - }}}, + }}, }, expectedError: apis.FieldError{ Message: `volumeMount name "tekton-internal-foo" cannot start with "tekton-internal-"`, @@ -881,14 +855,12 @@ func TestTaskSpecValidateError(t *testing.T) { name: "workspace mount path already in volumeMounts", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "myimage", - Command: []string{"command"}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "my-mount", - MountPath: "/foo", - }}, - }, + Image: "myimage", + Command: []string{"command"}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "my-mount", + MountPath: "/foo", + }}, }}, Workspaces: []v1beta1.WorkspaceDeclaration{{ Name: "some-workspace", @@ -903,14 +875,12 @@ func TestTaskSpecValidateError(t *testing.T) { name: "workspace default mount path already in volumeMounts", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "myimage", - Command: []string{"command"}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "my-mount", - MountPath: "/workspace/some-workspace/", - }}, - }, + Image: "myimage", + Command: []string{"command"}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "my-mount", + MountPath: "/workspace/some-workspace/", + }}, }}, Workspaces: []v1beta1.WorkspaceDeclaration{{ Name: "some-workspace", @@ -923,7 +893,7 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "workspace mount path already in stepTemplate", fields: fields{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "my-mount", MountPath: "/foo", @@ -942,7 +912,7 @@ func TestTaskSpecValidateError(t *testing.T) { }, { name: "workspace default mount path already in stepTemplate", fields: fields{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "my-mount", MountPath: "/workspace/some-workspace", @@ -990,10 +960,8 @@ func TestTaskSpecValidateError(t *testing.T) { name: "context not validate", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, Script: ` #!/usr/bin/env bash hello "$(context.task.missing)"`, @@ -1052,10 +1020,8 @@ func TestStepAndSidecarWorkspaces(t *testing.T) { name: "valid step workspace usage", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - Args: []string{"arg"}, - }, + Image: "my-image", + Args: []string{"arg"}, Workspaces: []v1beta1.WorkspaceUsage{{ Name: "foo-workspace", MountPath: "/a/custom/mountpath", @@ -1103,9 +1069,7 @@ func TestStepAndSidecarWorkspacesErrors(t *testing.T) { name: "step workspace that refers to non-existent workspace declaration fails", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "foo", - }, + Image: "foo", Workspaces: []v1beta1.WorkspaceUsage{{ Name: "foo", }}, @@ -1119,14 +1083,10 @@ func TestStepAndSidecarWorkspacesErrors(t *testing.T) { name: "sidecar workspace that refers to non-existent workspace declaration fails", fields: fields{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "foo", - }, + Image: "foo", }}, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - Image: "foo", - }, + Image: "foo", Workspaces: []v1beta1.WorkspaceUsage{{ Name: "foo", }}, @@ -1174,28 +1134,22 @@ func TestStepOnError(t *testing.T) { name: "valid step - valid onError usage - set to continue - alpha API", steps: []v1beta1.Step{{ OnError: "continue", - Container: corev1.Container{ - Image: "image", - Args: []string{"arg"}, - }, + Image: "image", + Args: []string{"arg"}, }}, }, { name: "valid step - valid onError usage - set to stopAndFail - alpha API", steps: []v1beta1.Step{{ OnError: "stopAndFail", - Container: corev1.Container{ - Image: "image", - Args: []string{"arg"}, - }, + Image: "image", + Args: []string{"arg"}, }}, }, { name: "invalid step - onError set to invalid value - alpha API", steps: []v1beta1.Step{{ OnError: "onError", - Container: corev1.Container{ - Image: "image", - Args: []string{"arg"}, - }, + Image: "image", + Args: []string{"arg"}, }}, expectedError: &apis.FieldError{ Message: fmt.Sprintf("invalid value: onError"), @@ -1236,9 +1190,7 @@ func TestIncompatibleAPIVersions(t *testing.T) { Name: "foo", }}, Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "foo", - }, + Image: "foo", Workspaces: []v1beta1.WorkspaceUsage{{ Name: "foo", }}, @@ -1252,14 +1204,10 @@ func TestIncompatibleAPIVersions(t *testing.T) { Name: "foo", }}, Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "foo", - }, + Image: "foo", }}, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - Image: "foo", - }, + Image: "foo", Workspaces: []v1beta1.WorkspaceUsage{{ Name: "foo", }}, @@ -1270,9 +1218,7 @@ func TestIncompatibleAPIVersions(t *testing.T) { requiredVersion: "alpha", spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "my-image", - }, + Image: "my-image", Script: ` #!win powershell -File script-1`, diff --git a/pkg/apis/pipeline/v1beta1/taskrun_validation_test.go b/pkg/apis/pipeline/v1beta1/taskrun_validation_test.go index ca08a59755c..5e81dfb76c3 100644 --- a/pkg/apis/pipeline/v1beta1/taskrun_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/taskrun_validation_test.go @@ -207,10 +207,10 @@ func TestTaskRunSpec_Invalidate(t *testing.T) { Name: "taskrefname", }, TaskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "myimage", - }}}, + }}, }, }, wantErr: apis.ErrMultipleOneOf("taskRef", "taskSpec"), @@ -236,10 +236,10 @@ func TestTaskRunSpec_Invalidate(t *testing.T) { name: "invalid taskspec", spec: v1beta1.TaskRunSpec{ TaskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "invalid-name-with-$weird-char/%", Image: "myimage", - }}}, + }}, }, }, wantErr: &apis.FieldError{ @@ -511,10 +511,10 @@ func TestTaskRunSpec_Validate(t *testing.T) { name: "taskspec without a taskRef", spec: v1beta1.TaskRunSpec{ TaskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "myimage", - }}}, + }}, }, }, }, { @@ -522,10 +522,10 @@ func TestTaskRunSpec_Validate(t *testing.T) { spec: v1beta1.TaskRunSpec{ Timeout: &metav1.Duration{Duration: 0}, TaskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "myimage", - }}}, + }}, }, }, }, { @@ -537,10 +537,10 @@ func TestTaskRunSpec_Validate(t *testing.T) { Value: *v1beta1.NewArrayOrString("value"), }}, TaskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "mystep", Image: "myimage", - }}}, + }}, }, }, }, { @@ -548,10 +548,8 @@ func TestTaskRunSpec_Validate(t *testing.T) { spec: v1beta1.TaskRunSpec{ TaskSpec: &v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "mystep", - Image: "myimage", - }, + Name: "mystep", + Image: "myimage", Script: `echo "creds-init writes to $(credentials.path)"`, }}, }, diff --git a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go index 983a234151b..50e3cdbc3a7 100644 --- a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go @@ -1297,7 +1297,73 @@ func (in *ResultRef) DeepCopy() *ResultRef { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Sidecar) DeepCopyInto(out *Sidecar) { *out = *in - in.Container.DeepCopyInto(&out.Container) + if in.Command != nil { + in, out := &in.Command, &out.Command + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]v1.ContainerPort, len(*in)) + copy(*out, *in) + } + if in.EnvFrom != nil { + in, out := &in.EnvFrom, &out.EnvFrom + *out = make([]v1.EnvFromSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Resources.DeepCopyInto(&out.Resources) + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]v1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeDevices != nil { + in, out := &in.VolumeDevices, &out.VolumeDevices + *out = make([]v1.VolumeDevice, len(*in)) + copy(*out, *in) + } + if in.LivenessProbe != nil { + in, out := &in.LivenessProbe, &out.LivenessProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.ReadinessProbe != nil { + in, out := &in.ReadinessProbe, &out.ReadinessProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.StartupProbe != nil { + in, out := &in.StartupProbe, &out.StartupProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.Lifecycle != nil { + in, out := &in.Lifecycle, &out.Lifecycle + *out = new(v1.Lifecycle) + (*in).DeepCopyInto(*out) + } + if in.SecurityContext != nil { + in, out := &in.SecurityContext, &out.SecurityContext + *out = new(v1.SecurityContext) + (*in).DeepCopyInto(*out) + } if in.Workspaces != nil { in, out := &in.Workspaces, &out.Workspaces *out = make([]WorkspaceUsage, len(*in)) @@ -1359,7 +1425,73 @@ func (in *SkippedTask) DeepCopy() *SkippedTask { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Step) DeepCopyInto(out *Step) { *out = *in - in.Container.DeepCopyInto(&out.Container) + if in.Command != nil { + in, out := &in.Command, &out.Command + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]v1.ContainerPort, len(*in)) + copy(*out, *in) + } + if in.EnvFrom != nil { + in, out := &in.EnvFrom, &out.EnvFrom + *out = make([]v1.EnvFromSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Resources.DeepCopyInto(&out.Resources) + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]v1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeDevices != nil { + in, out := &in.VolumeDevices, &out.VolumeDevices + *out = make([]v1.VolumeDevice, len(*in)) + copy(*out, *in) + } + if in.LivenessProbe != nil { + in, out := &in.LivenessProbe, &out.LivenessProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.ReadinessProbe != nil { + in, out := &in.ReadinessProbe, &out.ReadinessProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.StartupProbe != nil { + in, out := &in.StartupProbe, &out.StartupProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.Lifecycle != nil { + in, out := &in.Lifecycle, &out.Lifecycle + *out = new(v1.Lifecycle) + (*in).DeepCopyInto(*out) + } + if in.SecurityContext != nil { + in, out := &in.SecurityContext, &out.SecurityContext + *out = new(v1.SecurityContext) + (*in).DeepCopyInto(*out) + } if in.Timeout != nil { in, out := &in.Timeout, &out.Timeout *out = new(metav1.Duration) @@ -1400,6 +1532,89 @@ func (in *StepState) DeepCopy() *StepState { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StepTemplate) DeepCopyInto(out *StepTemplate) { + *out = *in + if in.Command != nil { + in, out := &in.Command, &out.Command + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]v1.ContainerPort, len(*in)) + copy(*out, *in) + } + if in.EnvFrom != nil { + in, out := &in.EnvFrom, &out.EnvFrom + *out = make([]v1.EnvFromSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + in.Resources.DeepCopyInto(&out.Resources) + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]v1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.VolumeDevices != nil { + in, out := &in.VolumeDevices, &out.VolumeDevices + *out = make([]v1.VolumeDevice, len(*in)) + copy(*out, *in) + } + if in.LivenessProbe != nil { + in, out := &in.LivenessProbe, &out.LivenessProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.ReadinessProbe != nil { + in, out := &in.ReadinessProbe, &out.ReadinessProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.StartupProbe != nil { + in, out := &in.StartupProbe, &out.StartupProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.Lifecycle != nil { + in, out := &in.Lifecycle, &out.Lifecycle + *out = new(v1.Lifecycle) + (*in).DeepCopyInto(*out) + } + if in.SecurityContext != nil { + in, out := &in.SecurityContext, &out.SecurityContext + *out = new(v1.SecurityContext) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepTemplate. +func (in *StepTemplate) DeepCopy() *StepTemplate { + if in == nil { + return nil + } + out := new(StepTemplate) + 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 @@ -1965,7 +2180,7 @@ func (in *TaskSpec) DeepCopyInto(out *TaskSpec) { } if in.StepTemplate != nil { in, out := &in.StepTemplate, &out.StepTemplate - *out = new(v1.Container) + *out = new(StepTemplate) (*in).DeepCopyInto(*out) } if in.Sidecars != nil { diff --git a/pkg/apis/resource/v1alpha1/cluster/cluster_resource.go b/pkg/apis/resource/v1alpha1/cluster/cluster_resource.go index 939d6ec19b0..542c06cc2da 100644 --- a/pkg/apis/resource/v1alpha1/cluster/cluster_resource.go +++ b/pkg/apis/resource/v1alpha1/cluster/cluster_resource.go @@ -186,7 +186,7 @@ func (s *Resource) GetInputTaskModifier(ts *v1beta1.TaskSpec, path string) (v1be } envVars = append(envVars, ev) } - step := v1beta1.Step{Container: corev1.Container{ + step := v1beta1.Step{ Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix("kubeconfig"), Image: s.KubeconfigWriterImage, Command: []string{"/ko-app/kubeconfigwriter"}, @@ -194,7 +194,7 @@ func (s *Resource) GetInputTaskModifier(ts *v1beta1.TaskSpec, path string) (v1be "-clusterConfig", s.String(), }, Env: envVars, - }} + } return &v1beta1.InternalTaskModifier{ StepsToPrepend: []v1beta1.Step{ step, diff --git a/pkg/apis/resource/v1alpha1/cluster/cluster_resource_test.go b/pkg/apis/resource/v1alpha1/cluster/cluster_resource_test.go index 1c01366cf0e..bcb642a14ba 100644 --- a/pkg/apis/resource/v1alpha1/cluster/cluster_resource_test.go +++ b/pkg/apis/resource/v1alpha1/cluster/cluster_resource_test.go @@ -285,28 +285,26 @@ func TestClusterResource_GetInputTaskModifier(t *testing.T) { ts := v1beta1.TaskSpec{} wantSteps := []v1beta1.Step{ { - Container: corev1.Container{ - Name: "kubeconfig-9l9zj", - Image: "override-with-kubeconfig-writer:latest", - Command: []string{"/ko-app/kubeconfigwriter"}, - Args: []string{"-clusterConfig", `{"name":"test-cluster-resource","type":"cluster","url":"http://10.10.10.10","revision":"","username":"","password":"","namespace":"","token":"","Insecure":false,"cadata":null,"clientKeyData":null,"clientCertificateData":null,"secrets":[{"fieldName":"cadata","secretKey":"cadatakey","secretName":"secret1"}]}`}, - Env: []corev1.EnvVar{ - { - Name: "TEKTON_RESOURCE_NAME", - Value: "test-cluster-resource", - }, - { - Name: "CADATA", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "secret1", - }, - Key: "cadatakey", + Name: "kubeconfig-9l9zj", + Image: "override-with-kubeconfig-writer:latest", + Command: []string{"/ko-app/kubeconfigwriter"}, + Args: []string{"-clusterConfig", `{"name":"test-cluster-resource","type":"cluster","url":"http://10.10.10.10","revision":"","username":"","password":"","namespace":"","token":"","Insecure":false,"cadata":null,"clientKeyData":null,"clientCertificateData":null,"secrets":[{"fieldName":"cadata","secretKey":"cadatakey","secretName":"secret1"}]}`}, + Env: []corev1.EnvVar{ + { + Name: "TEKTON_RESOURCE_NAME", + Value: "test-cluster-resource", + }, + { + Name: "CADATA", + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "secret1", }, + Key: "cadatakey", }, - }}, - }, + }, + }}, }, } diff --git a/pkg/apis/resource/v1alpha1/git/git_resource.go b/pkg/apis/resource/v1alpha1/git/git_resource.go index 5e102c9440e..1b9c2e2269b 100644 --- a/pkg/apis/resource/v1alpha1/git/git_resource.go +++ b/pkg/apis/resource/v1alpha1/git/git_resource.go @@ -188,18 +188,16 @@ func (s *Resource) GetInputTaskModifier(_ *v1beta1.TaskSpec, path string) (v1bet } step := v1beta1.Step{ - Container: corev1.Container{ - Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(gitSource + "-" + s.Name), - Image: s.GitImage, - Command: []string{"/ko-app/git-init"}, - Args: args, - WorkingDir: pipeline.WorkspaceDir, - // This is used to populate the ResourceResult status. - Env: env, - SecurityContext: &corev1.SecurityContext{ - // The git pipeline resource only works when running as root. - RunAsUser: ptr.Int64(0), - }, + Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(gitSource + "-" + s.Name), + Image: s.GitImage, + Command: []string{"/ko-app/git-init"}, + Args: args, + WorkingDir: pipeline.WorkspaceDir, + // This is used to populate the ResourceResult status. + Env: env, + SecurityContext: &corev1.SecurityContext{ + // The git pipeline resource only works when running as root. + RunAsUser: ptr.Int64(0), }, } diff --git a/pkg/apis/resource/v1alpha1/git/git_resource_test.go b/pkg/apis/resource/v1alpha1/git/git_resource_test.go index 2d2e0a9ffce..3d0847727d1 100644 --- a/pkg/apis/resource/v1alpha1/git/git_resource_test.go +++ b/pkg/apis/resource/v1alpha1/git/git_resource_test.go @@ -547,7 +547,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { for _, tc := range []struct { desc string gitResource *git.Resource - want corev1.Container + want v1beta1.Step }{{ desc: "With basic values", gitResource: &git.Resource{ @@ -564,7 +564,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { HTTPSProxy: "https-proxy.git.com", NOProxy: "no-proxy.git.com", }, - want: corev1.Container{ + want: v1beta1.Step{ Name: "git-source-git-resource-9l9zj", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -602,7 +602,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { HTTPSProxy: "https-proxy.git.com", NOProxy: "no-proxy.git.com", }, - want: corev1.Container{ + want: v1beta1.Step{ Name: "git-source-git-resource-mz4c7", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -641,7 +641,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { HTTPSProxy: "https-proxy.git.com", NOProxy: "no-proxy.git.com", }, - want: corev1.Container{ + want: v1beta1.Step{ Name: "git-source-git-resource-mssqb", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -681,7 +681,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { HTTPSProxy: "https-proxy.git.com", NOProxy: "no-proxy.git.com", }, - want: corev1.Container{ + want: v1beta1.Step{ Name: "git-source-git-resource-78c5n", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -720,7 +720,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { HTTPSProxy: "https-proxy.git.com", NOProxy: "no-proxy.git.com", }, - want: corev1.Container{ + want: v1beta1.Step{ Name: "git-source-git-resource-6nl7g", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -758,7 +758,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { HTTPProxy: "http-proxy.git.com", NOProxy: "no-proxy.git.com", }, - want: corev1.Container{ + want: v1beta1.Step{ Name: "git-source-git-resource-j2tds", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -796,7 +796,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { HTTPProxy: "http-proxy.git.com", HTTPSProxy: "https-proxy.git.com", }, - want: corev1.Container{ + want: v1beta1.Step{ Name: "git-source-git-resource-vr6ds", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -835,7 +835,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { HTTPSProxy: "https-proxy.git.com", NOProxy: "no-proxy.git.com", }, - want: corev1.Container{ + want: v1beta1.Step{ Name: "git-source-git-resource-l22wn", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -876,7 +876,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { HTTPSProxy: "https-proxy.git.com", NOProxy: "no-proxy.git.com", }, - want: corev1.Container{ + want: v1beta1.Step{ Name: "git-source-git-resource-twkr2", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -905,7 +905,7 @@ func TestGitResource_GetDownloadTaskModifier(t *testing.T) { t.Fatalf("Unexpected error getting GetDownloadTaskModifier: %s", err) } - if d := cmp.Diff([]v1beta1.Step{{Container: tc.want}}, modifier.GetStepsToPrepend()); d != "" { + if d := cmp.Diff([]v1beta1.Step{tc.want}, modifier.GetStepsToPrepend()); d != "" { t.Errorf("Mismatch of GitResource DownloadContainerSpec %s", diff.PrintWantGot(d)) } }) diff --git a/pkg/apis/resource/v1alpha1/pullrequest/pull_request_resource.go b/pkg/apis/resource/v1alpha1/pullrequest/pull_request_resource.go index f3035e42f3d..efdaee48df9 100644 --- a/pkg/apis/resource/v1alpha1/pullrequest/pull_request_resource.go +++ b/pkg/apis/resource/v1alpha1/pullrequest/pull_request_resource.go @@ -168,7 +168,7 @@ func (s *Resource) getSteps(mode string, sourcePath string) []pipelinev1beta1.St } } - return []pipelinev1beta1.Step{{Container: corev1.Container{ + return []pipelinev1beta1.Step{{ Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(prSource + "-" + s.Name), Image: s.PRImage, Command: []string{"/ko-app/pullrequest-init"}, @@ -179,5 +179,5 @@ func (s *Resource) getSteps(mode string, sourcePath string) []pipelinev1beta1.St // The pullrequest pipeline resource only works when running as root. RunAsUser: ptr.Int64(0), }, - }}} + }} } diff --git a/pkg/apis/resource/v1alpha1/pullrequest/pull_request_resource_test.go b/pkg/apis/resource/v1alpha1/pullrequest/pull_request_resource_test.go index 602c60c6263..15bb1722cba 100644 --- a/pkg/apis/resource/v1alpha1/pullrequest/pull_request_resource_test.go +++ b/pkg/apis/resource/v1alpha1/pullrequest/pull_request_resource_test.go @@ -113,7 +113,7 @@ func containerTestCases(mode string) []testcase { PRImage: "override-with-pr:latest", InsecureSkipTLSVerify: false, }, - out: []v1beta1.Step{{Container: corev1.Container{ + out: []v1beta1.Step{{ Name: "pr-source-nocreds-9l9zj", Image: "override-with-pr:latest", WorkingDir: pipeline.WorkspaceDir, @@ -121,7 +121,7 @@ func containerTestCases(mode string) []testcase { Args: []string{"-url", "https://example.com", "-path", workspace, "-mode", mode}, Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "nocreds"}}, SecurityContext: securityContext, - }}}, + }}, }, { in: &pullrequest.Resource{ Name: "creds", @@ -135,7 +135,7 @@ func containerTestCases(mode string) []testcase { PRImage: "override-with-pr:latest", Provider: "github", }, - out: []v1beta1.Step{{Container: corev1.Container{ + out: []v1beta1.Step{{ Name: "pr-source-creds-mz4c7", Image: "override-with-pr:latest", WorkingDir: pipeline.WorkspaceDir, @@ -155,7 +155,7 @@ func containerTestCases(mode string) []testcase { }, }}, SecurityContext: securityContext, - }}}, + }}, }, { in: &pullrequest.Resource{ Name: "nocreds", @@ -163,7 +163,7 @@ func containerTestCases(mode string) []testcase { PRImage: "override-with-pr:latest", InsecureSkipTLSVerify: true, }, - out: []v1beta1.Step{{Container: corev1.Container{ + out: []v1beta1.Step{{ Name: "pr-source-nocreds-mssqb", Image: "override-with-pr:latest", WorkingDir: pipeline.WorkspaceDir, @@ -171,7 +171,7 @@ func containerTestCases(mode string) []testcase { Args: []string{"-url", "https://example.com", "-path", workspace, "-mode", mode, "-insecure-skip-tls-verify=true"}, Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "nocreds"}}, SecurityContext: securityContext, - }}}, + }}, }, { in: &pullrequest.Resource{ Name: "strict-json-comments", @@ -179,7 +179,7 @@ func containerTestCases(mode string) []testcase { PRImage: "override-with-pr:latest", DisableStrictJSONComments: true, }, - out: []v1beta1.Step{{Container: corev1.Container{ + out: []v1beta1.Step{{ Name: "pr-source-strict-json-comments-78c5n", Image: "override-with-pr:latest", WorkingDir: pipeline.WorkspaceDir, @@ -187,7 +187,7 @@ func containerTestCases(mode string) []testcase { Args: []string{"-url", "https://example.com", "-path", workspace, "-mode", mode, "-disable-strict-json-comments=true"}, Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "strict-json-comments"}}, SecurityContext: securityContext, - }}}, + }}, }} } diff --git a/pkg/apis/resource/v1alpha1/storage/artifact_bucket.go b/pkg/apis/resource/v1alpha1/storage/artifact_bucket.go index 0c23798b29b..48b4986b419 100644 --- a/pkg/apis/resource/v1alpha1/storage/artifact_bucket.go +++ b/pkg/apis/resource/v1alpha1/storage/artifact_bucket.go @@ -57,32 +57,32 @@ func (b *ArtifactBucket) StorageBasePath(pr *v1beta1.PipelineRun) string { func (b *ArtifactBucket) GetCopyFromStorageToSteps(name, sourcePath, destinationPath string) []v1beta1.Step { envVars, secretVolumeMount := getSecretEnvVarsAndVolumeMounts("bucket", secretVolumeMountPath, b.Secrets) - return []v1beta1.Step{{Container: corev1.Container{ + return []v1beta1.Step{{ Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("artifact-dest-mkdir-%s", name)), Image: b.ShellImage, Command: []string{"mkdir", "-p", destinationPath}, - }}, {Container: corev1.Container{ + }, { Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("artifact-copy-from-%s", name)), Image: b.GsutilImage, Command: []string{"gsutil"}, Args: []string{"cp", "-P", "-r", fmt.Sprintf("%s/%s/*", b.Location, sourcePath), destinationPath}, Env: envVars, VolumeMounts: secretVolumeMount, - }}} + }} } // GetCopyToStorageFromSteps returns a container used to upload artifacts for temporary storage func (b *ArtifactBucket) GetCopyToStorageFromSteps(name, sourcePath, destinationPath string) []v1beta1.Step { envVars, secretVolumeMount := getSecretEnvVarsAndVolumeMounts("bucket", secretVolumeMountPath, b.Secrets) - return []v1beta1.Step{{Container: corev1.Container{ + return []v1beta1.Step{{ Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("artifact-copy-to-%s", name)), Image: b.GsutilImage, Command: []string{"gsutil"}, Args: []string{"cp", "-P", "-r", sourcePath, fmt.Sprintf("%s/%s", b.Location, destinationPath)}, Env: envVars, VolumeMounts: secretVolumeMount, - }}} + }} } // GetSecretsVolumes returns the list of volumes for secrets to be mounted diff --git a/pkg/apis/resource/v1alpha1/storage/artifact_bucket_test.go b/pkg/apis/resource/v1alpha1/storage/artifact_bucket_test.go index 8360f2df750..ffeb8e51cb4 100644 --- a/pkg/apis/resource/v1alpha1/storage/artifact_bucket_test.go +++ b/pkg/apis/resource/v1alpha1/storage/artifact_bucket_test.go @@ -50,18 +50,18 @@ var ( func TestBucketGetCopyFromContainerSpec(t *testing.T) { names.TestingSeed() - want := []v1alpha1.Step{{Container: corev1.Container{ + want := []v1alpha1.Step{{ Name: "artifact-dest-mkdir-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/destination"}, - }}, {Container: corev1.Container{ + }, { Name: "artifact-copy-from-workspace-mz4c7", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, Args: []string{"cp", "-P", "-r", "gs://fake-bucket/src-path/*", "/workspace/destination"}, Env: []corev1.EnvVar{{Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: fmt.Sprintf("/var/bucketsecret/%s/serviceaccount", secretName)}}, VolumeMounts: []corev1.VolumeMount{{Name: expectedVolumeName, MountPath: fmt.Sprintf("/var/bucketsecret/%s", secretName)}}, - }}} + }} got := bucket.GetCopyFromStorageToSteps("workspace", "src-path", "/workspace/destination") if d := cmp.Diff(got, want); d != "" { @@ -71,14 +71,14 @@ func TestBucketGetCopyFromContainerSpec(t *testing.T) { func TestBucketGetCopyToContainerSpec(t *testing.T) { names.TestingSeed() - want := []v1alpha1.Step{{Container: corev1.Container{ + want := []v1alpha1.Step{{ Name: "artifact-copy-to-workspace-9l9zj", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, Args: []string{"cp", "-P", "-r", "src-path", "gs://fake-bucket/workspace/destination"}, Env: []corev1.EnvVar{{Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: fmt.Sprintf("/var/bucketsecret/%s/serviceaccount", secretName)}}, VolumeMounts: []corev1.VolumeMount{{Name: expectedVolumeName, MountPath: fmt.Sprintf("/var/bucketsecret/%s", secretName)}}, - }}} + }} got := bucket.GetCopyToStorageFromSteps("workspace", "src-path", "workspace/destination") if d := cmp.Diff(got, want); d != "" { diff --git a/pkg/apis/resource/v1alpha1/storage/artifact_pvc.go b/pkg/apis/resource/v1alpha1/storage/artifact_pvc.go index 80c882ad3d6..117e90a7e72 100644 --- a/pkg/apis/resource/v1alpha1/storage/artifact_pvc.go +++ b/pkg/apis/resource/v1alpha1/storage/artifact_pvc.go @@ -51,7 +51,7 @@ func (p *ArtifactPVC) StorageBasePath(pr *v1beta1.PipelineRun) string { // GetCopyFromStorageToSteps returns a container used to download artifacts from temporary storage. func (p *ArtifactPVC) GetCopyFromStorageToSteps(name, sourcePath, destinationPath string) []v1beta1.Step { - return []v1beta1.Step{{Container: corev1.Container{ + return []v1beta1.Step{{ Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("source-copy-%s", name)), Image: p.ShellImage, Command: []string{"cp", "-r", fmt.Sprintf("%s/.", sourcePath), destinationPath}, @@ -59,12 +59,12 @@ func (p *ArtifactPVC) GetCopyFromStorageToSteps(name, sourcePath, destinationPat Name: "TEKTON_RESOURCE_NAME", Value: name, }}, - }}} + }} } // GetCopyToStorageFromSteps returns a container used to upload artifacts for temporary storage. func (p *ArtifactPVC) GetCopyToStorageFromSteps(name, sourcePath, destinationPath string) []v1beta1.Step { - return []v1beta1.Step{{Container: corev1.Container{ + return []v1beta1.Step{{ Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("source-mkdir-%s", name)), Image: p.ShellImage, // This requires us to run as root, and the ShellImage is nonroot @@ -74,7 +74,7 @@ func (p *ArtifactPVC) GetCopyToStorageFromSteps(name, sourcePath, destinationPat }, Command: []string{"mkdir", "-p", destinationPath}, VolumeMounts: []corev1.VolumeMount{GetPvcMount(p.Name)}, - }}, {Container: corev1.Container{ + }, { Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("source-copy-%s", name)), Image: p.ShellImage, // This requires us to run as root, and the ShellImage is nonroot @@ -88,7 +88,7 @@ func (p *ArtifactPVC) GetCopyToStorageFromSteps(name, sourcePath, destinationPat Name: "TEKTON_RESOURCE_NAME", Value: name, }}, - }}} + }} } // GetPvcMount returns a mounting of the volume with the mount path /pvc. diff --git a/pkg/apis/resource/v1alpha1/storage/artifact_pvc_test.go b/pkg/apis/resource/v1alpha1/storage/artifact_pvc_test.go index 011c79e8c5c..1894a9ac10f 100644 --- a/pkg/apis/resource/v1alpha1/storage/artifact_pvc_test.go +++ b/pkg/apis/resource/v1alpha1/storage/artifact_pvc_test.go @@ -36,13 +36,13 @@ func TestPVCGetCopyFromContainerSpec(t *testing.T) { Name: "pipelinerun-pvc", ShellImage: "busybox", } - want := []v1beta1.Step{{Container: corev1.Container{ + want := []v1beta1.Step{{ Name: "source-copy-workspace-9l9zj", Image: "busybox", Command: []string{"cp", "-r", "src-path/.", "/workspace/destination"}, Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "workspace"}}, - }}} + }} got := pvc.GetCopyFromStorageToSteps("workspace", "src-path", "/workspace/destination") if d := cmp.Diff(got, want); d != "" { @@ -57,7 +57,7 @@ func TestPVCGetCopyToContainerSpec(t *testing.T) { Name: "pipelinerun-pvc", ShellImage: "busybox", } - want := []v1beta1.Step{{Container: corev1.Container{ + want := []v1beta1.Step{{ Name: "source-mkdir-workspace-9l9zj", Image: "busybox", SecurityContext: &corev1.SecurityContext{ @@ -65,7 +65,7 @@ func TestPVCGetCopyToContainerSpec(t *testing.T) { }, Command: []string{"mkdir", "-p", "/workspace/destination"}, VolumeMounts: []corev1.VolumeMount{{MountPath: "/pvc", Name: "pipelinerun-pvc"}}, - }}, {Container: corev1.Container{ + }, { Name: "source-copy-workspace-mz4c7", Image: "busybox", SecurityContext: &corev1.SecurityContext{ @@ -74,7 +74,7 @@ func TestPVCGetCopyToContainerSpec(t *testing.T) { Command: []string{"cp", "-r", "src-path/.", "/workspace/destination"}, VolumeMounts: []corev1.VolumeMount{{MountPath: "/pvc", Name: "pipelinerun-pvc"}}, Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "workspace"}}, - }}} + }} got := pvc.GetCopyToStorageFromSteps("workspace", "src-path", "/workspace/destination") if d := cmp.Diff(got, want); d != "" { @@ -100,11 +100,11 @@ func TestPVCGetPvcMount(t *testing.T) { func TestPVCGetMakeStep(t *testing.T) { names.TestingSeed() - want := v1beta1.Step{Container: corev1.Container{ + want := v1beta1.Step{ Name: "create-dir-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/destination"}, - }} + } got := storage.CreateDirStep("busybox", "workspace", "/workspace/destination") if d := cmp.Diff(got, want); d != "" { t.Errorf("Diff:\n%s", diff.PrintWantGot(d)) diff --git a/pkg/apis/resource/v1alpha1/storage/gcs.go b/pkg/apis/resource/v1alpha1/storage/gcs.go index 78a7c2cd97f..9660a3975fa 100644 --- a/pkg/apis/resource/v1alpha1/storage/gcs.go +++ b/pkg/apis/resource/v1alpha1/storage/gcs.go @@ -121,13 +121,13 @@ func (s *GCSResource) GetOutputTaskModifier(ts *v1beta1.TaskSpec, path string) ( envVars = append(envVars, corev1.EnvVar{Name: "HOME", Value: pipeline.HomeDir}) - step := v1beta1.Step{Container: corev1.Container{ + step := v1beta1.Step{ Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("upload-%s", s.Name)), Image: s.GsutilImage, Command: []string{"gsutil"}, Args: args, VolumeMounts: secretVolumeMount, - Env: envVars}, + Env: envVars, } volumes := getStorageVolumeSpec(s, *ts) @@ -155,13 +155,11 @@ func (s *GCSResource) GetInputTaskModifier(ts *v1beta1.TaskSpec, path string) (v steps := []v1beta1.Step{ CreateDirStep(s.ShellImage, s.Name, path), { - Script: script, - Container: corev1.Container{ - Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("fetch-%s", s.Name)), - Image: s.GsutilImage, - Env: envVars, - VolumeMounts: secretVolumeMount, - }, + Script: script, + Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("fetch-%s", s.Name)), + Image: s.GsutilImage, + Env: envVars, + VolumeMounts: secretVolumeMount, }, } diff --git a/pkg/apis/resource/v1alpha1/storage/gcs_test.go b/pkg/apis/resource/v1alpha1/storage/gcs_test.go index b4678ee6420..9c8eb904458 100644 --- a/pkg/apis/resource/v1alpha1/storage/gcs_test.go +++ b/pkg/apis/resource/v1alpha1/storage/gcs_test.go @@ -271,11 +271,11 @@ func TestGetInputSteps(t *testing.T) { ShellImage: "busybox", GsutilImage: "gcr.io/google.com/cloudsdktool/cloud-sdk", }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-gcs-valid-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace"}, - }}, { + }, { Script: `#!/usr/bin/env bash if [[ "${GOOGLE_APPLICATION_CREDENTIALS}" != "" ]]; then echo GOOGLE_APPLICATION_CREDENTIALS is set, activating Service Account... @@ -283,21 +283,19 @@ if [[ "${GOOGLE_APPLICATION_CREDENTIALS}" != "" ]]; then fi gsutil rsync -d -r gs://some-bucket /workspace `, - Container: corev1.Container{ - Name: "fetch-gcs-valid-mz4c7", - Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", - Env: []corev1.EnvVar{{ - Name: "GOOGLE_APPLICATION_CREDENTIALS", - Value: "/var/secret/secretName/key.json", - }, { - Name: "HOME", - Value: "/tekton/home", - }}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "volume-gcs-valid-secretName", - MountPath: "/var/secret/secretName", - }}, - }, + Name: "fetch-gcs-valid-mz4c7", + Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", + Env: []corev1.EnvVar{{ + Name: "GOOGLE_APPLICATION_CREDENTIALS", + Value: "/var/secret/secretName/key.json", + }, { + Name: "HOME", + Value: "/tekton/home", + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "volume-gcs-valid-secretName", + MountPath: "/var/secret/secretName", + }}, }}, }, { name: "duplicate secret mount paths", @@ -316,11 +314,11 @@ gsutil rsync -d -r gs://some-bucket /workspace ShellImage: "busybox", GsutilImage: "gcr.io/google.com/cloudsdktool/cloud-sdk", }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-gcs-valid-mssqb", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace"}, - }}, { + }, { Script: `#!/usr/bin/env bash if [[ "${GOOGLE_APPLICATION_CREDENTIALS}" != "" ]]; then echo GOOGLE_APPLICATION_CREDENTIALS is set, activating Service Account... @@ -328,21 +326,19 @@ if [[ "${GOOGLE_APPLICATION_CREDENTIALS}" != "" ]]; then fi gsutil cp gs://some-bucket /workspace `, - Container: corev1.Container{ - Name: "fetch-gcs-valid-78c5n", - Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", - Env: []corev1.EnvVar{{ - Name: "GOOGLE_APPLICATION_CREDENTIALS", - Value: "/var/secret/secretName/key.json", - }, { - Name: "HOME", - Value: "/tekton/home", - }}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "volume-gcs-valid-secretName", - MountPath: "/var/secret/secretName", - }}, - }, + Name: "fetch-gcs-valid-78c5n", + Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", + Env: []corev1.EnvVar{{ + Name: "GOOGLE_APPLICATION_CREDENTIALS", + Value: "/var/secret/secretName/key.json", + }, { + Name: "HOME", + Value: "/tekton/home", + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "volume-gcs-valid-secretName", + MountPath: "/var/secret/secretName", + }}, }}, }} { t.Run(tc.name, func(t *testing.T) { @@ -379,7 +375,7 @@ func TestGetOutputTaskModifier(t *testing.T) { }}, GsutilImage: "gcr.io/google.com/cloudsdktool/cloud-sdk", }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "upload-gcs-valid-9l9zj", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, @@ -395,7 +391,7 @@ func TestGetOutputTaskModifier(t *testing.T) { Name: "volume-gcs-valid-secretName", MountPath: "/var/secret/secretName", }}, - }}}, + }}, }, { name: "duplicate secret mount paths", gcsResource: &storage.GCSResource{ @@ -412,7 +408,7 @@ func TestGetOutputTaskModifier(t *testing.T) { }}, GsutilImage: "gcr.io/google.com/cloudsdktool/cloud-sdk", }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "upload-gcs-valid-mz4c7", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, @@ -428,7 +424,7 @@ func TestGetOutputTaskModifier(t *testing.T) { Name: "volume-gcs-valid-secretName", MountPath: "/var/secret/secretName", }}, - }}}, + }}, }, { name: "valid upload to protected buckets with single file", gcsResource: &storage.GCSResource{ @@ -437,7 +433,7 @@ func TestGetOutputTaskModifier(t *testing.T) { TypeDir: false, GsutilImage: "gcr.io/google.com/cloudsdktool/cloud-sdk", }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "upload-gcs-valid-mssqb", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, @@ -446,7 +442,7 @@ func TestGetOutputTaskModifier(t *testing.T) { Name: "HOME", Value: "/tekton/home", }}, - }}}, + }}, }} { t.Run(tc.name, func(t *testing.T) { ts := v1beta1.TaskSpec{} diff --git a/pkg/apis/resource/v1alpha1/storage/storage.go b/pkg/apis/resource/v1alpha1/storage/storage.go index 5b5467fc22a..7fa7bf13e39 100644 --- a/pkg/apis/resource/v1alpha1/storage/storage.go +++ b/pkg/apis/resource/v1alpha1/storage/storage.go @@ -84,9 +84,9 @@ func getStorageVolumeSpec(s PipelineStorageResourceInterface, spec v1beta1.TaskS // CreateDirStep returns a Step that creates a given directory with a given name. func CreateDirStep(shellImage string, name, destinationPath string) v1beta1.Step { - return v1beta1.Step{Container: corev1.Container{ + return v1beta1.Step{ Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(fmt.Sprintf("create-dir-%s", strings.ToLower(name))), Image: shellImage, Command: []string{"mkdir", "-p", destinationPath}, - }} + } } diff --git a/pkg/pod/pod_test.go b/pkg/pod/pod_test.go index 70c6f85d34e..e573cebe606 100644 --- a/pkg/pod/pod_test.go +++ b/pkg/pod/pod_test.go @@ -113,15 +113,15 @@ func TestPodBuild(t *testing.T) { }{{ desc: "simple", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -160,15 +160,15 @@ func TestPodBuild(t *testing.T) { }, }, ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -202,18 +202,18 @@ func TestPodBuild(t *testing.T) { }, { desc: "simple with running-in-environment-with-injected-sidecar set to false", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, featureFlags: map[string]string{ featureInjectedSidecar: "false", }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -250,11 +250,11 @@ func TestPodBuild(t *testing.T) { }, { desc: "with service account", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, trs: v1beta1.TaskRunSpec{ ServiceAccountName: "service-account", @@ -262,7 +262,7 @@ func TestPodBuild(t *testing.T) { want: &corev1.PodSpec{ ServiceAccountName: "service-account", RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -303,11 +303,11 @@ func TestPodBuild(t *testing.T) { }, { desc: "with-pod-template", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, trs: v1beta1.TaskRunSpec{ PodTemplate: &pod.Template{ @@ -329,7 +329,7 @@ func TestPodBuild(t *testing.T) { }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -378,15 +378,15 @@ func TestPodBuild(t *testing.T) { }, { desc: "very long step name", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ 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, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "a-very-very-long-character-step-name-to-trigger-max-len----and-invalid-characters"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "a-very-very-long-character-step-name-to-trigger-max-len----and-invalid-characters"}})}, Containers: []corev1.Container{{ Name: "step-a-very-very-long-character-step-name-to-trigger-max-len", // step name trimmed. Image: "image", @@ -420,15 +420,15 @@ func TestPodBuild(t *testing.T) { }, { desc: "step name ends with non alphanumeric", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "ends-with-invalid-%%__$$", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "ends-with-invalid-%%__$$"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "ends-with-invalid-%%__$$"}})}, Containers: []corev1.Container{{ Name: "step-ends-with-invalid", // invalid suffix removed. Image: "image", @@ -462,18 +462,18 @@ func TestPodBuild(t *testing.T) { }, { desc: "workingDir in workspace", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ 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{ placeToolsInit, - tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}}), + tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}}), { Name: "working-dir-initializer", Image: images.WorkingDirInitImage, @@ -517,22 +517,20 @@ func TestPodBuild(t *testing.T) { }, { desc: "sidecar container", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "primary-name", Image: "primary-image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - Name: "sc-name", - Image: "sidecar-image", - }, + Name: "sc-name", + Image: "sidecar-image", }}, }, wantAnnotations: map[string]string{}, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "primary-name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "primary-name"}})}, Containers: []corev1.Container{{ Name: "step-primary-name", Image: "primary-image", @@ -572,16 +570,14 @@ func TestPodBuild(t *testing.T) { }, { desc: "sidecar container with script", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "primary-name", Image: "primary-image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - Name: "sc-name", - Image: "sidecar-image", - }, + Name: "sc-name", + Image: "sidecar-image", Script: "#!/bin/sh\necho hello from sidecar", }}, }, @@ -590,7 +586,7 @@ func TestPodBuild(t *testing.T) { RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{ placeToolsInit, - tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "primary-name"}}}), + tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "primary-name"}}), { Name: "place-scripts", Image: "busybox", @@ -643,16 +639,14 @@ _EOF_ }, { desc: "sidecar container with enable-ready-annotation-on-pod-create", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "primary-name", Image: "primary-image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - Name: "sc-name", - Image: "sidecar-image", - }, + Name: "sc-name", + Image: "sidecar-image", }}, }, featureFlags: map[string]string{ @@ -661,7 +655,7 @@ _EOF_ wantAnnotations: map[string]string{}, // no ready annotations on pod create since sidecars are present want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "primary-name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "primary-name"}})}, Containers: []corev1.Container{{ Name: "step-primary-name", Image: "primary-image", @@ -698,7 +692,7 @@ _EOF_ }, { desc: "resource request", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. Resources: corev1.ResourceRequirements{ @@ -707,7 +701,7 @@ _EOF_ corev1.ResourceMemory: resource.MustParse("10Gi"), }, }, - }}, {Container: corev1.Container{ + }, { Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. Resources: corev1.ResourceRequirements{ @@ -716,13 +710,13 @@ _EOF_ corev1.ResourceMemory: resource.MustParse("100Gi"), }, }, - }}}, + }}, }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{ - {Container: corev1.Container{Name: "unnamed-0"}}, - {Container: corev1.Container{Name: "unnamed-1"}}, + {Name: "unnamed-0"}, + {Name: "unnamed-1"}, })}, Containers: []corev1.Container{{ Name: "step-unnamed-0", @@ -794,7 +788,7 @@ _EOF_ }, { desc: "with stepOverrides", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", Image: "image", Command: []string{"cmd"}, @@ -804,7 +798,7 @@ _EOF_ corev1.ResourceMemory: resource.MustParse("10Gi"), }, }, - }}}, + }}, }, trs: v1beta1.TaskRunSpec{ StepOverrides: []v1beta1.TaskRunStepOverride{{ @@ -820,7 +814,7 @@ _EOF_ want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{ - {Container: corev1.Container{Name: "step1"}}, + {Name: "step1"}, })}, Containers: []corev1.Container{{ Name: "step-step1", @@ -861,7 +855,7 @@ _EOF_ }, { desc: "with stepOverrides and stepTemplate", ts: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ Resources: corev1.ResourceRequirements{ Requests: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("8"), @@ -869,11 +863,11 @@ _EOF_ }, }, }, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", Image: "image", Command: []string{"cmd"}, - }}}, + }}, }, trs: v1beta1.TaskRunSpec{ StepOverrides: []v1beta1.TaskRunStepOverride{{ @@ -889,7 +883,7 @@ _EOF_ want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{ - {Container: corev1.Container{Name: "step1"}}, + {Name: "step1"}, })}, Containers: []corev1.Container{{ Name: "step-step1", @@ -930,20 +924,18 @@ _EOF_ }, { desc: "with sidecarOverrides", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "primary-name", Image: "primary-image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - Name: "sc-name", - Image: "sidecar-image", - Resources: corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("8"), - corev1.ResourceMemory: resource.MustParse("10Gi"), - }, + Name: "sc-name", + Image: "sidecar-image", + Resources: corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + corev1.ResourceCPU: resource.MustParse("8"), + corev1.ResourceMemory: resource.MustParse("10Gi"), }, }, }}, @@ -962,7 +954,7 @@ _EOF_ wantAnnotations: map[string]string{}, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "primary-name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "primary-name"}})}, Containers: []corev1.Container{{ Name: "step-primary-name", Image: "primary-image", @@ -1005,30 +997,24 @@ _EOF_ }, { desc: "step with script and stepTemplate", ts: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ Env: []corev1.EnvVar{{Name: "FOO", Value: "bar"}}, Args: []string{"template", "args"}, }, Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "one", - Image: "image", - }, + Name: "one", + Image: "image", Script: "#!/bin/sh\necho hello from step one", }, { - Container: corev1.Container{ - Name: "two", - Image: "image", - VolumeMounts: []corev1.VolumeMount{{Name: "i-have-a-volume-mount"}}, - }, + Name: "two", + Image: "image", + VolumeMounts: []corev1.VolumeMount{{Name: "i-have-a-volume-mount"}}, Script: `#!/usr/bin/env python print("Hello from Python")`, }, { - Container: corev1.Container{ - Name: "regular-step", - Image: "image", - Command: []string{"regular", "command"}, - }, + Name: "regular-step", + Image: "image", + Command: []string{"regular", "command"}, }}, }, want: &corev1.PodSpec{ @@ -1036,9 +1022,9 @@ print("Hello from Python")`, InitContainers: []corev1.Container{ placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{ - {Container: corev1.Container{Name: "one"}}, - {Container: corev1.Container{Name: "two"}}, - {Container: corev1.Container{Name: "regular-step"}}, + {Name: "one"}, + {Name: "two"}, + {Name: "regular-step"}, }), { Name: "place-scripts", @@ -1154,17 +1140,15 @@ _EOF_ desc: "step with script that uses two dollar signs", ts: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "one", - Image: "image", - }, + Name: "one", + Image: "image", Script: "#!/bin/sh\n$$", }}, }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, InitContainers: []corev1.Container{placeToolsInit, - tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "one"}}}), + tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "one"}}), { Name: "place-scripts", Image: images.ShellImage, @@ -1214,11 +1198,9 @@ _EOF_ ts: v1beta1.TaskSpec{ Steps: []v1beta1.Step{ { - Container: corev1.Container{ - Name: "schedule-me", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }, + Name: "schedule-me", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. }, }, }, @@ -1229,7 +1211,7 @@ _EOF_ }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "schedule-me"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "schedule-me"}})}, SchedulerName: "there-scheduler", Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ Name: "tekton-creds-init-home-0", @@ -1267,11 +1249,9 @@ _EOF_ ts: v1beta1.TaskSpec{ Steps: []v1beta1.Step{ { - Container: corev1.Container{ - Name: "image-pull", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }, + Name: "image-pull", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. }, }, }, @@ -1282,7 +1262,7 @@ _EOF_ }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "image-pull"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "image-pull"}})}, Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ Name: "tekton-creds-init-home-0", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, @@ -1320,11 +1300,9 @@ _EOF_ Steps: []v1beta1.Step{ { - Container: corev1.Container{ - Name: "host-aliases", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }, + Name: "host-aliases", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. }, }, }, @@ -1335,7 +1313,7 @@ _EOF_ }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "host-aliases"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "host-aliases"}})}, Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ Name: "tekton-creds-init-home-0", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory}}, @@ -1371,11 +1349,9 @@ _EOF_ ts: v1beta1.TaskSpec{ Steps: []v1beta1.Step{ { - Container: corev1.Container{ - Name: "use-my-hostNetwork", - Image: "image", - Command: []string{"cmd"}, // avoid entrypoint lookup. - }, + Name: "use-my-hostNetwork", + Image: "image", + Command: []string{"cmd"}, // avoid entrypoint lookup. }, }, }, @@ -1386,7 +1362,7 @@ _EOF_ }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "use-my-hostNetwork"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "use-my-hostNetwork"}})}, HostNetwork: true, Volumes: append(implicitVolumes, binVolume, runVolume(0), downwardVolume, corev1.Volume{ Name: "tekton-creds-init-home-0", @@ -1421,17 +1397,16 @@ _EOF_ }, { desc: "step-with-timeout", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }, Timeout: &metav1.Duration{Duration: time.Second}, }}, }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -1467,11 +1442,10 @@ _EOF_ }, { desc: "step-with-no-timeout-equivalent-to-0-second-timeout", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }, Timeout: &metav1.Duration{Duration: 0 * time.Second}, }}, }, @@ -1480,7 +1454,7 @@ _EOF_ }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -1519,15 +1493,15 @@ _EOF_ "disable-creds-init": "true", }, ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -1556,18 +1530,18 @@ _EOF_ desc: "hermetic env var", featureFlags: map[string]string{"enable-api-fields": "alpha"}, ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, trAnnotation: map[string]string{ "experimental.tekton.dev/execution-mode": "hermetic", }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -1605,19 +1579,19 @@ _EOF_ desc: "override hermetic env var", featureFlags: map[string]string{"enable-api-fields": "alpha"}, ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. Env: []corev1.EnvVar{{Name: "TEKTON_HERMETIC", Value: "something_else"}}, - }}}, + }}, }, trAnnotation: map[string]string{ "experimental.tekton.dev/execution-mode": "hermetic", }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -1656,11 +1630,11 @@ _EOF_ }, { desc: "pod for a taskRun with retries", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, trStatus: v1beta1.TaskRunStatus{ TaskRunStatusFields: v1beta1.TaskRunStatusFields{ @@ -1683,7 +1657,7 @@ _EOF_ }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -1718,17 +1692,17 @@ _EOF_ }, { desc: "long-taskrun-name", ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, trName: "task-run-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789", wantPodName: "task-run-0123456789-01234560d38957287bb0283c59440df14069f59-pod", want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -1873,15 +1847,15 @@ func TestPodBuildwithAlphaAPIEnabled(t *testing.T) { }, }, ts: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "image", Command: []string{"cmd"}, // avoid entrypoint lookup. - }}}, + }}, }, want: &corev1.PodSpec{ RestartPolicy: corev1.RestartPolicyNever, - InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Container: corev1.Container{Name: "name"}}})}, + InitContainers: []corev1.Container{placeToolsInit, tektonDirInit(images.EntrypointImage, []v1beta1.Step{{Name: "name"}})}, Containers: []corev1.Container{{ Name: "step-name", Image: "image", @@ -2022,9 +1996,7 @@ func TestMakeLabels(t *testing.T) { func TestShouldAddReadyAnnotationonPodCreate(t *testing.T) { sd := v1beta1.Sidecar{ - Container: corev1.Container{ - Name: "a-sidecar", - }, + Name: "a-sidecar", } tcs := []struct { description string diff --git a/pkg/pod/script.go b/pkg/pod/script.go index 2f886b355d6..8ca0043f41b 100644 --- a/pkg/pod/script.go +++ b/pkg/pod/script.go @@ -97,12 +97,13 @@ func convertScripts(shellImageLinux string, shellImageWin string, steps []v1beta breakpoints := []string{} sideCarSteps := []v1beta1.Step{} - for _, step := range sidecars { + for _, sidecar := range sidecars { + c := sidecar.ToK8sContainer() sidecarStep := v1beta1.Step{ - Container: step.Container, - Script: step.Script, - Timeout: &metav1.Duration{}, + Script: sidecar.Script, + Timeout: &metav1.Duration{}, } + sidecarStep.SetContainerFields(*c) sideCarSteps = append(sideCarSteps, sidecarStep) } @@ -131,7 +132,7 @@ func convertListOfSteps(steps []v1beta1.Step, initContainer *corev1.Container, p for i, s := range steps { if s.Script == "" { // Nothing to convert. - containers = append(containers, s.Container) + containers = append(containers, *s.ToK8sContainer()) continue } @@ -194,7 +195,7 @@ cat > ${scriptfile} << '%s' } steps[i].VolumeMounts = append(steps[i].VolumeMounts, debugScriptsVolumeMount, debugInfoVolumeMount) } - containers = append(containers, steps[i].Container) + containers = append(containers, *steps[i].ToK8sContainer()) } // Place debug scripts if breakpoints are enabled diff --git a/pkg/pod/script_test.go b/pkg/pod/script_test.go index 71e90169010..6ab62821422 100644 --- a/pkg/pod/script_test.go +++ b/pkg/pod/script_test.go @@ -28,13 +28,9 @@ import ( func TestConvertScripts_NothingToConvert_EmptySidecars(t *testing.T) { gotInit, gotScripts, gotSidecars := convertScripts(images.ShellImage, images.ShellImageWin, []v1beta1.Step{{ - Container: corev1.Container{ - Image: "step-1", - }, + Image: "step-1", }, { - Container: corev1.Container{ - Image: "step-2", - }, + Image: "step-2", }}, []v1beta1.Sidecar{}, nil) want := []corev1.Container{{ Image: "step-1", @@ -55,13 +51,9 @@ func TestConvertScripts_NothingToConvert_EmptySidecars(t *testing.T) { func TestConvertScripts_NothingToConvert_NilSidecars(t *testing.T) { gotInit, gotScripts, gotSidecars := convertScripts(images.ShellImage, images.ShellImageWin, []v1beta1.Step{{ - Container: corev1.Container{ - Image: "step-1", - }, + Image: "step-1", }, { - Container: corev1.Container{ - Image: "step-2", - }, + Image: "step-2", }}, nil, nil) want := []corev1.Container{{ Image: "step-1", @@ -82,17 +74,11 @@ func TestConvertScripts_NothingToConvert_NilSidecars(t *testing.T) { func TestConvertScripts_NothingToConvert_WithSidecar(t *testing.T) { gotInit, gotScripts, gotSidecars := convertScripts(images.ShellImage, images.ShellImageWin, []v1beta1.Step{{ - Container: corev1.Container{ - Image: "step-1", - }, + Image: "step-1", }, { - Container: corev1.Container{ - Image: "step-2", - }, + Image: "step-2", }}, []v1beta1.Sidecar{{ - Container: corev1.Container{ - Image: "sidecar-1", - }, + Image: "sidecar-1", }}, nil) want := []corev1.Container{{ Image: "step-1", @@ -133,26 +119,22 @@ func TestConvertScripts(t *testing.T) { gotInit, gotSteps, gotSidecars := convertScripts(images.ShellImage, images.ShellImageWin, []v1beta1.Step{{ Script: `#!/bin/sh script-1`, - Container: corev1.Container{Image: "step-1"}, + Image: "step-1", }, { // No script to convert here. - Container: corev1.Container{Image: "step-2"}, + Image: "step-2", }, { Script: ` #!/bin/sh script-3`, - Container: corev1.Container{ - Image: "step-3", - VolumeMounts: preExistingVolumeMounts, - Args: []string{"my", "args"}, - }, + Image: "step-3", + VolumeMounts: preExistingVolumeMounts, + Args: []string{"my", "args"}, }, { - Script: `no-shebang`, - Container: corev1.Container{ - Image: "step-3", - VolumeMounts: preExistingVolumeMounts, - Args: []string{"my", "args"}, - }, + Script: `no-shebang`, + Image: "step-3", + VolumeMounts: preExistingVolumeMounts, + Args: []string{"my", "args"}, }}, []v1beta1.Sidecar{}, nil) wantInit := &corev1.Container{ Name: "place-scripts", @@ -226,26 +208,22 @@ func TestConvertScripts_WithBreakpoint_OnFailure(t *testing.T) { gotInit, gotSteps, gotSidecars := convertScripts(images.ShellImage, images.ShellImageWin, []v1beta1.Step{{ Script: `#!/bin/sh script-1`, - Container: corev1.Container{Image: "step-1"}, + Image: "step-1", }, { // No script to convert here. - Container: corev1.Container{Image: "step-2"}, + Image: "step-2", }, { Script: ` #!/bin/sh script-3`, - Container: corev1.Container{ - Image: "step-3", - VolumeMounts: preExistingVolumeMounts, - Args: []string{"my", "args"}, - }, + Image: "step-3", + VolumeMounts: preExistingVolumeMounts, + Args: []string{"my", "args"}, }, { - Script: `no-shebang`, - Container: corev1.Container{ - Image: "step-3", - VolumeMounts: preExistingVolumeMounts, - Args: []string{"my", "args"}, - }, + Script: `no-shebang`, + Image: "step-3", + VolumeMounts: preExistingVolumeMounts, + Args: []string{"my", "args"}, }}, []v1beta1.Sidecar{}, &v1beta1.TaskRunDebug{ Breakpoint: []string{breakpointOnFailure}, }) @@ -368,22 +346,20 @@ func TestConvertScripts_WithSidecar(t *testing.T) { gotInit, gotSteps, gotSidecars := convertScripts(images.ShellImage, images.ShellImageWin, []v1beta1.Step{{ Script: `#!/bin/sh script-1`, - Container: corev1.Container{Image: "step-1"}, + Image: "step-1", }, { // No script to convert here.: - Container: corev1.Container{Image: "step-2"}, + Image: "step-2", }, { Script: `#!/bin/sh script-3`, - Container: corev1.Container{ - Image: "step-3", - VolumeMounts: preExistingVolumeMounts, - Args: []string{"my", "args"}, - }, + Image: "step-3", + VolumeMounts: preExistingVolumeMounts, + Args: []string{"my", "args"}, }}, []v1beta1.Sidecar{{ Script: `#!/bin/sh sidecar-1`, - Container: corev1.Container{Image: "sidecar-1"}, + Image: "sidecar-1", }}, nil) wantInit := &corev1.Container{ Name: "place-scripts", @@ -462,26 +438,22 @@ func TestConvertScripts_Windows(t *testing.T) { gotInit, gotSteps, gotSidecars := convertScripts(images.ShellImage, images.ShellImageWin, []v1beta1.Step{{ Script: `#!win pwsh -File script-1`, - Container: corev1.Container{Image: "step-1"}, + Image: "step-1", }, { // No script to convert here. - Container: corev1.Container{Image: "step-2"}, + Image: "step-2", }, { Script: `#!win powershell -File script-3`, - Container: corev1.Container{ - Image: "step-3", - VolumeMounts: preExistingVolumeMounts, - Args: []string{"my", "args"}, - }, + Image: "step-3", + VolumeMounts: preExistingVolumeMounts, + Args: []string{"my", "args"}, }, { Script: `#!win no-shebang`, - Container: corev1.Container{ - Image: "step-3", - VolumeMounts: preExistingVolumeMounts, - Args: []string{"my", "args"}, - }, + Image: "step-3", + VolumeMounts: preExistingVolumeMounts, + Args: []string{"my", "args"}, }}, []v1beta1.Sidecar{}, nil) wantInit := &corev1.Container{ Name: "place-scripts", @@ -549,22 +521,20 @@ func TestConvertScripts_Windows_WithSidecar(t *testing.T) { gotInit, gotSteps, gotSidecars := convertScripts(images.ShellImage, images.ShellImageWin, []v1beta1.Step{{ Script: `#!win pwsh -File script-1`, - Container: corev1.Container{Image: "step-1"}, + Image: "step-1", }, { // No script to convert here.: - Container: corev1.Container{Image: "step-2"}, + Image: "step-2", }, { Script: `#!win powershell -File script-3`, - Container: corev1.Container{ - Image: "step-3", - VolumeMounts: preExistingVolumeMounts, - Args: []string{"my", "args"}, - }, + Image: "step-3", + VolumeMounts: preExistingVolumeMounts, + Args: []string{"my", "args"}, }}, []v1beta1.Sidecar{{ Script: `#!win pwsh -File sidecar-1`, - Container: corev1.Container{Image: "sidecar-1"}, + Image: "sidecar-1", }}, nil) wantInit := &corev1.Container{ Name: "place-scripts", @@ -630,11 +600,11 @@ func TestConvertScripts_Windows_SidecarOnly(t *testing.T) { gotInit, gotSteps, gotSidecars := convertScripts(images.ShellImage, images.ShellImageWin, []v1beta1.Step{{ // No script to convert here.: - Container: corev1.Container{Image: "step-1"}, + Image: "step-1", }}, []v1beta1.Sidecar{{ Script: `#!win python sidecar-1`, - Container: corev1.Container{Image: "sidecar-1"}, + Image: "sidecar-1", }}, nil) wantInit := &corev1.Container{ Name: "place-scripts", diff --git a/pkg/reconciler/pipelinerun/pipelinerun_test.go b/pkg/reconciler/pipelinerun/pipelinerun_test.go index 293036aa08f..2dcc1ef25c0 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun_test.go +++ b/pkg/reconciler/pipelinerun/pipelinerun_test.go @@ -3780,11 +3780,9 @@ func makeExpectedTr(condName, ccName string, labels, annotations map[string]stri Spec: v1beta1.TaskRunSpec{ TaskSpec: &v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "condition-check-" + condName, - Image: "foo", - Args: []string{"bar"}, - }, + Name: "condition-check-" + condName, + Image: "foo", + Args: []string{"bar"}, }}, }, ServiceAccountName: "test-sa", @@ -7135,10 +7133,8 @@ func getTaskRunWithTaskSpec(tr, pr, p, t string, labels, annotations map[string] Spec: v1beta1.TaskRunSpec{ TaskSpec: &v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "mystep", - Image: "myimage", - }, + Name: "mystep", + Image: "myimage", }}, }, ServiceAccountName: config.DefaultServiceAccountValue, diff --git a/pkg/reconciler/pipelinerun/resources/conditionresolution_test.go b/pkg/reconciler/pipelinerun/resources/conditionresolution_test.go index a94a9151dbc..33bfb4349b1 100644 --- a/pkg/reconciler/pipelinerun/resources/conditionresolution_test.go +++ b/pkg/reconciler/pipelinerun/resources/conditionresolution_test.go @@ -203,18 +203,16 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { }, Spec: v1alpha1.ConditionSpec{ Check: v1alpha1.Step{ - Container: corev1.Container{ - Name: "foo", - Image: "ubuntu", - }, + Name: "foo", + Image: "ubuntu", }, }, }, want: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "foo", Image: "ubuntu", - }}}, + }}, }, }, { name: "default-container-name", @@ -224,18 +222,16 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { }, Spec: v1alpha1.ConditionSpec{ Check: v1alpha1.Step{ - Container: corev1.Container{ - Name: "", - Image: "ubuntu", - }, + Name: "", + Image: "ubuntu", }, }, }, want: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "condition-check-bar", Image: "ubuntu", - }}}, + }}, }, }, { name: "very-long-condition-name", @@ -245,19 +241,17 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { }, Spec: v1alpha1.ConditionSpec{ Check: v1alpha1.Step{ - Container: corev1.Container{ - Name: "", - Image: "ubuntu", - }, + Name: "", + Image: "ubuntu", }, }, }, want: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ // Shortened via: names.SimpleNameGenerator.RestrictLength Name: "condition-check-very-very-very-very-very-very-very-very-very-ve", Image: "ubuntu", - }}}, + }}, }, }, { name: "with-input-params", @@ -267,11 +261,9 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { }, Spec: v1alpha1.ConditionSpec{ Check: v1alpha1.Step{ - Container: corev1.Container{ - Name: "$(params.name)", - Image: "$(params.img)", - WorkingDir: "$(params.not.replaced)", - }, + Name: "$(params.name)", + Image: "$(params.img)", + WorkingDir: "$(params.not.replaced)", }, Params: []v1alpha1.ParamSpec{ { @@ -286,11 +278,11 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { }, }, want: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "$(inputs.params.name)", Image: "$(inputs.params.img)", WorkingDir: "$(params.not.replaced)", - }}}, + }}, Params: []v1beta1.ParamSpec{{ Name: "name", Type: "string", @@ -307,11 +299,9 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { }, Spec: v1alpha1.ConditionSpec{ Check: v1alpha1.Step{ - Container: corev1.Container{ - Name: "name", - Image: "ubuntu", - Args: []string{"$(resources.git-resource.revision)"}, - }, + Name: "name", + Image: "ubuntu", + Args: []string{"$(resources.git-resource.revision)"}, }, Resources: []v1alpha1.ResourceDeclaration{{ Name: "git-resource", @@ -334,11 +324,11 @@ func TestResolvedConditionCheck_ConditionToTaskSpec(t *testing.T) { }, }, want: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "name", Image: "ubuntu", Args: []string{"master"}, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: []v1beta1.TaskResource{{ ResourceDeclaration: v1beta1.ResourceDeclaration{ diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go index ad4da12b550..d2551a214f8 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go @@ -140,9 +140,9 @@ var task = &v1beta1.Task{ Name: "task", }, Spec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", - }}}, + }}, }, } @@ -627,9 +627,9 @@ var taskWithOptionalResourcesDeprecated = &v1beta1.Task{ Name: "task", }, Spec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: []v1beta1.TaskResource{{ResourceDeclaration: v1beta1.ResourceDeclaration{ Name: "optional-input", @@ -657,9 +657,9 @@ var taskWithOptionalResources = &v1beta1.Task{ Name: "task", }, Spec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: []v1beta1.TaskResource{{ResourceDeclaration: v1beta1.ResourceDeclaration{ Name: "optional-input", @@ -1794,9 +1794,7 @@ func TestResolvePipelineRun(t *testing.T) { Name: "mytask4", TaskSpec: &v1beta1.EmbeddedTask{ TaskSpec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{ - Container: corev1.Container{Name: "step1"}, - }}, + Steps: []v1beta1.Step{{Name: "step1"}}, }, }, }, diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunstate_test.go b/pkg/reconciler/pipelinerun/resources/pipelinerunstate_test.go index ffc8ddff6c7..1153cd9acb5 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinerunstate_test.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinerunstate_test.go @@ -894,9 +894,9 @@ func buildPipelineStateWithLargeDepencyGraph(t *testing.T) PipelineRunState { Name: "task", }, Spec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", - }}}, + }}, }, } var pipelineRunState PipelineRunState diff --git a/pkg/reconciler/taskrun/resources/apply.go b/pkg/reconciler/taskrun/resources/apply.go index c8dcb75320d..6533950017e 100644 --- a/pkg/reconciler/taskrun/resources/apply.go +++ b/pkg/reconciler/taskrun/resources/apply.go @@ -248,7 +248,10 @@ func ApplyReplacements(spec *v1beta1.TaskSpec, stringReplacements map[string]str // Apply variable expansion to stepTemplate fields. if spec.StepTemplate != nil { - v1beta1.ApplyStepReplacements(&v1beta1.Step{Container: *spec.StepTemplate}, stringReplacements, arrayReplacements) + c := spec.StepTemplate.ToK8sContainer() + step := v1beta1.Step{} + step.SetContainerFields(*c) + v1beta1.ApplyStepReplacements(&step, stringReplacements, arrayReplacements) } // Apply variable expansion to the build's volumes diff --git a/pkg/reconciler/taskrun/resources/apply_test.go b/pkg/reconciler/taskrun/resources/apply_test.go index 29c256969b6..e1b0c7fb949 100644 --- a/pkg/reconciler/taskrun/resources/apply_test.go +++ b/pkg/reconciler/taskrun/resources/apply_test.go @@ -50,46 +50,44 @@ var ( simpleTaskSpec = &v1beta1.TaskSpec{ Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ + Name: "foo", + Image: `$(params["myimage"])`, + Env: []corev1.EnvVar{{ Name: "foo", - Image: `$(params["myimage"])`, - Env: []corev1.EnvVar{{ - Name: "foo", - Value: "$(params['FOO'])", - }}, - }, + Value: "$(params['FOO'])", + }}, }}, - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ Env: []corev1.EnvVar{{ Name: "template-var", Value: `$(params["FOO"])`, }}, }, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "foo", Image: "$(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: "$(params.something)", Args: []string{"$(outputs.resources.imageToUse.url)"}, - }}, {Container: corev1.Container{ + }, { Name: "foo", Image: `$(params["myimage"])`, - }}, {Container: corev1.Container{ + }, { Name: "baz", Image: "$(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:$(params.FOO)", VolumeMounts: []corev1.VolumeMount{{ @@ -97,7 +95,7 @@ var ( MountPath: "path/to/$(params.FOO)", SubPath: "sub/$(params.FOO)/path", }}, - }}, {Container: corev1.Container{ + }, { Name: "foo", Image: "busybox:$(params.FOO)", Env: []corev1.EnvVar{{ @@ -131,13 +129,13 @@ var ( LocalObjectReference: corev1.LocalObjectReference{Name: "secret-$(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: "$(params.FOO)", VolumeSource: corev1.VolumeSource{ @@ -224,11 +222,11 @@ var ( } gcsTaskSpec = &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "foobar", Image: "someImage", Args: []string{"$(outputs.resources.bucket.path)"}, - }}}, + }}, Resources: &v1beta1.TaskResources{ Outputs: []v1beta1.TaskResource{{ ResourceDeclaration: v1beta1.ResourceDeclaration{ @@ -239,51 +237,51 @@ var ( } arrayParamTaskSpec = &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "simple-image", Image: "some-image", - }}, {Container: corev1.Container{ + }, { Name: "image-with-c-specified", Image: "some-other-image", Command: []string{"echo"}, Args: []string{"first", "second", "$(params.array-param)", "last"}, - }}}, + }}, } arrayAndStringParamTaskSpec = &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "simple-image", Image: "some-image", - }}, {Container: corev1.Container{ + }, { Name: "image-with-c-specified", Image: "some-other-image", Command: []string{"echo"}, Args: []string{"$(params.normal-param)", "second", "$(params.array-param)", "last"}, - }}}, + }}, } multipleArrayParamsTaskSpec = &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "simple-image", Image: "some-image", - }}, {Container: corev1.Container{ + }, { Name: "image-with-c-specified", Image: "some-other-image", Command: []string{"cmd", "$(params.another-array-param)"}, Args: []string{"first", "second", "$(params.array-param)", "last"}, - }}}, + }}, } multipleArrayAndStringsParamsTaskSpec = &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "simple-image", Image: "image-$(params.string-param2)", - }}, {Container: corev1.Container{ + }, { Name: "image-with-c-specified", Image: "some-other-image", Command: []string{"cmd", "$(params.array-param1)"}, Args: []string{"$(params.array-param2)", "second", "$(params.array-param1)", "$(params.string-param1)", "last"}, - }}}, + }}, } arrayTaskRun0Elements = &v1beta1.TaskRun{ @@ -566,8 +564,8 @@ func TestApplyParameters(t *testing.T) { spec.Volumes[4].VolumeSource.CSI.VolumeAttributes["secretProviderClass"] = "world" spec.Volumes[4].VolumeSource.CSI.NodePublishSecretRef.Name = "world" - spec.Sidecars[0].Container.Image = "bar" - spec.Sidecars[0].Container.Env[0].Value = "world" + spec.Sidecars[0].Image = "bar" + spec.Sidecars[0].Env[0].Value = "world" }) got := resources.ApplyParameters(simpleTaskSpec, tr, dp...) if d := cmp.Diff(want, got); d != "" { @@ -641,7 +639,7 @@ func TestApplyResources(t *testing.T) { func TestApplyWorkspaces(t *testing.T) { names.TestingSeed() ts := &v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ Env: []corev1.EnvVar{{ Name: "template-var", Value: "$(workspaces.myws.volume)", @@ -653,12 +651,12 @@ func TestApplyWorkspaces(t *testing.T) { Value: "$(workspaces.otherws.claim)", }}, }, - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "$(workspaces.myws.volume)", Image: "$(workspaces.otherws.volume)", WorkingDir: "$(workspaces.otherws.volume)", Args: []string{"$(workspaces.myws.path)"}, - }}, {Container: corev1.Container{ + }, { Name: "foo", Image: "bar", VolumeMounts: []corev1.VolumeMount{{ @@ -666,7 +664,7 @@ func TestApplyWorkspaces(t *testing.T) { MountPath: "path/to/$(workspaces.otherws.path)", SubPath: "$(workspaces.myws.volume)", }}, - }}, {Container: corev1.Container{ + }, { Name: "foo", Image: "bar", Env: []corev1.EnvVar{{ @@ -687,7 +685,7 @@ func TestApplyWorkspaces(t *testing.T) { LocalObjectReference: corev1.LocalObjectReference{Name: "$(workspaces.myws.volume)"}, }, }}, - }}}, + }}, Volumes: []corev1.Volume{{ Name: "$(workspaces.myws.volume)", VolumeSource: corev1.VolumeSource{ @@ -886,18 +884,14 @@ func TestContext(t *testing.T) { tr: v1beta1.TaskRun{}, spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "$(context.task.name)-1", - }, + Name: "ImageName", + Image: "$(context.task.name)-1", }}, }, want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "Task1-1", - }, + Name: "ImageName", + Image: "Task1-1", }}, }, }, { @@ -910,18 +904,14 @@ func TestContext(t *testing.T) { }, spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "$(context.task.name)-1", - }, + Name: "ImageName", + Image: "$(context.task.name)-1", }}, }, want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "Task1-1", - }, + Name: "ImageName", + Image: "Task1-1", }}, }, }, { @@ -934,18 +924,14 @@ func TestContext(t *testing.T) { }, spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "$(context.taskRun.name)-1", - }, + Name: "ImageName", + Image: "$(context.taskRun.name)-1", }}, }, want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "taskrunName-1", - }, + Name: "ImageName", + Image: "taskrunName-1", }}, }, }, { @@ -954,18 +940,14 @@ func TestContext(t *testing.T) { tr: v1beta1.TaskRun{}, spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "$(context.taskRun.name)-1", - }, + Name: "ImageName", + Image: "$(context.taskRun.name)-1", }}, }, want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "-1", - }, + Name: "ImageName", + Image: "-1", }}, }, }, { @@ -974,18 +956,14 @@ func TestContext(t *testing.T) { tr: v1beta1.TaskRun{}, spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "$(context.taskRun.namespace)-1", - }, + Name: "ImageName", + Image: "$(context.taskRun.namespace)-1", }}, }, want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "-1", - }, + Name: "ImageName", + Image: "-1", }}, }, }, { @@ -999,18 +977,14 @@ func TestContext(t *testing.T) { }, spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "$(context.taskRun.namespace)-1", - }, + Name: "ImageName", + Image: "$(context.taskRun.namespace)-1", }}, }, want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "trNamespace-1", - }, + Name: "ImageName", + Image: "trNamespace-1", }}, }, }, { @@ -1018,18 +992,14 @@ func TestContext(t *testing.T) { tr: v1beta1.TaskRun{}, spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "$(context.task.name)-1", - }, + Name: "ImageName", + Image: "$(context.task.name)-1", }}, }, want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "-1", - }, + Name: "ImageName", + Image: "-1", }}, }, }, { @@ -1042,18 +1012,14 @@ func TestContext(t *testing.T) { }, spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "$(context.taskRun.uid)", - }, + Name: "ImageName", + Image: "$(context.taskRun.uid)", }}, }, want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "UID-1", - }, + Name: "ImageName", + Image: "UID-1", }}, }, }, { @@ -1081,18 +1047,14 @@ func TestContext(t *testing.T) { }, spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "$(context.task.retry-count)-1", - }, + Name: "ImageName", + Image: "$(context.task.retry-count)-1", }}, }, want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "2-1", - }, + Name: "ImageName", + Image: "2-1", }}, }, }, { @@ -1100,18 +1062,14 @@ func TestContext(t *testing.T) { tr: v1beta1.TaskRun{}, spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "$(context.task.retry-count)-1", - }, + Name: "ImageName", + Image: "$(context.task.retry-count)-1", }}, }, want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "ImageName", - Image: "0-1", - }, + Name: "ImageName", + Image: "0-1", }}, }, }} { @@ -1135,23 +1093,17 @@ func TestTaskResults(t *testing.T) { Description: "The current date in humand readable format"}, }, Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "print-date-unix-timestamp", - Image: "bash:latest", - Args: []string{"$(results[\"current.date.unix.timestamp\"].path)"}, - }, + Name: "print-date-unix-timestamp", + Image: "bash:latest", + Args: []string{"$(results[\"current.date.unix.timestamp\"].path)"}, Script: "#!/usr/bin/env bash\ndate +%s | tee $(results[\"current.date.unix.timestamp\"].path)", }, { - Container: corev1.Container{ - Name: "print-date-human-readable", - Image: "bash:latest", - }, + Name: "print-date-human-readable", + Image: "bash:latest", Script: "#!/usr/bin/env bash\ndate | tee $(results.current-date-human-readable.path)", }, { - Container: corev1.Container{ - Name: "print-date-human-readable-again", - Image: "bash:latest", - }, + Name: "print-date-human-readable-again", + Image: "bash:latest", Script: "#!/usr/bin/env bash\ndate | tee $(results['current-date-human-readable'].path)", }}, } @@ -1171,21 +1123,15 @@ func TestApplyStepExitCodePath(t *testing.T) { names.TestingSeed() ts := &v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "bash:latest", - }, + Image: "bash:latest", Script: "#!/usr/bin/env bash\nexit 11", }, { - Container: corev1.Container{ - Name: "failing-step", - Image: "bash:latest", - }, + Name: "failing-step", + Image: "bash:latest", Script: "#!/usr/bin/env bash\ncat $(steps.step-unnamed-0.exitCode.path)", }, { - Container: corev1.Container{ - Name: "check-failing-step", - Image: "bash:latest", - }, + Name: "check-failing-step", + Image: "bash:latest", Script: "#!/usr/bin/env bash\ncat $(steps.step-failing-step.exitCode.path)", }}, } @@ -1209,19 +1155,15 @@ func TestApplyCredentialsPath(t *testing.T) { description: "replacement in spec container", spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Command: []string{"cp"}, - Args: []string{"-R", "$(credentials.path)/", "$HOME"}, - }, + Command: []string{"cp"}, + Args: []string{"-R", "$(credentials.path)/", "$HOME"}, }}, }, path: "/tekton/creds", want: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Command: []string{"cp"}, - Args: []string{"-R", "/tekton/creds/", "$HOME"}, - }, + Command: []string{"cp"}, + Args: []string{"-R", "/tekton/creds/", "$HOME"}, }}, }, }, { diff --git a/pkg/reconciler/taskrun/resources/image_exporter.go b/pkg/reconciler/taskrun/resources/image_exporter.go index 8634378cb36..b03b98a277d 100644 --- a/pkg/reconciler/taskrun/resources/image_exporter.go +++ b/pkg/reconciler/taskrun/resources/image_exporter.go @@ -24,7 +24,6 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1/image" "github.com/tektoncd/pipeline/pkg/names" - corev1 "k8s.io/api/core/v1" ) const imageDigestExporterContainerName = "image-digest-exporter" @@ -91,12 +90,12 @@ func AddOutputImageDigestExporter( } func imageDigestExporterStep(imageDigestExporterImage string, imagesJSON []byte) v1beta1.Step { - return v1beta1.Step{Container: corev1.Container{ + return v1beta1.Step{ Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(imageDigestExporterContainerName), Image: imageDigestExporterImage, Command: []string{"/ko-app/imagedigestexporter"}, Args: []string{ "-images", string(imagesJSON), }, - }} + } } diff --git a/pkg/reconciler/taskrun/resources/image_exporter_test.go b/pkg/reconciler/taskrun/resources/image_exporter_test.go index f90cea50988..aba62bf4ab3 100644 --- a/pkg/reconciler/taskrun/resources/image_exporter_test.go +++ b/pkg/reconciler/taskrun/resources/image_exporter_test.go @@ -24,7 +24,6 @@ import ( resourcev1alpha1 "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1" "github.com/tektoncd/pipeline/test/diff" "github.com/tektoncd/pipeline/test/names" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -42,9 +41,9 @@ func TestAddOutputImageDigestExporter(t *testing.T) { Namespace: "marshmallow", }, Spec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: []v1beta1.TaskResource{{ ResourceDeclaration: v1beta1.ResourceDeclaration{ @@ -87,14 +86,14 @@ func TestAddOutputImageDigestExporter(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "step1", - }}, {Container: corev1.Container{ + }, { Name: "image-digest-exporter-9l9zj", Image: "override-with-imagedigest-exporter-image:latest", Command: []string{"/ko-app/imagedigestexporter"}, Args: []string{"-images", "[{\"name\":\"source-image\",\"type\":\"image\",\"url\":\"gcr.io/some-image-1\",\"digest\":\"\",\"OutputImageDir\":\"/workspace/output/source-image\"}]"}, - }}}, + }}, }, { desc: "image resource in task with multiple steps", task: &v1beta1.Task{ @@ -103,11 +102,11 @@ func TestAddOutputImageDigestExporter(t *testing.T) { Namespace: "marshmallow", }, Spec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", - }}, {Container: corev1.Container{ + }, { Name: "step2", - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: []v1beta1.TaskResource{{ ResourceDeclaration: v1beta1.ResourceDeclaration{ @@ -150,16 +149,16 @@ func TestAddOutputImageDigestExporter(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "step1", - }}, {Container: corev1.Container{ + }, { Name: "step2", - }}, {Container: corev1.Container{ + }, { Name: "image-digest-exporter-9l9zj", Image: "override-with-imagedigest-exporter-image:latest", Command: []string{"/ko-app/imagedigestexporter"}, Args: []string{"-images", "[{\"name\":\"source-image\",\"type\":\"image\",\"url\":\"gcr.io/some-image-1\",\"digest\":\"\",\"OutputImageDir\":\"/workspace/output/source-image\"}]"}, - }}}, + }}, }} { t.Run(c.desc, func(t *testing.T) { names.TestingSeed() diff --git a/pkg/reconciler/taskrun/resources/input_resource_test.go b/pkg/reconciler/taskrun/resources/input_resource_test.go index 6a7751d85cc..2920696f533 100644 --- a/pkg/reconciler/taskrun/resources/input_resource_test.go +++ b/pkg/reconciler/taskrun/resources/input_resource_test.go @@ -363,7 +363,7 @@ func TestAddInputResourceToTask(t *testing.T) { taskRun: taskRun, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "git-source-the-git-9l9zj", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -374,7 +374,7 @@ func TestAddInputResourceToTask(t *testing.T) { {Name: "HOME", Value: pipeline.HomeDir}, }, SecurityContext: gitResourceSecurityContext, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: gitInputs, }, @@ -405,7 +405,7 @@ func TestAddInputResourceToTask(t *testing.T) { }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "git-source-the-git-with-branch-9l9zj", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -416,7 +416,7 @@ func TestAddInputResourceToTask(t *testing.T) { {Name: "HOME", Value: pipeline.HomeDir}, }, SecurityContext: gitResourceSecurityContext, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: gitInputs, }, @@ -454,7 +454,7 @@ func TestAddInputResourceToTask(t *testing.T) { }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "git-source-the-git-with-branch-mz4c7", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -465,7 +465,7 @@ func TestAddInputResourceToTask(t *testing.T) { {Name: "HOME", Value: pipeline.HomeDir}, }, SecurityContext: gitResourceSecurityContext, - }}, {Container: corev1.Container{ + }, { Name: "git-source-the-git-with-branch-9l9zj", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -476,7 +476,7 @@ func TestAddInputResourceToTask(t *testing.T) { {Name: "HOME", Value: pipeline.HomeDir}, }, SecurityContext: gitResourceSecurityContext, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: multipleGitInputs, }, @@ -507,7 +507,7 @@ func TestAddInputResourceToTask(t *testing.T) { }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "git-source-the-git-9l9zj", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -518,7 +518,7 @@ func TestAddInputResourceToTask(t *testing.T) { {Name: "HOME", Value: pipeline.HomeDir}, }, SecurityContext: gitResourceSecurityContext, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: gitInputs, }, @@ -549,7 +549,7 @@ func TestAddInputResourceToTask(t *testing.T) { }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "git-source-the-git-with-branch-9l9zj", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -560,7 +560,7 @@ func TestAddInputResourceToTask(t *testing.T) { {Name: "HOME", Value: pipeline.HomeDir}, }, SecurityContext: gitResourceSecurityContext, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: gitInputs, }, @@ -593,17 +593,17 @@ func TestAddInputResourceToTask(t *testing.T) { }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ 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"}}, Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "gitspace"}}, - }}}, + }}, Volumes: []corev1.Volume{{ Name: "pipelinerun-pvc", VolumeSource: corev1.VolumeSource{ @@ -640,7 +640,7 @@ func TestAddInputResourceToTask(t *testing.T) { }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "git-source-the-git-with-sslVerify-false-9l9zj", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -651,7 +651,7 @@ func TestAddInputResourceToTask(t *testing.T) { {Name: "HOME", Value: pipeline.HomeDir}, }, SecurityContext: gitResourceSecurityContext, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: gitInputs, }, @@ -679,11 +679,11 @@ func TestAddInputResourceToTask(t *testing.T) { }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ 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... @@ -691,14 +691,12 @@ if [[ "${GOOGLE_APPLICATION_CREDENTIALS}" != "" ]]; then fi gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir `, - Container: corev1.Container{ - Name: "fetch-storage1-mz4c7", - Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", - Env: []corev1.EnvVar{{ - Name: "HOME", - Value: pipeline.HomeDir, - }}, - }, + Name: "fetch-storage1-mz4c7", + Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", + Env: []corev1.EnvVar{{ + Name: "HOME", + Value: pipeline.HomeDir, + }}, }}, Resources: &v1beta1.TaskResources{ Inputs: gcsInputs, @@ -732,11 +730,11 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ 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"}, @@ -745,7 +743,7 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir Name: "TEKTON_RESOURCE_NAME", Value: "workspace", }}, - }}}, + }}, Volumes: []corev1.Volume{{ Name: "pipelinerun-pvc", VolumeSource: corev1.VolumeSource{ @@ -857,16 +855,14 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir want: &v1beta1.TaskSpec{ Steps: []v1beta1.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=","clientKeyData":"Y2xpZW50LWtleS1kYXRh","clientCertificateData":"Y2xpZW50LWNlcnRpZmljYXRlLWRhdGE=","secrets":null}`, - }, - Env: []corev1.EnvVar{ - {Name: "TEKTON_RESOURCE_NAME", Value: "cluster3"}, - }, + 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=","clientKeyData":"Y2xpZW50LWtleS1kYXRh","clientCertificateData":"Y2xpZW50LWNlcnRpZmljYXRlLWRhdGE=","secrets":null}`, + }, + Env: []corev1.EnvVar{ + {Name: "TEKTON_RESOURCE_NAME", Value: "cluster3"}, }, }, }, @@ -912,27 +908,25 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir want: &v1beta1.TaskSpec{ Steps: []v1beta1.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,"clientKeyData":null,"clientCertificateData":null,"secrets":[{"fieldName":"cadata","secretKey":"cadatakey","secretName":"secret1"}]}`, - }, - Env: []corev1.EnvVar{ - {Name: "TEKTON_RESOURCE_NAME", Value: "cluster2"}, - { - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: "secret1", - }, - Key: "cadatakey", + 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,"clientKeyData":null,"clientCertificateData":null,"secrets":[{"fieldName":"cadata","secretKey":"cadatakey","secretName":"secret1"}]}`, + }, + Env: []corev1.EnvVar{ + {Name: "TEKTON_RESOURCE_NAME", Value: "cluster2"}, + { + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: "secret1", }, + Key: "cadatakey", }, - Name: "CADATA", - }}, - }, + }, + Name: "CADATA", + }}, }, }, Resources: &v1beta1.TaskResources{ @@ -965,7 +959,7 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "git-source-the-git-with-branch-9l9zj", Image: "override-with-git:latest", Command: []string{"/ko-app/git-init"}, @@ -976,7 +970,7 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-dir {Name: "HOME", Value: pipeline.HomeDir}, }, SecurityContext: gitResourceSecurityContext, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: optionalGitInputs, }, @@ -1085,11 +1079,11 @@ func TestStorageInputResource(t *testing.T) { }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ 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... @@ -1097,11 +1091,9 @@ if [[ "${GOOGLE_APPLICATION_CREDENTIALS}" != "" ]]; then fi gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-input-resource `, - Container: corev1.Container{ - Name: "fetch-gcs-input-resource-mz4c7", - Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", - Env: []corev1.EnvVar{{Name: "HOME", Value: pipeline.HomeDir}}, - }, + Name: "fetch-gcs-input-resource-mz4c7", + Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", + Env: []corev1.EnvVar{{Name: "HOME", Value: pipeline.HomeDir}}, }}, Resources: &v1beta1.TaskResources{ Inputs: gcsStorageInputs, @@ -1156,11 +1148,11 @@ gsutil cp gs://fake-bucket/rules.zip /workspace/gcs-input-resource }, wantErr: false, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ 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... @@ -1168,16 +1160,14 @@ if [[ "${GOOGLE_APPLICATION_CREDENTIALS}" != "" ]]; then fi gsutil rsync -d -r gs://fake-bucket/rules.zip /workspace/gcs-input-resource `, - Container: corev1.Container{ - Name: "fetch-storage-gcs-keys-mz4c7", - Image: "gcr.io/google.com/cloudsdktool/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"}, - {Name: "HOME", Value: pipeline.HomeDir}, - }, + Name: "fetch-storage-gcs-keys-mz4c7", + Image: "gcr.io/google.com/cloudsdktool/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"}, + {Name: "HOME", Value: pipeline.HomeDir}, }, }}, Resources: &v1beta1.TaskResources{ @@ -1320,18 +1310,18 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }, }, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "artifact-dest-mkdir-gitspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/gitspace"}, - }}, {Container: corev1.Container{ + }, { Name: "artifact-copy-from-gitspace-mz4c7", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path/*", "/workspace/gitspace"}, Env: gcsEnv, VolumeMounts: gcsVolumeMounts, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: gitInputs, }, @@ -1364,18 +1354,18 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }, }, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ 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: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path/*", "/workspace/gcs-dir"}, Env: gcsEnv, VolumeMounts: gcsVolumeMounts, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: gcsInputs, }, @@ -1416,29 +1406,29 @@ func TestAddStepsToTaskWithBucketFromConfigMap(t *testing.T) { }, }, want: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ 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: "gcr.io/google.com/cloudsdktool/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: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, Args: []string{"cp", "-P", "-r", "gs://fake-bucket/prev-task-path2/*", "/workspace/gcs-dir"}, Env: gcsEnv, VolumeMounts: gcsVolumeMounts, - }}}, + }}, Resources: &v1beta1.TaskResources{ Inputs: multipleGcsInputs, }, diff --git a/pkg/reconciler/taskrun/resources/output_resource_test.go b/pkg/reconciler/taskrun/resources/output_resource_test.go index 165fa7da7d4..5882cc2aedd 100644 --- a/pkg/reconciler/taskrun/resources/output_resource_test.go +++ b/pkg/reconciler/taskrun/resources/output_resource_test.go @@ -220,11 +220,11 @@ func TestValidOutputResources(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}, {Container: corev1.Container{ + }, { Name: "source-mkdir-source-git-mz4c7", Image: "busybox", SecurityContext: &corev1.SecurityContext{ @@ -235,7 +235,7 @@ func TestValidOutputResources(t *testing.T) { Name: "pipelinerun-pvc", MountPath: "/pvc", }}, - }}, {Container: corev1.Container{ + }, { Name: "source-copy-source-git-mssqb", Image: "busybox", SecurityContext: &corev1.SecurityContext{ @@ -247,7 +247,7 @@ func TestValidOutputResources(t *testing.T) { MountPath: "/pvc", }}, Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "source-git"}}, - }}}, + }}, wantVolumes: []corev1.Volume{ { Name: "pipelinerun-pvc", @@ -300,11 +300,11 @@ func TestValidOutputResources(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}, {Container: corev1.Container{ + }, { Name: "source-mkdir-source-git-mz4c7", Image: "busybox", SecurityContext: &corev1.SecurityContext{ @@ -315,7 +315,7 @@ func TestValidOutputResources(t *testing.T) { Name: "pipelinerun-pvc", MountPath: "/pvc", }}, - }}, {Container: corev1.Container{ + }, { Name: "source-copy-source-git-mssqb", Image: "busybox", SecurityContext: &corev1.SecurityContext{ @@ -327,7 +327,7 @@ func TestValidOutputResources(t *testing.T) { MountPath: "/pvc", }}, Env: []corev1.EnvVar{{Name: "TEKTON_RESOURCE_NAME", Value: "source-git"}}, - }}}, + }}, wantVolumes: []corev1.Volume{ { Name: "pipelinerun-pvc", @@ -380,11 +380,11 @@ func TestValidOutputResources(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}}, + }}, wantVolumes: nil, }, { name: "git resource in output", @@ -422,11 +422,11 @@ func TestValidOutputResources(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}}, + }}, }, { name: "storage resource as both input and output", desc: "storage resource defined in both input and output with parents pipelinerun reference", @@ -483,12 +483,12 @@ func TestValidOutputResources(t *testing.T) { }, }, wantSteps: []v1beta1.Step{ - {Container: corev1.Container{ + { Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}, - {Container: corev1.Container{ + }, + { Name: "source-mkdir-source-gcs-mz4c7", Image: "busybox", SecurityContext: &corev1.SecurityContext{ @@ -496,8 +496,8 @@ func TestValidOutputResources(t *testing.T) { }, Command: []string{"mkdir", "-p", "pipeline-task-path"}, VolumeMounts: []corev1.VolumeMount{{Name: "pipelinerun-parent-pvc", MountPath: "/pvc"}}, - }}, - {Container: corev1.Container{ + }, + { Name: "source-copy-source-gcs-mssqb", Image: "busybox", SecurityContext: &corev1.SecurityContext{ @@ -508,8 +508,8 @@ func TestValidOutputResources(t *testing.T) { Env: []corev1.EnvVar{ {Name: "TEKTON_RESOURCE_NAME", Value: "source-gcs"}, }, - }}, - {Container: corev1.Container{ + }, + { Name: "upload-source-gcs-78c5n", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", VolumeMounts: []corev1.VolumeMount{{ @@ -522,7 +522,7 @@ func TestValidOutputResources(t *testing.T) { {Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/sname/key.json"}, {Name: "HOME", Value: pipeline.HomeDir}, }, - }}, + }, }, wantVolumes: []corev1.Volume{{ @@ -583,12 +583,12 @@ func TestValidOutputResources(t *testing.T) { }, }, wantSteps: []v1beta1.Step{ - {Container: corev1.Container{ + { Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}, - {Container: corev1.Container{ + }, + { Name: "source-mkdir-source-gcs-mz4c7", Image: "busybox", SecurityContext: &corev1.SecurityContext{ @@ -596,8 +596,8 @@ func TestValidOutputResources(t *testing.T) { }, Command: []string{"mkdir", "-p", "pipeline-task-path"}, VolumeMounts: []corev1.VolumeMount{{Name: "pipelinerun-pvc", MountPath: "/pvc"}}, - }}, - {Container: corev1.Container{ + }, + { Name: "source-copy-source-gcs-mssqb", Image: "busybox", SecurityContext: &corev1.SecurityContext{ @@ -608,8 +608,8 @@ func TestValidOutputResources(t *testing.T) { Env: []corev1.EnvVar{ {Name: "TEKTON_RESOURCE_NAME", Value: "source-gcs"}, }, - }}, - {Container: corev1.Container{ + }, + { Name: "upload-source-gcs-78c5n", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", VolumeMounts: []corev1.VolumeMount{{ @@ -621,7 +621,7 @@ func TestValidOutputResources(t *testing.T) { }, Command: []string{"gsutil"}, Args: []string{"rsync", "-d", "-r", "/workspace/output/source-workspace", "gs://some-bucket"}, - }}, + }, }, wantVolumes: []corev1.Volume{{ Name: "volume-source-gcs-sname", @@ -676,12 +676,12 @@ func TestValidOutputResources(t *testing.T) { }, }, wantSteps: []v1beta1.Step{ - {Container: corev1.Container{ + { Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}, - {Container: corev1.Container{ + }, + { Name: "upload-source-gcs-mz4c7", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", VolumeMounts: []corev1.VolumeMount{{ @@ -693,7 +693,7 @@ func TestValidOutputResources(t *testing.T) { }, Command: []string{"gsutil"}, Args: []string{"rsync", "-d", "-r", "/workspace/output/source-workspace", "gs://some-bucket"}, - }}, + }, }, wantVolumes: []corev1.Volume{{ Name: "volume-source-gcs-sname", @@ -738,12 +738,12 @@ func TestValidOutputResources(t *testing.T) { }, }, wantSteps: []v1beta1.Step{ - {Container: corev1.Container{ + { Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}, - {Container: corev1.Container{ + }, + { Name: "upload-source-gcs-mz4c7", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", VolumeMounts: []corev1.VolumeMount{{ @@ -755,7 +755,7 @@ func TestValidOutputResources(t *testing.T) { }, Command: []string{"gsutil"}, Args: []string{"rsync", "-d", "-r", "/workspace/output/source-workspace", "gs://some-bucket"}, - }}, + }, }, wantVolumes: []corev1.Volume{{ Name: "volume-source-gcs-sname", @@ -803,11 +803,11 @@ func TestValidOutputResources(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}}, + }}, }, { name: "Resource with TargetPath as output", desc: "Resource with TargetPath defined only in output", @@ -849,11 +849,11 @@ func TestValidOutputResources(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace"}, - }}}, + }}, }, { desc: "image output resource with no steps", taskRun: &v1beta1.TaskRun{ @@ -889,11 +889,11 @@ func TestValidOutputResources(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}}, + }}, }, { desc: "multiple image output resource with no steps", taskRun: &v1beta1.TaskRun{ @@ -940,15 +940,15 @@ func TestValidOutputResources(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-1-mz4c7", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace-1"}, - }}, {Container: corev1.Container{ + }, { Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}}, + }}, }} { t.Run(c.name, func(t *testing.T) { names.TestingSeed() @@ -1032,16 +1032,16 @@ func TestValidOutputResourcesWithBucketStorage(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}, {Container: corev1.Container{ + }, { Name: "artifact-copy-to-source-git-mz4c7", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, Args: []string{"cp", "-P", "-r", "/workspace/output/source-workspace", "gs://fake-bucket/pipeline-task-name"}, - }}}, + }}, }, { name: "git resource in output only with bucket storage", desc: "git resource declared as output with pipelinerun owner reference", @@ -1083,16 +1083,16 @@ func TestValidOutputResourcesWithBucketStorage(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}, {Container: corev1.Container{ + }, { Name: "artifact-copy-to-source-git-mz4c7", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, Args: []string{"cp", "-P", "-r", "/workspace/output/source-workspace", "gs://fake-bucket/pipeline-task-name"}, - }}}, + }}, }, { name: "git resource in output", desc: "git resource declared in output without pipelinerun owner reference", @@ -1129,11 +1129,11 @@ func TestValidOutputResourcesWithBucketStorage(t *testing.T) { }, }, }, - wantSteps: []v1beta1.Step{{Container: corev1.Container{ + wantSteps: []v1beta1.Step{{ Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}}, + }}, }} { t.Run(c.name, func(t *testing.T) { outputTestResourceSetup() @@ -1473,18 +1473,18 @@ func TestInputOutputBucketResources(t *testing.T) { }, }, wantSteps: []v1beta1.Step{ - {Container: corev1.Container{ + { Name: "create-dir-source-workspace-mssqb", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, - }}, - {Container: corev1.Container{ + }, + { Name: "artifact-dest-mkdir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/faraway-disk"}, VolumeMounts: nil, - }}, - {Container: corev1.Container{ + }, + { Name: "artifact-copy-from-source-workspace-mz4c7", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, @@ -1500,8 +1500,8 @@ func TestInputOutputBucketResources(t *testing.T) { Value: "/var/bucketsecret/sname/key.json", }}, VolumeMounts: []corev1.VolumeMount{{Name: "volume-bucket-sname", MountPath: "/var/bucketsecret/sname"}}, - }}, - {Container: corev1.Container{ + }, + { Name: "upload-source-gcs-bucket-78c5n", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", VolumeMounts: nil, @@ -1511,7 +1511,7 @@ func TestInputOutputBucketResources(t *testing.T) { Name: "HOME", Value: pipeline.HomeDir, }}, - }}, + }, }, wantVolumes: []corev1.Volume{{ Name: "volume-bucket-sname", @@ -1588,18 +1588,18 @@ func TestInputOutputBucketResources(t *testing.T) { }, }, wantSteps: []v1beta1.Step{ - {Container: corev1.Container{ + { Name: "create-dir-source-workspace-3-6nl7g", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace-3"}, - }}, - {Container: corev1.Container{ + }, + { Name: "artifact-dest-mkdir-source-workspace-mssqb", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/faraway-disk"}, VolumeMounts: nil, - }}, - {Container: corev1.Container{ + }, + { Name: "artifact-copy-from-source-workspace-78c5n", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, @@ -1617,15 +1617,15 @@ func TestInputOutputBucketResources(t *testing.T) { }, }, VolumeMounts: []corev1.VolumeMount{{Name: "volume-bucket-sname", MountPath: "/var/bucketsecret/sname"}}, - }}, - {Container: corev1.Container{ + }, + { Name: "artifact-dest-mkdir-source-workspace-2-9l9zj", Image: "busybox", VolumeMounts: nil, Command: []string{"mkdir", "-p", "/workspace/faraway-disk-2"}, Env: nil, - }}, - {Container: corev1.Container{ + }, + { Name: "artifact-copy-from-source-workspace-2-mz4c7", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, @@ -1637,7 +1637,7 @@ func TestInputOutputBucketResources(t *testing.T) { }, }, VolumeMounts: []corev1.VolumeMount{{Name: "volume-bucket-sname", MountPath: "/var/bucketsecret/sname"}}, - }}, {Container: corev1.Container{ + }, { Name: "upload-source-gcs-bucket-3-j2tds", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, @@ -1646,7 +1646,7 @@ func TestInputOutputBucketResources(t *testing.T) { Name: "HOME", Value: pipeline.HomeDir, }}, - }}, + }, }, wantVolumes: []corev1.Volume{{ Name: "volume-bucket-sname", @@ -1707,18 +1707,18 @@ func TestInputOutputBucketResources(t *testing.T) { }, }, wantSteps: []v1beta1.Step{ - {Container: corev1.Container{ + { Name: "create-dir-source-workspace-2-mssqb", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace-2"}, - }}, - {Container: corev1.Container{ + }, + { Name: "create-dir-source-workspace-9l9zj", Image: "busybox", Command: []string{"mkdir", "-p", "/workspace/output/source-workspace"}, VolumeMounts: nil, - }}, - {Container: corev1.Container{ + }, + { Name: "upload-source-gcs-bucket-mz4c7", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", Command: []string{"gsutil"}, @@ -1733,8 +1733,8 @@ func TestInputOutputBucketResources(t *testing.T) { Name: "HOME", Value: pipeline.HomeDir, }}, - }}, - {Container: corev1.Container{ + }, + { Name: "upload-source-gcs-bucket-2-78c5n", Image: "gcr.io/google.com/cloudsdktool/cloud-sdk", VolumeMounts: nil, @@ -1744,7 +1744,7 @@ func TestInputOutputBucketResources(t *testing.T) { Name: "HOME", Value: pipeline.HomeDir, }}, - }}, + }, }, wantVolumes: []corev1.Volume{{ Name: "volume-bucket-sname", diff --git a/pkg/reconciler/taskrun/resources/taskref_test.go b/pkg/reconciler/taskrun/resources/taskref_test.go index 8f06538288f..861204243cb 100644 --- a/pkg/reconciler/taskrun/resources/taskref_test.go +++ b/pkg/reconciler/taskrun/resources/taskref_test.go @@ -51,9 +51,7 @@ var ( }, Spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "something", - }, + Image: "something", }}, }, } @@ -67,9 +65,7 @@ var ( }, Spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "something", - }, + Image: "something", }}, }, } @@ -252,9 +248,7 @@ func TestGetTaskFunc(t *testing.T) { }, Spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "something", - }, + Image: "something", }}, Params: []v1beta1.ParamSpec{{ Name: "foo", @@ -277,9 +271,7 @@ func TestGetTaskFunc(t *testing.T) { }, Spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "something", - }, + Image: "something", }}, Params: []v1beta1.ParamSpec{{ Name: "foo", @@ -307,9 +299,7 @@ func TestGetTaskFunc(t *testing.T) { Name: "foo", }}, Steps: []v1alpha1.Step{{ - Container: corev1.Container{ - Image: "something", - }, + Image: "something", }}, }, }, @@ -326,9 +316,7 @@ func TestGetTaskFunc(t *testing.T) { }, Spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "something", - }, + Image: "something", }}, Params: []v1beta1.ParamSpec{{ Name: "foo", @@ -460,9 +448,7 @@ func TestGetTaskFuncFromTaskRunSpecAlreadyFetched(t *testing.T) { name := "anyname-really" TaskSpec := v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "myimage", - }, + Image: "myimage", Script: ` #!/usr/bin/env bash echo hello diff --git a/pkg/reconciler/taskrun/resources/taskresourceresolution_test.go b/pkg/reconciler/taskrun/resources/taskresourceresolution_test.go index ab608daa669..1ed819649ad 100644 --- a/pkg/reconciler/taskrun/resources/taskresourceresolution_test.go +++ b/pkg/reconciler/taskrun/resources/taskresourceresolution_test.go @@ -22,7 +22,6 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" resourcev1alpha1 "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1" - corev1 "k8s.io/api/core/v1" kerrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -77,9 +76,9 @@ func TestResolveTaskRun(t *testing.T) { taskName := "orchestrate" kind := v1beta1.NamespacedTaskKind taskSpec := v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", - }}, + }, }} resources := []*resourcev1alpha1.PipelineResource{{ @@ -207,9 +206,9 @@ func TestResolveTaskRun_missingInput(t *testing.T) { func TestResolveTaskRun_noResources(t *testing.T) { taskSpec := v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", - }}, + }, }} gr := func(n string) (*resourcev1alpha1.PipelineResource, error) { diff --git a/pkg/reconciler/taskrun/resources/taskspec_test.go b/pkg/reconciler/taskrun/resources/taskspec_test.go index 1f8f9450aec..cc9d1d1057a 100644 --- a/pkg/reconciler/taskrun/resources/taskspec_test.go +++ b/pkg/reconciler/taskrun/resources/taskspec_test.go @@ -22,7 +22,6 @@ import ( "testing" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -32,9 +31,9 @@ func TestGetTaskSpec_Ref(t *testing.T) { Name: "orchestrate", }, Spec: v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", - }}}, + }}, }, } tr := &v1beta1.TaskRun{ @@ -70,9 +69,9 @@ func TestGetTaskSpec_Embedded(t *testing.T) { }, Spec: v1beta1.TaskRunSpec{ TaskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Name: "step1", - }}}, + }}, }, }, } diff --git a/pkg/reconciler/taskrun/taskrun_test.go b/pkg/reconciler/taskrun/taskrun_test.go index 9927a2fd281..8cb6457bd02 100644 --- a/pkg/reconciler/taskrun/taskrun_test.go +++ b/pkg/reconciler/taskrun/taskrun_test.go @@ -112,11 +112,9 @@ var ( cloudEventTarget2 = "https://bar" simpleStep = v1beta1.Step{ - Container: corev1.Container{ - Name: "simple-step", - Image: "foo", - Command: []string{"/mycmd"}, - }, + Name: "simple-step", + Image: "foo", + Command: []string{"/mycmd"}, } simpleTask = &v1beta1.Task{ ObjectMeta: objectMeta("test-task", "foo"), @@ -145,10 +143,8 @@ var ( ObjectMeta: objectMeta("test-task-sidecar", "foo"), Spec: v1beta1.TaskSpec{ Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - Name: "sidecar", - Image: "image-id", - }, + Name: "sidecar", + Image: "image-id", }}, }, } @@ -157,16 +153,12 @@ var ( Spec: v1beta1.TaskSpec{ Sidecars: []v1beta1.Sidecar{ { - Container: corev1.Container{ - Name: "sidecar", - Image: "image-id", - }, + Name: "sidecar", + Image: "image-id", }, { - Container: corev1.Container{ - Name: "sidecar2", - Image: "image-id", - }, + Name: "sidecar2", + Image: "image-id", }, }, }, @@ -205,11 +197,9 @@ var ( ObjectMeta: objectMeta("test-with-sa", "foo"), Spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "sa-step", - Image: "foo", - Command: []string{"/mycmd"}, - }, + Name: "sa-step", + Image: "foo", + Command: []string{"/mycmd"}, }}, }, } @@ -253,27 +243,23 @@ var ( }, Steps: []v1beta1.Step{ { - Container: corev1.Container{ - Image: "myimage", - Name: "mycontainer", - Command: []string{"/mycmd"}, - Args: []string{ - "--my-arg=$(inputs.params.myarg)", - "--my-arg-with-default=$(inputs.params.myarghasdefault)", - "--my-arg-with-default2=$(inputs.params.myarghasdefault2)", - "--my-additional-arg=$(outputs.resources.myimage.url)", - "--my-taskname-arg=$(context.task.name)", - "--my-taskrun-arg=$(context.taskRun.name)", - }, + Image: "myimage", + Name: "mycontainer", + Command: []string{"/mycmd"}, + Args: []string{ + "--my-arg=$(inputs.params.myarg)", + "--my-arg-with-default=$(inputs.params.myarghasdefault)", + "--my-arg-with-default2=$(inputs.params.myarghasdefault2)", + "--my-additional-arg=$(outputs.resources.myimage.url)", + "--my-taskname-arg=$(context.task.name)", + "--my-taskrun-arg=$(context.taskRun.name)", }, }, { - Container: corev1.Container{ - Image: "myotherimage", - Name: "myothercontainer", - Command: []string{"/mycmd"}, - Args: []string{"--my-other-arg=$(inputs.resources.workspace.url)"}, - }, + Image: "myotherimage", + Name: "myothercontainer", + Command: []string{"/mycmd"}, + Args: []string{"--my-other-arg=$(inputs.resources.workspace.url)"}, }, }, Volumes: []corev1.Volume{{ @@ -3823,12 +3809,10 @@ func Test_validateTaskSpecRequestResources_ValidResources(t *testing.T) { taskSpec: &v1beta1.TaskSpec{ Steps: []v1beta1.Step{ { - Container: corev1.Container{ - Image: "image", - Command: []string{"cmd"}, - }, + Image: "image", + Command: []string{"cmd"}, }}, - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ Resources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("4"), @@ -3840,7 +3824,7 @@ func Test_validateTaskSpecRequestResources_ValidResources(t *testing.T) { }, { name: "no limit configured", taskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "image", Command: []string{"cmd"}, Resources: corev1.ResourceRequirements{ @@ -3849,12 +3833,12 @@ func Test_validateTaskSpecRequestResources_ValidResources(t *testing.T) { corev1.ResourceMemory: resource.MustParse("4Gi"), }, }, - }}}, + }}, }, }, { name: "request less or equal than step limit but larger than steptemplate limit", taskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "image", Command: []string{"cmd"}, Resources: corev1.ResourceRequirements{ @@ -3867,8 +3851,8 @@ func Test_validateTaskSpecRequestResources_ValidResources(t *testing.T) { corev1.ResourceMemory: resource.MustParse("8Gi"), }, }, - }}}, - StepTemplate: &corev1.Container{ + }}, + StepTemplate: &v1beta1.StepTemplate{ Resources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("4"), @@ -3880,7 +3864,7 @@ func Test_validateTaskSpecRequestResources_ValidResources(t *testing.T) { }, { name: "request less or equal than step limit", taskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "image", Command: []string{"cmd"}, Resources: corev1.ResourceRequirements{ @@ -3893,12 +3877,12 @@ func Test_validateTaskSpecRequestResources_ValidResources(t *testing.T) { corev1.ResourceMemory: resource.MustParse("8Gi"), }, }, - }}}, + }}, }, }, { name: "request less or equal than steptemplate limit", taskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "image", Command: []string{"cmd"}, Resources: corev1.ResourceRequirements{ @@ -3907,8 +3891,8 @@ func Test_validateTaskSpecRequestResources_ValidResources(t *testing.T) { corev1.ResourceMemory: resource.MustParse("4Gi"), }, }, - }}}, - StepTemplate: &corev1.Container{ + }}, + StepTemplate: &v1beta1.StepTemplate{ Resources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("8"), @@ -3937,7 +3921,7 @@ func Test_validateTaskSpecRequestResources_InvalidResources(t *testing.T) { }{{ name: "step request larger than step limit", taskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "image", Command: []string{"cmd"}, Resources: corev1.ResourceRequirements{ @@ -3950,11 +3934,11 @@ func Test_validateTaskSpecRequestResources_InvalidResources(t *testing.T) { corev1.ResourceMemory: resource.MustParse("4Gi"), }, }, - }}}}, + }}}, }, { name: "step request larger than steptemplate limit", taskSpec: &v1beta1.TaskSpec{ - Steps: []v1beta1.Step{{Container: corev1.Container{ + Steps: []v1beta1.Step{{ Image: "image", Command: []string{"cmd"}, Resources: corev1.ResourceRequirements{ @@ -3963,8 +3947,8 @@ func Test_validateTaskSpecRequestResources_InvalidResources(t *testing.T) { corev1.ResourceMemory: resource.MustParse("8Gi"), }, }, - }}}, - StepTemplate: &corev1.Container{ + }}, + StepTemplate: &v1beta1.StepTemplate{ Resources: corev1.ResourceRequirements{ Limits: corev1.ResourceList{ corev1.ResourceCPU: resource.MustParse("8"), diff --git a/pkg/reconciler/taskrun/validate_resources_test.go b/pkg/reconciler/taskrun/validate_resources_test.go index c5e84be8338..685efb3c42f 100644 --- a/pkg/reconciler/taskrun/validate_resources_test.go +++ b/pkg/reconciler/taskrun/validate_resources_test.go @@ -21,7 +21,6 @@ import ( "testing" "github.com/tektoncd/pipeline/pkg/apis/resource/v1alpha1" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/tektoncd/pipeline/pkg/apis/config" @@ -38,10 +37,8 @@ func TestValidateResolvedTaskResources_ValidResources(t *testing.T) { }, Spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "myimage", - Command: []string{"mycmd"}, - }, + Image: "myimage", + Command: []string{"mycmd"}, }}, Resources: &v1beta1.TaskResources{ Inputs: []v1beta1.TaskResource{ @@ -129,10 +126,8 @@ func TestValidateResolvedTaskResources_ValidParams(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "myimage", - Command: []string{"mycmd"}, - }, + Image: "myimage", + Command: []string{"mycmd"}, }}, Params: []v1beta1.ParamSpec{ { @@ -178,10 +173,8 @@ func TestValidateResolvedTaskResources_InvalidParams(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Spec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Image: "myimage", - Command: []string{"mycmd"}, - }, + Image: "myimage", + Command: []string{"mycmd"}, }}, Params: []v1beta1.ParamSpec{ { @@ -432,13 +425,9 @@ func TestValidateOverrides(t *testing.T) { name: "valid stepOverrides", ts: &v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "step1", - }, + Name: "step1", }, { - Container: corev1.Container{ - Name: "step2", - }, + Name: "step2", }}, }, trs: &v1beta1.TaskRunSpec{ @@ -450,13 +439,9 @@ func TestValidateOverrides(t *testing.T) { name: "valid sidecarOverrides", ts: &v1beta1.TaskSpec{ Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - Name: "step1", - }, + Name: "step1", }, { - Container: corev1.Container{ - Name: "step2", - }, + Name: "step2", }}, }, trs: &v1beta1.TaskRunSpec{ diff --git a/pkg/workspace/apply.go b/pkg/workspace/apply.go index 21d173ba76a..d7d0e38ed18 100644 --- a/pkg/workspace/apply.go +++ b/pkg/workspace/apply.go @@ -98,7 +98,7 @@ func Apply(ctx context.Context, ts v1beta1.TaskSpec, wb []v1beta1.WorkspaceBindi // Initialize StepTemplate if it hasn't been already if ts.StepTemplate == nil { - ts.StepTemplate = &corev1.Container{} + ts.StepTemplate = &v1beta1.StepTemplate{} } isolatedWorkspaces := sets.NewString() diff --git a/pkg/workspace/apply_test.go b/pkg/workspace/apply_test.go index 6fcaa3a03b6..af4c9397358 100644 --- a/pkg/workspace/apply_test.go +++ b/pkg/workspace/apply_test.go @@ -217,7 +217,7 @@ func TestApply(t *testing.T) { SubPath: "/foo/bar/baz", }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-9l9zj", MountPath: "/workspace/custom", @@ -251,7 +251,7 @@ func TestApply(t *testing.T) { SubPath: "/foo/bar/baz", }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-mz4c7", MountPath: "/workspace/custom", @@ -273,7 +273,7 @@ func TestApply(t *testing.T) { }, { name: "task spec already has volumes and stepTemplate", ts: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "awesome-volume", MountPath: "/", @@ -297,7 +297,7 @@ func TestApply(t *testing.T) { SubPath: "/foo/bar/baz", }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "awesome-volume", MountPath: "/", @@ -328,16 +328,14 @@ func TestApply(t *testing.T) { name: "0 workspace bindings", ts: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "foo", - }}}, + Name: "foo", + }}, }, workspaces: []v1beta1.WorkspaceBinding{}, expectedTaskSpec: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{ - Name: "foo", - }}}, + Name: "foo", + }}, }, }, { name: "binding multiple workspaces", @@ -361,7 +359,7 @@ func TestApply(t *testing.T) { }, }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-78c5n", MountPath: "/workspace/custom", @@ -415,7 +413,7 @@ func TestApply(t *testing.T) { SubPath: "/very/professional/work/space", }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-j2tds", MountPath: "/workspace/custom", @@ -455,7 +453,7 @@ func TestApply(t *testing.T) { }, }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-l22wn", MountPath: "/my/fancy/mount/path", @@ -490,7 +488,7 @@ func TestApply(t *testing.T) { }, }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-twkr2", MountPath: "/my/fancy/mount/path", @@ -540,7 +538,7 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { Name: "source", }}, }}, - Sidecars: []v1beta1.Sidecar{{Container: corev1.Container{Name: "foo"}}}, + Sidecars: []v1beta1.Sidecar{{Name: "foo"}}, Workspaces: []v1beta1.WorkspaceDeclaration{{ Name: "source", }}, @@ -552,7 +550,7 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }, }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{}, + StepTemplate: &v1beta1.StepTemplate{}, Volumes: []corev1.Volume{{ Name: "ws-9l9zj", VolumeSource: corev1.VolumeSource{ @@ -562,17 +560,15 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }, }}, Steps: []v1beta1.Step{{ - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "ws-9l9zj", - MountPath: "/workspace/source", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "ws-9l9zj", + MountPath: "/workspace/source", + }}, Workspaces: []v1beta1.WorkspaceUsage{{ Name: "source", }}, }}, - Sidecars: []v1beta1.Sidecar{{Container: corev1.Container{Name: "foo"}}}, + Sidecars: []v1beta1.Sidecar{{Name: "foo"}}, Workspaces: []v1beta1.WorkspaceDeclaration{{ Name: "source", }}, @@ -581,7 +577,7 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { name: "workspace isolated to sidecar does not appear in steps", ts: v1beta1.TaskSpec{ Steps: []v1beta1.Step{{ - Container: corev1.Container{Name: "step1"}, + Name: "step1", }}, Sidecars: []v1beta1.Sidecar{{ Workspaces: []v1beta1.WorkspaceUsage{{ @@ -599,7 +595,7 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }, }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{}, + StepTemplate: &v1beta1.StepTemplate{}, Volumes: []corev1.Volume{{ Name: "ws-mz4c7", VolumeSource: corev1.VolumeSource{ @@ -609,15 +605,13 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }, }}, Steps: []v1beta1.Step{{ - Container: corev1.Container{Name: "step1"}, + Name: "step1", }}, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "ws-mz4c7", - MountPath: "/workspace/source", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "ws-mz4c7", + MountPath: "/workspace/source", + }}, Workspaces: []v1beta1.WorkspaceUsage{{ Name: "source", }}, @@ -634,7 +628,7 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { Name: "source", }}, }, { - Container: corev1.Container{Name: "step2"}, + Name: "step2", }}, Sidecars: []v1beta1.Sidecar{{ Workspaces: []v1beta1.WorkspaceUsage{{ @@ -652,7 +646,7 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }, }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{}, + StepTemplate: &v1beta1.StepTemplate{}, Volumes: []corev1.Volume{{ Name: "ws-mssqb", VolumeSource: corev1.VolumeSource{ @@ -662,25 +656,21 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }, }}, Steps: []v1beta1.Step{{ - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "ws-mssqb", - MountPath: "/workspace/source", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "ws-mssqb", + MountPath: "/workspace/source", + }}, Workspaces: []v1beta1.WorkspaceUsage{{ Name: "source", }}, }, { - Container: corev1.Container{Name: "step2"}, + Name: "step2", }}, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "ws-mssqb", - MountPath: "/workspace/source", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "ws-mssqb", + MountPath: "/workspace/source", + }}, Workspaces: []v1beta1.WorkspaceUsage{{ Name: "source", }}, @@ -705,7 +695,7 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }, }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-78c5n", MountPath: "/workspace/source", }}, @@ -720,12 +710,10 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }}, Steps: []v1beta1.Step{{}}, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "ws-78c5n", - MountPath: "/workspace/source", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "ws-78c5n", + MountPath: "/workspace/source", + }}, }}, Workspaces: []v1beta1.WorkspaceDeclaration{{ Name: "source", @@ -757,7 +745,7 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }, }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{}, + StepTemplate: &v1beta1.StepTemplate{}, Volumes: []corev1.Volume{{ Name: "ws-6nl7g", VolumeSource: corev1.VolumeSource{ @@ -771,24 +759,20 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { Name: "source", MountPath: "/foo", }}, - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "ws-6nl7g", - MountPath: "/foo", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "ws-6nl7g", + MountPath: "/foo", + }}, }}, Sidecars: []v1beta1.Sidecar{{ Workspaces: []v1beta1.WorkspaceUsage{{ Name: "source", MountPath: "/bar", }}, - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "ws-6nl7g", - MountPath: "/bar", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "ws-6nl7g", + MountPath: "/bar", + }}, }}, Workspaces: []v1beta1.WorkspaceDeclaration{{ Name: "source", @@ -803,13 +787,11 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { ReadOnly: true, }}, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - Name: "conflicting volume mount sidecar", - VolumeMounts: []corev1.VolumeMount{{ - Name: "mount-path-conflicts", - MountPath: "/my/fancy/mount/path", - }}, - }, + Name: "conflicting volume mount sidecar", + VolumeMounts: []corev1.VolumeMount{{ + Name: "mount-path-conflicts", + MountPath: "/my/fancy/mount/path", + }}, }}, }, workspaces: []v1beta1.WorkspaceBinding{{ @@ -819,7 +801,7 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }, }}, expectedTaskSpec: v1beta1.TaskSpec{ - StepTemplate: &corev1.Container{ + StepTemplate: &v1beta1.StepTemplate{ VolumeMounts: []corev1.VolumeMount{{ Name: "ws-j2tds", MountPath: "/my/fancy/mount/path", @@ -827,13 +809,11 @@ func TestApply_IsolatedWorkspaces(t *testing.T) { }}, }, Sidecars: []v1beta1.Sidecar{{ - Container: corev1.Container{ - Name: "conflicting volume mount sidecar", - VolumeMounts: []corev1.VolumeMount{{ - Name: "mount-path-conflicts", - MountPath: "/my/fancy/mount/path", - }}, - }, + Name: "conflicting volume mount sidecar", + VolumeMounts: []corev1.VolumeMount{{ + Name: "mount-path-conflicts", + MountPath: "/my/fancy/mount/path", + }}, }}, Volumes: []corev1.Volume{{ Name: "ws-j2tds", @@ -901,12 +881,10 @@ func TestAddSidecarVolumeMount(t *testing.T) { MountPath: "/workspace/foo", }, expectedSidecar: v1beta1.Sidecar{ - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "foo", - MountPath: "/workspace/foo", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "foo", + MountPath: "/workspace/foo", + }}, }, }, { sidecarMounts: []corev1.VolumeMount{}, @@ -915,12 +893,10 @@ func TestAddSidecarVolumeMount(t *testing.T) { MountPath: "/workspace/foo", }, expectedSidecar: v1beta1.Sidecar{ - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "foo", - MountPath: "/workspace/foo", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "foo", + MountPath: "/workspace/foo", + }}, }, }, { sidecarMounts: []corev1.VolumeMount{{ @@ -932,12 +908,10 @@ func TestAddSidecarVolumeMount(t *testing.T) { MountPath: "/workspace/bar", }, expectedSidecar: v1beta1.Sidecar{ - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "bar", - MountPath: "/workspace/bar", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "bar", + MountPath: "/workspace/bar", + }}, }, }, { sidecarMounts: []corev1.VolumeMount{{ @@ -949,19 +923,17 @@ func TestAddSidecarVolumeMount(t *testing.T) { MountPath: "/workspace/foo", }, expectedSidecar: v1beta1.Sidecar{ - Container: corev1.Container{ - VolumeMounts: []corev1.VolumeMount{{ - Name: "bar", - MountPath: "/workspace/bar", - }, { - Name: "foo", - MountPath: "/workspace/foo", - }}, - }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "bar", + MountPath: "/workspace/bar", + }, { + Name: "foo", + MountPath: "/workspace/foo", + }}, }, }} { sidecar := v1beta1.Sidecar{} - sidecar.Container.VolumeMounts = tc.sidecarMounts + sidecar.VolumeMounts = tc.sidecarMounts workspace.AddSidecarVolumeMount(&sidecar, tc.volumeMount) if d := cmp.Diff(tc.expectedSidecar, sidecar); d != "" { t.Error(diff.PrintWantGot(d)) diff --git a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go index 431bf47ddc4..71037169c40 100644 --- a/vendor/github.com/Azure/azure-sdk-for-go/version/version.go +++ b/vendor/github.com/Azure/azure-sdk-for-go/version/version.go @@ -4,4 +4,4 @@ package version // Licensed under the MIT License. See License.txt in the project root for license information. // Number contains the semantic version of this SDK. -const Number = "v62.0.0" +const Number = "v63.3.0" diff --git a/vendor/modules.txt b/vendor/modules.txt index ba7aaedf9a1..6ca40f7baa1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -7,7 +7,7 @@ contrib.go.opencensus.io/exporter/ocagent # contrib.go.opencensus.io/exporter/prometheus v0.4.0 ## explicit; go 1.13 contrib.go.opencensus.io/exporter/prometheus -# github.com/Azure/azure-sdk-for-go v62.0.0+incompatible +# github.com/Azure/azure-sdk-for-go v63.3.0+incompatible ## explicit github.com/Azure/azure-sdk-for-go/services/preview/containerregistry/runtime/2019-08-15-preview/containerregistry github.com/Azure/azure-sdk-for-go/version