From 4ed07fb67d11a875f10173a2a20e9149157b77ce Mon Sep 17 00:00:00 2001 From: Michael Scherer Date: Fri, 12 Nov 2021 12:56:57 +0100 Subject: [PATCH] Always create working directory when using compat API Docker/Moby always create the working directory, and some tools rely on that behavior (example, woodpecker/drone). Fixes #11842 Signed-off-by: Michael Scherer Signed-off-by: Matthew Heon --- pkg/api/handlers/compat/containers_create.go | 2 ++ pkg/specgen/generate/container_create.go | 3 +++ pkg/specgen/specgen.go | 4 ++++ test/python/docker/compat/test_containers.py | 14 ++++++++++++++ 4 files changed, 23 insertions(+) diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 94d20a04a3..1e175d664b 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -86,6 +86,8 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen")) return } + // moby always create the working directory + sg.CreateWorkingDir = true ic := abi.ContainerEngine{Libpod: runtime} report, err := ic.ContainerCreate(r.Context(), sg) diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index f82b2a3c6a..fc66145df1 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -333,6 +333,9 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen. if s.WorkDir == "" { s.WorkDir = "/" } + if s.CreateWorkingDir { + options = append(options, libpod.WithCreateWorkingDir()) + } if s.StopSignal != nil { options = append(options, libpod.WithStopSignal(*s.StopSignal)) } diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go index 0c30c498a1..50ef3f1970 100644 --- a/pkg/specgen/specgen.go +++ b/pkg/specgen/specgen.go @@ -264,6 +264,10 @@ type ContainerStorageConfig struct { // If unset, the default, /, will be used. // Optional. WorkDir string `json:"work_dir,omitempty"` + // Create the working directory if it doesn't exist. + // If unset, it doesn't create it. + // Optional. + CreateWorkingDir bool `json:"create_working_dir,omitempty"` // RootfsPropagation is the rootfs propagation mode for the container. // If not set, the default of rslave will be used. // Optional. diff --git a/test/python/docker/compat/test_containers.py b/test/python/docker/compat/test_containers.py index 1ad1e7f153..e6f7d992de 100644 --- a/test/python/docker/compat/test_containers.py +++ b/test/python/docker/compat/test_containers.py @@ -251,3 +251,17 @@ def test_mount_preexisting_dir(self): ctr.start() ret, out = ctr.exec_run(["stat", "-c", "%u:%g", "/workspace"]) self.assertEqual(out.rstrip(), b'1042:1043', "UID/GID set in dockerfile") + + + def test_non_existant_workdir(self): + dockerfile = (B'FROM quay.io/libpod/alpine:latest\n' + B'USER root\n' + B'WORKDIR /workspace/scratch\n' + B'RUN touch test') + img: Image + img, out = self.client.images.build(fileobj=io.BytesIO(dockerfile)) + ctr: Container = self.client.containers.create(image=img.id, detach=True, command="top", + volumes=["test_non_existant_workdir:/workspace"]) + ctr.start() + ret, out = ctr.exec_run(["stat", "/workspace/scratch/test"]) + self.assertEqual(ret, 0, "Working directory created if it doesn't exist")