mirror of
https://github.com/containers/podman.git
synced 2025-12-15 11:42:28 +08:00
support multi-image (docker) archives
Support loading and saving tarballs with more than one image. Add a new `/libpod/images/export` endpoint to the rest API to allow for exporting/saving multiple images into an archive. Note that a non-release version of containers/image is vendored. A release version must be vendored before cutting a new Podman release. We force the containers/image version via a replace in the go.mod file; this way go won't try to match the versions. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
@@ -269,4 +269,12 @@ var _ = Describe("Podman load", func() {
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
})
|
||||
|
||||
It("podman load multi-image archive", func() {
|
||||
result := podmanTest.PodmanNoCache([]string{"load", "-i", "./testdata/image/docker-two-images.tar.xz"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(result.LineInOutputContains("example.com/empty:latest")).To(BeTrue())
|
||||
Expect(result.LineInOutputContains("example.com/empty/but:different")).To(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -251,6 +251,49 @@ var _ = Describe("Podman pull", func() {
|
||||
session = podmanTest.PodmanNoCache([]string{"rmi", "alpine"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
// Pulling a multi-image archive without further specifying
|
||||
// which image _must_ error out. Pulling is restricted to one
|
||||
// image.
|
||||
session = podmanTest.PodmanNoCache([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz")})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
expectedError := "Unexpected tar manifest.json: expected 1 item, got 2"
|
||||
found, _ := session.ErrorGrepString(expectedError)
|
||||
Expect(found).To(Equal(true))
|
||||
|
||||
// Now pull _one_ image from a multi-image archive via the name
|
||||
// and index syntax.
|
||||
session = podmanTest.PodmanNoCache([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:@0")})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.PodmanNoCache([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:example.com/empty:latest")})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.PodmanNoCache([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:@1")})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.PodmanNoCache([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:example.com/empty/but:different")})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
// Now check for some errors.
|
||||
session = podmanTest.PodmanNoCache([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:foo.com/does/not/exist:latest")})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
expectedError = "Tag \"foo.com/does/not/exist:latest\" not found"
|
||||
found, _ = session.ErrorGrepString(expectedError)
|
||||
Expect(found).To(Equal(true))
|
||||
|
||||
session = podmanTest.PodmanNoCache([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:@2")})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
expectedError = "Invalid source index @2, only 2 manifest items available"
|
||||
found, _ = session.ErrorGrepString(expectedError)
|
||||
Expect(found).To(Equal(true))
|
||||
})
|
||||
|
||||
It("podman pull from oci-archive", func() {
|
||||
|
||||
@@ -128,4 +128,51 @@ var _ = Describe("Podman save", func() {
|
||||
save.WaitWithDefaultTimeout()
|
||||
Expect(save.ExitCode()).To(Equal(0))
|
||||
})
|
||||
|
||||
It("podman save --multi-image-archive (tagged images)", func() {
|
||||
multiImageSave(podmanTest, RESTORE_IMAGES)
|
||||
})
|
||||
|
||||
It("podman save --multi-image-archive (untagged images)", func() {
|
||||
// Refer to images via ID instead of tag.
|
||||
session := podmanTest.PodmanNoCache([]string{"images", "--format", "{{.ID}}"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
ids := session.OutputToStringArray()
|
||||
|
||||
Expect(len(RESTORE_IMAGES), len(ids))
|
||||
multiImageSave(podmanTest, ids)
|
||||
})
|
||||
})
|
||||
|
||||
// Create a multi-image archive, remove all images, load it and
|
||||
// make sure that all images are (again) present.
|
||||
func multiImageSave(podmanTest *PodmanTestIntegration, images []string) {
|
||||
// Create the archive.
|
||||
outfile := filepath.Join(podmanTest.TempDir, "temp.tar")
|
||||
session := podmanTest.PodmanNoCache(append([]string{"save", "-o", outfile, "--multi-image-archive"}, images...))
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
// Remove all images.
|
||||
session = podmanTest.PodmanNoCache([]string{"rmi", "-af"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
// Now load the archive.
|
||||
session = podmanTest.PodmanNoCache([]string{"load", "-i", outfile})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
// Grep for each image in the `podman load` output.
|
||||
for _, image := range images {
|
||||
found, _ := session.GrepString(image)
|
||||
Expect(found).Should(BeTrue())
|
||||
}
|
||||
|
||||
// Make sure that each image has really been loaded.
|
||||
for _, image := range images {
|
||||
session = podmanTest.PodmanNoCache([]string{"image", "exists", image})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
}
|
||||
}
|
||||
|
||||
1
test/e2e/testdata/image
vendored
Symbolic link
1
test/e2e/testdata/image
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../libpod/image/testdata/
|
||||
Reference in New Issue
Block a user