mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
This change makes the `GraphDriver` field in `image.InspectResponse` optional. This field will only be returned when using moby engine graph drivers as a backend storage implementation. It will be omitted when using the containerd image backend. Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
106 lines
2.9 KiB
Go
106 lines
2.9 KiB
Go
package images
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"github.com/distribution/reference"
|
|
imagetypes "github.com/moby/moby/api/types/image"
|
|
"github.com/moby/moby/api/types/storage"
|
|
"github.com/moby/moby/v2/daemon/internal/image"
|
|
"github.com/moby/moby/v2/daemon/internal/layer"
|
|
"github.com/moby/moby/v2/daemon/server/backend"
|
|
)
|
|
|
|
func (i *ImageService) ImageInspect(ctx context.Context, refOrID string, opts backend.ImageInspectOpts) (*imagetypes.InspectResponse, error) {
|
|
img, err := i.GetImage(ctx, refOrID, backend.GetImageOpts{Platform: opts.Platform})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
size, layerMetadata, err := i.getLayerSizeAndMetadata(img)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
lastUpdated, err := i.imageStore.GetLastUpdated(img.ID())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var repoTags, repoDigests []string
|
|
for _, ref := range i.referenceStore.References(img.ID().Digest()) {
|
|
switch ref.(type) {
|
|
case reference.NamedTagged:
|
|
repoTags = append(repoTags, reference.FamiliarString(ref))
|
|
case reference.Canonical:
|
|
repoDigests = append(repoDigests, reference.FamiliarString(ref))
|
|
}
|
|
}
|
|
|
|
comment := img.Comment
|
|
if comment == "" && len(img.History) > 0 {
|
|
comment = img.History[len(img.History)-1].Comment
|
|
}
|
|
|
|
var created string
|
|
if img.Created != nil {
|
|
created = img.Created.Format(time.RFC3339Nano)
|
|
}
|
|
|
|
var layers []string
|
|
for _, l := range img.RootFS.DiffIDs {
|
|
layers = append(layers, l.String())
|
|
}
|
|
|
|
imgConfig := containerConfigToDockerOCIImageConfig(img.Config)
|
|
return &imagetypes.InspectResponse{
|
|
ID: img.ID().String(),
|
|
RepoTags: repoTags,
|
|
RepoDigests: repoDigests,
|
|
Parent: img.Parent.String(),
|
|
Comment: comment,
|
|
Created: created,
|
|
Container: img.Container, //nolint:staticcheck // ignore SA1019: field is deprecated, but still set on API < v1.45.
|
|
ContainerConfig: &img.ContainerConfig, //nolint:staticcheck // ignore SA1019: field is deprecated, but still set on API < v1.45.
|
|
DockerVersion: img.DockerVersion,
|
|
Author: img.Author,
|
|
Config: &imgConfig,
|
|
Architecture: img.Architecture,
|
|
Variant: img.Variant,
|
|
Os: img.OperatingSystem(),
|
|
OsVersion: img.OSVersion,
|
|
Size: size,
|
|
GraphDriver: &storage.DriverData{
|
|
Name: i.layerStore.DriverName(),
|
|
Data: layerMetadata,
|
|
},
|
|
RootFS: imagetypes.RootFS{
|
|
Type: img.RootFS.Type,
|
|
Layers: layers,
|
|
},
|
|
Metadata: imagetypes.Metadata{
|
|
LastTagTime: lastUpdated,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (i *ImageService) getLayerSizeAndMetadata(img *image.Image) (int64, map[string]string, error) {
|
|
var size int64
|
|
var layerMetadata map[string]string
|
|
layerID := img.RootFS.ChainID()
|
|
if layerID != "" {
|
|
l, err := i.layerStore.Get(layerID)
|
|
if err != nil {
|
|
return 0, nil, err
|
|
}
|
|
defer layer.ReleaseAndLog(i.layerStore, l)
|
|
size = l.Size()
|
|
layerMetadata, err = l.Metadata()
|
|
if err != nil {
|
|
return 0, nil, err
|
|
}
|
|
}
|
|
return size, layerMetadata, nil
|
|
}
|