diff --git a/internal/runtime/kubernetes/resources.go b/internal/runtime/kubernetes/resources.go index 10b0ad8..631f9cf 100644 --- a/internal/runtime/kubernetes/resources.go +++ b/internal/runtime/kubernetes/resources.go @@ -41,25 +41,42 @@ const ( registryConfigEnvName = "DRUID_RUNTIME_REGISTRY_CONFIG_JSON" registryConfigSecretKey = "config.json" registryConfigScript = `printf '%s' "$DRUID_RUNTIME_REGISTRY_CONFIG_JSON" > /tmp/druid-registry.json && exec druid --config /tmp/druid-registry.json "$@"` + workerPullRootEnvName = "DRUID_WORKER_ROOT" + workerPullScript = `set -eu +if [ -n "${DRUID_RUNTIME_REGISTRY_CONFIG_JSON:-}" ]; then + printf '%s' "$DRUID_RUNTIME_REGISTRY_CONFIG_JSON" > /tmp/druid-registry.json + druid --config /tmp/druid-registry.json "$@" +else + druid "$@" +fi +chown -R 1000:1000 "$DRUID_WORKER_ROOT"` ) func workerPullJobSpec(namespace string, jobName string, pvc string, image string, action ports.RuntimeWorkerAction, imagePullSecret string, registryConfigSecret string, registryPlainHTTP bool) *batchv1.Job { command := []string{ - "druid", "worker", "pull", + "sh", "-c", workerPullScript, "druid-worker-pull", + "worker", "pull", "--artifact", action.Artifact, "--runtime-id", action.RuntimeID, "--mode", string(action.Mode), "--root", action.MountPath, "--callback-url", action.CallbackURL, } - if registryConfigSecret != "" { - command = append([]string{"sh", "-c", registryConfigScript, "sh"}, command[1:]...) - } job := helperJobSpec(namespace, jobName, pvc, image, command, imagePullSecret, map[string]string{ labelComponent: "worker-pull", }) container := &job.Spec.Template.Spec.Containers[0] - container.Env = append(container.Env, corev1.EnvVar{Name: "DRUID_WORKER_TOKEN", Value: action.CallbackToken}) + runAsRoot := int64(0) + runAsNonRoot := false + container.SecurityContext = &corev1.SecurityContext{ + RunAsUser: &runAsRoot, + RunAsGroup: &runAsRoot, + RunAsNonRoot: &runAsNonRoot, + } + container.Env = append(container.Env, + corev1.EnvVar{Name: "DRUID_WORKER_TOKEN", Value: action.CallbackToken}, + corev1.EnvVar{Name: workerPullRootEnvName, Value: action.MountPath}, + ) if registryConfigSecret != "" { container.Env = append(container.Env, corev1.EnvVar{ Name: registryConfigEnvName, diff --git a/internal/runtime/kubernetes/resources_test.go b/internal/runtime/kubernetes/resources_test.go index 386b95b..ba0d5f8 100644 --- a/internal/runtime/kubernetes/resources_test.go +++ b/internal/runtime/kubernetes/resources_test.go @@ -213,7 +213,7 @@ func TestWorkerPullJobSpecRunsDruidWorkerPull(t *testing.T) { job := workerPullJobSpec("druid", "worker-pull", "runtime-pvc", "druid-cli:test", action, "pull-secret", "runtime-registry", true) container := job.Spec.Template.Spec.Containers[0] command := strings.Join(container.Command, " ") - for _, want := range []string{"druid --config /tmp/druid-registry.json", "worker pull", "--mode update", "--runtime-id deployment-123", "--callback-url"} { + for _, want := range []string{"druid --config /tmp/druid-registry.json", "worker pull", "--mode update", "--runtime-id deployment-123", "--callback-url", "chown -R 1000:1000"} { if !strings.Contains(command, want) { t.Fatalf("command = %#v, want %s", container.Command, want) } @@ -228,6 +228,18 @@ func TestWorkerPullJobSpecRunsDruidWorkerPull(t *testing.T) { if env["DRUID_WORKER_TOKEN"] != "secret-token" || env["DRUID_REGISTRY_PLAIN_HTTP"] != "true" { t.Fatalf("env = %#v", container.Env) } + if env[workerPullRootEnvName] != "/scroll" { + t.Fatalf("%s = %q, want /scroll", workerPullRootEnvName, env[workerPullRootEnvName]) + } + if container.SecurityContext == nil || container.SecurityContext.RunAsUser == nil || *container.SecurityContext.RunAsUser != 0 { + t.Fatalf("worker pull must run as root to repair PVC ownership, securityContext = %#v", container.SecurityContext) + } + if container.SecurityContext.RunAsGroup == nil || *container.SecurityContext.RunAsGroup != 0 { + t.Fatalf("worker pull runAsGroup = %#v, want 0", container.SecurityContext.RunAsGroup) + } + if container.SecurityContext.RunAsNonRoot == nil || *container.SecurityContext.RunAsNonRoot { + t.Fatalf("worker pull runAsNonRoot = %#v, want false", container.SecurityContext.RunAsNonRoot) + } if len(job.Spec.Template.Spec.ImagePullSecrets) != 1 || job.Spec.Template.Spec.ImagePullSecrets[0].Name != "pull-secret" { t.Fatalf("image pull secrets = %#v", job.Spec.Template.Spec.ImagePullSecrets) }