Browse Source

Merge pull request #46588 from vvoland/c8d-history-ids

c8d/history: Fill ID and Tags for all entries
Sebastiaan van Stijn 1 năm trước cách đây
mục cha
commit
3149c3efe6

+ 22 - 0
daemon/containerd/image_children.go

@@ -10,6 +10,7 @@ import (
 	"github.com/containerd/containerd/platforms"
 	"github.com/containerd/containerd/platforms"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/image"
+	"github.com/opencontainers/go-digest"
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 	"github.com/pkg/errors"
 	"github.com/pkg/errors"
 )
 )
@@ -190,6 +191,27 @@ func (i *ImageService) parents(ctx context.Context, id image.ID) ([]imageWithRoo
 	return parents, nil
 	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 {
 type imageWithRootfs struct {
 	img    containerdimages.Image
 	img    containerdimages.Image
 	rootfs ocispec.RootFS
 	rootfs ocispec.RootFS

+ 32 - 13
daemon/containerd/image_history.go

@@ -4,6 +4,8 @@ import (
 	"context"
 	"context"
 	"sort"
 	"sort"
 
 
+	"github.com/containerd/containerd/images"
+	"github.com/containerd/containerd/log"
 	cplatforms "github.com/containerd/containerd/platforms"
 	cplatforms "github.com/containerd/containerd/platforms"
 	"github.com/distribution/reference"
 	"github.com/distribution/reference"
 	imagetype "github.com/docker/docker/api/types/image"
 	imagetype "github.com/docker/docker/api/types/image"
@@ -17,7 +19,7 @@ import (
 // ImageHistory returns a slice of HistoryResponseItem structures for the
 // ImageHistory returns a slice of HistoryResponseItem structures for the
 // specified image name by walking the image lineage.
 // specified image name by walking the image lineage.
 func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imagetype.HistoryResponseItem, error) {
 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 {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -27,7 +29,7 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imaget
 	platform := platforms.AllPlatformsWithPreference(cplatforms.Default())
 	platform := platforms.AllPlatformsWithPreference(cplatforms.Default())
 
 
 	var presentImages []ocispec.Image
 	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)
 		conf, err := img.Config(ctx)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
@@ -89,26 +91,43 @@ func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imaget
 		}}, history...)
 		}}, 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 {
 		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
 				continue
 			}
 			}
-			name, err := reference.ParseNamed(t.Name)
+			name, err := reference.ParseNamed(img.Name)
 			if err != nil {
 			if err != nil {
 				return nil, err
 				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
 	return history, nil