github.com/containers/podman/v5@v5.1.0-rc1/test/e2e/create_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "runtime" 8 "strconv" 9 "strings" 10 11 . "github.com/containers/podman/v5/test/utils" 12 "github.com/containers/storage/pkg/stringid" 13 . "github.com/onsi/ginkgo/v2" 14 . "github.com/onsi/gomega" 15 . "github.com/onsi/gomega/gexec" 16 ) 17 18 var _ = Describe("Podman create", func() { 19 20 It("podman create container based on a local image", func() { 21 session := podmanTest.Podman([]string{"create", "--name", "local_image_test", ALPINE, "ls"}) 22 session.WaitWithDefaultTimeout() 23 cid := session.OutputToString() 24 Expect(session).Should(ExitCleanly()) 25 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 26 27 check := podmanTest.Podman([]string{"inspect", "local_image_test"}) 28 check.WaitWithDefaultTimeout() 29 data := check.InspectContainerToJSON() 30 Expect(data[0].ID).To(ContainSubstring(cid)) 31 }) 32 33 It("podman create container based on a remote image", func() { 34 session := podmanTest.Podman([]string{"create", BB_GLIBC, "ls"}) 35 session.WaitWithDefaultTimeout() 36 Expect(session).Should(Exit(0)) 37 Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull " + BB_GLIBC)) 38 Expect(session.ErrorToString()).To(ContainSubstring("Writing manifest to image destination")) 39 40 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 41 }) 42 43 It("podman container create --tls-verify", func() { 44 port := "5040" 45 lock := GetPortLock(port) 46 defer lock.Unlock() 47 session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", port + ":5000", REGISTRY_IMAGE, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) 48 session.WaitWithDefaultTimeout() 49 Expect(session).Should(ExitCleanly()) 50 51 if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { 52 Fail("Cannot start docker registry.") 53 } 54 55 pushedImage := "localhost:" + port + "/pushed" + strings.ToLower(RandomString(5)) + ":" + RandomString(8) 56 push := podmanTest.Podman([]string{"push", "--tls-verify=false", ALPINE, pushedImage}) 57 push.WaitWithDefaultTimeout() 58 Expect(push).To(Exit(0)) 59 Expect(push.ErrorToString()).To(ContainSubstring("Writing manifest to image destination")) 60 61 create := podmanTest.Podman([]string{"container", "create", pushedImage}) 62 create.WaitWithDefaultTimeout() 63 Expect(create).Should(ExitWithError(125, "http: server gave HTTP response to HTTPS client")) 64 Expect(create.ErrorToString()).To(ContainSubstring("pinging container registry localhost:" + port)) 65 66 create = podmanTest.Podman([]string{"create", "--tls-verify=false", pushedImage, "echo", "got here"}) 67 create.WaitWithDefaultTimeout() 68 Expect(create).Should(Exit(0)) 69 Expect(create.ErrorToString()).To(ContainSubstring("Trying to pull " + pushedImage)) 70 }) 71 72 It("podman create using short options", func() { 73 session := podmanTest.Podman([]string{"create", ALPINE, "ls"}) 74 session.WaitWithDefaultTimeout() 75 Expect(session).Should(ExitCleanly()) 76 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 77 }) 78 79 It("podman create using existing name", func() { 80 session := podmanTest.Podman([]string{"create", "--name=foo", ALPINE, "ls"}) 81 session.WaitWithDefaultTimeout() 82 Expect(session).Should(ExitCleanly()) 83 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 84 85 session = podmanTest.Podman([]string{"create", "--name=foo", ALPINE, "ls"}) 86 session.WaitWithDefaultTimeout() 87 Expect(session).Should(ExitWithError(125, `creating container storage: the container name "foo" is already in use by`)) 88 }) 89 90 It("podman create adds rdt-class", func() { 91 session := podmanTest.Podman([]string{"create", "--rdt-class", "COS1", "--name", "rdt_test", ALPINE, "ls"}) 92 session.WaitWithDefaultTimeout() 93 Expect(session).Should(ExitCleanly()) 94 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 95 96 check := podmanTest.Podman([]string{"inspect", "rdt_test"}) 97 check.WaitWithDefaultTimeout() 98 data := check.InspectContainerToJSON() 99 Expect(data[0].HostConfig.IntelRdtClosID).To(Equal("COS1")) 100 }) 101 102 It("podman create adds annotation", func() { 103 session := podmanTest.Podman([]string{"create", "--annotation", "HELLO=WORLD,WithComma", "--name", "annotate_test", ALPINE, "ls"}) 104 session.WaitWithDefaultTimeout() 105 Expect(session).Should(ExitCleanly()) 106 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 107 108 check := podmanTest.Podman([]string{"inspect", "annotate_test"}) 109 check.WaitWithDefaultTimeout() 110 data := check.InspectContainerToJSON() 111 Expect(data[0].Config.Annotations).To(HaveKeyWithValue("HELLO", "WORLD,WithComma")) 112 }) 113 114 It("podman create --entrypoint command", func() { 115 session := podmanTest.Podman([]string{"create", "--name", "entrypoint_test", "--entrypoint", "/bin/foobar", ALPINE}) 116 session.WaitWithDefaultTimeout() 117 Expect(session).Should(ExitCleanly()) 118 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 119 120 result := podmanTest.Podman([]string{"inspect", "entrypoint_test", "--format", "{{.Config.Entrypoint}}"}) 121 result.WaitWithDefaultTimeout() 122 Expect(result).Should(ExitCleanly()) 123 Expect(result.OutputToString()).To(Equal("[/bin/foobar]")) 124 }) 125 126 It("podman create --entrypoint \"\"", func() { 127 session := podmanTest.Podman([]string{"create", "--entrypoint", "", ALPINE, "ls"}) 128 session.WaitWithDefaultTimeout() 129 Expect(session).Should(ExitCleanly()) 130 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 131 132 result := podmanTest.Podman([]string{"inspect", session.OutputToString(), "--format", "{{.Config.Entrypoint}}"}) 133 result.WaitWithDefaultTimeout() 134 Expect(result).Should(ExitCleanly()) 135 Expect(result.OutputToString()).To(Equal("[]")) 136 }) 137 138 It("podman create --entrypoint json", func() { 139 jsonString := `[ "/bin/foo", "-c"]` 140 session := podmanTest.Podman([]string{"create", "--name", "entrypoint_json", "--entrypoint", jsonString, ALPINE}) 141 session.WaitWithDefaultTimeout() 142 Expect(session).Should(ExitCleanly()) 143 Expect(podmanTest.NumberOfContainers()).To(Equal(1)) 144 145 result := podmanTest.Podman([]string{"inspect", "entrypoint_json", "--format", "{{.Config.Entrypoint}}"}) 146 result.WaitWithDefaultTimeout() 147 Expect(result).Should(ExitCleanly()) 148 Expect(result.OutputToString()).To(Equal("[/bin/foo -c]")) 149 }) 150 151 It("podman create --mount flag with multiple mounts", func() { 152 vol1 := filepath.Join(podmanTest.TempDir, "vol-test1") 153 err := os.MkdirAll(vol1, 0755) 154 Expect(err).ToNot(HaveOccurred()) 155 vol2 := filepath.Join(podmanTest.TempDir, "vol-test2") 156 err = os.MkdirAll(vol2, 0755) 157 Expect(err).ToNot(HaveOccurred()) 158 159 session := podmanTest.Podman([]string{"create", "--name", "test", "--mount", "type=bind,src=" + vol1 + ",target=/myvol1,z", "--mount", "type=bind,src=" + vol2 + ",target=/myvol2,z", ALPINE, "touch", "/myvol2/foo.txt"}) 160 session.WaitWithDefaultTimeout() 161 Expect(session).Should(ExitCleanly()) 162 163 session = podmanTest.Podman([]string{"start", "-a", "test"}) 164 session.WaitWithDefaultTimeout() 165 Expect(session).Should(ExitCleanly()) 166 Expect(session.OutputToString()).ToNot(ContainSubstring("cannot touch")) 167 }) 168 169 It("podman create with --mount flag", func() { 170 if podmanTest.Host.Arch == "ppc64le" { 171 Skip("skip failing test on ppc64le") 172 } 173 174 mountPath := filepath.Join(podmanTest.TempDir, "secrets") 175 err := os.Mkdir(mountPath, 0755) 176 Expect(err).ToNot(HaveOccurred()) 177 session := podmanTest.Podman([]string{"create", "--name", "test", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) 178 session.WaitWithDefaultTimeout() 179 Expect(session).Should(ExitCleanly()) 180 session = podmanTest.Podman([]string{"start", "-a", "test"}) 181 session.WaitWithDefaultTimeout() 182 Expect(session).Should(ExitCleanly()) 183 Expect(session.OutputToString()).To(ContainSubstring("/create/test rw")) 184 185 session = podmanTest.Podman([]string{"create", "--name", "test_ro", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,ro", mountPath), ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) 186 session.WaitWithDefaultTimeout() 187 Expect(session).Should(ExitCleanly()) 188 session = podmanTest.Podman([]string{"start", "-a", "test_ro"}) 189 session.WaitWithDefaultTimeout() 190 Expect(session).Should(ExitCleanly()) 191 Expect(session.OutputToString()).To(ContainSubstring("/create/test ro")) 192 193 session = podmanTest.Podman([]string{"create", "--name", "test_shared", "--mount", fmt.Sprintf("type=bind,src=%s,target=/create/test,shared", mountPath), ALPINE, "awk", `$5 == "/create/test" { print $6 " " $7}`, "/proc/self/mountinfo"}) 194 session.WaitWithDefaultTimeout() 195 Expect(session).Should(ExitCleanly()) 196 session = podmanTest.Podman([]string{"start", "-a", "test_shared"}) 197 session.WaitWithDefaultTimeout() 198 Expect(session).Should(ExitCleanly()) 199 Expect(session.OutputToString()).To(ContainSubstring("rw")) 200 Expect(session.OutputToString()).To(ContainSubstring("shared")) 201 202 mountPath = filepath.Join(podmanTest.TempDir, "scratchpad") 203 err = os.Mkdir(mountPath, 0755) 204 Expect(err).ToNot(HaveOccurred()) 205 session = podmanTest.Podman([]string{"create", "--name", "test_tmpfs", "--mount", "type=tmpfs,target=/create/test", ALPINE, "grep", "/create/test", "/proc/self/mountinfo"}) 206 session.WaitWithDefaultTimeout() 207 Expect(session).Should(ExitCleanly()) 208 session = podmanTest.Podman([]string{"start", "-a", "test_tmpfs"}) 209 session.WaitWithDefaultTimeout() 210 Expect(session).Should(ExitCleanly()) 211 Expect(session.OutputToString()).To(ContainSubstring("/create/test rw,nosuid,nodev,relatime - tmpfs")) 212 }) 213 214 It("podman create --pod automatically", func() { 215 session := podmanTest.Podman([]string{"create", "--pod", "new:foobar", ALPINE, "ls"}) 216 session.WaitWithDefaultTimeout() 217 Expect(session).Should(ExitCleanly()) 218 219 check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"}) 220 check.WaitWithDefaultTimeout() 221 Expect(check.OutputToString()).To(ContainSubstring("foobar")) 222 }) 223 224 It("podman create --pod-id-file", func() { 225 // First, make sure that --pod and --pod-id-file yield an error 226 // if used together. 227 session := podmanTest.Podman([]string{"create", "--pod", "foo", "--pod-id-file", "bar", ALPINE, "ls"}) 228 session.WaitWithDefaultTimeout() 229 Expect(session).Should(ExitWithError(125, "cannot specify both --pod and --pod-id-file")) 230 231 podName := "rudolph" 232 ctrName := "prancer" 233 podIDFile := filepath.Join(tempdir, "pod-id-file") 234 235 // Now, let's create a pod with --pod-id-file. 236 session = podmanTest.Podman([]string{"pod", "create", "--pod-id-file", podIDFile, "--name", podName}) 237 session.WaitWithDefaultTimeout() 238 Expect(session).Should(ExitCleanly()) 239 240 session = podmanTest.Podman([]string{"pod", "inspect", podName}) 241 session.WaitWithDefaultTimeout() 242 Expect(session).Should(ExitCleanly()) 243 Expect(session.OutputToString()).To(BeValidJSON()) 244 podData := session.InspectPodToJSON() 245 246 // Finally we can create a container with --pod-id-file and do 247 // some checks to make sure it's working as expected. 248 session = podmanTest.Podman([]string{"create", "--pod-id-file", podIDFile, "--name", ctrName, ALPINE, "top"}) 249 session.WaitWithDefaultTimeout() 250 Expect(session).Should(ExitCleanly()) 251 252 ctrJSON := podmanTest.InspectContainer(ctrName) 253 Expect(podData).To(HaveField("ID", ctrJSON[0].Pod)) // Make sure the container's pod matches the pod's ID 254 }) 255 256 It("podman run entrypoint and cmd test", func() { 257 name := "test101" 258 create := podmanTest.Podman([]string{"create", "--name", name, REDIS_IMAGE}) 259 create.WaitWithDefaultTimeout() 260 Expect(create).Should(ExitCleanly()) 261 262 ctrJSON := podmanTest.InspectContainer(name) 263 Expect(ctrJSON).To(HaveLen(1)) 264 Expect(ctrJSON[0].Config.Cmd).To(HaveLen(1)) 265 Expect(ctrJSON[0].Config.Cmd[0]).To(Equal("redis-server")) 266 Expect(ctrJSON[0].Config.Entrypoint).To(HaveLen(1)) 267 Expect(ctrJSON[0].Config.Entrypoint[0]).To(Equal("docker-entrypoint.sh")) 268 }) 269 270 It("podman create --pull", func() { 271 session := podmanTest.Podman([]string{"create", "--pull", "never", "--name=foo", "testimage:00000000"}) 272 session.WaitWithDefaultTimeout() 273 Expect(session).To(ExitWithError(125, "testimage:00000000: image not known")) 274 275 session = podmanTest.Podman([]string{"create", "--pull", "always", "--name=foo", "testimage:00000000"}) 276 session.WaitWithDefaultTimeout() 277 Expect(session).Should(Exit(0)) 278 Expect(session.ErrorToString()).To(ContainSubstring("Copying blob"), "progress message from pull") 279 }) 280 281 It("podman create using image list by tag", func() { 282 session := podmanTest.Podman([]string{"create", "-q", "--pull=always", "--arch=arm64", "--name=foo", ALPINELISTTAG}) 283 session.WaitWithDefaultTimeout() 284 Expect(session).Should(ExitCleanly()) 285 session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"}) 286 session.WaitWithDefaultTimeout() 287 Expect(session).Should(ExitCleanly()) 288 Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64ID)) 289 session = podmanTest.Podman([]string{"inspect", "--format", "{{.ImageName}}", "foo"}) 290 session.WaitWithDefaultTimeout() 291 Expect(session).Should(ExitCleanly()) 292 Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTTAG)) 293 }) 294 295 It("podman create using image list by digest", func() { 296 session := podmanTest.Podman([]string{"create", "--pull=always", "--arch=arm64", "--name=foo", ALPINELISTDIGEST}) 297 session.WaitWithDefaultTimeout() 298 Expect(session).Should(Exit(0)) 299 Expect(session.ErrorToString()).To(ContainSubstring("Writing manifest to image destination"), "progress message from pull") 300 session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"}) 301 session.WaitWithDefaultTimeout() 302 Expect(session).Should(ExitCleanly()) 303 Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64ID)) 304 session = podmanTest.Podman([]string{"inspect", "--format", "{{.ImageName}}", "foo"}) 305 session.WaitWithDefaultTimeout() 306 Expect(session).Should(ExitCleanly()) 307 Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINELISTDIGEST)) 308 }) 309 310 It("podman create using image list instance by digest", func() { 311 session := podmanTest.Podman([]string{"create", "-q", "--pull=always", "--arch=arm64", "--name=foo", ALPINEARM64DIGEST}) 312 session.WaitWithDefaultTimeout() 313 Expect(session).Should(ExitCleanly()) 314 session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"}) 315 session.WaitWithDefaultTimeout() 316 Expect(session).Should(ExitCleanly()) 317 Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64ID)) 318 session = podmanTest.Podman([]string{"inspect", "--format", "{{.ImageName}}", "foo"}) 319 session.WaitWithDefaultTimeout() 320 Expect(session).Should(ExitCleanly()) 321 Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) 322 }) 323 324 It("podman create using cross-arch image list instance by digest", func() { 325 session := podmanTest.Podman([]string{"create", "-q", "--pull=always", "--arch=arm64", "--name=foo", ALPINEARM64DIGEST}) 326 session.WaitWithDefaultTimeout() 327 Expect(session).Should(ExitCleanly()) 328 session = podmanTest.Podman([]string{"inspect", "--format", "{{.Image}}", "foo"}) 329 session.WaitWithDefaultTimeout() 330 Expect(session).Should(ExitCleanly()) 331 Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64ID)) 332 session = podmanTest.Podman([]string{"inspect", "--format", "{{.ImageName}}", "foo"}) 333 session.WaitWithDefaultTimeout() 334 Expect(session).Should(ExitCleanly()) 335 Expect(string(session.Out.Contents())).To(ContainSubstring(ALPINEARM64DIGEST)) 336 }) 337 338 It("podman create --authfile with nonexistent authfile", func() { 339 bogus := filepath.Join(podmanTest.TempDir, "bogus.conf") 340 session := podmanTest.Podman([]string{"create", "--authfile", bogus, "--name=foo", ALPINE}) 341 session.WaitWithDefaultTimeout() 342 Expect(session).To(ExitWithError(125, "credential file is not accessible: ")) 343 Expect(session.ErrorToString()).To(ContainSubstring("no such file or directory")) 344 }) 345 346 It("podman create --signature-policy", func() { 347 session := podmanTest.Podman([]string{"create", "--pull=always", "--signature-policy", "/no/such/file", ALPINE}) 348 session.WaitWithDefaultTimeout() 349 if IsRemote() { 350 Expect(session).To(ExitWithError(125, "unknown flag: --signature-policy")) 351 return 352 } else { 353 Expect(session).To(ExitWithError(125, "open /no/such/file: no such file or directory")) 354 } 355 356 session = podmanTest.Podman([]string{"create", "-q", "--pull=always", "--signature-policy", "/etc/containers/policy.json", ALPINE}) 357 session.WaitWithDefaultTimeout() 358 Expect(session).Should(ExitCleanly()) 359 }) 360 361 It("podman create with unset label", func() { 362 // Alpine is assumed to have no labels here, which seems safe 363 ctrName := "testctr" 364 session := podmanTest.Podman([]string{"create", "--label", "TESTKEY1=", "--label", "TESTKEY2", "--name", ctrName, ALPINE, "top"}) 365 session.WaitWithDefaultTimeout() 366 Expect(session).Should(ExitCleanly()) 367 368 inspect := podmanTest.Podman([]string{"inspect", ctrName}) 369 inspect.WaitWithDefaultTimeout() 370 data := inspect.InspectContainerToJSON() 371 Expect(data).To(HaveLen(1), "len(InspectContainerToJSON)") 372 Expect(data[0].Config.Labels).To(HaveLen(2)) 373 Expect(data[0].Config.Labels).To(HaveKey("TESTKEY1")) 374 Expect(data[0].Config.Labels).To(HaveKey("TESTKEY2")) 375 }) 376 377 It("podman create with set label", func() { 378 // Alpine is assumed to have no labels here, which seems safe 379 ctrName := "testctr" 380 session := podmanTest.Podman([]string{"create", "--label", "TESTKEY1=value1", "--label", "TESTKEY2=bar", "--name", ctrName, ALPINE, "top"}) 381 session.WaitWithDefaultTimeout() 382 Expect(session).Should(ExitCleanly()) 383 384 inspect := podmanTest.Podman([]string{"inspect", ctrName}) 385 inspect.WaitWithDefaultTimeout() 386 data := inspect.InspectContainerToJSON() 387 Expect(data).To(HaveLen(1)) 388 Expect(data[0].Config.Labels).To(HaveLen(2)) 389 Expect(data[0].Config.Labels).To(HaveKeyWithValue("TESTKEY1", "value1")) 390 Expect(data[0].Config.Labels).To(HaveKeyWithValue("TESTKEY2", "bar")) 391 }) 392 393 It("podman create with --restart=on-failure:5 parses correctly", func() { 394 ctrName := "testctr" 395 session := podmanTest.Podman([]string{"create", "-t", "--restart", "on-failure:5", "--name", ctrName, ALPINE, "/bin/sh"}) 396 session.WaitWithDefaultTimeout() 397 Expect(session).Should(ExitCleanly()) 398 399 inspect := podmanTest.Podman([]string{"inspect", ctrName}) 400 inspect.WaitWithDefaultTimeout() 401 data := inspect.InspectContainerToJSON() 402 Expect(data).To(HaveLen(1)) 403 Expect(data[0].HostConfig.RestartPolicy).To(HaveField("Name", "on-failure")) 404 Expect(data[0].HostConfig.RestartPolicy).To(HaveField("MaximumRetryCount", uint(5))) 405 }) 406 407 It("podman create with --restart-policy=always:5 fails", func() { 408 session := podmanTest.Podman([]string{"create", "-t", "--restart", "always:5", ALPINE, "/bin/sh"}) 409 session.WaitWithDefaultTimeout() 410 Expect(session).To(ExitWithError(125, "restart policy retries can only be specified with on-failure restart policy")) 411 }) 412 413 It("podman create with --restart-policy unless-stopped", func() { 414 ctrName := "testctr" 415 unlessStopped := "unless-stopped" 416 session := podmanTest.Podman([]string{"create", "-t", "--restart", unlessStopped, "--name", ctrName, ALPINE, "/bin/sh"}) 417 session.WaitWithDefaultTimeout() 418 Expect(session).Should(ExitCleanly()) 419 420 inspect := podmanTest.Podman([]string{"inspect", ctrName}) 421 inspect.WaitWithDefaultTimeout() 422 data := inspect.InspectContainerToJSON() 423 Expect(data).To(HaveLen(1)) 424 Expect(data[0].HostConfig.RestartPolicy).To(HaveField("Name", unlessStopped)) 425 }) 426 427 It("podman create with -m 1000000 sets swap to 2000000", func() { 428 SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1") 429 numMem := 1000000 430 ctrName := "testCtr" 431 session := podmanTest.Podman([]string{"create", "-t", "-m", fmt.Sprintf("%db", numMem), "--name", ctrName, ALPINE, "/bin/sh"}) 432 session.WaitWithDefaultTimeout() 433 Expect(session).Should(ExitCleanly()) 434 435 inspect := podmanTest.Podman([]string{"inspect", ctrName}) 436 inspect.WaitWithDefaultTimeout() 437 data := inspect.InspectContainerToJSON() 438 Expect(data).To(HaveLen(1)) 439 Expect(data[0].HostConfig).To(HaveField("MemorySwap", int64(2*numMem))) 440 }) 441 442 It("podman create --cpus 5 sets nanocpus", func() { 443 SkipIfRootlessCgroupsV1("Not supported for rootless + CgroupsV1") 444 numCpus := 5 445 nanoCPUs := numCpus * 1000000000 446 ctrName := "testCtr" 447 session := podmanTest.Podman([]string{"create", "-t", "--cpus", strconv.Itoa(numCpus), "--name", ctrName, ALPINE, "/bin/sh"}) 448 session.WaitWithDefaultTimeout() 449 Expect(session).Should(ExitCleanly()) 450 451 inspect := podmanTest.Podman([]string{"inspect", ctrName}) 452 inspect.WaitWithDefaultTimeout() 453 data := inspect.InspectContainerToJSON() 454 Expect(data).To(HaveLen(1)) 455 Expect(data[0].HostConfig).To(HaveField("NanoCpus", int64(nanoCPUs))) 456 }) 457 458 It("podman create --replace", func() { 459 // Make sure we error out with --name. 460 session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"}) 461 session.WaitWithDefaultTimeout() 462 Expect(session).Should(ExitWithError(125, "cannot replace container without --name being set")) 463 464 // Create and replace 5 times in a row the "same" container. 465 ctrName := "testCtr" 466 for i := 0; i < 5; i++ { 467 session = podmanTest.Podman([]string{"create", "--replace", "--name", ctrName, ALPINE, "/bin/sh"}) 468 session.WaitWithDefaultTimeout() 469 Expect(session).Should(ExitCleanly()) 470 } 471 }) 472 473 It("podman create sets default stop signal 15", func() { 474 ctrName := "testCtr" 475 session := podmanTest.Podman([]string{"create", "--name", ctrName, ALPINE, "/bin/sh"}) 476 session.WaitWithDefaultTimeout() 477 Expect(session).Should(ExitCleanly()) 478 479 inspect := podmanTest.Podman([]string{"inspect", ctrName}) 480 inspect.WaitWithDefaultTimeout() 481 data := inspect.InspectContainerToJSON() 482 Expect(data).To(HaveLen(1)) 483 Expect(data[0].Config).To(HaveField("StopSignal", "SIGTERM")) 484 }) 485 486 It("podman create --tz", func() { 487 session := podmanTest.Podman([]string{"create", "--tz", "foo", "--name", "bad", ALPINE, "date"}) 488 session.WaitWithDefaultTimeout() 489 Expect(session).To(ExitWithError(125, "running container create option: finding timezone: unknown time zone foo")) 490 491 session = podmanTest.Podman([]string{"create", "--tz", "America", "--name", "dir", ALPINE, "date"}) 492 session.WaitWithDefaultTimeout() 493 Expect(session).To(ExitWithError(125, "running container create option: finding timezone: is a directory")) 494 495 session = podmanTest.Podman([]string{"create", "--tz", "Pacific/Honolulu", "--name", "zone", ALPINE, "date"}) 496 session.WaitWithDefaultTimeout() 497 inspect := podmanTest.Podman([]string{"inspect", "zone"}) 498 inspect.WaitWithDefaultTimeout() 499 data := inspect.InspectContainerToJSON() 500 Expect(data).To(HaveLen(1)) 501 Expect(data[0].Config).To(HaveField("Timezone", "Pacific/Honolulu")) 502 503 session = podmanTest.Podman([]string{"create", "--tz", "local", "--name", "lcl", ALPINE, "date"}) 504 session.WaitWithDefaultTimeout() 505 inspect = podmanTest.Podman([]string{"inspect", "lcl"}) 506 inspect.WaitWithDefaultTimeout() 507 data = inspect.InspectContainerToJSON() 508 Expect(data).To(HaveLen(1)) 509 Expect(data[0].Config).To(HaveField("Timezone", "local")) 510 }) 511 512 It("podman create --umask", func() { 513 if !strings.Contains(podmanTest.OCIRuntime, "crun") { 514 Skip("Test only works on crun") 515 } 516 517 session := podmanTest.Podman([]string{"create", "--name", "default", ALPINE}) 518 session.WaitWithDefaultTimeout() 519 inspect := podmanTest.Podman([]string{"inspect", "default"}) 520 inspect.WaitWithDefaultTimeout() 521 data := inspect.InspectContainerToJSON() 522 Expect(data).To(HaveLen(1)) 523 Expect(data[0].Config).To(HaveField("Umask", "0022")) 524 525 session = podmanTest.Podman([]string{"create", "--umask", "0002", "--name", "umask", ALPINE}) 526 session.WaitWithDefaultTimeout() 527 inspect = podmanTest.Podman([]string{"inspect", "umask"}) 528 inspect.WaitWithDefaultTimeout() 529 data = inspect.InspectContainerToJSON() 530 Expect(data).To(HaveLen(1)) 531 Expect(data[0].Config).To(HaveField("Umask", "0002")) 532 533 session = podmanTest.Podman([]string{"create", "--umask", "0077", "--name", "fedora", fedoraMinimal}) 534 session.WaitWithDefaultTimeout() 535 inspect = podmanTest.Podman([]string{"inspect", "fedora"}) 536 inspect.WaitWithDefaultTimeout() 537 data = inspect.InspectContainerToJSON() 538 Expect(data).To(HaveLen(1)) 539 Expect(data[0].Config).To(HaveField("Umask", "0077")) 540 541 session = podmanTest.Podman([]string{"create", "--umask", "22", "--name", "umask-short", ALPINE}) 542 session.WaitWithDefaultTimeout() 543 inspect = podmanTest.Podman([]string{"inspect", "umask-short"}) 544 inspect.WaitWithDefaultTimeout() 545 data = inspect.InspectContainerToJSON() 546 Expect(data).To(HaveLen(1)) 547 Expect(data[0].Config).To(HaveField("Umask", "0022")) 548 549 session = podmanTest.Podman([]string{"create", "--umask", "9999", "--name", "bad", ALPINE}) 550 session.WaitWithDefaultTimeout() 551 Expect(session).To(ExitWithError(125, "invalid umask string 9999: invalid argument")) 552 }) 553 554 It("create container in pod with IP should fail", func() { 555 SkipIfRootless("Setting IP not supported in rootless mode without network") 556 name := "createwithstaticip" 557 pod := podmanTest.RunTopContainerInPod("", "new:"+name) 558 pod.WaitWithDefaultTimeout() 559 Expect(pod).Should(ExitCleanly()) 560 561 session := podmanTest.Podman([]string{"create", "--pod", name, "--ip", "192.168.1.2", ALPINE, "top"}) 562 session.WaitWithDefaultTimeout() 563 Expect(session).Should(ExitWithError(125, "invalid config provided: networks must be defined when the pod is created: network cannot be configured when it is shared with a pod")) 564 }) 565 566 It("create container in pod with mac should fail", func() { 567 SkipIfRootless("Setting MAC Address not supported in rootless mode without network") 568 name := "createwithstaticmac" 569 pod := podmanTest.RunTopContainerInPod("", "new:"+name) 570 pod.WaitWithDefaultTimeout() 571 Expect(pod).Should(ExitCleanly()) 572 573 session := podmanTest.Podman([]string{"create", "--pod", name, "--mac-address", "52:54:00:6d:2f:82", ALPINE, "top"}) 574 session.WaitWithDefaultTimeout() 575 Expect(session).Should(ExitWithError(125, "invalid config provided: networks must be defined when the pod is created: network cannot be configured when it is shared with a pod")) 576 }) 577 578 It("create container in pod with network should not fail", func() { 579 name := "createwithnetwork" 580 pod := podmanTest.RunTopContainerInPod("", "new:"+name) 581 pod.WaitWithDefaultTimeout() 582 Expect(pod).Should(ExitCleanly()) 583 584 netName := "pod" + stringid.GenerateRandomID() 585 session := podmanTest.Podman([]string{"network", "create", netName}) 586 session.WaitWithDefaultTimeout() 587 Expect(session).Should(ExitCleanly()) 588 defer podmanTest.removeNetwork(netName) 589 590 session = podmanTest.Podman([]string{"create", "--pod", name, "--network", netName, ALPINE, "top"}) 591 session.WaitWithDefaultTimeout() 592 Expect(session).Should(ExitCleanly()) 593 }) 594 595 It("create container in pod with ports should fail", func() { 596 name := "createwithports" 597 pod := podmanTest.RunTopContainerInPod("", "new:"+name) 598 pod.WaitWithDefaultTimeout() 599 Expect(pod).Should(ExitCleanly()) 600 601 session := podmanTest.Podman([]string{"create", "--pod", name, "-p", "8086:80", ALPINE, "top"}) 602 session.WaitWithDefaultTimeout() 603 Expect(session).Should(ExitWithError(125, "invalid config provided: published or exposed ports must be defined when the pod is created: network cannot be configured when it is shared with a pod")) 604 }) 605 606 It("create container in pod publish ports should fail", func() { 607 name := "createwithpublishports" 608 pod := podmanTest.RunTopContainerInPod("", "new:"+name) 609 pod.WaitWithDefaultTimeout() 610 Expect(pod).Should(ExitCleanly()) 611 612 session := podmanTest.Podman([]string{"create", "--pod", name, "-P", ALPINE, "top"}) 613 session.WaitWithDefaultTimeout() 614 Expect(session).Should(ExitWithError(125, "invalid config provided: published or exposed ports must be defined when the pod is created: network cannot be configured when it is shared with a pod")) 615 }) 616 617 It("create use local store image if input image contains a manifest list", func() { 618 session := podmanTest.Podman([]string{"pull", "-q", BB}) 619 session.WaitWithDefaultTimeout() 620 Expect(session).Should(ExitCleanly()) 621 622 session = podmanTest.Podman([]string{"manifest", "create", "mylist"}) 623 session.WaitWithDefaultTimeout() 624 Expect(session).Should(ExitCleanly()) 625 626 session = podmanTest.Podman([]string{"manifest", "add", "--all", "mylist", BB}) 627 session.WaitWithDefaultTimeout() 628 Expect(session).Should(ExitCleanly()) 629 630 session = podmanTest.Podman([]string{"create", "mylist"}) 631 session.WaitWithDefaultTimeout() 632 Expect(session).Should(ExitCleanly()) 633 }) 634 635 It("podman create -d should fail, can not detach create containers", func() { 636 session := podmanTest.Podman([]string{"create", "-d", ALPINE}) 637 session.WaitWithDefaultTimeout() 638 Expect(session).Should(ExitWithError(125, "unknown shorthand flag: 'd' in -d")) 639 640 session = podmanTest.Podman([]string{"create", "--detach", ALPINE}) 641 session.WaitWithDefaultTimeout() 642 Expect(session).Should(ExitWithError(125, "unknown flag")) 643 Expect(session.ErrorToString()).To(ContainSubstring("unknown flag: --detach")) 644 645 session = podmanTest.Podman([]string{"create", "--detach-keys", "ctrl-x", ALPINE}) 646 session.WaitWithDefaultTimeout() 647 Expect(session).Should(ExitWithError(125, "unknown flag: --detach-keys")) 648 }) 649 650 It("podman create --platform", func() { 651 session := podmanTest.Podman([]string{"create", "--platform=linux/bogus", ALPINE}) 652 session.WaitWithDefaultTimeout() 653 Expect(session).Should(ExitWithError(125, "no image found in manifest list for architecture bogus")) 654 655 session = podmanTest.Podman([]string{"create", "--platform=linux/arm64", "--os", "windows", ALPINE}) 656 session.WaitWithDefaultTimeout() 657 Expect(session).Should(ExitWithError(125, "--platform option can not be specified with --arch or --os")) 658 659 session = podmanTest.Podman([]string{"create", "-q", "--platform=linux/arm64", ALPINE}) 660 session.WaitWithDefaultTimeout() 661 Expect(session).Should(ExitCleanly()) 662 663 setup := podmanTest.Podman([]string{"container", "inspect", session.OutputToString()}) 664 setup.WaitWithDefaultTimeout() 665 Expect(setup).Should(ExitCleanly()) 666 667 data := setup.InspectContainerToJSON() 668 setup = podmanTest.Podman([]string{"image", "inspect", data[0].Image}) 669 setup.WaitWithDefaultTimeout() 670 Expect(setup).Should(ExitCleanly()) 671 672 idata := setup.InspectImageJSON() // returns []inspect.ImageData 673 Expect(idata).To(HaveLen(1)) 674 Expect(idata[0]).To(HaveField("Os", runtime.GOOS)) 675 Expect(idata[0]).To(HaveField("Architecture", "arm64")) 676 }) 677 678 It("podman create --uid/gidmap --pod conflict test", func() { 679 create := podmanTest.Podman([]string{"create", "--uidmap", "0:1000:1000", "--pod", "new:testing123", ALPINE}) 680 create.WaitWithDefaultTimeout() 681 Expect(create).ShouldNot(ExitCleanly()) 682 Expect(create.ErrorToString()).To(ContainSubstring("cannot specify a new uid/gid map when entering a pod with an infra container")) 683 684 create = podmanTest.Podman([]string{"create", "--gidmap", "0:1000:1000", "--pod", "new:testing1234", ALPINE}) 685 create.WaitWithDefaultTimeout() 686 Expect(create).ShouldNot(ExitCleanly()) 687 Expect(create.ErrorToString()).To(ContainSubstring("cannot specify a new uid/gid map when entering a pod with an infra container")) 688 689 }) 690 691 It("podman create --chrootdirs inspection test", func() { 692 session := podmanTest.Podman([]string{"create", "--chrootdirs", "/var/local/qwerty", ALPINE}) 693 session.WaitWithDefaultTimeout() 694 Expect(session).Should(ExitCleanly()) 695 696 setup := podmanTest.Podman([]string{"container", "inspect", session.OutputToString()}) 697 setup.WaitWithDefaultTimeout() 698 Expect(setup).Should(ExitCleanly()) 699 700 data := setup.InspectContainerToJSON() 701 Expect(data).To(HaveLen(1)) 702 Expect(data[0].Config.ChrootDirs).To(HaveLen(1)) 703 Expect(data[0].Config.ChrootDirs[0]).To(Equal("/var/local/qwerty")) 704 }) 705 706 It("podman create --chrootdirs functionality test", func() { 707 session := podmanTest.Podman([]string{"create", "-t", "--chrootdirs", "/var/local/qwerty,withcomma", ALPINE, "/bin/cat"}) 708 session.WaitWithDefaultTimeout() 709 Expect(session).Should(ExitCleanly()) 710 ctrID := session.OutputToString() 711 712 setup := podmanTest.Podman([]string{"start", ctrID}) 713 setup.WaitWithDefaultTimeout() 714 Expect(setup).Should(ExitCleanly()) 715 716 setup = podmanTest.Podman([]string{"exec", ctrID, "cmp", "/etc/resolv.conf", "/var/local/qwerty,withcomma/etc/resolv.conf"}) 717 setup.WaitWithDefaultTimeout() 718 Expect(setup).Should(ExitCleanly()) 719 }) 720 721 It("create container with name subset of existing ID", func() { 722 create1 := podmanTest.Podman([]string{"create", "-t", ALPINE, "top"}) 723 create1.WaitWithDefaultTimeout() 724 Expect(create1).Should(ExitCleanly()) 725 ctr1ID := create1.OutputToString() 726 727 ctr2Name := ctr1ID[:5] 728 create2 := podmanTest.Podman([]string{"create", "-t", "--name", ctr2Name, ALPINE, "top"}) 729 create2.WaitWithDefaultTimeout() 730 Expect(create2).Should(ExitCleanly()) 731 732 inspect := podmanTest.Podman([]string{"inspect", "--format", "{{.Name}}", ctr2Name}) 733 inspect.WaitWithDefaultTimeout() 734 Expect(inspect).Should(ExitCleanly()) 735 Expect(inspect.OutputToString()).Should(Equal(ctr2Name)) 736 }) 737 })