summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2018-03-21 09:55:57 -0500
committerAtomic Bot <atomic-devel@projectatomic.io>2018-03-21 19:14:50 +0000
commitd0835493d51038dda2bc63530f4fb70ced9f98cf (patch)
treee8199183a90f2d09dd4eb1f7539031811503bddc
parent3428de0672afcd94ce65d7c29fd23e44e7e2b465 (diff)
downloadpodman-d0835493d51038dda2bc63530f4fb70ced9f98cf.tar.gz
podman-d0835493d51038dda2bc63530f4fb70ced9f98cf.tar.bz2
podman-d0835493d51038dda2bc63530f4fb70ced9f98cf.zip
Migrate podman inspect and tag to image library
Signed-off-by: baude <bbaude@redhat.com> Closes: #525 Approved by: baude
-rw-r--r--cmd/podman/create.go2
-rw-r--r--cmd/podman/inspect.go4
-rw-r--r--cmd/podman/run.go2
-rw-r--r--cmd/podman/tag.go47
-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
8 files changed, 160 insertions, 170 deletions
diff --git a/cmd/podman/create.go b/cmd/podman/create.go
index 947f6d2a6..af065817f 100644
--- a/cmd/podman/create.go
+++ b/cmd/podman/create.go
@@ -180,7 +180,7 @@ func createCmd(c *cli.Context) error {
if err != nil {
return err
}
- data, err := libpod.GetImageData(newImage)
+ data, err := newImage.Inspect()
createConfig, err := parseCreateOpts(c, runtime, newImage.Names()[0], data)
if err != nil {
return err
diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go
index b691b7a12..4c4154d88 100644
--- a/cmd/podman/inspect.go
+++ b/cmd/podman/inspect.go
@@ -133,7 +133,7 @@ func iterateInput(c *cli.Context, args []string, runtime *libpod.Runtime, inspec
inspectError = errors.Wrapf(err, "error getting image %q", input)
break
}
- data, err = libpod.GetImageData(image)
+ data, err = image.Inspect()
if err != nil {
inspectError = errors.Wrapf(err, "error parsing image data %q", image.ID())
break
@@ -146,7 +146,7 @@ func iterateInput(c *cli.Context, args []string, runtime *libpod.Runtime, inspec
inspectError = errors.Wrapf(err, "error getting image %q", input)
break
}
- data, err = libpod.GetImageData(image)
+ data, err = image.Inspect()
if err != nil {
inspectError = errors.Wrapf(err, "error parsing image data %q", image.ID())
break
diff --git a/cmd/podman/run.go b/cmd/podman/run.go
index f1e11f839..53b7083e3 100644
--- a/cmd/podman/run.go
+++ b/cmd/podman/run.go
@@ -54,7 +54,7 @@ func runCmd(c *cli.Context) error {
rtc := runtime.GetConfig()
newImage, err := runtime.ImageRuntime().New(c.Args()[0], rtc.SignaturePolicyPath, "", os.Stderr, nil, image.SigningOptions{})
- data, err := libpod.GetImageData(newImage)
+ data, err := newImage.Inspect()
if err != nil {
return err
}
diff --git a/cmd/podman/tag.go b/cmd/podman/tag.go
index b71ee97b8..d2a157e7f 100644
--- a/cmd/podman/tag.go
+++ b/cmd/podman/tag.go
@@ -1,10 +1,7 @@
package main
import (
- "github.com/containers/image/docker/reference"
- "github.com/containers/storage"
"github.com/pkg/errors"
- "github.com/projectatomic/libpod/libpod"
"github.com/urfave/cli"
)
@@ -30,51 +27,15 @@ func tagCmd(c *cli.Context) error {
}
defer runtime.Shutdown(false)
- newImage := runtime.NewImage(args[0])
- newImage.GetLocalImageName()
-
- img, err := runtime.GetImage(newImage.LocalName)
+ newImage, err := runtime.ImageRuntime().NewFromLocal(args[0])
if err != nil {
return err
}
- if img == nil {
- return errors.New("null image")
- }
- err = addImageNames(runtime, img, args[1:])
- if err != nil {
- return errors.Wrapf(err, "error adding names %v to image %q", args[1:], args[0])
- }
- return nil
-}
-func addImageNames(runtime *libpod.Runtime, image *storage.Image, addNames []string) error {
- // Add tags to the names if applicable
- names, err := expandedTags(addNames)
- if err != nil {
- return err
- }
- for _, name := range names {
- if err := runtime.TagImage(image, name); err != nil {
- return errors.Wrapf(err, "error adding name (%v) to image %q", name, image.ID)
+ for _, tagName := range args[1:] {
+ if err := newImage.TagImage(tagName); err != nil {
+ return errors.Wrapf(err, "error adding '%s' to image %q", tagName, newImage.InputName)
}
}
return nil
}
-
-func expandedTags(tags []string) ([]string, error) {
- expandedNames := []string{}
- for _, tag := range tags {
- var labelName string
- name, err := reference.Parse(tag)
- if err != nil {
- return nil, errors.Wrapf(err, "error parsing tag %q", name)
- }
- if _, ok := name.(reference.NamedTagged); ok {
- labelName = name.String()
- } else {
- labelName = name.String() + ":latest"
- }
- expandedNames = append(expandedNames, labelName)
- }
- return expandedNames, nil
-}
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
}