From a93298d4dbea0158a51ed5d1901a7e8be7d2e07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Thu, 29 Jun 2023 15:38:08 +0200 Subject: [PATCH] c8d/prune: Exclude dangling tag of the images used by containers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Paweł Gronowski --- daemon/containerd/image_prune.go | 3 +++ integration/image/prune_test.go | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 integration/image/prune_test.go diff --git a/daemon/containerd/image_prune.go b/daemon/containerd/image_prune.go index 7864cda4a0..abe9047997 100644 --- a/daemon/containerd/image_prune.go +++ b/daemon/containerd/image_prune.go @@ -95,6 +95,9 @@ func (i *ImageService) pruneUnused(ctx context.Context, filterFunc imageFilterFu var errs error // Exclude images used by existing containers for _, ctr := range containers { + // If the original image was deleted, make sure we don't delete the dangling image + delete(imagesToPrune, danglingImageName(ctr.ImageID.Digest())) + // Config.Image is the image reference passed by user. // For example: container created by `docker run alpine` will have Image="alpine" // Warning: This doesn't handle truncated ids: diff --git a/integration/image/prune_test.go b/integration/image/prune_test.go new file mode 100644 index 0000000000..48fb07ce6f --- /dev/null +++ b/integration/image/prune_test.go @@ -0,0 +1,33 @@ +package image + +import ( + "context" + "testing" + + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/integration/internal/container" + "github.com/docker/docker/testutil/environment" + "gotest.tools/v3/assert" + is "gotest.tools/v3/assert/cmp" + "gotest.tools/v3/skip" +) + +// Regression test for: https://github.com/moby/moby/issues/45732 +func TestPruneDontDeleteUsedDangling(t *testing.T) { + skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME: hack/make/.build-empty-images doesn't run on Windows") + + defer setupTest(t)() + client := testEnv.APIClient() + ctx := context.Background() + + danglingID := environment.GetTestDanglingImageId(testEnv) + + container.Create(ctx, t, client, + container.WithImage(danglingID), + container.WithCmd("sleep", "60")) + + pruned, err := client.ImagesPrune(ctx, filters.NewArgs(filters.Arg("dangling", "true"))) + + assert.NilError(t, err) + assert.Check(t, is.Len(pruned.ImagesDeleted, 0)) +}