summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_internal.go2
-rw-r--r--libpod/image/image.go178
-rw-r--r--libpod/image_inspect.go89
-rw-r--r--libpod/runtime_img.go6
4 files changed, 152 insertions, 123 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index c3cae8509..e228dd651 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -930,7 +930,7 @@ func (c *Container) addImageVolumes(g *generate.Generator) error {
if err != nil {
return err
}
- imageData, err := GetImageData(newImage)
+ imageData, err := newImage.Inspect()
if err != nil {
return err
}
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 15fc5174c..633a682cc 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -26,15 +26,23 @@ import (
"github.com/projectatomic/libpod/pkg/util"
)
+// imageConversions is used to cache image "cast" types
+type imageConversions struct {
+ imgRef types.Image
+ storeRef types.ImageReference
+}
+
// Image is the primary struct for dealing with images
// It is still very much a work in progress
type Image struct {
// Adding these two structs for now but will cull when we near
// completion of this library.
+ imageConversions
inspect.ImageData
inspect.ImageResult
- InputName string
- Local bool
+ inspectInfo *types.ImageInspectInfo
+ InputName string
+ Local bool
//runtime *libpod.Runtime
image *storage.Image
imageruntime *Runtime
@@ -226,11 +234,22 @@ func (i *Image) ID() string {
return i.image.ID
}
-// Digest returns the image's Manifest
+// Digest returns the image's digest
func (i *Image) Digest() digest.Digest {
return i.image.Digest
}
+// Manifest returns the image's manifest as a byte array
+// and manifest type as a string. The manifest type is
+// MediaTypeImageManifest from ociv1.
+func (i *Image) Manifest() ([]byte, string, error) {
+ imgRef, err := i.toImageRef()
+ if err != nil {
+ return nil, "", err
+ }
+ return imgRef.Manifest()
+}
+
// Names returns a string array of names associated with the image
func (i *Image) Names() []string {
return i.image.Names
@@ -253,20 +272,6 @@ func (i *Image) Remove(force bool) error {
return err
}
-func annotations(manifest []byte, manifestType string) map[string]string {
- annotations := make(map[string]string)
- switch manifestType {
- case ociv1.MediaTypeImageManifest:
- var m ociv1.Manifest
- if err := json.Unmarshal(manifest, &m); err == nil {
- for k, v := range m.Annotations {
- annotations[k] = v
- }
- }
- }
- return annotations
-}
-
// Decompose an Image
func (i *Image) Decompose() error {
return types2.NotImplementedError
@@ -349,6 +354,14 @@ func getImageDigest(src types.ImageReference, ctx *types.SystemContext) (string,
// TagImage adds a tag to the given image
func (i *Image) TagImage(tag string) error {
+ decomposedTag, err := decompose(tag)
+ if err != nil {
+ return err
+ }
+ // If the input does not have a tag, we need to add one (latest)
+ if !decomposedTag.isTagged {
+ tag = fmt.Sprintf("%s:%s", tag, decomposedTag.tag)
+ }
tags := i.Names()
if util.StringInSlice(tag, tags) {
return nil
@@ -426,7 +439,14 @@ func (i *Image) MatchesID(id string) bool {
// toStorageReference returns a *storageReference from an Image
func (i *Image) toStorageReference() (types.ImageReference, error) {
- return is.Transport.ParseStoreReference(i.imageruntime.store, i.ID())
+ if i.storeRef == nil {
+ storeRef, err := is.Transport.ParseStoreReference(i.imageruntime.store, i.ID())
+ if err != nil {
+ return nil, err
+ }
+ i.storeRef = storeRef
+ }
+ return i.storeRef, nil
}
// ToImageRef returns an image reference type from an image
@@ -437,15 +457,18 @@ func (i *Image) ToImageRef() (types.Image, error) {
// toImageRef returns an Image Reference type from an image
func (i *Image) toImageRef() (types.Image, error) {
- ref, err := is.Transport.ParseStoreReference(i.imageruntime.store, "@"+i.ID())
- if err != nil {
- return nil, errors.Wrapf(err, "error parsing reference to image %q", i.ID())
- }
- imgRef, err := ref.NewImage(nil)
- if err != nil {
- return nil, errors.Wrapf(err, "error reading image %q", i.ID())
+ if i.imgRef == nil {
+ ref, err := is.Transport.ParseStoreReference(i.imageruntime.store, "@"+i.ID())
+ if err != nil {
+ return nil, errors.Wrapf(err, "error parsing reference to image %q", i.ID())
+ }
+ imgRef, err := ref.NewImage(nil)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading image %q", i.ID())
+ }
+ i.imgRef = imgRef
}
- return imgRef, nil
+ return i.imgRef, nil
}
// sizer knows its size.
@@ -507,19 +530,114 @@ func (i *Image) Dangling() bool {
// Labels returns the image's labels
func (i *Image) Labels() (map[string]string, error) {
- sr, err := i.toStorageReference()
+ imgInspect, err := i.imageInspectInfo()
+ if err != nil {
+ return nil, nil
+ }
+ return imgInspect.Labels, nil
+}
+
+// Annotations returns the annotations of an image
+func (i *Image) Annotations() (map[string]string, error) {
+ manifest, manifestType, err := i.Manifest()
+ if err != nil {
+ return nil, err
+ }
+ annotations := make(map[string]string)
+ switch manifestType {
+ case ociv1.MediaTypeImageManifest:
+ var m ociv1.Manifest
+ if err := json.Unmarshal(manifest, &m); err == nil {
+ for k, v := range m.Annotations {
+ annotations[k] = v
+ }
+ }
+ }
+ return annotations, nil
+}
+
+// ociv1Image converts and image to an imgref and then an
+// ociv1 image type
+func (i *Image) ociv1Image() (*ociv1.Image, error) {
+ imgRef, err := i.toImageRef()
if err != nil {
return nil, err
}
- ic, err := sr.NewImage(&types.SystemContext{})
+ return imgRef.OCIConfig()
+}
+
+func (i *Image) imageInspectInfo() (*types.ImageInspectInfo, error) {
+ if i.inspectInfo == nil {
+ sr, err := i.toStorageReference()
+ if err != nil {
+ return nil, err
+ }
+ ic, err := sr.NewImage(&types.SystemContext{})
+ if err != nil {
+ return nil, err
+ }
+ imgInspect, err := ic.Inspect()
+ if err != nil {
+ return nil, err
+ }
+ i.inspectInfo = imgInspect
+ }
+ return i.inspectInfo, nil
+}
+
+// Inspect returns an image's inspect data
+func (i *Image) Inspect() (*inspect.ImageData, error) {
+ ociv1Img, err := i.ociv1Image()
if err != nil {
return nil, err
}
- imgInspect, err := ic.Inspect()
+ info, err := i.imageInspectInfo()
if err != nil {
return nil, err
}
- return imgInspect.Labels, nil
+ annotations, err := i.Annotations()
+ if err != nil {
+ return nil, err
+ }
+
+ size, err := i.Size()
+ if err != nil {
+ return nil, err
+ }
+
+ var repoDigests []string
+ for _, name := range i.Names() {
+ repoDigests = append(repoDigests, strings.SplitN(name, ":", 2)[0]+"@"+i.Digest().String())
+ }
+
+ driver, err := i.DriverData()
+ if err != nil {
+ return nil, err
+ }
+
+ data := &inspect.ImageData{
+ ID: i.ID(),
+ RepoTags: i.Names(),
+ RepoDigests: repoDigests,
+ Comment: ociv1Img.History[0].Comment,
+ Created: ociv1Img.Created,
+ Author: ociv1Img.Author,
+ Architecture: ociv1Img.Architecture,
+ Os: ociv1Img.OS,
+ ContainerConfig: &ociv1Img.Config,
+ Version: info.DockerVersion,
+ Size: int64(*size),
+ VirtualSize: int64(*size),
+ Annotations: annotations,
+ Digest: i.Digest(),
+ Labels: info.Labels,
+ RootFS: &inspect.RootFS{
+ Type: ociv1Img.RootFS.Type,
+ Layers: ociv1Img.RootFS.DiffIDs,
+ },
+ GraphDriver: driver,
+ }
+ return data, nil
}
// Import imports and image into the store and returns an image
diff --git a/libpod/image_inspect.go b/libpod/image_inspect.go
deleted file mode 100644
index bedad3668..000000000
--- a/libpod/image_inspect.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package libpod
-
-import (
- "encoding/json"
- "strings"
-
- digest "github.com/opencontainers/go-digest"
- ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
- "github.com/pkg/errors"
- "github.com/projectatomic/libpod/libpod/image"
- "github.com/projectatomic/libpod/pkg/inspect"
-)
-
-// GetImageData returns an image's inspect data
-func GetImageData(img *image.Image) (*inspect.ImageData, error) {
- imgRef, err := img.ToImageRef()
- if err != nil {
- return nil, err
- }
- size, err := imgRef.Size()
- if err != nil {
- return nil, err
- }
- manifest, manifestType, err := imgRef.Manifest()
- if err != nil {
- return nil, errors.Wrapf(err, "error reading manifest for image %q", img.ID)
- }
- imgDigest := digest.Digest("")
- if len(manifest) > 0 {
- imgDigest = digest.Canonical.FromBytes(manifest)
- }
- annotations := annotations(manifest, manifestType)
-
- ociv1Img, err := imgRef.OCIConfig()
- if err != nil {
- return nil, errors.Wrapf(err, "error getting oci image info %q", img.ID)
- }
- info, err := imgRef.Inspect()
- if err != nil {
- return nil, errors.Wrapf(err, "error getting image info %q", img.ID)
- }
-
- var repoDigests []string
- for _, name := range img.Names() {
- repoDigests = append(repoDigests, strings.SplitN(name, ":", 2)[0]+"@"+imgDigest.String())
- }
-
- driver, err := img.DriverData()
- if err != nil {
- return nil, err
- }
- data := &inspect.ImageData{
- ID: img.ID(),
- RepoTags: img.Names(),
- RepoDigests: repoDigests,
- Comment: ociv1Img.History[0].Comment,
- Created: ociv1Img.Created,
- Author: ociv1Img.Author,
- Architecture: ociv1Img.Architecture,
- Os: ociv1Img.OS,
- ContainerConfig: &ociv1Img.Config,
- Version: info.DockerVersion,
- Size: size,
- VirtualSize: size,
- Annotations: annotations,
- Digest: imgDigest,
- Labels: info.Labels,
- RootFS: &inspect.RootFS{
- Type: ociv1Img.RootFS.Type,
- Layers: ociv1Img.RootFS.DiffIDs,
- },
- GraphDriver: driver,
- }
- return data, nil
-}
-
-func annotations(manifest []byte, manifestType string) map[string]string {
- annotations := make(map[string]string)
- switch manifestType {
- case ociv1.MediaTypeImageManifest:
- var m ociv1.Manifest
- if err := json.Unmarshal(manifest, &m); err == nil {
- for k, v := range m.Annotations {
- annotations[k] = v
- }
- }
- }
- return annotations
-}
diff --git a/libpod/runtime_img.go b/libpod/runtime_img.go
index e3cb4e2c3..248d1c0aa 100644
--- a/libpod/runtime_img.go
+++ b/libpod/runtime_img.go
@@ -961,7 +961,7 @@ func (r *Runtime) GetImages(params *ImageFilterParams, filters ...ImageFilter) (
var imagesFiltered []*image.Image
for _, img := range images {
- info, err := GetImageData(img)
+ info, err := img.Inspect()
if err != nil {
return nil, err
@@ -1062,7 +1062,7 @@ func (r *Runtime) ParseImageFilter(imageInput, filter string) (*ImageFilterParam
params.Label = pair[1]
case "before":
if img, err := findImageInSlice(images, pair[1]); err == nil {
- info, err := GetImageData(img)
+ info, err := img.Inspect()
if err != nil {
return nil, err
}
@@ -1072,7 +1072,7 @@ func (r *Runtime) ParseImageFilter(imageInput, filter string) (*ImageFilterParam
}
case "since":
if img, err := findImageInSlice(images, pair[1]); err == nil {
- info, err := GetImageData(img)
+ info, err := img.Inspect()
if err != nil {
return nil, err
}