summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjorn Neergaard <bneergaard@mirantis.com>2023-02-23 14:25:03 -0700
committerGitHub <noreply@github.com>2023-02-23 14:25:03 -0700
commita9f17a28db970231c17fa52b1234f584ee08cc03 (patch)
tree9b4833c4936373ac5790e00b9e2370b05cf3fefe
parent855c68470805b1c2fcc2cf7890e2fae46d10ee63 (diff)
parentf8791db4beebc9a7d2cbeeb35131c029a07f2102 (diff)
downloaddocker-a9f17a28db970231c17fa52b1234f584ee08cc03.tar.gz
Merge pull request #44840 from vvoland/c8d-list-dangling-upstream
c8d/list: Fix Repo(Digests|Tags) for untagged images
-rw-r--r--api/server/router/image/image_routes.go7
-rw-r--r--daemon/containerd/image_list.go41
-rw-r--r--daemon/containerd/soft_delete.go4
-rw-r--r--daemon/images/image_list.go2
4 files changed, 48 insertions, 6 deletions
diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go
index 8b0fb9422f..3a4322371b 100644
--- a/api/server/router/image/image_routes.go
+++ b/api/server/router/image/image_routes.go
@@ -337,6 +337,13 @@ func (ir *imageRouter) getImagesJSON(ctx context.Context, w http.ResponseWriter,
return err
}
+ for _, img := range images {
+ if len(img.RepoTags) == 0 && len(img.RepoDigests) == 0 {
+ img.RepoTags = append(img.RepoTags, "<none>:<none>")
+ img.RepoDigests = append(img.RepoDigests, "<none>@<none>")
+ }
+ }
+
return httputils.WriteJSON(w, http.StatusOK, images)
}
diff --git a/daemon/containerd/image_list.go b/daemon/containerd/image_list.go
index e6bb6d17f8..fffbc6c48b 100644
--- a/daemon/containerd/image_list.go
+++ b/daemon/containerd/image_list.go
@@ -9,6 +9,7 @@ import (
"github.com/docker/docker/api/types/filters"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
+ "github.com/sirupsen/logrus"
)
var acceptedImageFilterTags = map[string]bool{
@@ -64,6 +65,7 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
root = make([]*[]digest.Digest, len(imgs))
layers = make(map[digest.Digest]int)
}
+
for n, img := range imgs {
if !filter(img) {
continue
@@ -91,12 +93,43 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
return nil, err
}
+ var repoTags, repoDigests []string
+ rawImg := img.Metadata()
+ target := rawImg.Target.Digest
+
+ logger := logrus.WithFields(logrus.Fields{
+ "name": img.Name(),
+ "digest": target,
+ })
+
+ ref, err := reference.ParseNamed(rawImg.Name)
+ if err != nil {
+ // If the image has unexpected name format (not a Named reference or a dangling image)
+ // add the offending name to RepoTags but also log an error to make it clear to the
+ // administrator that this is unexpected.
+ // TODO: Reconsider when containerd is more strict on image names, see:
+ // https://github.com/containerd/containerd/issues/7986
+ if !isDanglingImage(rawImg) {
+ logger.WithError(err).Error("failed to parse image name as reference")
+ repoTags = append(repoTags, img.Name())
+ }
+ } else {
+ repoTags = append(repoTags, reference.TagNameOnly(ref).String())
+
+ digested, err := reference.WithDigest(reference.TrimNamed(ref), target)
+ if err != nil {
+ logger.WithError(err).Error("failed to create digested reference")
+ } else {
+ repoDigests = append(repoDigests, digested.String())
+ }
+ }
+
summaries = append(summaries, &types.ImageSummary{
ParentID: "",
- ID: img.Target().Digest.String(),
- Created: img.Metadata().CreatedAt.Unix(),
- RepoDigests: []string{img.Name() + "@" + img.Target().Digest.String()}, // "hello-world@sha256:bfea6278a0a267fad2634554f4f0c6f31981eea41c553fdf5a83e95a41d40c38"},
- RepoTags: []string{img.Name()},
+ ID: target.String(),
+ Created: rawImg.CreatedAt.Unix(),
+ RepoDigests: repoDigests,
+ RepoTags: repoTags,
Size: size,
VirtualSize: virtualSize,
// -1 indicates that the value has not been set (avoids ambiguity
diff --git a/daemon/containerd/soft_delete.go b/daemon/containerd/soft_delete.go
index 79a530d90a..f751482214 100644
--- a/daemon/containerd/soft_delete.go
+++ b/daemon/containerd/soft_delete.go
@@ -59,3 +59,7 @@ func (i *ImageService) softImageDelete(ctx context.Context, img containerdimages
func danglingImageName(digest digest.Digest) string {
return "moby-dangling@" + digest.String()
}
+
+func isDanglingImage(image containerdimages.Image) bool {
+ return image.Name == danglingImageName(image.Target.Digest)
+}
diff --git a/daemon/images/image_list.go b/daemon/images/image_list.go
index 001853cae1..e940813c87 100644
--- a/daemon/images/image_list.go
+++ b/daemon/images/image_list.go
@@ -173,8 +173,6 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
if opts.Filters.Contains("reference") { // skip images with no references if filtering by reference
continue
}
- summary.RepoDigests = []string{"<none>@<none>"}
- summary.RepoTags = []string{"<none>:<none>"}
} else {
continue
}