summaryrefslogtreecommitdiff
path: root/libpod/image
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/image')
-rw-r--r--libpod/image/image.go33
-rw-r--r--libpod/image/manifests.go154
2 files changed, 179 insertions, 8 deletions
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 43fd52a1a..5f914ed79 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -916,12 +916,7 @@ func (i *Image) imageInspectInfo(ctx context.Context) (*types.ImageInspectInfo,
return i.inspectInfo, nil
}
-// Inspect returns an image's inspect data
-func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) {
- span, _ := opentracing.StartSpanFromContext(ctx, "imageInspect")
- span.SetTag("type", "image")
- defer span.Finish()
-
+func (i *Image) inspect(ctx context.Context, calculateSize bool) (*inspect.ImageData, error) {
ociv1Img, err := i.ociv1Image(ctx)
if err != nil {
ociv1Img = &ociv1.Image{}
@@ -936,8 +931,10 @@ func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) {
}
size := int64(-1)
- if usize, err := i.Size(ctx); err == nil {
- size = int64(*usize)
+ if calculateSize {
+ if usize, err := i.Size(ctx); err == nil {
+ size = int64(*usize)
+ }
}
repoTags, err := i.RepoTags()
@@ -1002,6 +999,26 @@ func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) {
return data, nil
}
+// Inspect returns an image's inspect data
+func (i *Image) Inspect(ctx context.Context) (*inspect.ImageData, error) {
+ span, _ := opentracing.StartSpanFromContext(ctx, "imageInspect")
+
+ span.SetTag("type", "image")
+ defer span.Finish()
+
+ return i.inspect(ctx, true)
+}
+
+// InspectNoSize returns an image's inspect data without calculating the size for the image
+func (i *Image) InspectNoSize(ctx context.Context) (*inspect.ImageData, error) {
+ span, _ := opentracing.StartSpanFromContext(ctx, "imageInspectNoSize")
+
+ span.SetTag("type", "image")
+ defer span.Finish()
+
+ return i.inspect(ctx, false)
+}
+
// Import imports and image into the store and returns an image
func (ir *Runtime) Import(ctx context.Context, path, reference string, writer io.Writer, signingOptions SigningOptions, imageConfig ociv1.Image) (*Image, error) {
src, err := tarball.Transport.ParseReference(path)
diff --git a/libpod/image/manifests.go b/libpod/image/manifests.go
new file mode 100644
index 000000000..9dbeb4cc5
--- /dev/null
+++ b/libpod/image/manifests.go
@@ -0,0 +1,154 @@
+package image
+
+import (
+ "context"
+
+ "github.com/containers/buildah/manifests"
+ "github.com/containers/image/v5/manifest"
+ "github.com/containers/image/v5/transports/alltransports"
+ "github.com/containers/image/v5/types"
+ "github.com/opencontainers/go-digest"
+ "github.com/pkg/errors"
+)
+
+// Options for adding a manifest
+// swagger:model ManifestAddOpts
+type ManifestAddOpts struct {
+ All bool `json:"all"`
+ Annotation map[string]string `json:"annotation"`
+ Arch string `json:"arch"`
+ Features []string `json:"features"`
+ Images []string `json:"images"`
+ OSVersion string `json:"os_version"`
+ Variant string `json:"variant"`
+}
+
+// InspectManifest returns a dockerized version of the manifest list
+func (i *Image) InspectManifest() (*manifest.Schema2List, error) {
+ list, err := i.getManifestList()
+ if err != nil {
+ return nil, err
+ }
+ return list.Docker(), nil
+}
+
+// RemoveManifest removes the given digest from the manifest list.
+func (i *Image) RemoveManifest(d digest.Digest) (string, error) {
+ list, err := i.getManifestList()
+ if err != nil {
+ return "", err
+ }
+ if err := list.Remove(d); err != nil {
+ return "", err
+ }
+ return list.SaveToImage(i.imageruntime.store, i.ID(), nil, "")
+}
+
+// getManifestList is a helper to obtain a manifest list
+func (i *Image) getManifestList() (manifests.List, error) {
+ _, list, err := manifests.LoadFromImage(i.imageruntime.store, i.ID())
+ return list, err
+}
+
+// CreateManifestList creates a new manifest list and can optionally add given images
+// to the list
+func CreateManifestList(rt *Runtime, systemContext types.SystemContext, names []string, imgs []string, all bool) (string, error) {
+ list := manifests.Create()
+ opts := ManifestAddOpts{Images: names, All: all}
+ for _, img := range imgs {
+ var ref types.ImageReference
+ newImage, err := rt.NewFromLocal(img)
+ if err == nil {
+ ir, err := newImage.toImageRef(context.Background())
+ if err != nil {
+ return "", err
+ }
+ if ir == nil {
+ return "", errors.New("unable to convert image to ImageReference")
+ }
+ ref = ir.Reference()
+ } else {
+ ref, err = alltransports.ParseImageName(img)
+ if err != nil {
+ return "", err
+ }
+ }
+ list, err = addManifestToList(ref, list, systemContext, opts)
+ if err != nil {
+ return "", err
+ }
+ }
+ return list.SaveToImage(rt.store, "", names, manifest.DockerV2ListMediaType)
+}
+
+func addManifestToList(ref types.ImageReference, list manifests.List, systemContext types.SystemContext, opts ManifestAddOpts) (manifests.List, error) {
+ d, err := list.Add(context.Background(), &systemContext, ref, opts.All)
+ if err != nil {
+ return nil, err
+ }
+ if len(opts.OSVersion) > 0 {
+ if err := list.SetOSVersion(d, opts.OSVersion); err != nil {
+ return nil, err
+ }
+ }
+ if len(opts.Features) > 0 {
+ if err := list.SetFeatures(d, opts.Features); err != nil {
+ return nil, err
+ }
+ }
+ if len(opts.Arch) > 0 {
+ if err := list.SetArchitecture(d, opts.Arch); err != nil {
+ return nil, err
+ }
+ }
+ if len(opts.Variant) > 0 {
+ if err := list.SetVariant(d, opts.Variant); err != nil {
+ return nil, err
+ }
+ }
+ if len(opts.Annotation) > 0 {
+ if err := list.SetAnnotations(&d, opts.Annotation); err != nil {
+ return nil, err
+ }
+ }
+ return list, err
+}
+
+// AddManifest adds a manifest to a given manifest list.
+func (i *Image) AddManifest(systemContext types.SystemContext, opts ManifestAddOpts) (string, error) {
+ var (
+ ref types.ImageReference
+ )
+ newImage, err := i.imageruntime.NewFromLocal(opts.Images[0])
+ if err == nil {
+ ir, err := newImage.toImageRef(context.Background())
+ if err != nil {
+ return "", err
+ }
+ ref = ir.Reference()
+ } else {
+ ref, err = alltransports.ParseImageName(opts.Images[0])
+ if err != nil {
+ return "", err
+ }
+ }
+ list, err := i.getManifestList()
+ if err != nil {
+ return "", err
+ }
+ list, err = addManifestToList(ref, list, systemContext, opts)
+ if err != nil {
+ return "", err
+ }
+ return list.SaveToImage(i.imageruntime.store, i.ID(), nil, "")
+}
+
+// PushManifest pushes a manifest to a destination
+func (i *Image) PushManifest(dest types.ImageReference, opts manifests.PushOptions) (digest.Digest, error) {
+ list, err := i.getManifestList()
+ if err != nil {
+ return "", err
+ }
+ _, d, err := list.Push(context.Background(), dest, opts)
+ return d, err
+}