Move some image related methods & struct to smaller files
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
parent
e3079b4704
commit
d5baf8ddcf
5 changed files with 312 additions and 277 deletions
277
daemon/daemon.go
277
daemon/daemon.go
|
@ -24,7 +24,6 @@ import (
|
|||
"github.com/Sirupsen/logrus"
|
||||
containerd "github.com/docker/containerd/api/grpc/types"
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/builder"
|
||||
"github.com/docker/docker/container"
|
||||
"github.com/docker/docker/daemon/events"
|
||||
"github.com/docker/docker/daemon/exec"
|
||||
|
@ -41,7 +40,6 @@ import (
|
|||
"github.com/docker/docker/distribution/xfer"
|
||||
"github.com/docker/docker/dockerversion"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/image/tarexport"
|
||||
"github.com/docker/docker/layer"
|
||||
"github.com/docker/docker/libcontainerd"
|
||||
"github.com/docker/docker/migrate/v1"
|
||||
|
@ -80,15 +78,6 @@ var (
|
|||
errSystemNotSupported = fmt.Errorf("The Docker daemon is not supported on this platform.")
|
||||
)
|
||||
|
||||
// ErrImageDoesNotExist is error returned when no image can be found for a reference.
|
||||
type ErrImageDoesNotExist struct {
|
||||
RefOrID string
|
||||
}
|
||||
|
||||
func (e ErrImageDoesNotExist) Error() string {
|
||||
return fmt.Sprintf("no such id: %s", e.RefOrID)
|
||||
}
|
||||
|
||||
// Daemon holds information about the Docker daemon.
|
||||
type Daemon struct {
|
||||
ID string
|
||||
|
@ -1008,221 +997,6 @@ func isBrokenPipe(e error) bool {
|
|||
return e == syscall.EPIPE
|
||||
}
|
||||
|
||||
// ExportImage exports a list of images to the given output stream. The
|
||||
// exported images are archived into a tar when written to the output
|
||||
// stream. All images with the given tag and all versions containing
|
||||
// the same tag are exported. names is the set of tags to export, and
|
||||
// outStream is the writer which the images are written to.
|
||||
func (daemon *Daemon) ExportImage(names []string, outStream io.Writer) error {
|
||||
imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore, daemon)
|
||||
return imageExporter.Save(names, outStream)
|
||||
}
|
||||
|
||||
// LookupImage looks up an image by name and returns it as an ImageInspect
|
||||
// structure.
|
||||
func (daemon *Daemon) LookupImage(name string) (*types.ImageInspect, error) {
|
||||
img, err := daemon.GetImage(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("No such image: %s", name)
|
||||
}
|
||||
|
||||
refs := daemon.referenceStore.References(img.ID())
|
||||
repoTags := []string{}
|
||||
repoDigests := []string{}
|
||||
for _, ref := range refs {
|
||||
switch ref.(type) {
|
||||
case reference.NamedTagged:
|
||||
repoTags = append(repoTags, ref.String())
|
||||
case reference.Canonical:
|
||||
repoDigests = append(repoDigests, ref.String())
|
||||
}
|
||||
}
|
||||
|
||||
var size int64
|
||||
var layerMetadata map[string]string
|
||||
layerID := img.RootFS.ChainID()
|
||||
if layerID != "" {
|
||||
l, err := daemon.layerStore.Get(layerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer layer.ReleaseAndLog(daemon.layerStore, l)
|
||||
size, err = l.Size()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
imageInspect := &types.ImageInspect{
|
||||
ID: img.ID().String(),
|
||||
RepoTags: repoTags,
|
||||
RepoDigests: repoDigests,
|
||||
Parent: img.Parent.String(),
|
||||
Comment: comment,
|
||||
Created: img.Created.Format(time.RFC3339Nano),
|
||||
Container: img.Container,
|
||||
ContainerConfig: &img.ContainerConfig,
|
||||
DockerVersion: img.DockerVersion,
|
||||
Author: img.Author,
|
||||
Config: img.Config,
|
||||
Architecture: img.Architecture,
|
||||
Os: img.OS,
|
||||
Size: size,
|
||||
VirtualSize: size, // TODO: field unused, deprecate
|
||||
RootFS: rootFSToAPIType(img.RootFS),
|
||||
}
|
||||
|
||||
imageInspect.GraphDriver.Name = daemon.GraphDriverName()
|
||||
|
||||
imageInspect.GraphDriver.Data = layerMetadata
|
||||
|
||||
return imageInspect, nil
|
||||
}
|
||||
|
||||
// LoadImage uploads a set of images into the repository. This is the
|
||||
// complement of ImageExport. The input stream is an uncompressed tar
|
||||
// ball containing images and metadata.
|
||||
func (daemon *Daemon) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
|
||||
imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore, daemon)
|
||||
return imageExporter.Load(inTar, outStream, quiet)
|
||||
}
|
||||
|
||||
// ImageHistory returns a slice of ImageHistory structures for the specified image
|
||||
// name by walking the image lineage.
|
||||
func (daemon *Daemon) ImageHistory(name string) ([]*types.ImageHistory, error) {
|
||||
img, err := daemon.GetImage(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
history := []*types.ImageHistory{}
|
||||
|
||||
layerCounter := 0
|
||||
rootFS := *img.RootFS
|
||||
rootFS.DiffIDs = nil
|
||||
|
||||
for _, h := range img.History {
|
||||
var layerSize int64
|
||||
|
||||
if !h.EmptyLayer {
|
||||
if len(img.RootFS.DiffIDs) <= layerCounter {
|
||||
return nil, fmt.Errorf("too many non-empty layers in History section")
|
||||
}
|
||||
|
||||
rootFS.Append(img.RootFS.DiffIDs[layerCounter])
|
||||
l, err := daemon.layerStore.Get(rootFS.ChainID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
layerSize, err = l.DiffSize()
|
||||
layer.ReleaseAndLog(daemon.layerStore, l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
layerCounter++
|
||||
}
|
||||
|
||||
history = append([]*types.ImageHistory{{
|
||||
ID: "<missing>",
|
||||
Created: h.Created.Unix(),
|
||||
CreatedBy: h.CreatedBy,
|
||||
Comment: h.Comment,
|
||||
Size: layerSize,
|
||||
}}, history...)
|
||||
}
|
||||
|
||||
// Fill in image IDs and tags
|
||||
histImg := img
|
||||
id := img.ID()
|
||||
for _, h := range history {
|
||||
h.ID = id.String()
|
||||
|
||||
var tags []string
|
||||
for _, r := range daemon.referenceStore.References(id) {
|
||||
if _, ok := r.(reference.NamedTagged); ok {
|
||||
tags = append(tags, r.String())
|
||||
}
|
||||
}
|
||||
|
||||
h.Tags = tags
|
||||
|
||||
id = histImg.Parent
|
||||
if id == "" {
|
||||
break
|
||||
}
|
||||
histImg, err = daemon.GetImage(id.String())
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return history, nil
|
||||
}
|
||||
|
||||
// GetImageID returns an image ID corresponding to the image referred to by
|
||||
// refOrID.
|
||||
func (daemon *Daemon) GetImageID(refOrID string) (image.ID, error) {
|
||||
id, ref, err := reference.ParseIDOrReference(refOrID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if id != "" {
|
||||
if _, err := daemon.imageStore.Get(image.ID(id)); err != nil {
|
||||
return "", ErrImageDoesNotExist{refOrID}
|
||||
}
|
||||
return image.ID(id), nil
|
||||
}
|
||||
|
||||
if id, err := daemon.referenceStore.Get(ref); err == nil {
|
||||
return id, nil
|
||||
}
|
||||
if tagged, ok := ref.(reference.NamedTagged); ok {
|
||||
if id, err := daemon.imageStore.Search(tagged.Tag()); err == nil {
|
||||
for _, namedRef := range daemon.referenceStore.References(id) {
|
||||
if namedRef.Name() == ref.Name() {
|
||||
return id, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search based on ID
|
||||
if id, err := daemon.imageStore.Search(refOrID); err == nil {
|
||||
return id, nil
|
||||
}
|
||||
|
||||
return "", ErrImageDoesNotExist{refOrID}
|
||||
}
|
||||
|
||||
// GetImage returns an image corresponding to the image referred to by refOrID.
|
||||
func (daemon *Daemon) GetImage(refOrID string) (*image.Image, error) {
|
||||
imgID, err := daemon.GetImageID(refOrID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return daemon.imageStore.Get(imgID)
|
||||
}
|
||||
|
||||
// GetImageOnBuild looks up a Docker image referenced by `name`.
|
||||
func (daemon *Daemon) GetImageOnBuild(name string) (builder.Image, error) {
|
||||
img, err := daemon.GetImage(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return img, nil
|
||||
}
|
||||
|
||||
// GraphDriverName returns the name of the graph driver used by the layer.Store
|
||||
func (daemon *Daemon) GraphDriverName() string {
|
||||
return daemon.layerStore.DriverName()
|
||||
|
@ -1243,57 +1017,6 @@ func (daemon *Daemon) GetRemappedUIDGID() (int, int) {
|
|||
return uid, gid
|
||||
}
|
||||
|
||||
// GetCachedImage returns the most recent created image that is a child
|
||||
// of the image with imgID, that had the same config when it was
|
||||
// created. nil is returned if a child cannot be found. An error is
|
||||
// returned if the parent image cannot be found.
|
||||
func (daemon *Daemon) GetCachedImage(imgID image.ID, config *containertypes.Config) (*image.Image, error) {
|
||||
// Loop on the children of the given image and check the config
|
||||
getMatch := func(siblings []image.ID) (*image.Image, error) {
|
||||
var match *image.Image
|
||||
for _, id := range siblings {
|
||||
img, err := daemon.imageStore.Get(id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find image %q", id)
|
||||
}
|
||||
|
||||
if runconfig.Compare(&img.ContainerConfig, config) {
|
||||
// check for the most up to date match
|
||||
if match == nil || match.Created.Before(img.Created) {
|
||||
match = img
|
||||
}
|
||||
}
|
||||
}
|
||||
return match, nil
|
||||
}
|
||||
|
||||
// In this case, this is `FROM scratch`, which isn't an actual image.
|
||||
if imgID == "" {
|
||||
images := daemon.imageStore.Map()
|
||||
var siblings []image.ID
|
||||
for id, img := range images {
|
||||
if img.Parent == imgID {
|
||||
siblings = append(siblings, id)
|
||||
}
|
||||
}
|
||||
return getMatch(siblings)
|
||||
}
|
||||
|
||||
// find match from child images
|
||||
siblings := daemon.imageStore.Children(imgID)
|
||||
return getMatch(siblings)
|
||||
}
|
||||
|
||||
// GetCachedImageOnBuild returns a reference to a cached image whose parent equals `parent`
|
||||
// and runconfig equals `cfg`. A cache miss is expected to return an empty ID and a nil error.
|
||||
func (daemon *Daemon) GetCachedImageOnBuild(imgID string, cfg *containertypes.Config) (string, error) {
|
||||
cache, err := daemon.GetCachedImage(image.ID(imgID), cfg)
|
||||
if cache == nil || err != nil {
|
||||
return "", err
|
||||
}
|
||||
return cache.ID().String(), nil
|
||||
}
|
||||
|
||||
// tempDir returns the default directory to use for temporary files.
|
||||
func tempDir(rootDir string, rootUID, rootGID int) (string, error) {
|
||||
var tmpDir string
|
||||
|
|
124
daemon/image.go
Normal file
124
daemon/image.go
Normal file
|
@ -0,0 +1,124 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/builder"
|
||||
"github.com/docker/docker/image"
|
||||
"github.com/docker/docker/reference"
|
||||
"github.com/docker/docker/runconfig"
|
||||
containertypes "github.com/docker/engine-api/types/container"
|
||||
)
|
||||
|
||||
// ErrImageDoesNotExist is error returned when no image can be found for a reference.
|
||||
type ErrImageDoesNotExist struct {
|
||||
RefOrID string
|
||||
}
|
||||
|
||||
func (e ErrImageDoesNotExist) Error() string {
|
||||
return fmt.Sprintf("no such id: %s", e.RefOrID)
|
||||
}
|
||||
|
||||
// GetImageID returns an image ID corresponding to the image referred to by
|
||||
// refOrID.
|
||||
func (daemon *Daemon) GetImageID(refOrID string) (image.ID, error) {
|
||||
id, ref, err := reference.ParseIDOrReference(refOrID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if id != "" {
|
||||
if _, err := daemon.imageStore.Get(image.ID(id)); err != nil {
|
||||
return "", ErrImageDoesNotExist{refOrID}
|
||||
}
|
||||
return image.ID(id), nil
|
||||
}
|
||||
|
||||
if id, err := daemon.referenceStore.Get(ref); err == nil {
|
||||
return id, nil
|
||||
}
|
||||
if tagged, ok := ref.(reference.NamedTagged); ok {
|
||||
if id, err := daemon.imageStore.Search(tagged.Tag()); err == nil {
|
||||
for _, namedRef := range daemon.referenceStore.References(id) {
|
||||
if namedRef.Name() == ref.Name() {
|
||||
return id, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search based on ID
|
||||
if id, err := daemon.imageStore.Search(refOrID); err == nil {
|
||||
return id, nil
|
||||
}
|
||||
|
||||
return "", ErrImageDoesNotExist{refOrID}
|
||||
}
|
||||
|
||||
// GetImage returns an image corresponding to the image referred to by refOrID.
|
||||
func (daemon *Daemon) GetImage(refOrID string) (*image.Image, error) {
|
||||
imgID, err := daemon.GetImageID(refOrID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return daemon.imageStore.Get(imgID)
|
||||
}
|
||||
|
||||
// GetImageOnBuild looks up a Docker image referenced by `name`.
|
||||
func (daemon *Daemon) GetImageOnBuild(name string) (builder.Image, error) {
|
||||
img, err := daemon.GetImage(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return img, nil
|
||||
}
|
||||
|
||||
// GetCachedImage returns the most recent created image that is a child
|
||||
// of the image with imgID, that had the same config when it was
|
||||
// created. nil is returned if a child cannot be found. An error is
|
||||
// returned if the parent image cannot be found.
|
||||
func (daemon *Daemon) GetCachedImage(imgID image.ID, config *containertypes.Config) (*image.Image, error) {
|
||||
// Loop on the children of the given image and check the config
|
||||
getMatch := func(siblings []image.ID) (*image.Image, error) {
|
||||
var match *image.Image
|
||||
for _, id := range siblings {
|
||||
img, err := daemon.imageStore.Get(id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find image %q", id)
|
||||
}
|
||||
|
||||
if runconfig.Compare(&img.ContainerConfig, config) {
|
||||
// check for the most up to date match
|
||||
if match == nil || match.Created.Before(img.Created) {
|
||||
match = img
|
||||
}
|
||||
}
|
||||
}
|
||||
return match, nil
|
||||
}
|
||||
|
||||
// In this case, this is `FROM scratch`, which isn't an actual image.
|
||||
if imgID == "" {
|
||||
images := daemon.imageStore.Map()
|
||||
var siblings []image.ID
|
||||
for id, img := range images {
|
||||
if img.Parent == imgID {
|
||||
siblings = append(siblings, id)
|
||||
}
|
||||
}
|
||||
return getMatch(siblings)
|
||||
}
|
||||
|
||||
// find match from child images
|
||||
siblings := daemon.imageStore.Children(imgID)
|
||||
return getMatch(siblings)
|
||||
}
|
||||
|
||||
// GetCachedImageOnBuild returns a reference to a cached image whose parent equals `parent`
|
||||
// and runconfig equals `cfg`. A cache miss is expected to return an empty ID and a nil error.
|
||||
func (daemon *Daemon) GetCachedImageOnBuild(imgID string, cfg *containertypes.Config) (string, error) {
|
||||
cache, err := daemon.GetCachedImage(image.ID(imgID), cfg)
|
||||
if cache == nil || err != nil {
|
||||
return "", err
|
||||
}
|
||||
return cache.ID().String(), nil
|
||||
}
|
25
daemon/image_exporter.go
Normal file
25
daemon/image_exporter.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/docker/docker/image/tarexport"
|
||||
)
|
||||
|
||||
// ExportImage exports a list of images to the given output stream. The
|
||||
// exported images are archived into a tar when written to the output
|
||||
// stream. All images with the given tag and all versions containing
|
||||
// the same tag are exported. names is the set of tags to export, and
|
||||
// outStream is the writer which the images are written to.
|
||||
func (daemon *Daemon) ExportImage(names []string, outStream io.Writer) error {
|
||||
imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore, daemon)
|
||||
return imageExporter.Save(names, outStream)
|
||||
}
|
||||
|
||||
// LoadImage uploads a set of images into the repository. This is the
|
||||
// complement of ImageExport. The input stream is an uncompressed tar
|
||||
// ball containing images and metadata.
|
||||
func (daemon *Daemon) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
|
||||
imageExporter := tarexport.NewTarExporter(daemon.imageStore, daemon.layerStore, daemon.referenceStore, daemon)
|
||||
return imageExporter.Load(inTar, outStream, quiet)
|
||||
}
|
82
daemon/image_history.go
Normal file
82
daemon/image_history.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/layer"
|
||||
"github.com/docker/docker/reference"
|
||||
"github.com/docker/engine-api/types"
|
||||
)
|
||||
|
||||
// ImageHistory returns a slice of ImageHistory structures for the specified image
|
||||
// name by walking the image lineage.
|
||||
func (daemon *Daemon) ImageHistory(name string) ([]*types.ImageHistory, error) {
|
||||
img, err := daemon.GetImage(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
history := []*types.ImageHistory{}
|
||||
|
||||
layerCounter := 0
|
||||
rootFS := *img.RootFS
|
||||
rootFS.DiffIDs = nil
|
||||
|
||||
for _, h := range img.History {
|
||||
var layerSize int64
|
||||
|
||||
if !h.EmptyLayer {
|
||||
if len(img.RootFS.DiffIDs) <= layerCounter {
|
||||
return nil, fmt.Errorf("too many non-empty layers in History section")
|
||||
}
|
||||
|
||||
rootFS.Append(img.RootFS.DiffIDs[layerCounter])
|
||||
l, err := daemon.layerStore.Get(rootFS.ChainID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
layerSize, err = l.DiffSize()
|
||||
layer.ReleaseAndLog(daemon.layerStore, l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
layerCounter++
|
||||
}
|
||||
|
||||
history = append([]*types.ImageHistory{{
|
||||
ID: "<missing>",
|
||||
Created: h.Created.Unix(),
|
||||
CreatedBy: h.CreatedBy,
|
||||
Comment: h.Comment,
|
||||
Size: layerSize,
|
||||
}}, history...)
|
||||
}
|
||||
|
||||
// Fill in image IDs and tags
|
||||
histImg := img
|
||||
id := img.ID()
|
||||
for _, h := range history {
|
||||
h.ID = id.String()
|
||||
|
||||
var tags []string
|
||||
for _, r := range daemon.referenceStore.References(id) {
|
||||
if _, ok := r.(reference.NamedTagged); ok {
|
||||
tags = append(tags, r.String())
|
||||
}
|
||||
}
|
||||
|
||||
h.Tags = tags
|
||||
|
||||
id = histImg.Parent
|
||||
if id == "" {
|
||||
break
|
||||
}
|
||||
histImg, err = daemon.GetImage(id.String())
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return history, nil
|
||||
}
|
81
daemon/image_inspect.go
Normal file
81
daemon/image_inspect.go
Normal file
|
@ -0,0 +1,81 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/layer"
|
||||
"github.com/docker/docker/reference"
|
||||
"github.com/docker/engine-api/types"
|
||||
)
|
||||
|
||||
// LookupImage looks up an image by name and returns it as an ImageInspect
|
||||
// structure.
|
||||
func (daemon *Daemon) LookupImage(name string) (*types.ImageInspect, error) {
|
||||
img, err := daemon.GetImage(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("No such image: %s", name)
|
||||
}
|
||||
|
||||
refs := daemon.referenceStore.References(img.ID())
|
||||
repoTags := []string{}
|
||||
repoDigests := []string{}
|
||||
for _, ref := range refs {
|
||||
switch ref.(type) {
|
||||
case reference.NamedTagged:
|
||||
repoTags = append(repoTags, ref.String())
|
||||
case reference.Canonical:
|
||||
repoDigests = append(repoDigests, ref.String())
|
||||
}
|
||||
}
|
||||
|
||||
var size int64
|
||||
var layerMetadata map[string]string
|
||||
layerID := img.RootFS.ChainID()
|
||||
if layerID != "" {
|
||||
l, err := daemon.layerStore.Get(layerID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer layer.ReleaseAndLog(daemon.layerStore, l)
|
||||
size, err = l.Size()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
imageInspect := &types.ImageInspect{
|
||||
ID: img.ID().String(),
|
||||
RepoTags: repoTags,
|
||||
RepoDigests: repoDigests,
|
||||
Parent: img.Parent.String(),
|
||||
Comment: comment,
|
||||
Created: img.Created.Format(time.RFC3339Nano),
|
||||
Container: img.Container,
|
||||
ContainerConfig: &img.ContainerConfig,
|
||||
DockerVersion: img.DockerVersion,
|
||||
Author: img.Author,
|
||||
Config: img.Config,
|
||||
Architecture: img.Architecture,
|
||||
Os: img.OS,
|
||||
Size: size,
|
||||
VirtualSize: size, // TODO: field unused, deprecate
|
||||
RootFS: rootFSToAPIType(img.RootFS),
|
||||
}
|
||||
|
||||
imageInspect.GraphDriver.Name = daemon.GraphDriverName()
|
||||
|
||||
imageInspect.GraphDriver.Data = layerMetadata
|
||||
|
||||
return imageInspect, nil
|
||||
}
|
Loading…
Add table
Reference in a new issue