2018-02-07 15:52:47 -05:00
|
|
|
package images // import "github.com/docker/docker/daemon/images"
|
2016-05-21 16:36:11 -04:00
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
|
2017-01-25 19:54:18 -05:00
|
|
|
"github.com/docker/distribution/reference"
|
2016-09-06 14:18:12 -04:00
|
|
|
"github.com/docker/docker/api/types"
|
2018-02-13 14:32:05 -05:00
|
|
|
"github.com/docker/docker/image"
|
2016-05-21 16:36:11 -04:00
|
|
|
"github.com/docker/docker/layer"
|
2016-12-10 03:03:38 -05:00
|
|
|
"github.com/pkg/errors"
|
2016-05-21 16:36:11 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
// LookupImage looks up an image by name and returns it as an ImageInspect
|
|
|
|
// structure.
|
2018-02-07 15:52:47 -05:00
|
|
|
func (i *ImageService) LookupImage(name string) (*types.ImageInspect, error) {
|
2020-03-19 16:54:48 -04:00
|
|
|
img, err := i.GetImage(name, nil)
|
2016-05-21 16:36:11 -04:00
|
|
|
if err != nil {
|
2016-12-10 03:03:38 -05:00
|
|
|
return nil, errors.Wrapf(err, "no such image: %s", name)
|
2016-05-21 16:36:11 -04:00
|
|
|
}
|
2022-01-25 06:15:50 -05:00
|
|
|
|
2018-02-02 17:18:46 -05:00
|
|
|
refs := i.referenceStore.References(img.ID().Digest())
|
2016-05-21 16:36:11 -04:00
|
|
|
repoTags := []string{}
|
|
|
|
repoDigests := []string{}
|
|
|
|
for _, ref := range refs {
|
|
|
|
switch ref.(type) {
|
|
|
|
case reference.NamedTagged:
|
2017-01-25 19:54:18 -05:00
|
|
|
repoTags = append(repoTags, reference.FamiliarString(ref))
|
2016-05-21 16:36:11 -04:00
|
|
|
case reference.Canonical:
|
2017-01-25 19:54:18 -05:00
|
|
|
repoDigests = append(repoDigests, reference.FamiliarString(ref))
|
2016-05-21 16:36:11 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var size int64
|
|
|
|
var layerMetadata map[string]string
|
|
|
|
layerID := img.RootFS.ChainID()
|
|
|
|
if layerID != "" {
|
2021-03-19 10:34:08 -04:00
|
|
|
l, err := i.layerStore.Get(layerID)
|
2016-05-21 16:36:11 -04:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-03-19 10:34:08 -04:00
|
|
|
defer layer.ReleaseAndLog(i.layerStore, l)
|
2022-01-21 13:01:34 -05:00
|
|
|
size = l.Size()
|
2016-05-21 16:36:11 -04:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2018-02-02 17:18:46 -05:00
|
|
|
lastUpdated, err := i.imageStore.GetLastUpdated(img.ID())
|
2017-03-02 15:47:02 -05:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-01-24 10:44:02 -05:00
|
|
|
return &types.ImageInspect{
|
2016-05-21 16:36:11 -04:00
|
|
|
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,
|
2019-04-26 18:12:43 -04:00
|
|
|
Variant: img.Variant,
|
2017-09-19 15:14:46 -04:00
|
|
|
Os: img.OperatingSystem(),
|
2016-09-28 18:02:28 -04:00
|
|
|
OsVersion: img.OSVersion,
|
2016-05-21 16:36:11 -04:00
|
|
|
Size: size,
|
|
|
|
VirtualSize: size, // TODO: field unused, deprecate
|
2022-01-24 10:44:02 -05:00
|
|
|
GraphDriver: types.GraphDriverData{
|
|
|
|
Name: i.layerStore.DriverName(),
|
|
|
|
Data: layerMetadata,
|
|
|
|
},
|
|
|
|
RootFS: rootFSToAPIType(img.RootFS),
|
2017-03-02 15:47:02 -05:00
|
|
|
Metadata: types.ImageMetadata{
|
|
|
|
LastTagTime: lastUpdated,
|
|
|
|
},
|
2022-01-24 10:44:02 -05:00
|
|
|
}, nil
|
2016-05-21 16:36:11 -04:00
|
|
|
}
|
2018-02-13 14:32:05 -05:00
|
|
|
|
|
|
|
func rootFSToAPIType(rootfs *image.RootFS) types.RootFS {
|
|
|
|
var layers []string
|
|
|
|
for _, l := range rootfs.DiffIDs {
|
|
|
|
layers = append(layers, l.String())
|
|
|
|
}
|
|
|
|
return types.RootFS{
|
|
|
|
Type: rootfs.Type,
|
|
|
|
Layers: layers,
|
|
|
|
}
|
|
|
|
}
|