diff options
author | baude <bbaude@redhat.com> | 2018-03-21 09:55:57 -0500 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-03-21 19:14:50 +0000 |
commit | d0835493d51038dda2bc63530f4fb70ced9f98cf (patch) | |
tree | e8199183a90f2d09dd4eb1f7539031811503bddc | |
parent | 3428de0672afcd94ce65d7c29fd23e44e7e2b465 (diff) | |
download | podman-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.go | 2 | ||||
-rw-r--r-- | cmd/podman/inspect.go | 4 | ||||
-rw-r--r-- | cmd/podman/run.go | 2 | ||||
-rw-r--r-- | cmd/podman/tag.go | 47 | ||||
-rw-r--r-- | libpod/container_internal.go | 2 | ||||
-rw-r--r-- | libpod/image/image.go | 178 | ||||
-rw-r--r-- | libpod/image_inspect.go | 89 | ||||
-rw-r--r-- | libpod/runtime_img.go | 6 |
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 } |