Skip to content

Commit

Permalink
Initialize working dirs inside workspace dir
Browse files Browse the repository at this point in the history
In order to allow steps to define workingDirs that are subdirectories of the workspace directory we need to make sure they have been created first since they will not exist on startup.

Fixes tektoncd#725
  • Loading branch information
dicarlo2 committed May 3, 2019
1 parent b208a72 commit 2f3691e
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
48 changes: 48 additions & 0 deletions pkg/reconciler/v1alpha1/taskrun/resources/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,14 @@ const (
unnamedInitContainerPrefix = "build-step-unnamed-"
// Name of the credential initialization container.
credsInit = "credential-initializer"
// Name of the working dir initialization container.
workingDirInit = "working-dir-initializer"
)

var (
// The container used to initialize working directories before the build runs.
bashWorkingDirImage = flag.String("bash-working-dir-image", "override-with-bash-noop:latest",
"The container image for preparing our Build's working directories.")
// The container used to initialize credentials before the build runs.
credsImage = flag.String("creds-image", "override-with-creds:latest",
"The container image for preparing our Build's credentials.")
Expand Down Expand Up @@ -162,6 +167,45 @@ func makeCredentialInitializer(serviceAccountName, namespace string, kubeclient
}, volumes, nil
}

func makeWorkingDirScript(workingDirs map[string]bool) string {
script := ""
for wd := range workingDirs {
if wd != "" {
p := filepath.Clean(wd)
if rel, err := filepath.Rel(workspaceDir, p); err == nil && !strings.HasPrefix(rel, ".") {
if script == "" {
script = fmt.Sprintf("mkdir -p %s", p)
} else {
script = fmt.Sprintf("%s %s", script, p)
}
}
}
}

return script
}

func makeWorkingDirInitializer(steps []corev1.Container) *corev1.Container {
workingDirs := make(map[string]bool)
for _, step := range steps {
workingDirs[step.WorkingDir] = true
}

if script := makeWorkingDirScript(workingDirs); script != "" {
return &corev1.Container{
Name: names.SimpleNameGenerator.RestrictLengthWithRandomSuffix(containerPrefix + workingDirInit),
Image: *bashWorkingDirImage,
Command: []string{"/ko-app/bash"},
Args: []string{"-args", script},
VolumeMounts: implicitVolumeMounts,
Env: implicitEnvVars,
WorkingDir: workspaceDir,
}
}

return nil
}

// GetPod returns the Pod for the given pod name
type GetPod func(string, metav1.GetOptions) (*corev1.Pod, error)

Expand Down Expand Up @@ -197,6 +241,10 @@ func MakePod(taskRun *v1alpha1.TaskRun, taskSpec v1alpha1.TaskSpec, kubeclient k
initContainers := []corev1.Container{*cred}
podContainers := []corev1.Container{}

if workingDir := makeWorkingDirInitializer(taskSpec.Steps); workingDir != nil {
initContainers = append(initContainers, *workingDir)
}

maxIndicesByResource := findMaxResourceRequest(taskSpec.Steps, corev1.ResourceCPU, corev1.ResourceMemory, corev1.ResourceEphemeralStorage)

for i := range taskSpec.Steps {
Expand Down
73 changes: 73 additions & 0 deletions pkg/reconciler/v1alpha1/taskrun/resources/pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package resources
import (
"crypto/rand"
"fmt"
"path/filepath"
"strings"
"testing"

Expand Down Expand Up @@ -314,6 +315,52 @@ func TestMakePod(t *testing.T) {
},
Volumes: implicitVolumes,
},
}, {
desc: "working-dir-in-workspace-dir",
ts: v1alpha1.TaskSpec{
Steps: []corev1.Container{{
Name: "name",
Image: "image",
WorkingDir: filepath.Join(workspaceDir, "test"),
}},
},
want: &corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyNever,
InitContainers: []corev1.Container{{
Name: containerPrefix + credsInit + "-9l9zj",
Image: *credsImage,
Command: []string{"/ko-app/creds-init"},
Args: []string{},
Env: implicitEnvVars,
VolumeMounts: implicitVolumeMounts,
WorkingDir: workspaceDir,
}, {
Name: containerPrefix + workingDirInit + "-mz4c7",
Image: *bashWorkingDirImage,
Command: []string{"/ko-app/bash"},
Args: []string{"-args", fmt.Sprintf("mkdir -p %s", filepath.Join(workspaceDir, "test"))},
Env: implicitEnvVars,
VolumeMounts: implicitVolumeMounts,
WorkingDir: workspaceDir,
}},
Containers: []corev1.Container{{
Name: "build-step-name",
Image: "image",
Env: implicitEnvVars,
VolumeMounts: implicitVolumeMounts,
WorkingDir: filepath.Join(workspaceDir, "test"),
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("0"),
corev1.ResourceMemory: resource.MustParse("0"),
corev1.ResourceEphemeralStorage: resource.MustParse("0"),
},
},
},
nopContainer,
},
Volumes: implicitVolumes,
},
}} {
t.Run(c.desc, func(t *testing.T) {
names.TestingSeed()
Expand Down Expand Up @@ -374,3 +421,29 @@ func TestMakePod(t *testing.T) {
})
}
}

func TestMakeWorkingDirScript(t *testing.T) {
for _, c := range []struct {
desc string
workingDirs map[string]bool
want string
}{{
desc: "default",
workingDirs: map[string]bool{"/workspace": true},
want: "",
}, {
desc: "simple",
workingDirs: map[string]bool{"/workspace/foo": true, "/workspace/bar": true, "/baz": true},
want: "mkdir -p /workspace/foo /workspace/bar",
}, {
desc: "empty",
workingDirs: map[string]bool{"/workspace": true, "": true, "/baz": true, "/workspacedir": true},
want: "",
}} {
t.Run(c.desc, func(t *testing.T) {
if script := makeWorkingDirScript(c.workingDirs); script != c.want {
t.Errorf("Expected `%v`, got `%v`", c.want, script)
}
})
}
}

0 comments on commit 2f3691e

Please sign in to comment.