summaryrefslogtreecommitdiff
path: root/libpod/image
diff options
context:
space:
mode:
authorumohnani8 <umohnani@redhat.com>2018-05-21 13:53:19 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2018-05-25 15:15:47 +0000
commitc8b72e57a75262c0edeea839e9e34bb0c3e03d13 (patch)
tree3a2bb7210d309e358bfe84a0ab0f60e57b9f2e2f /libpod/image
parent0a4ade1c175d3188ad55d22d751a86c96e060a44 (diff)
downloadpodman-c8b72e57a75262c0edeea839e9e34bb0c3e03d13.tar.gz
podman-c8b72e57a75262c0edeea839e9e34bb0c3e03d13.tar.bz2
podman-c8b72e57a75262c0edeea839e9e34bb0c3e03d13.zip
save and load should support multi-tag for docker-archive
The docker-archive tar files can have multiple tags for the same image stored in it. Load pulls all the tags found in the archive when loading a tar file. Save can oush multiple tags of the same image to a tar archive. Signed-off-by: umohnani8 <umohnani@redhat.com> Closes: #819 Approved by: rhatdan
Diffstat (limited to 'libpod/image')
-rw-r--r--libpod/image/docker_registry_options.go8
-rw-r--r--libpod/image/image.go43
-rw-r--r--libpod/image/pull.go41
-rw-r--r--libpod/image/utils.go23
4 files changed, 89 insertions, 26 deletions
diff --git a/libpod/image/docker_registry_options.go b/libpod/image/docker_registry_options.go
index bbb49df28..838edf2d0 100644
--- a/libpod/image/docker_registry_options.go
+++ b/libpod/image/docker_registry_options.go
@@ -1,6 +1,9 @@
package image
-import "github.com/containers/image/types"
+import (
+ "github.com/containers/image/docker/reference"
+ "github.com/containers/image/types"
+)
// DockerRegistryOptions encapsulates settings that affect how we connect or
// authenticate to a remote registry.
@@ -22,7 +25,7 @@ type DockerRegistryOptions struct {
// GetSystemContext constructs a new system context from the given signaturePolicy path and the
// values in the DockerRegistryOptions
-func (o DockerRegistryOptions) GetSystemContext(signaturePolicyPath, authFile string, forceCompress bool) *types.SystemContext {
+func (o DockerRegistryOptions) GetSystemContext(signaturePolicyPath, authFile string, forceCompress bool, additionalDockerArchiveTags []reference.NamedTagged) *types.SystemContext {
sc := &types.SystemContext{
SignaturePolicyPath: signaturePolicyPath,
DockerAuthConfig: o.DockerRegistryCreds,
@@ -30,6 +33,7 @@ func (o DockerRegistryOptions) GetSystemContext(signaturePolicyPath, authFile st
DockerInsecureSkipTLSVerify: o.DockerInsecureSkipTLSVerify,
AuthFilePath: authFile,
DirForceCompress: forceCompress,
+ DockerArchiveAdditionalTags: additionalDockerArchiveTags,
}
return sc
}
diff --git a/libpod/image/image.go b/libpod/image/image.go
index b7d9200ec..c8a929074 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -147,7 +147,7 @@ func (ir *Runtime) New(ctx context.Context, name, signaturePolicyPath, authfile
return nil, errors.Wrapf(err, "unable to pull %s", name)
}
- newImage.InputName = imageName
+ newImage.InputName = imageName[0]
img, err := newImage.getLocalImage()
if err != nil {
return nil, errors.Wrapf(err, "error retrieving local image after pulling %s", name)
@@ -156,6 +156,41 @@ func (ir *Runtime) New(ctx context.Context, name, signaturePolicyPath, authfile
return &newImage, nil
}
+// LoadFromArchive creates a new image object for images pulled from a tar archive (podman load)
+// This function is needed because it is possible for a tar archive to have multiple tags for one image
+func (ir *Runtime) LoadFromArchive(ctx context.Context, name, signaturePolicyPath string, writer io.Writer) ([]*Image, error) {
+ var newImages []*Image
+ newImage := Image{
+ InputName: name,
+ Local: false,
+ imageruntime: ir,
+ }
+
+ if signaturePolicyPath == "" {
+ signaturePolicyPath = ir.SignaturePolicyPath
+ }
+ imageNames, err := newImage.pullImage(ctx, writer, "", signaturePolicyPath, SigningOptions{}, &DockerRegistryOptions{}, false)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to pull %s", name)
+ }
+
+ for _, name := range imageNames {
+ newImage := Image{
+ InputName: name,
+ Local: true,
+ imageruntime: ir,
+ }
+ img, err := newImage.getLocalImage()
+ if err != nil {
+ return nil, errors.Wrapf(err, "error retrieving local image after pulling %s", name)
+ }
+ newImage.image = img
+ newImages = append(newImages, &newImage)
+ }
+
+ return newImages, nil
+}
+
// Shutdown closes down the storage and require a bool arg as to
// whether it should do so forcibly.
func (ir *Runtime) Shutdown(force bool) error {
@@ -428,7 +463,7 @@ func (i *Image) UntagImage(tag string) error {
}
// PushImage pushes the given image to a location described by the given path
-func (i *Image) PushImage(ctx context.Context, destination, manifestMIMEType, authFile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions SigningOptions, dockerRegistryOptions *DockerRegistryOptions, forceSecure bool) error {
+func (i *Image) PushImage(ctx context.Context, destination, manifestMIMEType, authFile, signaturePolicyPath string, writer io.Writer, forceCompress bool, signingOptions SigningOptions, dockerRegistryOptions *DockerRegistryOptions, forceSecure bool, additionalDockerArchiveTags []reference.NamedTagged) error {
if destination == "" {
return errors.Wrapf(syscall.EINVAL, "destination image name must be specified")
}
@@ -464,7 +499,7 @@ func (i *Image) PushImage(ctx context.Context, destination, manifestMIMEType, au
if err != nil {
return err
}
- copyOptions := getCopyOptions(writer, signaturePolicyPath, nil, dockerRegistryOptions, signingOptions, authFile, manifestMIMEType, forceCompress)
+ copyOptions := getCopyOptions(writer, signaturePolicyPath, nil, dockerRegistryOptions, signingOptions, authFile, manifestMIMEType, forceCompress, additionalDockerArchiveTags)
if strings.HasPrefix(DockerTransport, dest.Transport().Name()) {
imgRef, err := reference.Parse(dest.DockerReference().String())
if err != nil {
@@ -749,7 +784,7 @@ func (ir *Runtime) Import(ctx context.Context, path, reference string, writer io
return nil, err
}
defer policyContext.Destroy()
- copyOptions := getCopyOptions(writer, "", nil, nil, signingOptions, "", "", false)
+ copyOptions := getCopyOptions(writer, "", nil, nil, signingOptions, "", "", false, nil)
dest, err := is.Transport.ParseStoreReference(ir.store, reference)
if err != nil {
errors.Wrapf(err, "error getting image reference for %q", reference)
diff --git a/libpod/image/pull.go b/libpod/image/pull.go
index 38a8435de..cd915cb47 100644
--- a/libpod/image/pull.go
+++ b/libpod/image/pull.go
@@ -100,21 +100,25 @@ func (ir *Runtime) getPullListFromRef(ctx context.Context, srcRef types.ImageRef
}
pullStructs = append(pullStructs, pullInfo)
} else {
- var dest string
+ var dest []string
if len(manifest[0].RepoTags) > 0 {
- dest = manifest[0].RepoTags[0]
+ dest = append(dest, manifest[0].RepoTags...)
} else {
// If the input image has no repotags, we need to feed it a dest anyways
- dest, err = getImageDigest(ctx, srcRef, sc)
+ digest, err := getImageDigest(ctx, srcRef, sc)
if err != nil {
return nil, err
}
+ dest = append(dest, digest)
}
- pullInfo, err := ir.getPullStruct(srcRef, dest)
- if err != nil {
- return nil, err
+ // Need to load in all the repo tags from the manifest
+ for _, dst := range dest {
+ pullInfo, err := ir.getPullStruct(srcRef, dst)
+ if err != nil {
+ return nil, err
+ }
+ pullStructs = append(pullStructs, pullInfo)
}
- pullStructs = append(pullStructs, pullInfo)
}
} else if srcRef.Transport().Name() == OCIArchive {
// retrieve the manifest from index.json to access the image name
@@ -164,7 +168,7 @@ func (ir *Runtime) getPullListFromRef(ctx context.Context, srcRef types.ImageRef
// pullImage pulls an image from configured registries
// By default, only the latest tag (or a specific tag if requested) will be
// pulled.
-func (i *Image) pullImage(ctx context.Context, writer io.Writer, authfile, signaturePolicyPath string, signingOptions SigningOptions, dockerOptions *DockerRegistryOptions, forceSecure bool) (string, error) {
+func (i *Image) pullImage(ctx context.Context, writer io.Writer, authfile, signaturePolicyPath string, signingOptions SigningOptions, dockerOptions *DockerRegistryOptions, forceSecure bool) ([]string, error) {
// pullImage copies the image from the source to the destination
var pullStructs []*pullStruct
sc := GetSystemContext(signaturePolicyPath, authfile, false)
@@ -173,31 +177,31 @@ func (i *Image) pullImage(ctx context.Context, writer io.Writer, authfile, signa
// could be trying to pull from registry with short name
pullStructs, err = i.createNamesToPull()
if err != nil {
- return "", errors.Wrap(err, "error getting default registries to try")
+ return nil, errors.Wrap(err, "error getting default registries to try")
}
} else {
pullStructs, err = i.imageruntime.getPullListFromRef(ctx, srcRef, i.InputName, sc)
if err != nil {
- return "", errors.Wrapf(err, "error getting pullStruct info to pull image %q", i.InputName)
+ return nil, errors.Wrapf(err, "error getting pullStruct info to pull image %q", i.InputName)
}
}
policyContext, err := getPolicyContext(sc)
if err != nil {
- return "", err
+ return nil, err
}
defer policyContext.Destroy()
insecureRegistries, err := registries.GetInsecureRegistries()
if err != nil {
- return "", err
+ return nil, err
}
-
+ var images []string
for _, imageInfo := range pullStructs {
- copyOptions := getCopyOptions(writer, signaturePolicyPath, dockerOptions, nil, signingOptions, authfile, "", false)
+ copyOptions := getCopyOptions(writer, signaturePolicyPath, dockerOptions, nil, signingOptions, authfile, "", false, nil)
if strings.HasPrefix(DockerTransport, imageInfo.srcRef.Transport().Name()) {
imgRef, err := reference.Parse(imageInfo.srcRef.DockerReference().String())
if err != nil {
- return "", err
+ return nil, err
}
registry := reference.Domain(imgRef.(reference.Named))
@@ -215,10 +219,13 @@ func (i *Image) pullImage(ctx context.Context, writer io.Writer, authfile, signa
io.WriteString(writer, "Failed\n")
}
} else {
- return imageInfo.image, nil
+ if imageInfo.srcRef.Transport().Name() != DockerArchive {
+ return []string{imageInfo.image}, nil
+ }
+ images = append(images, imageInfo.image)
}
}
- return "", errors.Wrapf(err, "error pulling image from")
+ return images, errors.Wrapf(err, "error pulling image from")
}
// createNamesToPull looks at a decomposed image and determines the possible
diff --git a/libpod/image/utils.go b/libpod/image/utils.go
index 5392b86f0..661fece07 100644
--- a/libpod/image/utils.go
+++ b/libpod/image/utils.go
@@ -53,15 +53,15 @@ func findImageInRepotags(search imageParts, images []*Image) (*storage.Image, er
}
// getCopyOptions constructs a new containers/image/copy.Options{} struct from the given parameters
-func getCopyOptions(reportWriter io.Writer, signaturePolicyPath string, srcDockerRegistry, destDockerRegistry *DockerRegistryOptions, signing SigningOptions, authFile, manifestType string, forceCompress bool) *cp.Options {
+func getCopyOptions(reportWriter io.Writer, signaturePolicyPath string, srcDockerRegistry, destDockerRegistry *DockerRegistryOptions, signing SigningOptions, authFile, manifestType string, forceCompress bool, additionalDockerArchiveTags []reference.NamedTagged) *cp.Options {
if srcDockerRegistry == nil {
srcDockerRegistry = &DockerRegistryOptions{}
}
if destDockerRegistry == nil {
destDockerRegistry = &DockerRegistryOptions{}
}
- srcContext := srcDockerRegistry.GetSystemContext(signaturePolicyPath, authFile, forceCompress)
- destContext := destDockerRegistry.GetSystemContext(signaturePolicyPath, authFile, forceCompress)
+ srcContext := srcDockerRegistry.GetSystemContext(signaturePolicyPath, authFile, forceCompress, additionalDockerArchiveTags)
+ destContext := destDockerRegistry.GetSystemContext(signaturePolicyPath, authFile, forceCompress, additionalDockerArchiveTags)
return &cp.Options{
RemoveSignatures: signing.RemoveSignatures,
SignBy: signing.SignBy,
@@ -110,3 +110,20 @@ func ReposToMap(repotags []string) map[string][]string {
}
return repos
}
+
+// GetAdditionalTags returns a list of reference.NamedTagged for the
+// additional tags given in images
+func GetAdditionalTags(images []string) ([]reference.NamedTagged, error) {
+ var allTags []reference.NamedTagged
+ for _, img := range images {
+ ref, err := reference.ParseNormalizedNamed(img)
+ if err != nil {
+ return nil, errors.Wrapf(err, "error parsing additional tags")
+ }
+ refTagged, isTagged := ref.(reference.NamedTagged)
+ if isTagged {
+ allTags = append(allTags, refTagged)
+ }
+ }
+ return allTags, nil
+}