From c902e1a18701ac8e903314c688564e59cd1be997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Gronowski?= Date: Mon, 28 Oct 2024 10:12:39 +0100 Subject: [PATCH] c8d/inspect: Fix duplicate RepoDigests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multiple images with the same repository name but different tag caused the `RepoDigests` to contain duplicated entries for each of the image. Deduplicate the slice before setting the `RepoDigests` field. Signed-off-by: Paweł Gronowski (cherry picked from commit ba454f573b02922340761c0d44687c0b5daa60a6) Signed-off-by: Paweł Gronowski --- daemon/containerd/image.go | 3 ++- daemon/containerd/image_list.go | 3 ++- integration/image/inspect_test.go | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/daemon/containerd/image.go b/daemon/containerd/image.go index 72fe786ccd954..c43ceb3d26458 100644 --- a/daemon/containerd/image.go +++ b/daemon/containerd/image.go @@ -19,6 +19,7 @@ import ( "github.com/docker/docker/daemon/images" "github.com/docker/docker/errdefs" "github.com/docker/docker/image" + "github.com/docker/docker/internal/sliceutil" imagespec "github.com/moby/docker-image-spec/specs-go/v1" "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" @@ -109,7 +110,7 @@ func (i *ImageService) GetImage(ctx context.Context, refOrID string, options bac } img.Details = &image.Details{ - References: refs, + References: sliceutil.Dedup(refs), Size: size, Metadata: nil, Driver: i.snapshotter, diff --git a/daemon/containerd/image_list.go b/daemon/containerd/image_list.go index a66e8476b19ff..f9818e7d9a403 100644 --- a/daemon/containerd/image_list.go +++ b/daemon/containerd/image_list.go @@ -22,6 +22,7 @@ import ( imagetypes "github.com/docker/docker/api/types/image" timetypes "github.com/docker/docker/api/types/time" "github.com/docker/docker/errdefs" + "github.com/docker/docker/internal/sliceutil" "github.com/moby/buildkit/util/attestation" dockerspec "github.com/moby/docker-image-spec/specs-go/v1" "github.com/opencontainers/go-digest" @@ -501,7 +502,7 @@ func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore con summary := &imagetypes.Summary{ ParentID: rawImg.Labels[imageLabelClassicBuilderParent], ID: target.String(), - RepoDigests: repoDigests, + RepoDigests: sliceutil.Dedup(repoDigests), RepoTags: repoTags, Size: totalSize, Labels: cfg.Config.Labels, diff --git a/integration/image/inspect_test.go b/integration/image/inspect_test.go index e512ed6ce8eb1..1668fb937e1bf 100644 --- a/integration/image/inspect_test.go +++ b/integration/image/inspect_test.go @@ -4,6 +4,7 @@ import ( "encoding/json" "testing" + "github.com/docker/docker/api/types/image" "github.com/docker/docker/internal/testutils/specialimage" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -34,3 +35,27 @@ func TestImageInspectEmptyTagsAndDigests(t *testing.T) { assert.Check(t, is.Len(rawJson["RepoTags"], 0)) assert.Check(t, is.Len(rawJson["RepoDigests"], 0)) } + +// Regression test for: https://github.com/moby/moby/issues/48747 +func TestImageInspectUniqueRepoDigests(t *testing.T) { + ctx := setupTest(t) + + client := testEnv.APIClient() + + before, _, err := client.ImageInspectWithRaw(ctx, "busybox") + assert.NilError(t, err) + + for _, tag := range []string{"master", "newest"} { + imgName := "busybox:" + tag + err := client.ImageTag(ctx, "busybox", imgName) + assert.NilError(t, err) + defer func() { + _, _ = client.ImageRemove(ctx, imgName, image.RemoveOptions{Force: true}) + }() + } + + after, _, err := client.ImageInspectWithRaw(ctx, "busybox") + assert.NilError(t, err) + + assert.Check(t, is.Len(after.RepoDigests, len(before.RepoDigests))) +}