cri-o/libkpod/image/imageData.go

129 lines
3.4 KiB
Go
Raw Normal View History

package image
import (
"time"
"github.com/containers/image/docker/reference"
"github.com/containers/storage"
"github.com/kubernetes-incubator/cri-o/cmd/kpod/docker"
"github.com/kubernetes-incubator/cri-o/libkpod/driver"
digest "github.com/opencontainers/go-digest"
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
// ImageData handles the data used when inspecting a container
// nolint
type ImageData struct {
ID string
Tags []string
Digests []string
Digest digest.Digest
Parent string
Comment string
Created *time.Time
Container string
ContainerConfig docker.Config
Author string
Config ociv1.ImageConfig
Architecture string
OS string
Size uint
VirtualSize uint
GraphDriver driver.Data
RootFS ociv1.RootFS
}
// ParseImageNames parses the names we've stored with an image into a list of
// tagged references and a list of references which contain digests.
func ParseImageNames(names []string) (tags, digests []string, err error) {
for _, name := range names {
if named, err := reference.ParseNamed(name); err == nil {
if digested, ok := named.(reference.Digested); ok {
canonical, err := reference.WithDigest(named, digested.Digest())
if err == nil {
digests = append(digests, canonical.String())
}
} else {
if reference.IsNameOnly(named) {
named = reference.TagNameOnly(named)
}
if tagged, ok := named.(reference.Tagged); ok {
namedTagged, err := reference.WithTag(named, tagged.Tag())
if err == nil {
tags = append(tags, namedTagged.String())
}
}
}
}
}
return tags, digests, nil
}
// GetImageData gets the ImageData for a container with the given name in the given store.
func GetImageData(store storage.Store, name string) (*ImageData, error) {
img, err := FindImage(store, name)
if err != nil {
return nil, errors.Wrapf(err, "error reading image %q", name)
}
cid, err := GetImageCopyData(store, name)
if err != nil {
return nil, errors.Wrapf(err, "error reading image %q", name)
}
tags, digests, err := ParseImageNames(img.Names)
if err != nil {
return nil, errors.Wrapf(err, "error parsing image names for %q", name)
}
driverName, err := driver.GetDriverName(store)
if err != nil {
return nil, err
}
topLayerID := img.TopLayer
driverMetadata, err := driver.GetDriverMetadata(store, topLayerID)
if err != nil {
return nil, err
}
layer, err := store.Layer(topLayerID)
if err != nil {
return nil, err
}
size, err := store.DiffSize(layer.Parent, layer.ID)
if err != nil {
return nil, err
}
digest, virtualSize, err := DigestAndSize(store, *img)
if err != nil {
return nil, err
}
return &ImageData{
ID: img.ID,
Tags: tags,
Digests: digests,
Digest: digest,
Parent: string(cid.Docker.Parent),
Comment: cid.OCIv1.History[0].Comment,
Created: cid.OCIv1.Created,
Container: cid.Docker.Container,
ContainerConfig: cid.Docker.ContainerConfig,
Author: cid.OCIv1.Author,
Config: cid.OCIv1.Config,
Architecture: cid.OCIv1.Architecture,
OS: cid.OCIv1.OS,
Size: uint(size),
VirtualSize: uint(virtualSize),
GraphDriver: driver.Data{
Name: driverName,
Data: driverMetadata,
},
RootFS: cid.OCIv1.RootFS,
}, nil
}