From f5fd4de15ef8e62332cb814c2b3218129953e36c Mon Sep 17 00:00:00 2001 From: Michael Scherer Date: Sat, 13 Nov 2021 19:18:57 +0100 Subject: [PATCH] Download image when starting a container using the compat API Docker/moby will automatically pull images when using the API (or the CLI, for that matter) to create a container, but podman don't. This break the compatibility with some software. --- pkg/api/handlers/compat/containers_create.go | 18 +++++++++++++----- test/python/docker/compat/test_containers.py | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go index 1e175d664b..d0a3a0fa28 100644 --- a/pkg/api/handlers/compat/containers_create.go +++ b/pkg/api/handlers/compat/containers_create.go @@ -4,6 +4,7 @@ import ( "encoding/json" "net/http" + "github.com/containers/common/pkg/config" "github.com/containers/podman/v3/cmd/podman/common" "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/pkg/api/handlers" @@ -54,13 +55,20 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) { newImage, resolvedName, err := runtime.LibimageRuntime().LookupImage(body.Config.Image, nil) if err != nil { - if errors.Cause(err) == storage.ErrImageUnknown { - utils.Error(w, "No such image", http.StatusNotFound, err) + if errors.Cause(err) != storage.ErrImageUnknown { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error looking up image")) + return + } + _, err = runtime.LibimageRuntime().Pull(r.Context(), body.Config.Image, config.PullPolicyAlways, nil) + if err != nil { + utils.Error(w, "No such image", http.StatusNotFound, errors.Wrap(err, "Cannot pull image")) + return + } + newImage, resolvedName, err = runtime.LibimageRuntime().LookupImage(body.Config.Image, nil) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error looking up image after pulling")) return } - - utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "error looking up image")) - return } // Take body structure and convert to cliopts diff --git a/test/python/docker/compat/test_containers.py b/test/python/docker/compat/test_containers.py index e6f7d992de..5aa173e218 100644 --- a/test/python/docker/compat/test_containers.py +++ b/test/python/docker/compat/test_containers.py @@ -265,3 +265,19 @@ def test_non_existant_workdir(self): ctr.start() ret, out = ctr.exec_run(["stat", "/workspace/scratch/test"]) self.assertEqual(ret, 0, "Working directory created if it doesn't exist") + + def test_non_local_image(self): + self.assertEqual(len(self.client.images.list(filters={"reference": "alpine"})), 1) + + for c in self.client.containers.list(all=True): + c.remove(force=True) + + self.client.images.remove(constant.ALPINE) + + self.assertEqual(len(self.client.images.list(filters={"reference": "alpine"})), 0) + + ctr: Container = self.client.containers.create(image=constant.ALPINE, detach=True, + name="non_local", command="top") + ctr.start() + + self.assertEqual(len(self.client.images.list(filters={"reference": "alpine"})), 1)