From ffc48071ecad32d8e195b9522d2da202a830a982 Mon Sep 17 00:00:00 2001 From: Christie Wilson Date: Thu, 11 Jul 2019 21:13:39 -0400 Subject: [PATCH] =?UTF-8?q?Massive=20hack=20to=20prevent=20attempted=20mou?= =?UTF-8?q?nt=20of=20non-existent=20PVC=20=F0=9F=92=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In #1007 @dlorenc and I tried to fix the case where a PVC wasn't needed for output -> input linking and it was being created anyway. What we forgot to do was check to see where that PVC was being mounted. It turns out that if a TaskRun has an output and is created by a PipelineRun (this is checked via the owner reference), the TaskRun assumes it needs to mount the volume and further adds containers to copy the output data to the (possibly) non-existent PVC. @castlemilk caught this problem in #1068. The real fix here is probably going to involve an interface change b/c we can't assume that just being owned by a PipelineRun means that a linking PVC is going to be involved. This commit is a terrible and probably race condition hack to make it so that if the PVC the TaskRun is expecting doesn't exist, it doesn't attempt to add containers that will copy data to it. Making the hack even worse is that instead of adding more actual unit tests, I updated the test to run all the existing unit tests twice, once with this PVC existing and once with it not, and I manipulated the test so that in the case where it doesn't exist, the expected outcome is different. This is a terrible way to write tests and I hope we either don't merge this or we fix it quickly afterward. @dlorenc and I are going to work on a better fix tomorrow. I also modified our end to end PipelineRun test to include an output resource so we could reproduce the issue that @castlemilk reported. --- .../v1alpha1/pipelinerun/pipelinerun_test.go | 34 +- .../taskrun/resources/output_resource.go | 24 +- .../taskrun/resources/output_resource_test.go | 1099 +++++++++-------- test/pipelinerun_test.go | 20 +- 4 files changed, 630 insertions(+), 547 deletions(-) diff --git a/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun_test.go b/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun_test.go index 233e8ed9c80..0626d125186 100644 --- a/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun_test.go +++ b/pkg/reconciler/v1alpha1/pipelinerun/pipelinerun_test.go @@ -696,20 +696,38 @@ func TestReconcileWithTimeout(t *testing.T) { } func TestReconcileWithoutPVC(t *testing.T) { + rs := []*v1alpha1.PipelineResource{tb.PipelineResource("dance-party", "foo", + tb.PipelineResourceSpec(v1alpha1.PipelineResourceTypeGit), + )} ps := []*v1alpha1.Pipeline{tb.Pipeline("test-pipeline", "foo", tb.PipelineSpec( - tb.PipelineTask("hello-world-1", "hello-world"), - tb.PipelineTask("hello-world-2", "hello-world"), + tb.PipelineDeclaredResource("party", v1alpha1.PipelineResourceTypeGit), + // Though these use the same resource as input and output, they are not linked with `from` so no PVC is needed + tb.PipelineTask("hello-world-1", "time-output", + tb.PipelineTaskOutputResource("time", "party"), + ), + tb.PipelineTask("hello-world-2", "time-input", + tb.PipelineTaskInputResource("time", "party"), + ), ))} prs := []*v1alpha1.PipelineRun{tb.PipelineRun("test-pipeline-run", "foo", - tb.PipelineRunSpec("test-pipeline")), + tb.PipelineRunSpec("test-pipeline", + tb.PipelineRunResourceBinding("party", tb.PipelineResourceBindingRef("dance-party")), + )), } - ts := []*v1alpha1.Task{tb.Task("hello-world", "foo")} + ts := []*v1alpha1.Task{ + tb.Task("time-input", "foo", tb.TaskSpec( + tb.TaskInputs(tb.InputsResource("time", v1alpha1.PipelineResourceTypeGit)), + )), + tb.Task("time-output", "foo", tb.TaskSpec( + tb.TaskOutputs(tb.OutputsResource("time", v1alpha1.PipelineResourceTypeGit)), + ))} d := test.Data{ - PipelineRuns: prs, - Pipelines: ps, - Tasks: ts, + PipelineResources: rs, + PipelineRuns: prs, + Pipelines: ps, + Tasks: ts, } // create fake recorder for testing @@ -730,7 +748,7 @@ func TestReconcileWithoutPVC(t *testing.T) { t.Fatalf("Somehow had error getting reconciled run out of fake client: %s", err) } - // Check that the expected TaskRun was created + // Check that no PVC was created for _, a := range clients.Kube.Actions() { if ca, ok := a.(ktesting.CreateAction); ok { obj := ca.GetObject() diff --git a/pkg/reconciler/v1alpha1/taskrun/resources/output_resource.go b/pkg/reconciler/v1alpha1/taskrun/resources/output_resource.go index d5015276666..7e75da3a561 100644 --- a/pkg/reconciler/v1alpha1/taskrun/resources/output_resource.go +++ b/pkg/reconciler/v1alpha1/taskrun/resources/output_resource.go @@ -25,6 +25,8 @@ import ( "go.uber.org/zap" "golang.org/x/xerrors" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) @@ -43,8 +45,8 @@ var ( // This function also reads the inputs to check if resources are redeclared in inputs and has any custom // target directory. // Steps executed: -// 1. If taskrun has owner reference as pipelinerun then all outputs are copied to parents PVC -// and also runs any custom upload steps (upload to blob store) +// 1. If taskrun has owner reference as pipelinerun and the expected parent PVC exists, then all outputs +// are copied to parents PVC and also runs any custom upload steps (upload to blob store) // 2. If taskrun does not have pipelinerun as owner reference then all outputs resources execute their custom // upload steps (like upload to blob store ) // @@ -68,8 +70,22 @@ func AddOutputResources( pvcName := taskRun.GetPipelineRunPVCName() as, err := artifacts.GetArtifactStorage(pvcName, kubeclient, logger) + if err != nil { - return nil, err + return nil, xerrors.Errorf("couldn't determine artifact storage: %w", err) + } + + if as.GetType() == v1alpha1.ArtifactStoragePVCType { + // TODO(#1068) There is probably a race condition here - this is just a hack to work around the bug in 0.5.0 while we + // work on a real long term fix + if _, err := kubeclient.CoreV1().PersistentVolumeClaims(taskRun.Namespace).Get(pvcName, metav1.GetOptions{}); err != nil { + // If there is no "parent" PVC, we shouldn't try to attach it and upload to it + if errors.IsNotFound(err) { + as = &artifacts.ArtifactStorageNone{} + } else { + return nil, xerrors.Errorf("error checking for possible parent PVC volume %s: %w", pvcName, err) + } + } } // track resources that are present in input of task cuz these resources will be copied onto PVC @@ -91,6 +107,7 @@ func AddOutputResources( if !ok || resource == nil { return nil, xerrors.Errorf("failed to get output pipeline Resource for task %q resource %v", taskName, boundResource) } + var ( resourceContainers []corev1.Container resourceVolumes []corev1.Volume @@ -132,6 +149,7 @@ func AddOutputResources( } if allowedOutputResources[resource.GetType()] && taskRun.HasPipelineRunOwnerReference() { + var newSteps []corev1.Container for _, dPath := range boundResource.Paths { containers := as.GetCopyToStorageFromContainerSpec(resource.GetName(), sourcePath, dPath) diff --git a/pkg/reconciler/v1alpha1/taskrun/resources/output_resource_test.go b/pkg/reconciler/v1alpha1/taskrun/resources/output_resource_test.go index ea7dd78940f..3ac72aa2690 100644 --- a/pkg/reconciler/v1alpha1/taskrun/resources/output_resource_test.go +++ b/pkg/reconciler/v1alpha1/taskrun/resources/output_resource_test.go @@ -17,6 +17,7 @@ limitations under the License. package resources import ( + "strings" "testing" "github.com/google/go-cmp/cmp" @@ -97,614 +98,650 @@ func outputResourceSetup(t *testing.T) { outputResources[r.Name] = ri } } -func TestValidOutputResources(t *testing.T) { - for _, c := range []struct { - name string - desc string - task *v1alpha1.Task - taskRun *v1alpha1.TaskRun - wantSteps []corev1.Container - wantVolumes []corev1.Volume - }{{ - name: "git resource in input and output", - desc: "git resource declared as both input and output with pipelinerun owner reference", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-output-steps", - Namespace: "marshmallow", - OwnerReferences: []metav1.OwnerReference{{ - Kind: "PipelineRun", - Name: "pipelinerun", - }}, - }, - Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-git", - }, +func TestValidOutputResources(t *testing.T) { + for _, pvcExists := range []bool{true, false} { + for _, c := range []struct { + name string + desc string + task *v1alpha1.Task + taskRun *v1alpha1.TaskRun + wantSteps []corev1.Container + wantVolumes []corev1.Volume + }{{ + name: "git resource in input and output", + desc: "git resource declared as both input and output with pipelinerun owner reference", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-output-steps", + Namespace: "marshmallow", + OwnerReferences: []metav1.OwnerReference{{ + Kind: "PipelineRun", + Name: "pipelinerun", }}, }, - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-git", - }, - Paths: []string{"pipeline-task-name"}, - }}, + Spec: v1alpha1.TaskRunSpec{ + Inputs: v1alpha1.TaskRunInputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-git", + }, + }}, + }, + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-git", + }, + Paths: []string{"pipeline-task-name"}, + }}, + }, }, }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskSpec{ - Inputs: &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "git", - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", }, - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "git", - }}, + Spec: v1alpha1.TaskSpec{ + Inputs: &v1alpha1.Inputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "git", + }}, + }, + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "git", + }}, + }, }, }, - }, - wantSteps: []corev1.Container{{ - Name: "source-mkdir-source-git-9l9zj", - Image: "override-with-bash-noop:latest", - Command: []string{"/ko-app/bash"}, - Args: []string{"-args", "mkdir -p pipeline-task-name"}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "pipelinerun-pvc", - MountPath: "/pvc", + wantSteps: []corev1.Container{{ + Name: "source-mkdir-source-git-9l9zj", + Image: "override-with-bash-noop:latest", + Command: []string{"/ko-app/bash"}, + Args: []string{"-args", "mkdir -p pipeline-task-name"}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "pipelinerun-pvc", + MountPath: "/pvc", + }}, + }, { + Name: "source-copy-source-git-mz4c7", + Image: "override-with-bash-noop:latest", + Command: []string{"/ko-app/bash"}, + Args: []string{"-args", "cp -r /workspace/source-workspace/. pipeline-task-name"}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "pipelinerun-pvc", + MountPath: "/pvc", + }}, }}, }, { - Name: "source-copy-source-git-mz4c7", - Image: "override-with-bash-noop:latest", - Command: []string{"/ko-app/bash"}, - Args: []string{"-args", "cp -r /workspace/source-workspace/. pipeline-task-name"}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "pipelinerun-pvc", - MountPath: "/pvc", - }}, - }}, - }, { - name: "git resource in output only", - desc: "git resource declared as output with pipelinerun owner reference", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-output-steps", - Namespace: "marshmallow", - OwnerReferences: []metav1.OwnerReference{{ - Kind: "PipelineRun", - Name: "pipelinerun", - }}, - }, - Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-git", - }, - Paths: []string{"pipeline-task-name"}, + name: "git resource in output only", + desc: "git resource declared as output with pipelinerun owner reference", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-output-steps", + Namespace: "marshmallow", + OwnerReferences: []metav1.OwnerReference{{ + Kind: "PipelineRun", + Name: "pipelinerun", }}, }, + Spec: v1alpha1.TaskRunSpec{ + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-git", + }, + Paths: []string{"pipeline-task-name"}, + }}, + }, + }, }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "git", - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskSpec{ + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "git", + }}, + }, }, }, - }, - wantSteps: []corev1.Container{{ - Name: "source-mkdir-source-git-9l9zj", - Image: "override-with-bash-noop:latest", - Command: []string{"/ko-app/bash"}, - Args: []string{"-args", "mkdir -p pipeline-task-name"}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "pipelinerun-pvc", - MountPath: "/pvc", + wantSteps: []corev1.Container{{ + Name: "source-mkdir-source-git-9l9zj", + Image: "override-with-bash-noop:latest", + Command: []string{"/ko-app/bash"}, + Args: []string{"-args", "mkdir -p pipeline-task-name"}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "pipelinerun-pvc", + MountPath: "/pvc", + }}, + }, { + Name: "source-copy-source-git-mz4c7", + Image: "override-with-bash-noop:latest", + Command: []string{"/ko-app/bash"}, + Args: []string{"-args", "cp -r /workspace/output/source-workspace/. pipeline-task-name"}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "pipelinerun-pvc", + MountPath: "/pvc", + }}, }}, }, { - Name: "source-copy-source-git-mz4c7", - Image: "override-with-bash-noop:latest", - Command: []string{"/ko-app/bash"}, - Args: []string{"-args", "cp -r /workspace/output/source-workspace/. pipeline-task-name"}, - VolumeMounts: []corev1.VolumeMount{{ - Name: "pipelinerun-pvc", - MountPath: "/pvc", - }}, - }}, - }, { - name: "image resource in output with pipelinerun with owner", - desc: "image resource declared as output with pipelinerun owner reference should not generate any steps", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-output-steps", - Namespace: "marshmallow", - OwnerReferences: []metav1.OwnerReference{{ - Kind: "PipelineRun", - Name: "pipelinerun", - }}, - }, - Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-image", - }, - Paths: []string{"pipeline-task-name"}, + name: "image resource in output with pipelinerun with owner", + desc: "image resource declared as output with pipelinerun owner reference should not generate any steps", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-output-steps", + Namespace: "marshmallow", + OwnerReferences: []metav1.OwnerReference{{ + Kind: "PipelineRun", + Name: "pipelinerun", }}, }, - }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "image", - }}, + Spec: v1alpha1.TaskRunSpec{ + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-image", + }, + Paths: []string{"pipeline-task-name"}, + }}, + }, }, }, - }, - wantSteps: nil, - wantVolumes: nil, - }, { - name: "git resource in output", - desc: "git resource declared in output without pipelinerun owner reference", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-output-steps", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-git", - }, - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskSpec{ + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "image", + }}, + }, }, }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "git", - }}, + wantSteps: nil, + wantVolumes: nil, + }, { + name: "git resource in output", + desc: "git resource declared in output without pipelinerun owner reference", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-output-steps", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskRunSpec{ + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-git", + }, + }}, + }, }, }, - }, - }, { - name: "storage resource as both input and output", - desc: "storage resource defined in both input and output with parents pipelinerun reference", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-output-steps", - Namespace: "marshmallow", - OwnerReferences: []metav1.OwnerReference{{ - Kind: "PipelineRun", - Name: "pipelinerun-parent", - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskSpec{ + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "git", + }}, + }, + }, }, - Spec: v1alpha1.TaskRunSpec{ - Inputs: v1alpha1.TaskRunInputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-gcs", - }, + }, { + name: "storage resource as both input and output", + desc: "storage resource defined in both input and output with parents pipelinerun reference", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-output-steps", + Namespace: "marshmallow", + OwnerReferences: []metav1.OwnerReference{{ + Kind: "PipelineRun", + Name: "pipelinerun-parent", }}, }, - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-gcs", - }, - Paths: []string{"pipeline-task-path"}, - }}, + Spec: v1alpha1.TaskRunSpec{ + Inputs: v1alpha1.TaskRunInputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-gcs", + }, + }}, + }, + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-gcs", + }, + Paths: []string{"pipeline-task-path"}, + }}, + }, }, }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskSpec{ - Inputs: &v1alpha1.Inputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "storage", - TargetPath: "faraway-disk", - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", }, - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "storage", - }}, + Spec: v1alpha1.TaskSpec{ + Inputs: &v1alpha1.Inputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "storage", + TargetPath: "faraway-disk", + }}, + }, + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "storage", + }}, + }, }, }, - }, - wantSteps: []corev1.Container{{ - Name: "upload-source-gcs-9l9zj", - Image: "override-with-gsutil-image:latest", - VolumeMounts: []corev1.VolumeMount{{ - Name: "volume-source-gcs-sname", - MountPath: "/var/secret/sname", + wantSteps: []corev1.Container{{ + Name: "upload-source-gcs-9l9zj", + Image: "override-with-gsutil-image:latest", + VolumeMounts: []corev1.VolumeMount{{ + Name: "volume-source-gcs-sname", + MountPath: "/var/secret/sname", + }}, + Command: []string{"/ko-app/gsutil"}, + Args: []string{"-args", "rsync -d -r /workspace/faraway-disk gs://some-bucket"}, + Env: []corev1.EnvVar{{ + Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/sname/key.json", + }}, + }, { + Name: "source-mkdir-source-gcs-mz4c7", + Image: "override-with-bash-noop:latest", + Command: []string{"/ko-app/bash"}, + Args: []string{"-args", "mkdir -p pipeline-task-path"}, + VolumeMounts: []corev1.VolumeMount{{Name: "pipelinerun-parent-pvc", MountPath: "/pvc"}}, + }, { + Name: "source-copy-source-gcs-mssqb", + Image: "override-with-bash-noop:latest", + Command: []string{"/ko-app/bash"}, + Args: []string{"-args", "cp -r /workspace/faraway-disk/. pipeline-task-path"}, + VolumeMounts: []corev1.VolumeMount{{Name: "pipelinerun-parent-pvc", MountPath: "/pvc"}}, }}, - Command: []string{"/ko-app/gsutil"}, - Args: []string{"-args", "rsync -d -r /workspace/faraway-disk gs://some-bucket"}, - Env: []corev1.EnvVar{{ - Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/sname/key.json", + wantVolumes: []corev1.Volume{{ + Name: "volume-source-gcs-sname", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{SecretName: "sname"}, + }, }}, }, { - Name: "source-mkdir-source-gcs-mz4c7", - Image: "override-with-bash-noop:latest", - Command: []string{"/ko-app/bash"}, - Args: []string{"-args", "mkdir -p pipeline-task-path"}, - VolumeMounts: []corev1.VolumeMount{{Name: "pipelinerun-parent-pvc", MountPath: "/pvc"}}, - }, { - Name: "source-copy-source-gcs-mssqb", - Image: "override-with-bash-noop:latest", - Command: []string{"/ko-app/bash"}, - Args: []string{"-args", "cp -r /workspace/faraway-disk/. pipeline-task-path"}, - VolumeMounts: []corev1.VolumeMount{{Name: "pipelinerun-parent-pvc", MountPath: "/pvc"}}, - }}, - wantVolumes: []corev1.Volume{{ - Name: "volume-source-gcs-sname", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{SecretName: "sname"}, - }, - }}, - }, { - name: "storage resource as output", - desc: "storage resource defined only in output with pipeline ownder reference", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-only-output-step", - Namespace: "marshmallow", - OwnerReferences: []metav1.OwnerReference{{ - Kind: "PipelineRun", - Name: "pipelinerun", - }}, - }, - Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-gcs", - }, - Paths: []string{"pipeline-task-path"}, + name: "storage resource as output", + desc: "storage resource defined only in output with pipeline ownder reference", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-only-output-step", + Namespace: "marshmallow", + OwnerReferences: []metav1.OwnerReference{{ + Kind: "PipelineRun", + Name: "pipelinerun", }}, }, + Spec: v1alpha1.TaskRunSpec{ + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-gcs", + }, + Paths: []string{"pipeline-task-path"}, + }}, + }, + }, }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "storage", - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskSpec{ + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "storage", + }}, + }, }, }, - }, - wantSteps: []corev1.Container{{ - Name: "upload-source-gcs-9l9zj", - Image: "override-with-gsutil-image:latest", - VolumeMounts: []corev1.VolumeMount{{ - Name: "volume-source-gcs-sname", MountPath: "/var/secret/sname", + wantSteps: []corev1.Container{{ + Name: "upload-source-gcs-9l9zj", + Image: "override-with-gsutil-image:latest", + VolumeMounts: []corev1.VolumeMount{{ + Name: "volume-source-gcs-sname", MountPath: "/var/secret/sname", + }}, + Env: []corev1.EnvVar{{ + Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/sname/key.json", + }}, + Command: []string{"/ko-app/gsutil"}, + Args: []string{"-args", "rsync -d -r /workspace/output/source-workspace gs://some-bucket"}, + }, { + Name: "source-mkdir-source-gcs-mz4c7", + Image: "override-with-bash-noop:latest", + Command: []string{"/ko-app/bash"}, + Args: []string{"-args", "mkdir -p pipeline-task-path"}, + VolumeMounts: []corev1.VolumeMount{{Name: "pipelinerun-pvc", MountPath: "/pvc"}}, + }, { + Name: "source-copy-source-gcs-mssqb", + Image: "override-with-bash-noop:latest", + Command: []string{"/ko-app/bash"}, + Args: []string{"-args", "cp -r /workspace/output/source-workspace/. pipeline-task-path"}, + VolumeMounts: []corev1.VolumeMount{{Name: "pipelinerun-pvc", MountPath: "/pvc"}}, }}, - Env: []corev1.EnvVar{{ - Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/sname/key.json", + wantVolumes: []corev1.Volume{{ + Name: "volume-source-gcs-sname", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{SecretName: "sname"}, + }, }}, - Command: []string{"/ko-app/gsutil"}, - Args: []string{"-args", "rsync -d -r /workspace/output/source-workspace gs://some-bucket"}, }, { - Name: "source-mkdir-source-gcs-mz4c7", - Image: "override-with-bash-noop:latest", - Command: []string{"/ko-app/bash"}, - Args: []string{"-args", "mkdir -p pipeline-task-path"}, - VolumeMounts: []corev1.VolumeMount{{Name: "pipelinerun-pvc", MountPath: "/pvc"}}, - }, { - Name: "source-copy-source-gcs-mssqb", - Image: "override-with-bash-noop:latest", - Command: []string{"/ko-app/bash"}, - Args: []string{"-args", "cp -r /workspace/output/source-workspace/. pipeline-task-path"}, - VolumeMounts: []corev1.VolumeMount{{Name: "pipelinerun-pvc", MountPath: "/pvc"}}, - }}, - wantVolumes: []corev1.Volume{{ - Name: "volume-source-gcs-sname", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{SecretName: "sname"}, - }, - }}, - }, { - name: "storage resource as output with no owner", - desc: "storage resource defined only in output without pipelinerun reference", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-only-output-step", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-gcs", - }, - Paths: []string{"pipeline-task-path"}, - }}, + name: "storage resource as output with no owner", + desc: "storage resource defined only in output without pipelinerun reference", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-only-output-step", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskRunSpec{ + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-gcs", + }, + Paths: []string{"pipeline-task-path"}, + }}, + }, }, }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "storage", - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskSpec{ + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "storage", + }}, + }, }, }, - }, - wantSteps: []corev1.Container{{ - Name: "upload-source-gcs-9l9zj", - Image: "override-with-gsutil-image:latest", - VolumeMounts: []corev1.VolumeMount{{ - Name: "volume-source-gcs-sname", MountPath: "/var/secret/sname", + wantSteps: []corev1.Container{{ + Name: "upload-source-gcs-9l9zj", + Image: "override-with-gsutil-image:latest", + VolumeMounts: []corev1.VolumeMount{{ + Name: "volume-source-gcs-sname", MountPath: "/var/secret/sname", + }}, + Env: []corev1.EnvVar{{ + Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/sname/key.json", + }}, + Command: []string{"/ko-app/gsutil"}, + Args: []string{"-args", "rsync -d -r /workspace/output/source-workspace gs://some-bucket"}, }}, - Env: []corev1.EnvVar{{ - Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/sname/key.json", + wantVolumes: []corev1.Volume{{ + Name: "volume-source-gcs-sname", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{SecretName: "sname"}, + }, }}, - Command: []string{"/ko-app/gsutil"}, - Args: []string{"-args", "rsync -d -r /workspace/output/source-workspace gs://some-bucket"}, - }}, - wantVolumes: []corev1.Volume{{ - Name: "volume-source-gcs-sname", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{SecretName: "sname"}, - }, - }}, - }, { - name: "storage resource as output with matching build volumes", - desc: "storage resource defined only in output without pipelinerun reference", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-only-output-step", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-gcs", - }, - }}, + }, { + name: "storage resource as output with matching build volumes", + desc: "storage resource defined only in output without pipelinerun reference", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-only-output-step", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskRunSpec{ + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-gcs", + }, + }}, + }, }, }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "storage", - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskSpec{ + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "storage", + }}, + }, }, }, - }, - wantSteps: []corev1.Container{{ - Name: "upload-source-gcs-9l9zj", - Image: "override-with-gsutil-image:latest", - VolumeMounts: []corev1.VolumeMount{{ - Name: "volume-source-gcs-sname", MountPath: "/var/secret/sname", + wantSteps: []corev1.Container{{ + Name: "upload-source-gcs-9l9zj", + Image: "override-with-gsutil-image:latest", + VolumeMounts: []corev1.VolumeMount{{ + Name: "volume-source-gcs-sname", MountPath: "/var/secret/sname", + }}, + Env: []corev1.EnvVar{{ + Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/sname/key.json", + }}, + Command: []string{"/ko-app/gsutil"}, + Args: []string{"-args", "rsync -d -r /workspace/output/source-workspace gs://some-bucket"}, }}, - Env: []corev1.EnvVar{{ - Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: "/var/secret/sname/key.json", + wantVolumes: []corev1.Volume{{ + Name: "volume-source-gcs-sname", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{SecretName: "sname"}, + }, }}, - Command: []string{"/ko-app/gsutil"}, - Args: []string{"-args", "rsync -d -r /workspace/output/source-workspace gs://some-bucket"}, - }}, - wantVolumes: []corev1.Volume{{ - Name: "volume-source-gcs-sname", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{SecretName: "sname"}, - }, - }}, - }, { - name: "image resource as output", - desc: "image resource defined only in output", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-only-output-step", - Namespace: "marshmallow", - OwnerReferences: []metav1.OwnerReference{{ - Kind: "PipelineRun", - Name: "pipelinerun", - }}, - }, - Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-image", - }, + }, { + name: "image resource as output", + desc: "image resource defined only in output", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-only-output-step", + Namespace: "marshmallow", + OwnerReferences: []metav1.OwnerReference{{ + Kind: "PipelineRun", + Name: "pipelinerun", }}, }, - }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "image", - }}, + Spec: v1alpha1.TaskRunSpec{ + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-image", + }, + }}, + }, }, }, - }, - wantSteps: nil, - }, { - name: "Resource with TargetPath as output", - desc: "Resource with TargetPath defined only in output", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-only-output-step", - Namespace: "marshmallow", - OwnerReferences: []metav1.OwnerReference{{ - Kind: "PipelineRun", - Name: "pipelinerun", - }}, - }, - Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-image", - }, - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskSpec{ + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "image", + }}, + }, }, }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "image", - TargetPath: "/workspace", + wantSteps: nil, + }, { + name: "Resource with TargetPath as output", + desc: "Resource with TargetPath defined only in output", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-only-output-step", + Namespace: "marshmallow", + OwnerReferences: []metav1.OwnerReference{{ + Kind: "PipelineRun", + Name: "pipelinerun", }}, }, + Spec: v1alpha1.TaskRunSpec{ + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-image", + }, + }}, + }, + }, }, - }, - wantSteps: nil, - }, { - desc: "image output resource with no steps", - taskRun: &v1alpha1.TaskRun{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-taskrun-run-output-steps", - Namespace: "marshmallow", - }, - Spec: v1alpha1.TaskRunSpec{ - Outputs: v1alpha1.TaskRunOutputs{ - Resources: []v1alpha1.TaskResourceBinding{{ - Name: "source-workspace", - ResourceRef: v1alpha1.PipelineResourceRef{ - Name: "source-image", - }, - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskSpec{ + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "image", + TargetPath: "/workspace", + }}, + }, }, }, - }, - task: &v1alpha1.Task{ - ObjectMeta: metav1.ObjectMeta{ - Name: "task1", - Namespace: "marshmallow", + wantSteps: nil, + }, { + desc: "image output resource with no steps", + taskRun: &v1alpha1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-run-output-steps", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskRunSpec{ + Outputs: v1alpha1.TaskRunOutputs{ + Resources: []v1alpha1.TaskResourceBinding{{ + Name: "source-workspace", + ResourceRef: v1alpha1.PipelineResourceRef{ + Name: "source-image", + }, + }}, + }, + }, }, - Spec: v1alpha1.TaskSpec{ - Outputs: &v1alpha1.Outputs{ - Resources: []v1alpha1.TaskResource{{ - Name: "source-workspace", - Type: "image", - }}, + task: &v1alpha1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "task1", + Namespace: "marshmallow", + }, + Spec: v1alpha1.TaskSpec{ + Outputs: &v1alpha1.Outputs{ + Resources: []v1alpha1.TaskResource{{ + Name: "source-workspace", + Type: "image", + }}, + }, }, }, - }, - wantSteps: nil, - }} { - t.Run(c.name, func(t *testing.T) { - names.TestingSeed() - outputResourceSetup(t) - fakekubeclient := fakek8s.NewSimpleClientset() - got, err := AddOutputResources(fakekubeclient, c.task.Name, &c.task.Spec, c.taskRun, resolveOutputResources(c.taskRun), logger) - if err != nil { - t.Fatalf("Failed to declare output resources for test name %q ; test description %q: error %v", c.name, c.desc, err) + wantSteps: nil, + }} { + name := c.name + if pvcExists { + name = name + " with existing parent PVC" + } else { + name = name + " without existing parent PVC" } + t.Run(name, func(t *testing.T) { + names.TestingSeed() + outputResourceSetup(t) + fakekubeclient := fakek8s.NewSimpleClientset() + t.Log("RO NO") - if got != nil { - if d := cmp.Diff(got.Steps, c.wantSteps); d != "" { - t.Fatalf("post build steps mismatch: %s", d) - } - - if c.taskRun.GetPipelineRunPVCName() != "" { - c.wantVolumes = append( - c.wantVolumes, - corev1.Volume{ - Name: c.taskRun.GetPipelineRunPVCName(), - VolumeSource: corev1.VolumeSource{ - PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: c.taskRun.GetPipelineRunPVCName(), - }, + if pvcExists && c.taskRun.GetPipelineRunPVCName() != "" { + fakekubeclient.CoreV1().PersistentVolumeClaims("marshmallow").Create( + &corev1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: c.taskRun.GetPipelineRunPVCName(), + Namespace: "marshmallow", }, }, ) } - if d := cmp.Diff(got.Volumes, c.wantVolumes); d != "" { - t.Fatalf("post build steps volumes mismatch: %s", d) + var wantSteps []corev1.Container + if c.wantSteps != nil && !pvcExists { + steps := []corev1.Container{} + for i := range c.wantSteps { + // Since there is no PVC, we shouldn't include the steps that copy from the PVC + if !strings.HasPrefix(c.wantSteps[i].Name, "source-") { + steps = append(steps, c.wantSteps[i]) + } + } + if len(steps) > 0 { + wantSteps = steps + } + } else { + wantSteps = c.wantSteps } - } - }) + + got, err := AddOutputResources(fakekubeclient, c.task.Name, &c.task.Spec, c.taskRun, resolveOutputResources(c.taskRun), logger) + if err != nil { + t.Fatalf("Failed to declare output resources for test name %q ; test description %q: error %v", c.name, c.desc, err) + } + + if got != nil { + if d := cmp.Diff(wantSteps, got.Steps); d != "" { + t.Fatalf("post build steps mismatch: %s", d) + } + + if pvcExists && c.taskRun.GetPipelineRunPVCName() != "" { + c.wantVolumes = append( + c.wantVolumes, + corev1.Volume{ + Name: c.taskRun.GetPipelineRunPVCName(), + VolumeSource: corev1.VolumeSource{ + PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ + ClaimName: c.taskRun.GetPipelineRunPVCName(), + }, + }, + }, + ) + } + if d := cmp.Diff(c.wantVolumes, got.Volumes); d != "" { + t.Fatalf("post build steps volumes mismatch: %s", d) + } + } + }) + } } } diff --git a/test/pipelinerun_test.go b/test/pipelinerun_test.go index 90ea39ce24c..de0fca8dccd 100644 --- a/test/pipelinerun_test.go +++ b/test/pipelinerun_test.go @@ -67,8 +67,7 @@ func TestPipelineRun(t *testing.T) { t.Fatalf("Failed to create Task `%s`: %s", task.Name, err) } } - - for _, res := range getFanInFanOutGitResources(namespace) { + for _, res := range getKritisGitResources(namespace) { if _, err := c.PipelineResourceClient.Create(res); err != nil { t.Fatalf("Failed to create Pipeline Resource `%s`: %s", kanikoResourceName, err) } @@ -83,7 +82,7 @@ func TestPipelineRun(t *testing.T) { // 1 from PipelineRun and 4 from Tasks defined in pipelinerun expectedNumberOfEvents: 5, }, { - name: "service account propagation", + name: "simple pipeline with output and service account", testSetup: func(t *testing.T, c *clients, namespace string, index int) { t.Helper() if _, err := c.KubeClient.Kube.CoreV1().Secrets(namespace).Create(getPipelineRunSecret(index, namespace)); err != nil { @@ -95,6 +94,7 @@ func TestPipelineRun(t *testing.T) { } task := tb.Task(getName(taskName, index), namespace, tb.TaskSpec( + tb.TaskOutputs(tb.OutputsResource("my-resource", v1alpha1.PipelineResourceTypeGit)), // Reference build: https://github.com/knative/build/tree/master/test/docker-basic tb.Step("config-docker", "quay.io/rhpipeline/skopeo:alpine", tb.Command("skopeo"), @@ -105,6 +105,12 @@ func TestPipelineRun(t *testing.T) { t.Fatalf("Failed to create Task `%s`: %s", getName(taskName, index), err) } + for _, res := range getKritisGitResources(namespace) { + if _, err := c.PipelineResourceClient.Create(res); err != nil { + t.Fatalf("Failed to create Pipeline Resource `%s`: %s", kanikoResourceName, err) + } + } + if _, err := c.PipelineClient.Create(getHelloWorldPipelineWithSingularTask(index, namespace)); err != nil { t.Fatalf("Failed to create Pipeline `%s`: %s", getName(pipelineName, index), err) } @@ -202,7 +208,10 @@ func TestPipelineRun(t *testing.T) { func getHelloWorldPipelineWithSingularTask(suffix int, namespace string) *v1alpha1.Pipeline { return tb.Pipeline(getName(pipelineName, suffix), namespace, tb.PipelineSpec( - tb.PipelineTask(task1Name, getName(taskName, suffix)), + tb.PipelineDeclaredResource("resource", "resource"), + tb.PipelineTask(task1Name, getName(taskName, suffix), + tb.PipelineTaskOutputResource("my-resource", "resource"), + ), )) } @@ -282,7 +291,7 @@ func getFanInFanOutPipeline(suffix int, namespace string) *v1alpha1.Pipeline { )) } -func getFanInFanOutGitResources(namespace string) []*v1alpha1.PipelineResource { +func getKritisGitResources(namespace string) []*v1alpha1.PipelineResource { return []*v1alpha1.PipelineResource{ tb.PipelineResource("kritis-resource-git", namespace, tb.PipelineResourceSpec( v1alpha1.PipelineResourceTypeGit, @@ -343,6 +352,7 @@ func getHelloWorldPipelineRun(suffix int, namespace string) *v1alpha1.PipelineRu return tb.PipelineRun(getName(pipelineRunName, suffix), namespace, tb.PipelineRunLabel("hello-world-key", "hello-world-value"), tb.PipelineRunSpec(getName(pipelineName, suffix), + tb.PipelineRunResourceBinding("resource", tb.PipelineResourceBindingRef("kritis-resource-git")), tb.PipelineRunServiceAccount(fmt.Sprintf("%s%d", saName, suffix)), ), )