github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/test/e2e/save_test.go (about) 1 package integration 2 3 import ( 4 "io/ioutil" 5 "os" 6 "os/exec" 7 "path/filepath" 8 "strconv" 9 "strings" 10 11 "github.com/hanks177/podman/v4/pkg/rootless" 12 . "github.com/hanks177/podman/v4/test/utils" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 . "github.com/onsi/gomega/gexec" 16 ) 17 18 var _ = Describe("Podman save", func() { 19 var ( 20 tempdir string 21 err error 22 podmanTest *PodmanTestIntegration 23 ) 24 25 BeforeEach(func() { 26 tempdir, err = CreateTempDirInTempDir() 27 if err != nil { 28 os.Exit(1) 29 } 30 podmanTest = PodmanTestCreate(tempdir) 31 podmanTest.Setup() 32 }) 33 34 AfterEach(func() { 35 podmanTest.Cleanup() 36 f := CurrentGinkgoTestDescription() 37 processTestResult(f) 38 39 }) 40 41 It("podman save output flag", func() { 42 outfile := filepath.Join(podmanTest.TempDir, "alpine.tar") 43 44 save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINE}) 45 save.WaitWithDefaultTimeout() 46 Expect(save).Should(Exit(0)) 47 }) 48 49 It("podman save oci flag", func() { 50 outfile := filepath.Join(podmanTest.TempDir, "alpine.tar") 51 52 save := podmanTest.Podman([]string{"save", "-o", outfile, "--format", "oci-archive", ALPINE}) 53 save.WaitWithDefaultTimeout() 54 Expect(save).Should(Exit(0)) 55 }) 56 57 It("podman save with stdout", func() { 58 Skip("Pipe redirection in ginkgo probably won't work") 59 outfile := filepath.Join(podmanTest.TempDir, "alpine.tar") 60 61 save := podmanTest.Podman([]string{"save", ALPINE, ">", outfile}) 62 save.WaitWithDefaultTimeout() 63 Expect(save).Should(Exit(0)) 64 }) 65 66 It("podman save quiet flag", func() { 67 outfile := filepath.Join(podmanTest.TempDir, "alpine.tar") 68 69 save := podmanTest.Podman([]string{"save", "-q", "-o", outfile, ALPINE}) 70 save.WaitWithDefaultTimeout() 71 Expect(save).Should(Exit(0)) 72 }) 73 74 It("podman save bogus image", func() { 75 outfile := filepath.Join(podmanTest.TempDir, "alpine.tar") 76 77 save := podmanTest.Podman([]string{"save", "-o", outfile, "FOOBAR"}) 78 save.WaitWithDefaultTimeout() 79 Expect(save).To(ExitWithError()) 80 }) 81 82 It("podman save to directory with oci format", func() { 83 if rootless.IsRootless() { 84 Skip("Requires a fix in containers image for chown/lchown") 85 } 86 outdir := filepath.Join(podmanTest.TempDir, "save") 87 88 save := podmanTest.Podman([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE}) 89 save.WaitWithDefaultTimeout() 90 Expect(save).Should(Exit(0)) 91 }) 92 93 It("podman save to directory with v2s2 docker format", func() { 94 if rootless.IsRootless() { 95 Skip("Requires a fix in containers image for chown/lchown") 96 } 97 outdir := filepath.Join(podmanTest.TempDir, "save") 98 99 save := podmanTest.Podman([]string{"save", "--format", "docker-dir", "-o", outdir, ALPINE}) 100 save.WaitWithDefaultTimeout() 101 Expect(save).Should(Exit(0)) 102 }) 103 104 It("podman save to directory with docker format and compression", func() { 105 if rootless.IsRootless() && podmanTest.RemoteTest { 106 Skip("Requires a fix in containers image for chown/lchown") 107 } 108 outdir := filepath.Join(podmanTest.TempDir, "save") 109 110 save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-dir", "-o", outdir, ALPINE}) 111 save.WaitWithDefaultTimeout() 112 Expect(save).Should(Exit(0)) 113 }) 114 115 It("podman save to directory with --compress but not use docker-dir and oci-dir", func() { 116 if rootless.IsRootless() && podmanTest.RemoteTest { 117 Skip("Requires a fix in containers image for chown/lchown") 118 } 119 outdir := filepath.Join(podmanTest.TempDir, "save") 120 121 save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-archive", "-o", outdir, ALPINE}) 122 save.WaitWithDefaultTimeout() 123 // should not be 0 124 Expect(save).To(ExitWithError()) 125 126 save = podmanTest.Podman([]string{"save", "--compress", "--format", "oci-archive", "-o", outdir, ALPINE}) 127 save.WaitWithDefaultTimeout() 128 // should not be 0 129 Expect(save).To(ExitWithError()) 130 131 }) 132 133 It("podman save bad filename", func() { 134 outdir := filepath.Join(podmanTest.TempDir, "save:colon") 135 136 save := podmanTest.Podman([]string{"save", "--compress", "--format", "docker-dir", "-o", outdir, ALPINE}) 137 save.WaitWithDefaultTimeout() 138 Expect(save).To(ExitWithError()) 139 }) 140 141 It("podman save remove signature", func() { 142 podmanTest.AddImageToRWStore(ALPINE) 143 SkipIfRootless("FIXME: Need get in rootless push sign") 144 if podmanTest.Host.Arch == "ppc64le" { 145 Skip("No registry image for ppc64le") 146 } 147 tempGNUPGHOME := filepath.Join(podmanTest.TempDir, "tmpGPG") 148 err := os.Mkdir(tempGNUPGHOME, os.ModePerm) 149 Expect(err).To(BeNil()) 150 origGNUPGHOME := os.Getenv("GNUPGHOME") 151 err = os.Setenv("GNUPGHOME", tempGNUPGHOME) 152 Expect(err).To(BeNil()) 153 defer os.Setenv("GNUPGHOME", origGNUPGHOME) 154 155 port := 5000 156 session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", strings.Join([]string{strconv.Itoa(port), strconv.Itoa(port)}, ":"), "quay.io/libpod/registry:2.6"}) 157 session.WaitWithDefaultTimeout() 158 Expect(session).Should(Exit(0)) 159 if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { 160 Skip("Cannot start docker registry.") 161 } 162 163 cmd := exec.Command("gpg", "--import", "sign/secret-key.asc") 164 err = cmd.Run() 165 Expect(err).To(BeNil()) 166 167 defaultYaml := filepath.Join(podmanTest.TempDir, "default.yaml") 168 cmd = exec.Command("cp", "/etc/containers/registries.d/default.yaml", defaultYaml) 169 if err = cmd.Run(); err != nil { 170 Skip("no signature store to verify") 171 } 172 defer func() { 173 cmd = exec.Command("cp", defaultYaml, "/etc/containers/registries.d/default.yaml") 174 err := cmd.Run() 175 Expect(err).ToNot(HaveOccurred()) 176 }() 177 178 cmd = exec.Command("cp", "sign/key.gpg", "/tmp/key.gpg") 179 Expect(cmd.Run()).To(BeNil()) 180 sigstore := ` 181 default-docker: 182 sigstore: file:///var/lib/containers/sigstore 183 sigstore-staging: file:///var/lib/containers/sigstore 184 ` 185 Expect(ioutil.WriteFile("/etc/containers/registries.d/default.yaml", []byte(sigstore), 0755)).To(BeNil()) 186 187 session = podmanTest.Podman([]string{"tag", ALPINE, "localhost:5000/alpine"}) 188 session.WaitWithDefaultTimeout() 189 Expect(session).Should(Exit(0)) 190 191 session = podmanTest.Podman([]string{"push", "--tls-verify=false", "--sign-by", "foo@bar.com", "localhost:5000/alpine"}) 192 session.WaitWithDefaultTimeout() 193 Expect(session).Should(Exit(0)) 194 195 session = podmanTest.Podman([]string{"rmi", ALPINE, "localhost:5000/alpine"}) 196 session.WaitWithDefaultTimeout() 197 Expect(session).Should(Exit(0)) 198 199 if !IsRemote() { 200 session = podmanTest.Podman([]string{"pull", "--tls-verify=false", "--signature-policy=sign/policy.json", "localhost:5000/alpine"}) 201 session.WaitWithDefaultTimeout() 202 Expect(session).Should(Exit(0)) 203 204 outfile := filepath.Join(podmanTest.TempDir, "temp.tar") 205 save := podmanTest.Podman([]string{"save", "remove-signatures=true", "-o", outfile, "localhost:5000/alpine"}) 206 save.WaitWithDefaultTimeout() 207 Expect(save).To(ExitWithError()) 208 } 209 }) 210 211 It("podman save image with digest reference", func() { 212 // pull a digest reference 213 session := podmanTest.Podman([]string{"pull", ALPINELISTDIGEST}) 214 session.WaitWithDefaultTimeout() 215 Expect(session).Should(Exit(0)) 216 217 // save a digest reference should exit without error. 218 outfile := filepath.Join(podmanTest.TempDir, "temp.tar") 219 save := podmanTest.Podman([]string{"save", "-o", outfile, ALPINELISTDIGEST}) 220 save.WaitWithDefaultTimeout() 221 Expect(save).Should(Exit(0)) 222 }) 223 224 It("podman save --multi-image-archive (tagged images)", func() { 225 multiImageSave(podmanTest, RESTORE_IMAGES) 226 }) 227 228 It("podman save --multi-image-archive (untagged images)", func() { 229 // #14468: to make execution time more predictable, save at 230 // most three images and sort them by size. 231 session := podmanTest.Podman([]string{"images", "--sort", "size", "--format", "{{.ID}}"}) 232 session.WaitWithDefaultTimeout() 233 Expect(session).Should(Exit(0)) 234 ids := session.OutputToStringArray() 235 236 Expect(len(ids)).To(BeNumerically(">", 1), "We need to have *some* images to save") 237 if len(ids) > 3 { 238 ids = ids[:3] 239 } 240 multiImageSave(podmanTest, ids) 241 }) 242 }) 243 244 // Create a multi-image archive, remove all images, load it and 245 // make sure that all images are (again) present. 246 func multiImageSave(podmanTest *PodmanTestIntegration, images []string) { 247 // Create the archive. 248 outfile := filepath.Join(podmanTest.TempDir, "temp.tar") 249 session := podmanTest.Podman(append([]string{"save", "-o", outfile, "--multi-image-archive"}, images...)) 250 session.WaitWithDefaultTimeout() 251 Expect(session).Should(Exit(0)) 252 253 // Remove all images. 254 session = podmanTest.Podman([]string{"rmi", "-af"}) 255 session.WaitWithDefaultTimeout() 256 Expect(session).Should(Exit(0)) 257 258 // Now load the archive. 259 session = podmanTest.Podman([]string{"load", "-i", outfile}) 260 session.WaitWithDefaultTimeout() 261 Expect(session).Should(Exit(0)) 262 // Grep for each image in the `podman load` output. 263 for _, image := range images { 264 Expect(session.OutputToString()).To(ContainSubstring(image)) 265 } 266 267 // Make sure that each image has really been loaded. 268 for _, image := range images { 269 session = podmanTest.Podman([]string{"image", "exists", image}) 270 session.WaitWithDefaultTimeout() 271 Expect(session).Should(Exit(0)) 272 } 273 }