Skip to content

Commit

Permalink
Merge pull request moby#46588 from vvoland/c8d-history-ids
Browse files Browse the repository at this point in the history
c8d/history: Fill ID and Tags for all entries
  • Loading branch information
thaJeztah authored Oct 10, 2023
2 parents 0a3fc95 + f99c4ec commit 3149c3e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 13 deletions.
22 changes: 22 additions & 0 deletions daemon/containerd/image_children.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/containerd/containerd/platforms"
"github.com/docker/docker/errdefs"
"github.com/docker/docker/image"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -190,6 +191,27 @@ func (i *ImageService) parents(ctx context.Context, id image.ID) ([]imageWithRoo
return parents, nil
}

// getParentsByBuilderLabel finds images that were a base for the given image
// by an image label set by the legacy builder.
// NOTE: This only works for images built with legacy builder (not Buildkit).
func (i *ImageService) getParentsByBuilderLabel(ctx context.Context, img containerdimages.Image) ([]containerdimages.Image, error) {
parent, ok := img.Labels[imageLabelClassicBuilderParent]
if !ok || parent == "" {
return nil, nil
}

dgst, err := digest.Parse(parent)
if err != nil {
log.G(ctx).WithFields(log.Fields{
"error": err,
"value": parent,
}).Warnf("invalid %s label value", imageLabelClassicBuilderParent)
return nil, nil
}

return i.client.ImageService().List(ctx, "target.digest=="+dgst.String())
}

type imageWithRootfs struct {
img containerdimages.Image
rootfs ocispec.RootFS
Expand Down
45 changes: 32 additions & 13 deletions daemon/containerd/image_history.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"sort"

"github.com/containerd/containerd/images"
"github.com/containerd/containerd/log"
cplatforms "github.com/containerd/containerd/platforms"
"github.com/distribution/reference"
imagetype "github.com/docker/docker/api/types/image"
Expand All @@ -17,7 +19,7 @@ import (
// ImageHistory returns a slice of HistoryResponseItem structures for the
// specified image name by walking the image lineage.
func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imagetype.HistoryResponseItem, error) {
desc, err := i.resolveImage(ctx, name)
img, err := i.resolveImage(ctx, name)
if err != nil {
return nil, err
}
Expand All @@ -27,7 +29,7 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imaget
platform := platforms.AllPlatformsWithPreference(cplatforms.Default())

var presentImages []ocispec.Image
err = i.walkImageManifests(ctx, desc, func(img *ImageManifest) error {
err = i.walkImageManifests(ctx, img, func(img *ImageManifest) error {
conf, err := img.Config(ctx)
if err != nil {
return err
Expand Down Expand Up @@ -89,26 +91,43 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imaget
}}, history...)
}

if len(history) != 0 {
history[0].ID = desc.Target.Digest.String()

tagged, err := i.client.ImageService().List(ctx, "target.digest=="+desc.Target.Digest.String())
findParents := func(img images.Image) []images.Image {
imgs, err := i.getParentsByBuilderLabel(ctx, img)
if err != nil {
return nil, err
log.G(ctx).WithFields(log.Fields{
"error": err,
"image": img,
}).Warnf("failed to list parent images")
return nil
}
return imgs
}

currentImg := img
for _, h := range history {
h.ID = currentImg.Target.Digest.String()
imgs := findParents(currentImg)

var tags []string
for _, t := range tagged {
if isDanglingImage(t) {
foundNext := false
for _, img := range imgs {
if _, ok := img.Labels[imageLabelClassicBuilderParent]; ok {
currentImg = img
foundNext = true
}

if isDanglingImage(img) {
continue
}
name, err := reference.ParseNamed(t.Name)
name, err := reference.ParseNamed(img.Name)
if err != nil {
return nil, err
}
tags = append(tags, reference.FamiliarString(name))
h.Tags = append(h.Tags, reference.FamiliarString(name))
}

if !foundNext {
break
}
history[0].Tags = tags
}

return history, nil
Expand Down

0 comments on commit 3149c3e

Please sign in to comment.