diff --git a/workflow/controller/workflowpod.go b/workflow/controller/workflowpod.go index 5837793c7548..36a63ac3e70e 100644 --- a/workflow/controller/workflowpod.go +++ b/workflow/controller/workflowpod.go @@ -702,6 +702,11 @@ func (woc *wfOperationCtx) addInputArtifactsVolumes(pod *apiv1.Pod, tmpl *wfv1.T if art.Path == "" { return errors.Errorf(errors.CodeBadRequest, "inputs.artifacts.%s did not specify a path", art.Name) } + if !art.HasLocation() && art.Optional { + woc.log.Infof("skip volume mount of %s (%s): optional artifact was not provided", + art.Name, art.Path) + continue + } overlap := common.FindOverlappingVolume(tmpl, art.Path) if overlap != nil { // artifact path overlaps with a mounted volume. do not mount the diff --git a/workflow/controller/workflowpod_test.go b/workflow/controller/workflowpod_test.go index 56a3770d3106..a6e7e5c11176 100644 --- a/workflow/controller/workflowpod_test.go +++ b/workflow/controller/workflowpod_test.go @@ -77,6 +77,65 @@ func TestScriptTemplateWithVolume(t *testing.T) { assert.NoError(t, err) } +var scriptTemplateWithOptionalInputArtifactProvided = ` +name: script-with-input-artifact +inputs: + artifacts: + - name: manifest + path: /manifest + optional: true + http: + url: https://raw.githubusercontent.com/argoproj/argo/stable/manifests/install.yaml +script: + image: alpine:latest + command: [sh] + source: | + ls -al +` + +var scriptTemplateWithOptionalInputArtifactNotProvided = ` +name: script-with-input-artifact +inputs: + artifacts: + - name: manifest + path: /manifest + optional: true +script: + image: alpine:latest + command: [sh] + source: | + ls -al +` +// TestScriptTemplateWithVolume ensure we can a script pod with input artifacts +func TestScriptTemplateWithoutVolumeOptionalArtifact(t *testing.T) { + volumeMount := apiv1.VolumeMount{ + Name: "input-artifacts", + ReadOnly: false, + MountPath: "/manifest", + SubPath: "manifest", + MountPropagation: nil, + SubPathExpr: "", + } + + // Ensure that volume mount is added when artifact is provided + tmpl := unmarshalTemplate(scriptTemplateWithOptionalInputArtifactProvided) + woc := newWoc() + mainCtr := tmpl.Script.Container + mainCtr.Args = append(mainCtr.Args, common.ExecutorScriptSourcePath) + pod, err := woc.createWorkflowPod(tmpl.Name, mainCtr, tmpl, true) + assert.NoError(t, err) + assert.Contains(t, pod.Spec.Containers[1].VolumeMounts, volumeMount) + + // Ensure that volume mount is not created when artifact is not provided + tmpl = unmarshalTemplate(scriptTemplateWithOptionalInputArtifactNotProvided) + woc = newWoc() + mainCtr = tmpl.Script.Container + mainCtr.Args = append(mainCtr.Args, common.ExecutorScriptSourcePath) + pod, err = woc.createWorkflowPod(tmpl.Name, mainCtr, tmpl, true) + assert.NoError(t, err) + assert.NotContains(t, pod.Spec.Containers[1].VolumeMounts, volumeMount) +} + // TestWFLevelServiceAccount verifies the ability to carry forward the service account name // for the pod from workflow.spec.serviceAccountName. func TestWFLevelServiceAccount(t *testing.T) {