summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSujil02 <sushah@redhat.com>2020-04-27 17:05:39 -0400
committerSujil02 <sushah@redhat.com>2020-04-28 18:26:46 -0400
commit2f2d05360b7a6bba0498712378b672173062b8a2 (patch)
tree87d8df79c1d0ebe257d799aaaec5003d850612ad
parente4b4eaae10d62a3043ac0120123a57bd2c14763e (diff)
downloadpodman-2f2d05360b7a6bba0498712378b672173062b8a2.tar.gz
podman-2f2d05360b7a6bba0498712378b672173062b8a2.tar.bz2
podman-2f2d05360b7a6bba0498712378b672173062b8a2.zip
Fixes podman save fails when specifying an image using a digest #5234
Adds check to parse normalized name and create docker archive dst reference for tagged untagged image. Relevant test case added. Signed-off-by: Sujil02 <sushah@redhat.com>
-rw-r--r--libpod/image/image.go27
-rw-r--r--test/e2e/save_test.go12
2 files changed, 34 insertions, 5 deletions
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 80cc6f15a..a0c4c942a 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -1412,14 +1412,14 @@ func (i *Image) Save(ctx context.Context, source, format, output string, moreTag
}
manifestType = manifest.DockerV2Schema2MediaType
case "docker-archive", "":
- dst := output
destImageName := imageNameForSaveDestination(i, source)
- if destImageName != "" {
- dst = fmt.Sprintf("%s:%s", dst, destImageName)
+ ref, err := dockerArchiveDstReference(destImageName)
+ if err != nil {
+ return err
}
- destRef, err = dockerarchive.ParseReference(dst) // FIXME? Add dockerarchive.NewReference
+ destRef, err = dockerarchive.NewReference(output, ref)
if err != nil {
- return errors.Wrapf(err, "error getting Docker archive ImageReference for %q", dst)
+ return errors.Wrapf(err, "error getting Docker archive ImageReference for %s:%v", output, ref)
}
default:
return errors.Errorf("unknown format option %q", format)
@@ -1439,6 +1439,23 @@ func (i *Image) Save(ctx context.Context, source, format, output string, moreTag
return nil
}
+// dockerArchiveDestReference returns a NamedTagged reference for a tagged image and nil for untagged image.
+func dockerArchiveDstReference(normalizedInput string) (reference.NamedTagged, error) {
+ if normalizedInput == "" {
+ return nil, nil
+ }
+ ref, err := reference.ParseNormalizedNamed(normalizedInput)
+ if err != nil {
+ return nil, errors.Wrapf(err, "docker-archive parsing reference %s", normalizedInput)
+ }
+ ref = reference.TagNameOnly(ref)
+ namedTagged, isTagged := ref.(reference.NamedTagged)
+ if !isTagged {
+ namedTagged = nil
+ }
+ return namedTagged, nil
+}
+
// GetConfigBlob returns a schema2image. If the image is not a schema2, then
// it will return an error
func (i *Image) GetConfigBlob(ctx context.Context) (*manifest.Schema2Image, error) {
diff --git a/test/e2e/save_test.go b/test/e2e/save_test.go
index 60825f975..aaa5ae180 100644
--- a/test/e2e/save_test.go
+++ b/test/e2e/save_test.go
@@ -116,4 +116,16 @@ var _ = Describe("Podman save", func() {
Expect(save).To(ExitWithError())
})
+ It("podman save image with digest reference", func() {
+ // pull a digest reference
+ session := podmanTest.PodmanNoCache([]string{"pull", ALPINELISTDIGEST})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ // save a digest reference should exit without error.
+ outfile := filepath.Join(podmanTest.TempDir, "temp.tar")
+ save := podmanTest.PodmanNoCache([]string{"save", "-o", outfile, ALPINELISTDIGEST})
+ save.WaitWithDefaultTimeout()
+ Expect(save.ExitCode()).To(Equal(0))
+ })
})