Skip to content

Commit ba454f5

Browse files
committed
c8d/inspect: Fix duplicate RepoDigests
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 <[email protected]>
1 parent 56445e1 commit ba454f5

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

daemon/containerd/image_inspect.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/docker/docker/api/types/backend"
1414
imagetypes "github.com/docker/docker/api/types/image"
1515
"github.com/docker/docker/api/types/storage"
16+
"github.com/docker/docker/internal/sliceutil"
1617
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
1718
"golang.org/x/sync/semaphore"
1819
)
@@ -103,7 +104,7 @@ func (i *ImageService) ImageInspect(ctx context.Context, refOrID string, _ backe
103104
return &imagetypes.InspectResponse{
104105
ID: img.ImageID(),
105106
RepoTags: repoTags,
106-
RepoDigests: repoDigests,
107+
RepoDigests: sliceutil.Dedup(repoDigests),
107108
Parent: img.Parent.String(),
108109
Comment: comment,
109110
Created: created,

integration/image/inspect_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/json"
55
"testing"
66

7+
"github.com/docker/docker/api/types/image"
78
"github.com/docker/docker/internal/testutils/specialimage"
89
"gotest.tools/v3/assert"
910
is "gotest.tools/v3/assert/cmp"
@@ -34,3 +35,27 @@ func TestImageInspectEmptyTagsAndDigests(t *testing.T) {
3435
assert.Check(t, is.Len(rawJson["RepoTags"], 0))
3536
assert.Check(t, is.Len(rawJson["RepoDigests"], 0))
3637
}
38+
39+
// Regression test for: https://github.com/moby/moby/issues/48747
40+
func TestImageInspectUniqueRepoDigests(t *testing.T) {
41+
ctx := setupTest(t)
42+
43+
client := testEnv.APIClient()
44+
45+
before, _, err := client.ImageInspectWithRaw(ctx, "busybox")
46+
assert.NilError(t, err)
47+
48+
for _, tag := range []string{"master", "newest"} {
49+
imgName := "busybox:" + tag
50+
err := client.ImageTag(ctx, "busybox", imgName)
51+
assert.NilError(t, err)
52+
defer func() {
53+
_, _ = client.ImageRemove(ctx, imgName, image.RemoveOptions{Force: true})
54+
}()
55+
}
56+
57+
after, _, err := client.ImageInspectWithRaw(ctx, "busybox")
58+
assert.NilError(t, err)
59+
60+
assert.Check(t, is.Len(after.RepoDigests, len(before.RepoDigests)))
61+
}

0 commit comments

Comments
 (0)