Merge pull request #44622 from thaJeztah/image_inspect_step1a

manage image inspect data in backend
This commit is contained in:
Sebastiaan van Stijn 2022-12-12 20:05:46 +01:00 committed by GitHub
commit 487fa4a469
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 62 additions and 34 deletions

View file

@ -22,7 +22,7 @@ type Backend interface {
type imageBackend interface {
ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error)
ImageHistory(imageName string) ([]*image.HistoryResponseItem, error)
ImageHistory(ctx context.Context, imageName string) ([]*image.HistoryResponseItem, error)
Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error)
GetImage(ctx context.Context, refOrID string, options image.GetImageOpts) (*dockerimage.Image, error)
TagImage(imageName, repository, tag string) (string, error)

View file

@ -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
}
@ -321,7 +300,7 @@ func (ir *imageRouter) getImagesJSON(ctx context.Context, w http.ResponseWriter,
}
func (ir *imageRouter) getImagesHistory(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
history, err := ir.backend.ImageHistory(vars["name"])
history, err := ir.backend.ImageHistory(ctx, vars["name"])
if err != nil {
return err
}

View file

@ -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
}

View file

@ -1,6 +1,7 @@
package containerd
import (
"context"
"errors"
imagetype "github.com/docker/docker/api/types/image"
@ -9,6 +10,6 @@ import (
// ImageHistory returns a slice of ImageHistory structures for the specified
// image name by walking the image lineage.
func (i *ImageService) ImageHistory(name string) ([]*imagetype.HistoryResponseItem, error) {
func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*imagetype.HistoryResponseItem, error) {
return nil, errdefs.NotImplemented(errors.New("not implemented"))
}

View file

@ -40,7 +40,7 @@ type ImageService interface {
TagImage(imageName, repository, tag string) (string, error)
TagImageWithReference(imageID image.ID, newTag reference.Named) error
GetImage(ctx context.Context, refOrID string, options imagetype.GetImageOpts) (*image.Image, error)
ImageHistory(name string) ([]*imagetype.HistoryResponseItem, error)
ImageHistory(ctx context.Context, name string) ([]*imagetype.HistoryResponseItem, error)
CommitImage(c backend.CommitConfig) (image.ID, error)
SquashImage(id, parent string) (string, error)

View file

@ -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

View file

@ -12,8 +12,7 @@ import (
// ImageHistory returns a slice of ImageHistory structures for the specified image
// name by walking the image lineage.
func (i *ImageService) ImageHistory(name string) ([]*image.HistoryResponseItem, error) {
ctx := context.TODO()
func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*image.HistoryResponseItem, error) {
start := time.Now()
img, err := i.GetImage(ctx, name, image.GetImageOpts{})
if err != nil {

View file

@ -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.