8000 [27.x backport] c8d/list: Don't exclude non-container images by vvoland · Pull Request #48402 · moby/moby · GitHub
[go: up one dir, main page]

Skip to content
Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions daemon/containerd/image_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,17 +393,25 @@ func (i *ImageService) imageSummary(ctx context.Context, img images.Image, platf
"error": err,
"image": img.Name,
}).Warn("unexpected image target (neither a manifest nor index)")
return nil, nil, nil
} else {
return nil, nil, err
}
return nil, nil, err
}

if best == nil {
// TODO we should probably show *something* for images we've pulled
// but are 100% shallow or an empty manifest list/index
// ("tianon/scratch:index" is an empty example image index and
// "tianon/scratch:list" is an empty example manifest list)
return nil, nil, nil
target := img.Target
return &imagetypes.Summary{
ID: target.Digest.String(),
RepoDigests: []string{target.Digest.String()},
RepoTags: tagsByDigest[target.Digest],
Size: totalSize,
// -1 indicates that the value has not been set (avoids ambiguity
// between 0 (default) and "not set". We cannot use a pointer (nil)
// for this, as the JSON representation uses "omitempty", which would
// consider both "0" and "nil" to be "empty".
SharedSize: -1,
Containers: -1,
}, nil, nil
}

image, err := i.singlePlatformImage(ctx, i.content, tagsByDigest[best.RealTarget.Digest], best)
Expand Down
27 changes: 24 additions & 3 deletions daemon/containerd/image_list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"math/rand"
"os"
"path/filepath"
"slices"
"sort"
"strconv"
"testing"
Expand Down Expand Up @@ -206,6 +207,9 @@ func TestImageList(t *testing.T) {
configTarget, err := specialimage.ConfigTarget(blobsDir)
assert.NilError(t, err)

textplain, err := specialimage.TextPlain(blobsDir)
assert.NilError(t, err)

cs := &blobsDirContentStore{blobs: filepath.Join(blobsDir, "blobs/sha256")}

for _, tc := range []struct {
10BC0 Expand Down Expand Up @@ -276,17 +280,34 @@ func TestImageList(t *testing.T) {
name: "three images, one is an empty index",
images: imagesFromIndex(multilayer, emptyIndex, twoplatform),
check: func(t *testing.T, all []*imagetypes.Summary) {
assert.Check(t, is.Len(all, 2))
assert.Check(t, is.Len(all, 3))
},
},
{
// Make sure an invalid image target doesn't break the whole operation
name: "one good image, second has config as a target",
images: imagesFromIndex(multilayer, configTarget),
check: func(t *testing.T, all []*imagetypes.Summary) {
assert.Check(t, is.Len(all, 1))
assert.Check(t, is.Len(all, 2))

sort.Slice(all, func(i, j int) bool {
return slices.Contains(all[i].RepoTags, "multilayer:latest")
})

assert.Check(t, is.Equal(all[0].ID, multilayer.Manifests[0].Digest.String()))
assert.Check(t, is.Len(all[0].Manifests, 1))

assert.Check(t, is.Equal(all[1].ID, configTarget.Manifests[0].Digest.String()))
assert.Check(t, is.Len(all[1].Manifests, 0))
},
},
{
name: "a non-container image manifest",
images: imagesFromIndex(textplain),
check: func(t *testing.T, all []*imagetypes.Summary) {
assert.Check(t, is.Len(all, 1))
assert.Check(t, is.Equal(all[0].ID, textplain.Manifests[0].Digest.String()))

assert.Assert(t, is.Len(all[0].Manifests, 0))
},
},
} {
Expand Down
39 changes: 39 additions & 0 deletions internal/testutils/specialimage/textplain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package specialimage

import (
"strings"

"github.com/distribution/reference"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

// TextPlain creates an non-container image that only contains a text/plain blob.
func TextPlain(dir string) (*ocispec.Index, error) {
ref, err := reference.ParseNormalizedNamed("tianon/test:text-plain")
if err != nil {
return nil, err
}

emptyJsonDesc, err := writeBlob(dir, "text/plain", strings.NewReader("{}"))
if err != nil {
return nil, err
}

configDesc := emptyJsonDesc
configDesc.MediaType = "application/vnd.oci.empty.v1+json"

desc, err := writeJsonBlob(dir, ocispec.MediaTypeImageManifest, ocispec.Manifest{
Config: configDesc,
Layers: []ocispec.Descriptor{
emptyJsonDesc,
},
})
if err != nil {
return nil, err
}
desc.Annotations = map[string]string{
"io.containerd.image.name": ref.String(),
}

return ociImage(dir, nil, desc)
}
Loading
0