فهرست منبع

c8d/list: Use walkImageManifests

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 5210f48bfc93373d93160b25509189654d338a46)
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
Paweł Gronowski 2 سال پیش
والد
کامیت
cbf0779bfc
1فایلهای تغییر یافته به همراه27 افزوده شده و 91 حذف شده
  1. 27 91
      daemon/containerd/image_list.go

+ 27 - 91
daemon/containerd/image_list.go

@@ -6,17 +6,14 @@ import (
 	"strings"
 	"strings"
 	"time"
 	"time"
 
 
-	"github.com/containerd/containerd"
 	"github.com/containerd/containerd/content"
 	"github.com/containerd/containerd/content"
 	cerrdefs "github.com/containerd/containerd/errdefs"
 	cerrdefs "github.com/containerd/containerd/errdefs"
 	"github.com/containerd/containerd/images"
 	"github.com/containerd/containerd/images"
 	"github.com/containerd/containerd/labels"
 	"github.com/containerd/containerd/labels"
-	"github.com/containerd/containerd/platforms"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/distribution/reference"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/api/types/filters"
 	timetypes "github.com/docker/docker/api/types/time"
 	timetypes "github.com/docker/docker/api/types/time"
-	"github.com/moby/buildkit/util/attestation"
 	"github.com/opencontainers/go-digest"
 	"github.com/opencontainers/go-digest"
 	"github.com/opencontainers/image-spec/identity"
 	"github.com/opencontainers/image-spec/identity"
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@@ -87,72 +84,41 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
 			continue
 			continue
 		}
 		}
 
 
-		err := images.Walk(ctx, images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
-			if images.IsIndexType(desc.MediaType) {
-				return images.Children(ctx, contentStore, desc)
+		err := i.walkImageManifests(ctx, img, func(img *ImageManifest) error {
+			if isPseudo, err := img.IsPseudoImage(ctx); isPseudo || err != nil {
+				return err
 			}
 			}
 
 
-			if images.IsManifestType(desc.MediaType) {
-				// Ignore buildkit attestation manifests
-				// https://github.com/moby/buildkit/blob/v0.11.4/docs/attestations/attestation-storage.md
-				// This would have also been caught by the isImageManifest call below, but it requires
-				// an additional content read and deserialization of Manifest.
-				if _, has := desc.Annotations[attestation.DockerAnnotationReferenceType]; has {
-					return nil, nil
-				}
-
-				mfst, err := images.Manifest(ctx, contentStore, desc, platforms.All)
-				if err != nil {
-					if cerrdefs.IsNotFound(err) {
-						return nil, nil
-					}
-					return nil, err
-				}
-
-				if !isImageManifest(mfst) {
-					return nil, nil
-				}
-
-				platform, err := getManifestPlatform(ctx, contentStore, desc, mfst.Config)
-				if err != nil {
-					if cerrdefs.IsNotFound(err) {
-						return nil, nil
-					}
-					return nil, err
-				}
+			available, err := img.CheckContentAvailable(ctx)
+			if err != nil {
+				logrus.WithFields(logrus.Fields{
+					logrus.ErrorKey: err,
+					"manifest":      img.Target(),
+					"image":         img.Name(),
+				}).Warn("checking availability of platform specific manifest failed")
+				return nil
+			}
 
 
-				pm := platforms.OnlyStrict(platform)
-				available, _, _, missing, err := images.Check(ctx, contentStore, img.Target, pm)
-				if err != nil {
-					logrus.WithFields(logrus.Fields{
-						logrus.ErrorKey: err,
-						"platform":      platform,
-						"image":         img.Target,
-					}).Warn("checking availability of platform content failed")
-					return nil, nil
-				}
-				if !available || len(missing) > 0 {
-					return nil, nil
-				}
+			if !available {
+				return nil
+			}
 
 
-				c8dImage := containerd.NewImageWithPlatform(i.client, img, pm)
-				image, chainIDs, err := i.singlePlatformImage(ctx, contentStore, c8dImage)
-				if err != nil {
-					return nil, err
-				}
+			image, chainIDs, err := i.singlePlatformImage(ctx, contentStore, img)
+			if err != nil {
+				return err
+			}
 
 
-				summaries = append(summaries, image)
+			summaries = append(summaries, image)
 
 
-				if opts.SharedSize {
-					root = append(root, &chainIDs)
-					for _, id := range chainIDs {
-						layers[id] = layers[id] + 1
-					}
+			if opts.SharedSize {
+				root = append(root, &chainIDs)
+				for _, id := range chainIDs {
+					layers[id] = layers[id] + 1
 				}
 				}
 			}
 			}
 
 
-			return nil, nil
-		}), img.Target)
+			return nil
+		})
 
 
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
@@ -173,7 +139,7 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
 	return summaries, nil
 	return summaries, nil
 }
 }
 
 
-func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore content.Store, image containerd.Image) (*types.ImageSummary, []digest.Digest, error) {
+func (i *ImageService) singlePlatformImage(ctx context.Context, contentStore content.Store, image *ImageManifest) (*types.ImageSummary, []digest.Digest, error) {
 	diffIDs, err := image.RootFS(ctx)
 	diffIDs, err := image.RootFS(ctx)
 	if err != nil {
 	if err != nil {
 		return nil, nil, err
 		return nil, nil, err
@@ -509,36 +475,6 @@ func computeSharedSize(chainIDs []digest.Digest, layers map[digest.Digest]int, s
 	return sharedSize, nil
 	return sharedSize, nil
 }
 }
 
 
-// getManifestPlatform returns a platform specified by the manifest descriptor
-// or reads it from its config.
-func getManifestPlatform(ctx context.Context, store content.Provider, manifestDesc, configDesc ocispec.Descriptor) (ocispec.Platform, error) {
-	var platform ocispec.Platform
-	if manifestDesc.Platform != nil {
-		platform = *manifestDesc.Platform
-	} else {
-		// Config is technically a v1.Image, but it has the same member as v1.Platform
-		// which makes the v1.Platform a subset of Image so we can unmarshal directly.
-		if err := readConfig(ctx, store, configDesc, &platform); err != nil {
-			return platform, err
-		}
-	}
-	return platforms.Normalize(platform), nil
-}
-
-// isImageManifest returns true if the manifest has no layers or any of its layers is a known image layer.
-// Some manifests use the image media type for compatibility, even if they are not a real image.
-func isImageManifest(mfst ocispec.Manifest) bool {
-	if len(mfst.Layers) == 0 {
-		return true
-	}
-	for _, l := range mfst.Layers {
-		if images.IsLayerType(l.MediaType) {
-			return true
-		}
-	}
-	return false
-}
-
 // readConfig reads content pointed by the descriptor and unmarshals it into a specified output.
 // readConfig reads content pointed by the descriptor and unmarshals it into a specified output.
 func readConfig(ctx context.Context, store content.Provider, desc ocispec.Descriptor, out interface{}) error {
 func readConfig(ctx context.Context, store content.Provider, desc ocispec.Descriptor, out interface{}) error {
 	data, err := content.ReadBlob(ctx, store, desc)
 	data, err := content.ReadBlob(ctx, store, desc)