Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/reconciler/buildrun/resources/image_processing.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func SetupImageProcessing(taskRun *pipelineapi.TaskRun, cfg *config.Config, crea
Value: "/trivy-cache-data",
})
// add the writeable volumes
sources.AppendWriteableVolumes(taskRun.Spec.TaskSpec, &imageProcessingStep)
sources.SetupHomeAndTmpVolumes(taskRun.Spec.TaskSpec, &imageProcessingStep)
// append the mutate step
taskRun.Spec.TaskSpec.Steps = append(taskRun.Spec.TaskSpec.Steps, imageProcessingStep)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/reconciler/buildrun/resources/sources/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func AppendBundleStep(cfg *config.Config, taskSpec *pipelineapi.TaskSpec, oci *b
if oci.Prune != nil && *oci.Prune == build.PruneAfterPull {
bundleStep.Args = append(bundleStep.Args, "--prune")
}

SetupHomeAndTmpVolumes(taskSpec, &bundleStep)
taskSpec.Steps = append(taskSpec.Steps, bundleStep)
}

Expand Down
1 change: 1 addition & 0 deletions pkg/reconciler/buildrun/resources/sources/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func AppendGitStep(
)
}

SetupHomeAndTmpVolumes(taskSpec, &gitStep)
// append the git step
taskSpec.Steps = append(taskSpec.Steps, gitStep)
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/reconciler/buildrun/resources/sources/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ var _ = Describe("Git", func() {
})

It("adds a volume for the secret", func() {
Expect(len(taskSpec.Volumes)).To(Equal(1))
Expect(len(taskSpec.Volumes)).To(Equal(3))
Expect(taskSpec.Volumes[0].Name).To(Equal("shp-a-secret"))
Expect(taskSpec.Volumes[0].VolumeSource.Secret).NotTo(BeNil())
Expect(taskSpec.Volumes[0].VolumeSource.Secret.SecretName).To(Equal("a.secret"))
Expand All @@ -100,7 +100,7 @@ var _ = Describe("Git", func() {
"--result-file-source-timestamp", "$(results.shp-source-default-source-timestamp.path)",
"--secret-path", "/workspace/shp-source-secret",
}))
Expect(len(taskSpec.Steps[0].VolumeMounts)).To(Equal(1))
Expect(len(taskSpec.Steps[0].VolumeMounts)).To(Equal(3))
Expect(taskSpec.Steps[0].VolumeMounts[0].Name).To(Equal("shp-a-secret"))
Expect(taskSpec.Steps[0].VolumeMounts[0].MountPath).To(Equal("/workspace/shp-source-secret"))
Expect(taskSpec.Steps[0].VolumeMounts[0].ReadOnly).To(BeTrue())
Expand Down Expand Up @@ -188,7 +188,7 @@ var _ = Describe("Git", func() {
Revision: ptr.To(revision),
CloneSecret: ptr.To("another.secret"),
}, "default")

Expect(len(taskSpec.Steps)).To(Equal(1))
Expect(taskSpec.Steps[0].Args).To(ContainElements(
"--url", "https://github.com/shipwright-io/another-repo",
Expand All @@ -200,4 +200,4 @@ var _ = Describe("Git", func() {
Expect(taskSpec.Steps[0].VolumeMounts).To(ContainElement(HaveField("Name", "shp-another-secret")))
})
})
})
})
1 change: 1 addition & 0 deletions pkg/reconciler/buildrun/resources/sources/local_copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ func AppendLocalCopyStep(cfg *config.Config, taskSpec *pipelineapi.TaskSpec, tim
if timeout != nil {
step.Args = append(step.Args, fmt.Sprintf("--timeout=%s", timeout.Duration.String()))
}
SetupHomeAndTmpVolumes(taskSpec, &step)
taskSpec.Steps = append(taskSpec.Steps, step)
}
16 changes: 13 additions & 3 deletions pkg/reconciler/buildrun/resources/sources/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ func FindResultValue(results []pipelineapi.TaskRunResult, sourceName, resultName
return ""
}

// AppendWriteableVolumes configures writable volumes for a specific step in a Tekton Task.
// It ensures that these volumes are not shared with other steps in the same pod.
func AppendWriteableVolumes(
// SetupHomeAndTmpVolumes creates writeable `emptyDir` volumes for the task step's `HOME` and `TMPDIR`
// locations, mounts them to well-known locations, and sets the appropriate environment variable values.
func SetupHomeAndTmpVolumes(
taskSpec *pipelineapi.TaskSpec,
targetStep *pipelineapi.Step,
) {
Expand All @@ -105,6 +105,16 @@ func AppendWriteableVolumes(
)
// Point the TMPDIR environment variable to the custom path.
setEnvVar(targetStep, "TMPDIR", tmpDir)

// Define a custom, isolated path for the home directory and mount it.
writeableHomeMountPath := "/shp-writable-home"
addStepEmptyDirVolume(
taskSpec,
targetStep,
generateVolumeName("shp-home-", targetStep.Name),
writeableHomeMountPath,
)
setEnvVar(targetStep, "HOME", writeableHomeMountPath)
}

// generateVolumeName creates a unique, DNS-1123 compliant volume name for a step.
Expand Down
123 changes: 123 additions & 0 deletions pkg/reconciler/buildrun/resources/sources/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,127 @@ var _ = Describe("Utils", func() {
Expect(len(taskSpec.Volumes)).To(Equal(1))
})
})

Context("SetupHomeAndTmpVolumes", func() {
var taskSpec *pipelineapi.TaskSpec
var targetStep *pipelineapi.Step

BeforeEach(func() {
taskSpec = &pipelineapi.TaskSpec{}
targetStep = &pipelineapi.Step{
Name: "test-step",
Env: []corev1.EnvVar{},
}
})

It("creates volumes and mounts for HOME and TMPDIR", func() {
sources.SetupHomeAndTmpVolumes(taskSpec, targetStep)

// Verify that two volumes were created
Expect(len(taskSpec.Volumes)).To(Equal(2))

// Verify volume types are EmptyDir
Expect(taskSpec.Volumes[0].VolumeSource.EmptyDir).NotTo(BeNil())
Expect(taskSpec.Volumes[1].VolumeSource.EmptyDir).NotTo(BeNil())

// Verify volume names start with expected prefixes
Expect(taskSpec.Volumes[0].Name).To(ContainSubstring("shp-tmp-"))
Expect(taskSpec.Volumes[1].Name).To(ContainSubstring("shp-home-"))

// Verify volume mounts were added to the step
Expect(len(targetStep.VolumeMounts)).To(Equal(2))

// Verify mount paths
Expect(targetStep.VolumeMounts[0].MountPath).To(Equal("/shp-tmp"))
Expect(targetStep.VolumeMounts[1].MountPath).To(Equal("/shp-writable-home"))

// Verify environment variables were set
Expect(len(targetStep.Env)).To(Equal(2))
Expect(targetStep.Env[0].Name).To(Equal("TMPDIR"))
Expect(targetStep.Env[0].Value).To(Equal("/shp-tmp"))
Expect(targetStep.Env[1].Name).To(Equal("HOME"))
Expect(targetStep.Env[1].Value).To(Equal("/shp-writable-home"))
})

It("overrides existing environment variables", func() {
// Set up existing environment variables
targetStep.Env = []corev1.EnvVar{
{Name: "HOME", Value: "/original/home"},
{Name: "TMPDIR", Value: "/original/tmp"},
{Name: "OTHER_VAR", Value: "other-value"},
}

sources.SetupHomeAndTmpVolumes(taskSpec, targetStep)

// Verify that existing env vars were overridden
Expect(len(targetStep.Env)).To(Equal(3))
// The original order is preserved, but values are overridden
Expect(targetStep.Env[0].Name).To(Equal("HOME"))
Expect(targetStep.Env[0].Value).To(Equal("/shp-writable-home"))
Expect(targetStep.Env[1].Name).To(Equal("TMPDIR"))
Expect(targetStep.Env[1].Value).To(Equal("/shp-tmp"))
Expect(targetStep.Env[2].Name).To(Equal("OTHER_VAR"))
Expect(targetStep.Env[2].Value).To(Equal("other-value"))
})

It("does not duplicate volumes when called multiple times", func() {
// Call the function twice
sources.SetupHomeAndTmpVolumes(taskSpec, targetStep)
sources.SetupHomeAndTmpVolumes(taskSpec, targetStep)

// Should still only have 2 volumes
Expect(len(taskSpec.Volumes)).To(Equal(2))
Expect(len(targetStep.VolumeMounts)).To(Equal(2))
})

It("handles step names with special characters", func() {
targetStep.Name = "step-with.special@chars!"

sources.SetupHomeAndTmpVolumes(taskSpec, targetStep)

// Verify volumes were created despite special characters
Expect(len(taskSpec.Volumes)).To(Equal(2))
Expect(len(targetStep.VolumeMounts)).To(Equal(2))

// Verify environment variables are still set correctly
Expect(targetStep.Env[0].Name).To(Equal("TMPDIR"))
Expect(targetStep.Env[0].Value).To(Equal("/shp-tmp"))
Expect(targetStep.Env[1].Name).To(Equal("HOME"))
Expect(targetStep.Env[1].Value).To(Equal("/shp-writable-home"))
})

It("works with existing volumes in TaskSpec", func() {
// Add an existing volume
taskSpec.Volumes = []corev1.Volume{
{
Name: "existing-volume",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
},
}

sources.SetupHomeAndTmpVolumes(taskSpec, targetStep)

// Should have 3 volumes total (1 existing + 2 new)
Expect(len(taskSpec.Volumes)).To(Equal(3))
Expect(len(targetStep.VolumeMounts)).To(Equal(2))
})

It("works with existing volume mounts in step", func() {
// Add an existing volume mount
targetStep.VolumeMounts = []corev1.VolumeMount{
{
Name: "existing-mount",
MountPath: "/existing/path",
},
}

sources.SetupHomeAndTmpVolumes(taskSpec, targetStep)

// Should have 3 volume mounts total (1 existing + 2 new)
Expect(len(targetStep.VolumeMounts)).To(Equal(3))
Expect(len(taskSpec.Volumes)).To(Equal(2))
})
})
})