github.com/containers/podman/v4@v4.9.4/test/e2e/rmi_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "sync" 6 7 . "github.com/containers/podman/v4/test/utils" 8 . "github.com/onsi/ginkgo/v2" 9 . "github.com/onsi/gomega" 10 . "github.com/onsi/gomega/gexec" 11 ) 12 13 var _ = Describe("Podman rmi", func() { 14 15 It("podman rmi bogus image", func() { 16 session := podmanTest.Podman([]string{"rmi", "debian:6.0.10"}) 17 session.WaitWithDefaultTimeout() 18 Expect(session).Should(Exit(1)) 19 20 }) 21 22 It("podman rmi with fq name", func() { 23 podmanTest.AddImageToRWStore(ALPINE) 24 session := podmanTest.Podman([]string{"rmi", ALPINE}) 25 session.WaitWithDefaultTimeout() 26 Expect(session).Should(ExitCleanly()) 27 28 }) 29 30 It("podman rmi with short name", func() { 31 podmanTest.AddImageToRWStore(CIRROS_IMAGE) 32 session := podmanTest.Podman([]string{"rmi", "cirros"}) 33 session.WaitWithDefaultTimeout() 34 Expect(session).Should(ExitCleanly()) 35 36 }) 37 38 It("podman rmi all images", func() { 39 podmanTest.AddImageToRWStore(NGINX_IMAGE) 40 session := podmanTest.Podman([]string{"rmi", "-a"}) 41 session.WaitWithDefaultTimeout() 42 images := podmanTest.Podman([]string{"images"}) 43 images.WaitWithDefaultTimeout() 44 Expect(session).Should(ExitCleanly()) 45 46 }) 47 48 It("podman rmi all images forcibly with short options", func() { 49 podmanTest.AddImageToRWStore(NGINX_IMAGE) 50 session := podmanTest.Podman([]string{"rmi", "-fa"}) 51 session.WaitWithDefaultTimeout() 52 Expect(session).Should(ExitCleanly()) 53 54 }) 55 56 It("podman rmi tagged image", func() { 57 podmanTest.AddImageToRWStore(CIRROS_IMAGE) 58 setup := podmanTest.Podman([]string{"images", "-q", CIRROS_IMAGE}) 59 setup.WaitWithDefaultTimeout() 60 Expect(setup).Should(ExitCleanly()) 61 62 session := podmanTest.Podman([]string{"tag", CIRROS_IMAGE, "foo:bar", "foo"}) 63 session.WaitWithDefaultTimeout() 64 Expect(session).Should(ExitCleanly()) 65 66 result := podmanTest.Podman([]string{"images", "-q", "foo"}) 67 result.WaitWithDefaultTimeout() 68 Expect(result).Should(ExitCleanly()) 69 70 Expect(result.OutputToString()).To(ContainSubstring(setup.OutputToString())) 71 }) 72 73 It("podman rmi image with tags by ID cannot be done without force", func() { 74 podmanTest.AddImageToRWStore(CIRROS_IMAGE) 75 setup := podmanTest.Podman([]string{"images", "-q", CIRROS_IMAGE}) 76 setup.WaitWithDefaultTimeout() 77 Expect(setup).Should(ExitCleanly()) 78 cirrosID := setup.OutputToString() 79 80 session := podmanTest.Podman([]string{"tag", "cirros", "foo:bar", "foo"}) 81 session.WaitWithDefaultTimeout() 82 Expect(session).Should(ExitCleanly()) 83 84 // Trying without --force should fail 85 result := podmanTest.Podman([]string{"rmi", cirrosID}) 86 result.WaitWithDefaultTimeout() 87 Expect(result).To(ExitWithError()) 88 89 // With --force it should work 90 resultForce := podmanTest.Podman([]string{"rmi", "-f", cirrosID}) 91 resultForce.WaitWithDefaultTimeout() 92 Expect(resultForce).Should(ExitCleanly()) 93 }) 94 95 It("podman rmi image that is a parent of another image", func() { 96 Skip("I need help with this one. i don't understand what is going on") 97 podmanTest.AddImageToRWStore(CIRROS_IMAGE) 98 session := podmanTest.Podman([]string{"run", "--name", "c_test", CIRROS_IMAGE, "true"}) 99 session.WaitWithDefaultTimeout() 100 Expect(session).Should(ExitCleanly()) 101 102 session = podmanTest.Podman([]string{"commit", "-q", "c_test", "test"}) 103 session.WaitWithDefaultTimeout() 104 Expect(session).Should(ExitCleanly()) 105 106 session = podmanTest.Podman([]string{"rm", "c_test"}) 107 session.WaitWithDefaultTimeout() 108 Expect(session).Should(ExitCleanly()) 109 110 session = podmanTest.Podman([]string{"rmi", CIRROS_IMAGE}) 111 session.WaitWithDefaultTimeout() 112 Expect(session).Should(ExitCleanly()) 113 114 session = podmanTest.Podman([]string{"images", "-q"}) 115 session.WaitWithDefaultTimeout() 116 Expect(session).Should(ExitCleanly()) 117 Expect(session.OutputToStringArray()).To(HaveLen(12)) 118 119 session = podmanTest.Podman([]string{"images", "--sort", "created", "--format", "{{.Id}}", "--all"}) 120 session.WaitWithDefaultTimeout() 121 Expect(session).Should(ExitCleanly()) 122 Expect(session.OutputToStringArray()).To(HaveLen(13), 123 "Output from 'podman images -q -a'") 124 untaggedImg := session.OutputToStringArray()[1] 125 126 session = podmanTest.Podman([]string{"rmi", "-f", untaggedImg}) 127 session.WaitWithDefaultTimeout() 128 Expect(session).Should(Exit(2), "UntaggedImg is '%s'", untaggedImg) 129 }) 130 131 It("podman rmi image that is created from another named imaged", func() { 132 podmanTest.AddImageToRWStore(ALPINE) 133 session := podmanTest.Podman([]string{"create", "--name", "c_test1", ALPINE, "true"}) 134 session.WaitWithDefaultTimeout() 135 Expect(session).Should(ExitCleanly()) 136 137 session = podmanTest.Podman([]string{"commit", "-q", "c_test1", "test1"}) 138 session.WaitWithDefaultTimeout() 139 Expect(session).Should(ExitCleanly()) 140 141 session = podmanTest.Podman([]string{"create", "--name", "c_test2", "test1", "true"}) 142 session.WaitWithDefaultTimeout() 143 Expect(session).Should(ExitCleanly()) 144 145 session = podmanTest.Podman([]string{"commit", "-q", "c_test2", "test2"}) 146 session.WaitWithDefaultTimeout() 147 Expect(session).Should(ExitCleanly()) 148 149 session = podmanTest.Podman([]string{"rm", "-a"}) 150 session.WaitWithDefaultTimeout() 151 Expect(session).Should(ExitCleanly()) 152 153 session = podmanTest.Podman([]string{"rmi", "test2"}) 154 session.WaitWithDefaultTimeout() 155 Expect(session).Should(ExitCleanly()) 156 157 session = podmanTest.Podman([]string{"images", "-q"}) 158 session.WaitWithDefaultTimeout() 159 Expect(session).Should(ExitCleanly()) 160 Expect(session.OutputToStringArray()).To(HaveLen(len(CACHE_IMAGES) + 1)) 161 }) 162 163 It("podman rmi with cached images", func() { 164 podmanTest.AddImageToRWStore(CIRROS_IMAGE) 165 dockerfile := fmt.Sprintf(`FROM %s 166 RUN mkdir hello 167 RUN touch test.txt 168 ENV foo=bar 169 `, CIRROS_IMAGE) 170 podmanTest.BuildImage(dockerfile, "test", "true") 171 172 dockerfile = fmt.Sprintf(`FROM %s 173 RUN mkdir hello 174 RUN touch test.txt 175 RUN mkdir blah 176 ENV foo=bar 177 `, CIRROS_IMAGE) 178 179 podmanTest.BuildImage(dockerfile, "test2", "true") 180 181 session := podmanTest.Podman([]string{"images", "-q", "-a"}) 182 session.WaitWithDefaultTimeout() 183 Expect(session).Should(ExitCleanly()) 184 numOfImages := len(session.OutputToStringArray()) 185 186 session = podmanTest.Podman([]string{"rmi", "test2"}) 187 session.WaitWithDefaultTimeout() 188 Expect(session).Should(ExitCleanly()) 189 190 session = podmanTest.Podman([]string{"images", "-q", "-a"}) 191 session.WaitWithDefaultTimeout() 192 Expect(session).Should(ExitCleanly()) 193 Expect(numOfImages - len(session.OutputToStringArray())).To(Equal(2)) 194 195 session = podmanTest.Podman([]string{"rmi", "test"}) 196 session.WaitWithDefaultTimeout() 197 Expect(session).Should(ExitCleanly()) 198 199 session = podmanTest.Podman([]string{"images", "-q", "-a"}) 200 session.WaitWithDefaultTimeout() 201 Expect(session).Should(ExitCleanly()) 202 Expect(session.OutputToStringArray()).To(HaveLen(len(CACHE_IMAGES) + 1)) 203 204 podmanTest.BuildImage(dockerfile, "test3", "true") 205 206 session = podmanTest.Podman([]string{"rmi", CIRROS_IMAGE}) 207 session.WaitWithDefaultTimeout() 208 Expect(session).Should(ExitCleanly()) 209 210 session = podmanTest.Podman([]string{"rmi", "test3"}) 211 session.WaitWithDefaultTimeout() 212 Expect(session).Should(ExitCleanly()) 213 214 session = podmanTest.Podman([]string{"images", "-q", "-a"}) 215 session.WaitWithDefaultTimeout() 216 Expect(session).Should(ExitCleanly()) 217 Expect(session.OutputToString()).To(HaveLen(142)) 218 }) 219 220 It("podman rmi -a with no images should be exit 0", func() { 221 session := podmanTest.Podman([]string{"rmi", "-fa"}) 222 session.WaitWithDefaultTimeout() 223 Expect(session).Should(ExitCleanly()) 224 225 session2 := podmanTest.Podman([]string{"rmi", "-fa"}) 226 session2.WaitWithDefaultTimeout() 227 Expect(session2).Should(ExitCleanly()) 228 }) 229 230 It("podman rmi -a with parent|child images", func() { 231 podmanTest.AddImageToRWStore(CIRROS_IMAGE) 232 dockerfile := fmt.Sprintf(`FROM %s AS base 233 RUN touch /1 234 ENV LOCAL=/1 235 RUN find $LOCAL 236 FROM base 237 RUN find $LOCAL 238 239 `, CIRROS_IMAGE) 240 podmanTest.BuildImage(dockerfile, "test", "true") 241 session := podmanTest.Podman([]string{"rmi", "-a"}) 242 session.WaitWithDefaultTimeout() 243 Expect(session).Should(ExitCleanly()) 244 245 images := podmanTest.Podman([]string{"images", "-aq"}) 246 images.WaitWithDefaultTimeout() 247 Expect(images).Should(ExitCleanly()) 248 Expect(images.OutputToStringArray()).To(HaveLen(len(CACHE_IMAGES))) 249 }) 250 251 // Don't rerun all tests; just assume that if we get that diagnostic, 252 // we're getting rmi 253 It("podman image rm is the same as rmi", func() { 254 session := podmanTest.Podman([]string{"image", "rm"}) 255 session.WaitWithDefaultTimeout() 256 Expect(session).Should(Exit(125)) 257 Expect(session.ErrorToString()).To(ContainSubstring("image name or ID must be specified")) 258 }) 259 260 It("podman image rm - concurrent with shared layers", func() { 261 // #6510 has shown a fairly simple reproducer to force storage 262 // errors during parallel image removal. Since it's subject to 263 // a race, we may not hit the condition a 100 percent of times 264 // but ocal reproducers hit it all the time. 265 266 podmanTest.AddImageToRWStore(CIRROS_IMAGE) 267 var wg sync.WaitGroup 268 269 // Prepare images 270 wg.Add(10) 271 for i := 0; i < 10; i++ { 272 go func(i int) { 273 defer GinkgoRecover() 274 defer wg.Done() 275 imageName := fmt.Sprintf("rmtest:%d", i) 276 containerfile := fmt.Sprintf(`FROM %s 277 RUN touch %s`, CIRROS_IMAGE, imageName) 278 279 podmanTest.BuildImage(containerfile, imageName, "false") 280 }(i) 281 } 282 wg.Wait() 283 284 // A herd of concurrent removals 285 wg.Add(10) 286 for i := 0; i < 10; i++ { 287 go func(i int) { 288 defer GinkgoRecover() 289 defer wg.Done() 290 291 imageName := fmt.Sprintf("rmtest:%d", i) 292 session := podmanTest.Podman([]string{"rmi", "-f", imageName}) 293 session.WaitWithDefaultTimeout() 294 Expect(session).Should(ExitCleanly()) 295 }(i) 296 } 297 wg.Wait() 298 }) 299 300 It("podman rmi --no-prune with dangling parents", func() { 301 podmanTest.AddImageToRWStore(ALPINE) 302 session := podmanTest.Podman([]string{"create", "--name", "c_test1", ALPINE, "true"}) 303 session.WaitWithDefaultTimeout() 304 Expect(session).Should(ExitCleanly()) 305 306 session = podmanTest.Podman([]string{"commit", "-q", "c_test1", "test1"}) 307 session.WaitWithDefaultTimeout() 308 Expect(session).Should(ExitCleanly()) 309 310 session = podmanTest.Podman([]string{"create", "--name", "c_test2", "test1", "true"}) 311 session.WaitWithDefaultTimeout() 312 Expect(session).Should(ExitCleanly()) 313 314 session = podmanTest.Podman([]string{"commit", "-q", "c_test2", "test2"}) 315 session.WaitWithDefaultTimeout() 316 Expect(session).Should(ExitCleanly()) 317 imageID2 := session.OutputToString() 318 319 session = podmanTest.Podman([]string{"create", "--name", "c_test3", "test2", "true"}) 320 session.WaitWithDefaultTimeout() 321 Expect(session).Should(ExitCleanly()) 322 323 session = podmanTest.Podman([]string{"commit", "-q", "c_test3", "test3"}) 324 session.WaitWithDefaultTimeout() 325 Expect(session).Should(ExitCleanly()) 326 imageID3 := session.OutputToString() 327 328 session = podmanTest.Podman([]string{"untag", "test2"}) 329 session.WaitWithDefaultTimeout() 330 Expect(session).Should(ExitCleanly()) 331 332 session = podmanTest.Podman([]string{"untag", "test1"}) 333 session.WaitWithDefaultTimeout() 334 Expect(session).Should(ExitCleanly()) 335 336 session = podmanTest.Podman([]string{"rmi", "-f", "--no-prune", "test3"}) 337 session.WaitWithDefaultTimeout() 338 Expect(session).Should(ExitCleanly()) 339 Expect(session.OutputToString()).To(ContainSubstring(imageID3)) 340 Expect(session.OutputToString()).NotTo(ContainSubstring(imageID2)) 341 }) 342 343 It("podman rmi --no-prune with undangling parents", func() { 344 podmanTest.AddImageToRWStore(ALPINE) 345 session := podmanTest.Podman([]string{"create", "--name", "c_test1", ALPINE, "true"}) 346 session.WaitWithDefaultTimeout() 347 Expect(session).Should(ExitCleanly()) 348 349 session = podmanTest.Podman([]string{"commit", "-q", "c_test1", "test1"}) 350 session.WaitWithDefaultTimeout() 351 Expect(session).Should(ExitCleanly()) 352 353 session = podmanTest.Podman([]string{"create", "--name", "c_test2", "test1", "true"}) 354 session.WaitWithDefaultTimeout() 355 Expect(session).Should(ExitCleanly()) 356 357 session = podmanTest.Podman([]string{"commit", "-q", "c_test2", "test2"}) 358 session.WaitWithDefaultTimeout() 359 Expect(session).Should(ExitCleanly()) 360 imageID2 := session.OutputToString() 361 362 session = podmanTest.Podman([]string{"create", "--name", "c_test3", "test2", "true"}) 363 session.WaitWithDefaultTimeout() 364 Expect(session).Should(ExitCleanly()) 365 366 session = podmanTest.Podman([]string{"commit", "-q", "c_test3", "test3"}) 367 session.WaitWithDefaultTimeout() 368 Expect(session).Should(ExitCleanly()) 369 imageID3 := session.OutputToString() 370 371 session = podmanTest.Podman([]string{"rmi", "-f", "--no-prune", "test3"}) 372 session.WaitWithDefaultTimeout() 373 Expect(session).Should(ExitCleanly()) 374 Expect(session.OutputToString()).To(ContainSubstring(imageID3)) 375 Expect(session.OutputToString()).NotTo(ContainSubstring(imageID2)) 376 }) 377 })