瀏覽代碼

manage image inspect data in backend

This allows differentiating how the detailed data is collected between
the containerd-integration code and the existing implementation.

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Nicolas De Loof 2 年之前
父節點
當前提交
8fb71ce208
共有 4 個文件被更改,包括 56 次插入28 次删除
  1. 6 27
      api/server/router/image/image_routes.go
  2. 1 0
      api/types/image/opts.go
  3. 38 1
      daemon/images/image.go
  4. 11 0
      image/image.go

+ 6 - 27
api/server/router/image/image_routes.go

@@ -17,7 +17,6 @@ import (
 	"github.com/docker/docker/api/types/versions"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/image"
-	"github.com/docker/docker/layer"
 	"github.com/docker/docker/pkg/ioutils"
 	"github.com/docker/docker/pkg/streamformatter"
 	specs "github.com/opencontainers/image-spec/specs-go/v1"
@@ -193,7 +192,7 @@ func (ir *imageRouter) deleteImages(ctx context.Context, w http.ResponseWriter,
 }
 
 func (ir *imageRouter) getImagesByName(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
-	img, err := ir.backend.GetImage(ctx, vars["name"], opts.GetImageOpts{})
+	img, err := ir.backend.GetImage(ctx, vars["name"], opts.GetImageOpts{Details: true})
 	if err != nil {
 		return err
 	}
@@ -218,31 +217,11 @@ func (ir *imageRouter) toImageInspect(img *image.Image) (*types.ImageInspect, er
 		}
 	}
 
-	var size int64
-	var layerMetadata map[string]string
-	if layerID := img.RootFS.ChainID(); layerID != "" {
-		l, err := ir.layerStore.Get(layerID)
-		if err != nil {
-			return nil, err
-		}
-		defer layer.ReleaseAndLog(ir.layerStore, l)
-		size = l.Size()
-		layerMetadata, err = l.Metadata()
-		if err != nil {
-			return nil, err
-		}
-	}
-
 	comment := img.Comment
 	if len(comment) == 0 && len(img.History) > 0 {
 		comment = img.History[len(img.History)-1].Comment
 	}
 
-	lastUpdated, err := ir.imageStore.GetLastUpdated(img.ID())
-	if err != nil {
-		return nil, err
-	}
-
 	return &types.ImageInspect{
 		ID:              img.ID().String(),
 		RepoTags:        repoTags,
@@ -259,15 +238,15 @@ func (ir *imageRouter) toImageInspect(img *image.Image) (*types.ImageInspect, er
 		Variant:         img.Variant,
 		Os:              img.OperatingSystem(),
 		OsVersion:       img.OSVersion,
-		Size:            size,
-		VirtualSize:     size, // TODO: field unused, deprecate
+		Size:            img.Details.Size,
+		VirtualSize:     img.Details.Size, // TODO: field unused, deprecate
 		GraphDriver: types.GraphDriverData{
-			Name: ir.layerStore.DriverName(),
-			Data: layerMetadata,
+			Name: img.Details.Driver,
+			Data: img.Details.Metadata,
 		},
 		RootFS: rootFSToAPIType(img.RootFS),
 		Metadata: types.ImageMetadata{
-			LastTagTime: lastUpdated,
+			LastTagTime: img.Details.LastUpdated,
 		},
 	}, nil
 }

+ 1 - 0
api/types/image/opts.go

@@ -5,4 +5,5 @@ import specs "github.com/opencontainers/image-spec/specs-go/v1"
 // GetImageOpts holds parameters to inspect an image.
 type GetImageOpts struct {
 	Platform *specs.Platform
+	Details  bool
 }

+ 38 - 1
daemon/images/image.go

@@ -15,6 +15,7 @@ import (
 	imagetypes "github.com/docker/docker/api/types/image"
 	"github.com/docker/docker/errdefs"
 	"github.com/docker/docker/image"
+	"github.com/docker/docker/layer"
 	"github.com/opencontainers/go-digest"
 	specs "github.com/opencontainers/image-spec/specs-go/v1"
 	"github.com/pkg/errors"
@@ -148,7 +149,43 @@ func (i *ImageService) manifestMatchesPlatform(ctx context.Context, img *image.I
 }
 
 // GetImage returns an image corresponding to the image referred to by refOrID.
-func (i *ImageService) GetImage(ctx context.Context, refOrID string, options imagetypes.GetImageOpts) (retImg *image.Image, retErr error) {
+func (i *ImageService) GetImage(ctx context.Context, refOrID string, options imagetypes.GetImageOpts) (*image.Image, error) {
+	img, err := i.getImage(ctx, refOrID, options)
+	if err != nil {
+		return nil, err
+	}
+	if options.Details {
+		var size int64
+		var layerMetadata map[string]string
+		layerID := img.RootFS.ChainID()
+		if layerID != "" {
+			l, err := i.layerStore.Get(layerID)
+			if err != nil {
+				return nil, err
+			}
+			defer layer.ReleaseAndLog(i.layerStore, l)
+			size = l.Size()
+			layerMetadata, err = l.Metadata()
+			if err != nil {
+				return nil, err
+			}
+		}
+
+		lastUpdated, err := i.imageStore.GetLastUpdated(img.ID())
+		if err != nil {
+			return nil, err
+		}
+		img.Details = &image.Details{
+			Size:        size,
+			Metadata:    layerMetadata,
+			Driver:      i.layerStore.DriverName(),
+			LastUpdated: lastUpdated,
+		}
+	}
+	return img, nil
+}
+
+func (i *ImageService) getImage(ctx context.Context, refOrID string, options imagetypes.GetImageOpts) (retImg *image.Image, retErr error) {
 	defer func() {
 		if retErr != nil || retImg == nil || options.Platform == nil {
 			return

+ 11 - 0
image/image.go

@@ -112,6 +112,17 @@ type Image struct {
 	// computedID is the ID computed from the hash of the image config.
 	// Not to be confused with the legacy V1 ID in V1Image.
 	computedID ID
+
+	// Details holds additional details about image
+	Details *Details `json:"-"`
+}
+
+// Details provides additional image data
+type Details struct {
+	Size        int64
+	Metadata    map[string]string
+	Driver      string
+	LastUpdated time.Time
 }
 
 // RawJSON returns the immutable JSON associated with the image.