From 50401b406167aa242794f8b6cfd9025a95df7e0e Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Mon, 25 Jul 2022 17:24:03 +0200 Subject: [PATCH] introduce GetImageOpts to manage image inspect data in backend Signed-off-by: Nicolas De Loof --- api/server/router/image/backend.go | 4 +- api/server/router/image/image_routes.go | 37 ++++------------ api/types/image/opts.go | 9 ++++ daemon/cluster/executor/backend.go | 3 +- daemon/cluster/executor/container/adapter.go | 3 +- daemon/containerd/service.go | 46 ++++++++++++++++---- daemon/create.go | 5 ++- daemon/image_service.go | 4 +- daemon/images/cache.go | 3 +- daemon/images/image.go | 40 ++++++++++++++++- daemon/images/image_builder.go | 5 ++- daemon/images/image_delete.go | 3 +- daemon/images/image_events.go | 3 +- daemon/images/image_history.go | 7 +-- daemon/images/image_pull.go | 3 +- daemon/images/image_tag.go | 3 +- daemon/images/images.go | 7 +-- daemon/list.go | 5 ++- daemon/oci_windows.go | 3 +- image/image.go | 11 +++++ 20 files changed, 142 insertions(+), 62 deletions(-) create mode 100644 api/types/image/opts.go diff --git a/api/server/router/image/backend.go b/api/server/router/image/backend.go index 19d11edbf4840..1b842a94fdc2e 100644 --- a/api/server/router/image/backend.go +++ b/api/server/router/image/backend.go @@ -22,9 +22,9 @@ 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, platform *specs.Platform) (*dockerimage.Image, error) + GetImage(ctx context.Context, refOrID string, options image.GetImageOpts) (*dockerimage.Image, error) TagImage(ctx context.Context, imageName, repository, tag string) (string, error) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (*types.ImagesPruneReport, error) } diff --git a/api/server/router/image/image_routes.go b/api/server/router/image/image_routes.go index 73b07a12d1aa1..bf87d4795b1bc 100644 --- a/api/server/router/image/image_routes.go +++ b/api/server/router/image/image_routes.go @@ -14,10 +14,10 @@ import ( "github.com/docker/docker/api/server/httputils" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + opts "github.com/docker/docker/api/types/image" "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" @@ -204,7 +204,7 @@ func (s *imageRouter) deleteImages(ctx context.Context, w http.ResponseWriter, r } func (s *imageRouter) getImagesByName(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { - image, err := s.backend.GetImage(ctx, vars["name"], nil) + image, err := s.backend.GetImage(ctx, vars["name"], opts.GetImageOpts{Details: true}) if err != nil { return err } @@ -230,32 +230,11 @@ func (s *imageRouter) toImageInspect(img *image.Image) (*types.ImageInspect, err } } - var size int64 - var layerMetadata map[string]string - layerID := img.RootFS.ChainID() - if layerID != "" { - l, err := s.layerStore.Get(layerID) - if err != nil { - return nil, err - } - defer layer.ReleaseAndLog(s.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 := s.imageStore.GetLastUpdated(img.ID()) - if err != nil { - return nil, err - } - return &types.ImageInspect{ ID: img.ID().String(), RepoTags: repoTags, @@ -272,15 +251,15 @@ func (s *imageRouter) toImageInspect(img *image.Image) (*types.ImageInspect, err 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: s.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 } @@ -335,7 +314,7 @@ func (s *imageRouter) getImagesJSON(ctx context.Context, w http.ResponseWriter, func (s *imageRouter) getImagesHistory(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { name := vars["name"] - history, err := s.backend.ImageHistory(name) + history, err := s.backend.ImageHistory(ctx, name) if err != nil { return err } diff --git a/api/types/image/opts.go b/api/types/image/opts.go new file mode 100644 index 0000000000000..a24f9059ab4f7 --- /dev/null +++ b/api/types/image/opts.go @@ -0,0 +1,9 @@ +package image + +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 +} diff --git a/daemon/cluster/executor/backend.go b/daemon/cluster/executor/backend.go index d2cd9a34c840f..1065fd43013f9 100644 --- a/daemon/cluster/executor/backend.go +++ b/daemon/cluster/executor/backend.go @@ -12,6 +12,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/events" "github.com/docker/docker/api/types/filters" + opts "github.com/docker/docker/api/types/image" "github.com/docker/docker/api/types/network" swarmtypes "github.com/docker/docker/api/types/swarm" "github.com/docker/docker/api/types/volume" @@ -75,5 +76,5 @@ type VolumeBackend interface { type ImageBackend interface { PullImage(ctx context.Context, image, tag string, platform *specs.Platform, metaHeaders map[string][]string, authConfig *types.AuthConfig, outStream io.Writer) error GetRepository(context.Context, reference.Named, *types.AuthConfig) (distribution.Repository, error) - GetImage(ctx context.Context, refOrID string, platform *specs.Platform) (retImg *image.Image, retErr error) + GetImage(ctx context.Context, refOrID string, options opts.GetImageOpts) (retImg *image.Image, retErr error) } diff --git a/daemon/cluster/executor/container/adapter.go b/daemon/cluster/executor/container/adapter.go index dc0f65a260ba0..0019480b0cbd7 100644 --- a/daemon/cluster/executor/container/adapter.go +++ b/daemon/cluster/executor/container/adapter.go @@ -16,6 +16,7 @@ import ( "github.com/docker/docker/api/types/backend" containertypes "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/events" + imagetypes "github.com/docker/docker/api/types/image" containerpkg "github.com/docker/docker/container" "github.com/docker/docker/daemon" "github.com/docker/docker/daemon/cluster/convert" @@ -74,7 +75,7 @@ func (c *containerAdapter) pullImage(ctx context.Context) error { named, err := reference.ParseNormalizedNamed(spec.Image) if err == nil { if _, ok := named.(reference.Canonical); ok { - _, err := c.imageBackend.GetImage(ctx, spec.Image, nil) + _, err := c.imageBackend.GetImage(ctx, spec.Image, imagetypes.GetImageOpts{}) if err == nil { return nil } diff --git a/daemon/containerd/service.go b/daemon/containerd/service.go index 45cc1a15d73da..97e1d47b295e8 100644 --- a/daemon/containerd/service.go +++ b/daemon/containerd/service.go @@ -411,7 +411,7 @@ func (cs *containerdStore) ImageDelete(ctx context.Context, imageRef string, for return records, nil } -func (cs *containerdStore) ImageHistory(name string) ([]*imagetype.HistoryResponseItem, error) { +func (cs *containerdStore) ImageHistory(ctx context.Context, name string) ([]*imagetype.HistoryResponseItem, error) { panic("not implemented") } @@ -573,34 +573,63 @@ func (cs *containerdStore) GetContainerdImage(ctx context.Context, refOrID strin return cs.resolveImageName2(ctx, refOrID) } -func (cs *containerdStore) GetImage(ctx context.Context, refOrID string, platform *v1.Platform) (*image.Image, error) { - desc, err := cs.ResolveImage(ctx, refOrID) +func (cs *containerdStore) GetImage(ctx context.Context, refOrID string, options imagetype.GetImageOpts) (*image.Image, error) { + ii, img, err := cs.getImage(ctx, refOrID, options.Platform) if err != nil { return nil, err } + if options.Details { + size, err := ii.Size(ctx) + if err != nil { + return nil, err + } + img.Details = &image.Details{ + Size: size, + Metadata: nil, + Driver: cs.GraphDriverName(), + LastUpdated: ii.Metadata().UpdatedAt, + } + } + return img, err +} + +func (cs *containerdStore) getImage(ctx context.Context, refOrID string, platform *v1.Platform) (containerd.Image, *image.Image, error) { + desc, err := cs.ResolveImage(ctx, refOrID) + if err != nil { + return nil, nil, err + } + ctrdimg, err := cs.resolveImageName2(ctx, refOrID) if err != nil { - return nil, err + return nil, nil, err } ii := containerd.NewImage(cs.client, ctrdimg) provider := cs.client.ContentStore() conf, err := ctrdimg.Config(ctx, provider, ii.Platform()) if err != nil { - return nil, err + return nil, nil, err } var ociimage v1.Image imageConfigBytes, err := content.ReadBlob(ctx, ii.ContentStore(), conf) if err != nil { - return nil, err + return nil, nil, err } if err := json.Unmarshal(imageConfigBytes, &ociimage); err != nil { - return nil, err + return nil, nil, err } - return &image.Image{ + fs, err := ii.RootFS(ctx) + if err != nil { + return nil, nil, err + } + rootfs := image.NewRootFS() + for _, id := range fs { + rootfs.Append(layer.DiffID(id)) + } + return ii, &image.Image{ V1Image: image.V1Image{ ID: string(desc.Digest), OS: ociimage.OS, @@ -613,6 +642,7 @@ func (cs *containerdStore) GetImage(ctx context.Context, refOrID string, platfor WorkingDir: ociimage.Config.WorkingDir, }, }, + RootFS: rootfs, }, nil } diff --git a/daemon/create.go b/daemon/create.go index b75cb04007ae7..5b2ec16c0d6f1 100644 --- a/daemon/create.go +++ b/daemon/create.go @@ -13,6 +13,7 @@ import ( "github.com/containerd/containerd/platforms" "github.com/docker/docker/api/types" containertypes "github.com/docker/docker/api/types/container" + imagetypes "github.com/docker/docker/api/types/image" networktypes "github.com/docker/docker/api/types/network" "github.com/docker/docker/container" "github.com/docker/docker/daemon/images" @@ -76,7 +77,7 @@ func (daemon *Daemon) containerCreate(ctx context.Context, opts createOpts) (con } if opts.params.Platform == nil && opts.params.Config.Image != "" { - if img, _ := daemon.imageService.GetImage(ctx, opts.params.Config.Image, opts.params.Platform); img != nil { + if img, _ := daemon.imageService.GetImage(ctx, opts.params.Config.Image, imagetypes.GetImageOpts{Platform: opts.params.Platform}); img != nil { p := maximumSpec() imgPlat := v1.Platform{ OS: img.OS, @@ -127,7 +128,7 @@ func (daemon *Daemon) create(ctx context.Context, opts createOpts) (retC *contai ) if opts.params.Config.Image != "" { - img, err = daemon.imageService.GetImage(ctx, opts.params.Config.Image, opts.params.Platform) + img, err = daemon.imageService.GetImage(ctx, opts.params.Config.Image, imagetypes.GetImageOpts{Platform: opts.params.Platform}) if err != nil { return nil, err } diff --git a/daemon/image_service.go b/daemon/image_service.go index 7e5694b2ab0c3..14478c855b9c4 100644 --- a/daemon/image_service.go +++ b/daemon/image_service.go @@ -40,8 +40,8 @@ type ImageService interface { ImportImage(ctx context.Context, src string, repository string, platform *v1.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error TagImage(ctx context.Context, imageName, repository, tag string) (string, error) TagImageWithReference(ctx context.Context, imageID image.ID, newTag reference.Named) error - GetImage(ctx context.Context, refOrID string, platform *v1.Platform) (*image.Image, error) - ImageHistory(name string) ([]*imagetype.HistoryResponseItem, error) + GetImage(ctx context.Context, refOrID string, options imagetype.GetImageOpts) (*image.Image, error) + ImageHistory(ctx context.Context, name string) ([]*imagetype.HistoryResponseItem, error) CommitImage(c backend.CommitConfig) (image.ID, error) SquashImage(id, parent string) (string, error) diff --git a/daemon/images/cache.go b/daemon/images/cache.go index 000d73211861a..858f2b9b4376c 100644 --- a/daemon/images/cache.go +++ b/daemon/images/cache.go @@ -3,6 +3,7 @@ package images // import "github.com/docker/docker/daemon/images" import ( "context" + imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/builder" "github.com/docker/docker/image/cache" "github.com/sirupsen/logrus" @@ -17,7 +18,7 @@ func (i *ImageService) MakeImageCache(ctx context.Context, sourceRefs []string) cache := cache.New(i.imageStore) for _, ref := range sourceRefs { - img, err := i.GetImage(ctx, ref, nil) + img, err := i.GetImage(ctx, ref, imagetypes.GetImageOpts{}) if err != nil { logrus.Warnf("Could not look up %s for cache resolution, skipping: %+v", ref, err) continue diff --git a/daemon/images/image.go b/daemon/images/image.go index 974bf1e7d088b..3bb37a0f8a3c4 100644 --- a/daemon/images/image.go +++ b/daemon/images/image.go @@ -12,8 +12,10 @@ import ( "github.com/containerd/containerd/leases" "github.com/containerd/containerd/platforms" "github.com/docker/distribution/reference" + 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 +150,43 @@ func (i *ImageService) manifestMatchesPlatform(img *image.Image, platform specs. } // GetImage returns an image corresponding to the image referred to by refOrID. -func (i *ImageService) GetImage(ctx context.Context, refOrID string, platform *specs.Platform) (retImg *image.Image, retErr error) { +func (i *ImageService) GetImage(ctx context.Context, refOrID string, options imagetypes.GetImageOpts) (*image.Image, error) { + img, err := i.getImage(refOrID, options.Platform) + 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(refOrID string, platform *specs.Platform) (retImg *image.Image, retErr error) { defer func() { if retErr != nil || retImg == nil || platform == nil { return diff --git a/daemon/images/image_builder.go b/daemon/images/image_builder.go index 60da65a2d6e21..931fe5cce212b 100644 --- a/daemon/images/image_builder.go +++ b/daemon/images/image_builder.go @@ -9,6 +9,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/backend" + imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/builder" "github.com/docker/docker/errdefs" "github.com/docker/docker/image" @@ -167,7 +168,7 @@ func (i *ImageService) pullForBuilder(ctx context.Context, name string, authConf return nil, err } - img, err := i.GetImage(nil, name, platform) + img, err := i.GetImage(nil, name, imagetypes.GetImageOpts{Platform: platform}) if errdefs.IsNotFound(err) && img != nil && platform != nil { imgPlat := specs.Platform{ OS: img.OS, @@ -211,7 +212,7 @@ func (i *ImageService) GetImageAndReleasableLayer(ctx context.Context, refOrID s } if opts.PullOption != backend.PullOptionForcePull { - image, err := i.GetImage(nil, refOrID, opts.Platform) + image, err := i.GetImage(nil, refOrID, imagetypes.GetImageOpts{Platform: opts.Platform}) if err != nil && opts.PullOption == backend.PullOptionNoPull { return nil, nil, err } diff --git a/daemon/images/image_delete.go b/daemon/images/image_delete.go index 2d3cabe264f50..b66bb7716736c 100644 --- a/daemon/images/image_delete.go +++ b/daemon/images/image_delete.go @@ -8,6 +8,7 @@ import ( "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/container" "github.com/docker/docker/errdefs" "github.com/docker/docker/image" @@ -63,7 +64,7 @@ func (i *ImageService) ImageDelete(ctx context.Context, imageRef string, force, start := time.Now() records := []types.ImageDeleteResponseItem{} - img, err := i.GetImage(ctx, imageRef, nil) + img, err := i.GetImage(ctx, imageRef, imagetypes.GetImageOpts{}) if err != nil { return nil, err } diff --git a/daemon/images/image_events.go b/daemon/images/image_events.go index e89a7c49c7e5e..294f3b4b3d7d7 100644 --- a/daemon/images/image_events.go +++ b/daemon/images/image_events.go @@ -2,6 +2,7 @@ package images // import "github.com/docker/docker/daemon/images" import ( "github.com/docker/docker/api/types/events" + imagetypes "github.com/docker/docker/api/types/image" ) // LogImageEvent generates an event related to an image with only the default attributes. @@ -11,7 +12,7 @@ func (i *ImageService) LogImageEvent(imageID, refName, action string) { // LogImageEventWithAttributes generates an event related to an image with specific given attributes. func (i *ImageService) LogImageEventWithAttributes(imageID, refName, action string, attributes map[string]string) { - img, err := i.GetImage(nil, imageID, nil) + img, err := i.GetImage(nil, imageID, imagetypes.GetImageOpts{}) if err == nil && img.Config != nil { // image has not been removed yet. // it could be missing if the event is `delete`. diff --git a/daemon/images/image_history.go b/daemon/images/image_history.go index b092b2f76f5ff..8a9f03d95005e 100644 --- a/daemon/images/image_history.go +++ b/daemon/images/image_history.go @@ -1,6 +1,7 @@ package images // import "github.com/docker/docker/daemon/images" import ( + "context" "fmt" "time" @@ -11,9 +12,9 @@ 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) { +func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*image.HistoryResponseItem, error) { start := time.Now() - img, err := i.GetImage(nil, name, nil) + img, err := i.GetImage(ctx, name, image.GetImageOpts{}) if err != nil { return nil, err } @@ -69,7 +70,7 @@ func (i *ImageService) ImageHistory(name string) ([]*image.HistoryResponseItem, if id == "" { break } - histImg, err = i.GetImage(nil, id.String(), nil) + histImg, err = i.GetImage(ctx, id.String(), image.GetImageOpts{}) if err != nil { break } diff --git a/daemon/images/image_pull.go b/daemon/images/image_pull.go index 15abf08cab92c..ce202ae83b6f5 100644 --- a/daemon/images/image_pull.go +++ b/daemon/images/image_pull.go @@ -11,6 +11,7 @@ import ( dist "github.com/docker/distribution" "github.com/docker/distribution/reference" "github.com/docker/docker/api/types" + imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/distribution" progressutils "github.com/docker/docker/distribution/utils" "github.com/docker/docker/errdefs" @@ -63,7 +64,7 @@ func (i *ImageService) PullImage(ctx context.Context, image, tag string, platfor // we allow the image to have a non-matching architecture. The code // below checks for this situation, and returns a warning to the client, // as well as logging it to the daemon logs. - img, err := i.GetImage(nil, image, platform) + img, err := i.GetImage(ctx, image, imagetypes.GetImageOpts{Platform: platform}) // Note that this is a special case where GetImage returns both an image // and an error: https://github.com/docker/docker/blob/v20.10.7/daemon/images/image.go#L175-L183 diff --git a/daemon/images/image_tag.go b/daemon/images/image_tag.go index 708b2689398f7..81d00d35fee8e 100644 --- a/daemon/images/image_tag.go +++ b/daemon/images/image_tag.go @@ -4,13 +4,14 @@ import ( "context" "github.com/docker/distribution/reference" + imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/image" ) // TagImage creates the tag specified by newTag, pointing to the image named // imageName (alternatively, imageName can also be an image ID). func (i *ImageService) TagImage(ctx context.Context, imageName, repository, tag string) (string, error) { - img, err := i.GetImage(nil, imageName, nil) + img, err := i.GetImage(ctx, imageName, imagetypes.GetImageOpts{}) if err != nil { return "", err } diff --git a/daemon/images/images.go b/daemon/images/images.go index 3124defc11ab9..750d9c61e79fa 100644 --- a/daemon/images/images.go +++ b/daemon/images/images.go @@ -7,6 +7,7 @@ import ( "sort" "time" + imagetypes "github.com/docker/docker/api/types/image" "github.com/pkg/errors" "github.com/docker/distribution/reference" @@ -39,7 +40,7 @@ func (i *ImageService) Map() map[image.ID]*image.Image { } // Images returns a filtered list of images. -func (i *ImageService) Images(_ context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error) { +func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error) { if err := opts.Filters.Validate(acceptedImageFilterTags); err != nil { return nil, err } @@ -58,7 +59,7 @@ func (i *ImageService) Images(_ context.Context, opts types.ImageListOptions) ([ err error ) err = opts.Filters.WalkValues("before", func(value string) error { - beforeFilter, err = i.GetImage(nil, value, nil) + beforeFilter, err = i.GetImage(ctx, value, imagetypes.GetImageOpts{}) return err }) if err != nil { @@ -66,7 +67,7 @@ func (i *ImageService) Images(_ context.Context, opts types.ImageListOptions) ([ } err = opts.Filters.WalkValues("since", func(value string) error { - sinceFilter, err = i.GetImage(nil, value, nil) + sinceFilter, err = i.GetImage(ctx, value, imagetypes.GetImageOpts{}) return err }) if err != nil { diff --git a/daemon/list.go b/daemon/list.go index a2e0601dc5f15..db9869c8c8297 100644 --- a/daemon/list.go +++ b/daemon/list.go @@ -9,6 +9,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/container" "github.com/docker/docker/daemon/images" "github.com/docker/docker/errdefs" @@ -321,7 +322,7 @@ func (daemon *Daemon) foldFilter(ctx context.Context, view container.View, confi if psFilters.Contains("ancestor") { ancestorFilter = true psFilters.WalkValues("ancestor", func(ancestor string) error { - img, err := daemon.imageService.GetImage(ctx, ancestor, nil) + img, err := daemon.imageService.GetImage(ctx, ancestor, imagetypes.GetImageOpts{}) if err != nil { logrus.Warnf("Error while looking up for image %v", ancestor) return nil @@ -585,7 +586,7 @@ func (daemon *Daemon) refreshImage(ctx context.Context, s *container.Snapshot, f c := s.Container image := s.Image // keep the original ref if still valid (hasn't changed) if image != s.ImageID { - img, err := daemon.imageService.GetImage(ctx, image, nil) + img, err := daemon.imageService.GetImage(ctx, image, imagetypes.GetImageOpts{}) if _, isDNE := err.(images.ErrImageDoesNotExist); err != nil && !isDNE { return nil, err } diff --git a/daemon/oci_windows.go b/daemon/oci_windows.go index 432933965625a..225c9942e1d03 100644 --- a/daemon/oci_windows.go +++ b/daemon/oci_windows.go @@ -9,6 +9,7 @@ import ( "strings" containertypes "github.com/docker/docker/api/types/container" + imagetypes "github.com/docker/docker/api/types/image" "github.com/docker/docker/container" "github.com/docker/docker/errdefs" "github.com/docker/docker/oci" @@ -27,7 +28,7 @@ const ( func (daemon *Daemon) createSpec(ctx context.Context, c *container.Container) (*specs.Spec, error) { - img, err := daemon.imageService.GetImage(ctx, string(c.ImageID), nil) + img, err := daemon.imageService.GetImage(ctx, string(c.ImageID), imagetypes.GetImageOpts{}) if err != nil { return nil, err } diff --git a/image/image.go b/image/image.go index 99e8af0cc78cb..25179a1c8a693 100644 --- a/image/image.go +++ b/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.