github.com/containers/podman/v4@v4.9.4/test/e2e/pod_create_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "os/user" 7 "path/filepath" 8 "strconv" 9 "strings" 10 "time" 11 12 "github.com/containers/common/pkg/apparmor" 13 "github.com/containers/common/pkg/seccomp" 14 "github.com/containers/common/pkg/sysinfo" 15 "github.com/containers/podman/v4/pkg/util" 16 . "github.com/containers/podman/v4/test/utils" 17 . "github.com/onsi/ginkgo/v2" 18 . "github.com/onsi/gomega" 19 . "github.com/onsi/gomega/gexec" 20 "github.com/opencontainers/selinux/go-selinux" 21 ) 22 23 var _ = Describe("Podman pod create", func() { 24 hostname, _ := os.Hostname() 25 26 It("podman create pod", func() { 27 _, ec, podID := podmanTest.CreatePod(nil) 28 Expect(ec).To(Equal(0)) 29 30 check := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc"}) 31 check.WaitWithDefaultTimeout() 32 Expect(check.OutputToString()).To(ContainSubstring(podID)) 33 Expect(check.OutputToStringArray()).To(HaveLen(1)) 34 }) 35 36 It("podman create pod with name", func() { 37 name := "test" 38 _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}}) 39 Expect(ec).To(Equal(0)) 40 41 check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"}) 42 check.WaitWithDefaultTimeout() 43 Expect(check.OutputToString()).To(ContainSubstring(name)) 44 }) 45 46 It("podman create pod with doubled name", func() { 47 name := "test" 48 _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}}) 49 Expect(ec).To(Equal(0)) 50 51 _, ec2, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}}) 52 Expect(ec2).To(Not(Equal(0))) 53 54 check := podmanTest.Podman([]string{"pod", "ps", "-q"}) 55 check.WaitWithDefaultTimeout() 56 Expect(check.OutputToStringArray()).To(HaveLen(1)) 57 }) 58 59 It("podman create pod without network portbindings", func() { 60 name := "test" 61 session := podmanTest.Podman([]string{"pod", "create", "--name", name}) 62 session.WaitWithDefaultTimeout() 63 Expect(session).Should(ExitCleanly()) 64 pod := session.OutputToString() 65 66 webserver := podmanTest.Podman([]string{"run", "--pod", pod, "-dt", NGINX_IMAGE}) 67 webserver.WaitWithDefaultTimeout() 68 Expect(webserver).Should(ExitCleanly()) 69 70 check := SystemExec("nc", []string{"-z", "localhost", "80"}) 71 Expect(check).Should(Exit(1)) 72 }) 73 74 It("podman create pod with network portbindings", func() { 75 name := "test" 76 port := GetPort() 77 session := podmanTest.Podman([]string{"pod", "create", "--name", name, "-p", fmt.Sprintf("%d:80", port)}) 78 session.WaitWithDefaultTimeout() 79 Expect(session).Should(ExitCleanly()) 80 pod := session.OutputToString() 81 82 webserver := podmanTest.Podman([]string{"run", "--pod", pod, "-dt", NGINX_IMAGE}) 83 webserver.WaitWithDefaultTimeout() 84 Expect(webserver).Should(ExitCleanly()) 85 Expect(ncz(port)).To(BeTrue(), "port %d is up", port) 86 }) 87 88 It("podman create pod with id file with network portbindings", func() { 89 file := filepath.Join(podmanTest.TempDir, "pod.id") 90 name := "test" 91 port := GetPort() 92 session := podmanTest.Podman([]string{"pod", "create", "--name", name, "--pod-id-file", file, "-p", fmt.Sprintf("%d:80", port)}) 93 session.WaitWithDefaultTimeout() 94 Expect(session).Should(ExitCleanly()) 95 96 webserver := podmanTest.Podman([]string{"run", "--pod-id-file", file, "-dt", NGINX_IMAGE}) 97 webserver.WaitWithDefaultTimeout() 98 Expect(webserver).Should(ExitCleanly()) 99 Expect(ncz(port)).To(BeTrue(), "port %d is up", port) 100 }) 101 102 It("podman create pod with no infra but portbindings should fail", func() { 103 name := "test" 104 session := podmanTest.Podman([]string{"pod", "create", "--infra=false", "--name", name, "-p", "80:80"}) 105 session.WaitWithDefaultTimeout() 106 Expect(session).Should(Exit(125)) 107 }) 108 109 It("podman create pod with --no-hosts", func() { 110 name := "test" 111 podCreate := podmanTest.Podman([]string{"pod", "create", "--no-hosts", "--name", name}) 112 podCreate.WaitWithDefaultTimeout() 113 Expect(podCreate).Should(ExitCleanly()) 114 115 alpineResolvConf := podmanTest.Podman([]string{"run", "--rm", "--no-hosts", ALPINE, "cat", "/etc/hosts"}) 116 alpineResolvConf.WaitWithDefaultTimeout() 117 Expect(alpineResolvConf).Should(ExitCleanly()) 118 119 podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/hosts"}) 120 podResolvConf.WaitWithDefaultTimeout() 121 Expect(podResolvConf).Should(ExitCleanly()) 122 Expect(podResolvConf.OutputToString()).To(Equal(alpineResolvConf.OutputToString())) 123 }) 124 125 It("podman create pod with --no-hosts and no infra should fail", func() { 126 name := "test" 127 podCreate := podmanTest.Podman([]string{"pod", "create", "--no-hosts", "--name", name, "--infra=false"}) 128 podCreate.WaitWithDefaultTimeout() 129 Expect(podCreate).Should(Exit(125)) 130 }) 131 132 It("podman create pod with --add-host", func() { 133 name := "test" 134 podCreate := podmanTest.Podman([]string{"pod", "create", "--add-host", "test.example.com:12.34.56.78", "--name", name}) 135 podCreate.WaitWithDefaultTimeout() 136 Expect(podCreate).Should(ExitCleanly()) 137 138 podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/hosts"}) 139 podResolvConf.WaitWithDefaultTimeout() 140 Expect(podResolvConf).Should(ExitCleanly()) 141 Expect(podResolvConf.OutputToString()).To(ContainSubstring("12.34.56.78 test.example.com")) 142 }) 143 144 It("podman create pod with --add-host and no infra should fail", func() { 145 name := "test" 146 podCreate := podmanTest.Podman([]string{"pod", "create", "--add-host", "test.example.com:12.34.56.78", "--name", name, "--infra=false"}) 147 podCreate.WaitWithDefaultTimeout() 148 Expect(podCreate).Should(Exit(125)) 149 }) 150 151 It("podman create pod with DNS server set", func() { 152 name := "test" 153 server := "12.34.56.78" 154 podCreate := podmanTest.Podman([]string{"pod", "create", "--dns", server, "--name", name}) 155 podCreate.WaitWithDefaultTimeout() 156 Expect(podCreate).Should(ExitCleanly()) 157 158 podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/resolv.conf"}) 159 podResolvConf.WaitWithDefaultTimeout() 160 Expect(podResolvConf).Should(ExitCleanly()) 161 Expect(podResolvConf.OutputToString()).To(ContainSubstring("nameserver %s", server)) 162 }) 163 164 It("podman create pod with DNS server set and no infra should fail", func() { 165 name := "test" 166 server := "12.34.56.78" 167 podCreate := podmanTest.Podman([]string{"pod", "create", "--dns", server, "--name", name, "--infra=false"}) 168 podCreate.WaitWithDefaultTimeout() 169 Expect(podCreate).Should(Exit(125)) 170 }) 171 172 It("podman create pod with DNS option set", func() { 173 name := "test" 174 option := "attempts:5" 175 podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-opt", option, "--name", name}) 176 podCreate.WaitWithDefaultTimeout() 177 Expect(podCreate).Should(ExitCleanly()) 178 179 podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/resolv.conf"}) 180 podResolvConf.WaitWithDefaultTimeout() 181 Expect(podResolvConf).Should(ExitCleanly()) 182 Expect(podResolvConf.OutputToString()).To(ContainSubstring(fmt.Sprintf("options %s", option))) 183 }) 184 185 It("podman create pod with DNS option set and no infra should fail", func() { 186 name := "test" 187 option := "attempts:5" 188 podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-opt", option, "--name", name, "--infra=false"}) 189 podCreate.WaitWithDefaultTimeout() 190 Expect(podCreate).Should(Exit(125)) 191 }) 192 193 It("podman create pod with DNS search domain set", func() { 194 name := "test" 195 search := "example.com" 196 podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-search", search, "--name", name}) 197 podCreate.WaitWithDefaultTimeout() 198 Expect(podCreate).Should(ExitCleanly()) 199 200 podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/resolv.conf"}) 201 podResolvConf.WaitWithDefaultTimeout() 202 Expect(podResolvConf).Should(ExitCleanly()) 203 Expect(podResolvConf.OutputToString()).To(ContainSubstring(fmt.Sprintf("search %s", search))) 204 }) 205 206 It("podman create pod with DNS search domain set and no infra should fail", func() { 207 name := "test" 208 search := "example.com" 209 podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-search", search, "--name", name, "--infra=false"}) 210 podCreate.WaitWithDefaultTimeout() 211 Expect(podCreate).Should(Exit(125)) 212 }) 213 214 It("podman create pod with IP address", func() { 215 name := "test" 216 ip := GetSafeIPAddress() 217 podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", name}) 218 podCreate.WaitWithDefaultTimeout() 219 // Rootless should error without network 220 if isRootless() { 221 Expect(podCreate).Should(Exit(125)) 222 } else { 223 Expect(podCreate).Should(ExitCleanly()) 224 podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "ip", "addr"}) 225 podResolvConf.WaitWithDefaultTimeout() 226 Expect(podResolvConf).Should(ExitCleanly()) 227 Expect(podResolvConf.OutputToString()).To(ContainSubstring(ip)) 228 } 229 }) 230 231 It("podman container in pod with IP address shares IP address", func() { 232 SkipIfRootless("Rootless does not support --ip without network") 233 podName := "test" 234 ctrName := "testCtr" 235 ip := GetSafeIPAddress() 236 podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", podName}) 237 podCreate.WaitWithDefaultTimeout() 238 Expect(podCreate).Should(ExitCleanly()) 239 podCtr := podmanTest.Podman([]string{"run", "--name", ctrName, "--pod", podName, "-d", "-t", ALPINE, "top"}) 240 podCtr.WaitWithDefaultTimeout() 241 Expect(podCtr).Should(ExitCleanly()) 242 ctrInspect := podmanTest.Podman([]string{"inspect", ctrName}) 243 ctrInspect.WaitWithDefaultTimeout() 244 Expect(ctrInspect).Should(ExitCleanly()) 245 ctrJSON := ctrInspect.InspectContainerToJSON() 246 Expect(ctrJSON[0].NetworkSettings).To(HaveField("IPAddress", ip)) 247 }) 248 249 It("podman create pod with IP address and no infra should fail", func() { 250 name := "test" 251 ip := GetSafeIPAddress() 252 podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", name, "--infra=false"}) 253 podCreate.WaitWithDefaultTimeout() 254 Expect(podCreate).Should(Exit(125)) 255 }) 256 257 It("podman create pod with MAC address", func() { 258 name := "test" 259 mac := "92:d0:c6:0a:29:35" 260 podCreate := podmanTest.Podman([]string{"pod", "create", "--mac-address", mac, "--name", name}) 261 podCreate.WaitWithDefaultTimeout() 262 // Rootless should error 263 if isRootless() { 264 Expect(podCreate).Should(Exit(125)) 265 } else { 266 Expect(podCreate).Should(ExitCleanly()) 267 podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "ip", "addr"}) 268 podResolvConf.WaitWithDefaultTimeout() 269 Expect(podResolvConf).Should(ExitCleanly()) 270 Expect(podResolvConf.OutputToString()).To(ContainSubstring(mac)) 271 } 272 }) 273 274 It("podman create pod with MAC address and no infra should fail", func() { 275 name := "test" 276 mac := "92:d0:c6:0a:29:35" 277 podCreate := podmanTest.Podman([]string{"pod", "create", "--mac-address", mac, "--name", name, "--infra=false"}) 278 podCreate.WaitWithDefaultTimeout() 279 Expect(podCreate).Should(Exit(125)) 280 }) 281 282 It("podman create pod and print id to external file", func() { 283 // Switch to temp dir and restore it afterwards 284 cwd, err := os.Getwd() 285 Expect(err).ToNot(HaveOccurred()) 286 Expect(os.Chdir(os.TempDir())).To(Succeed()) 287 288 targetFile := filepath.Join(podmanTest.TempDir, "idFile") 289 defer Expect(os.RemoveAll(targetFile)).To(BeNil()) 290 defer Expect(os.Chdir(cwd)).To(BeNil()) 291 292 session := podmanTest.Podman([]string{"pod", "create", "--name=abc", "--pod-id-file", targetFile}) 293 session.WaitWithDefaultTimeout() 294 Expect(session).Should(ExitCleanly()) 295 296 id, _ := os.ReadFile(targetFile) 297 check := podmanTest.Podman([]string{"pod", "inspect", "abc"}) 298 check.WaitWithDefaultTimeout() 299 data := check.InspectPodToJSON() 300 Expect(data).To(HaveField("ID", string(id))) 301 }) 302 303 It("podman pod create --replace", func() { 304 // Make sure we error out with --name. 305 session := podmanTest.Podman([]string{"pod", "create", "--replace", ALPINE, "/bin/sh"}) 306 session.WaitWithDefaultTimeout() 307 Expect(session).Should(Exit(125)) 308 309 // Create and replace 5 times in a row the "same" pod. 310 podName := "testCtr" 311 for i := 0; i < 5; i++ { 312 session = podmanTest.Podman([]string{"pod", "create", "--replace", "--name", podName}) 313 session.WaitWithDefaultTimeout() 314 Expect(session).Should(ExitCleanly()) 315 } 316 }) 317 318 It("podman create pod with defaults", func() { 319 name := "test" 320 session := podmanTest.Podman([]string{"pod", "create", "--name", name}) 321 session.WaitWithDefaultTimeout() 322 Expect(session).Should(ExitCleanly()) 323 324 check := podmanTest.Podman([]string{"pod", "inspect", name}) 325 check.WaitWithDefaultTimeout() 326 Expect(check).Should(ExitCleanly()) 327 data := check.InspectPodToJSON() 328 329 check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID}) 330 check1.WaitWithDefaultTimeout() 331 Expect(check1).Should(ExitCleanly()) 332 Expect(check1.OutputToString()).To(Equal("/catatonit -P")) 333 334 // check the Path and Args 335 check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID}) 336 check2.WaitWithDefaultTimeout() 337 Expect(check2).Should(ExitCleanly()) 338 Expect(check2.OutputToString()).To(Equal("/catatonit:[-P]")) 339 }) 340 341 It("podman create pod with --infra-command", func() { 342 name := "test" 343 session := podmanTest.Podman([]string{"pod", "create", "--infra-command", "/pause1", "--name", name}) 344 session.WaitWithDefaultTimeout() 345 Expect(session).Should(ExitCleanly()) 346 347 check := podmanTest.Podman([]string{"pod", "inspect", name}) 348 check.WaitWithDefaultTimeout() 349 Expect(check).Should(ExitCleanly()) 350 data := check.InspectPodToJSON() 351 352 check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID}) 353 check1.WaitWithDefaultTimeout() 354 Expect(check1).Should(ExitCleanly()) 355 Expect(check1.OutputToString()).To(Equal("/pause1")) 356 357 // check the Path and Args 358 check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID}) 359 check2.WaitWithDefaultTimeout() 360 Expect(check2).Should(ExitCleanly()) 361 Expect(check2.OutputToString()).To(Equal("/pause1:[/pause1]")) 362 }) 363 364 It("podman create pod with --infra-image", func() { 365 dockerfile := `FROM quay.io/libpod/alpine:latest 366 entrypoint ["/fromimage"] 367 ` 368 podmanTest.BuildImage(dockerfile, "localhost/infra", "false") 369 name := "test" 370 session := podmanTest.Podman([]string{"pod", "create", "--infra-image", "localhost/infra", "--name", name}) 371 session.WaitWithDefaultTimeout() 372 Expect(session).Should(ExitCleanly()) 373 374 check := podmanTest.Podman([]string{"pod", "inspect", name}) 375 check.WaitWithDefaultTimeout() 376 Expect(check).Should(ExitCleanly()) 377 data := check.InspectPodToJSON() 378 379 check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID}) 380 check1.WaitWithDefaultTimeout() 381 Expect(check1).Should(ExitCleanly()) 382 Expect(check1.OutputToString()).To(Equal("/fromimage")) 383 384 // check the Path and Args 385 check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID}) 386 check2.WaitWithDefaultTimeout() 387 Expect(check2).Should(ExitCleanly()) 388 Expect(check2.OutputToString()).To(Equal("/fromimage:[/fromimage]")) 389 }) 390 391 It("podman create pod with --infra-command --infra-image", func() { 392 dockerfile := `FROM quay.io/libpod/alpine:latest 393 entrypoint ["/fromimage"] 394 ` 395 podmanTest.BuildImage(dockerfile, "localhost/infra", "false") 396 name := "test" 397 session := podmanTest.Podman([]string{"pod", "create", "--infra-image", "localhost/infra", "--infra-command", "/fromcommand", "--name", name}) 398 session.WaitWithDefaultTimeout() 399 Expect(session).Should(ExitCleanly()) 400 401 check := podmanTest.Podman([]string{"pod", "inspect", name}) 402 check.WaitWithDefaultTimeout() 403 Expect(check).Should(ExitCleanly()) 404 data := check.InspectPodToJSON() 405 406 check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID}) 407 check1.WaitWithDefaultTimeout() 408 Expect(check1).Should(ExitCleanly()) 409 Expect(check1.OutputToString()).To(Equal("/fromcommand")) 410 411 // check the Path and Args 412 check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID}) 413 check2.WaitWithDefaultTimeout() 414 Expect(check2).Should(ExitCleanly()) 415 Expect(check2.OutputToString()).To(Equal("/fromcommand:[/fromcommand]")) 416 }) 417 418 It("podman create pod with slirp network option", func() { 419 name := "test" 420 session := podmanTest.Podman([]string{"pod", "create", "--name", name, "--network", "slirp4netns:port_handler=slirp4netns", "-p", "8082:8000"}) 421 session.WaitWithDefaultTimeout() 422 Expect(session).Should(ExitCleanly()) 423 424 check := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{.InfraConfig.NetworkOptions.slirp4netns}}", name}) 425 check.WaitWithDefaultTimeout() 426 Expect(check).Should(ExitCleanly()) 427 Expect(check.OutputToString()).To(Equal("[port_handler=slirp4netns]")) 428 }) 429 430 It("podman pod status test", func() { 431 podName := "testpod" 432 create := podmanTest.Podman([]string{"pod", "create", "--name", podName}) 433 create.WaitWithDefaultTimeout() 434 Expect(create).Should(ExitCleanly()) 435 436 status1 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName}) 437 status1.WaitWithDefaultTimeout() 438 Expect(status1).Should(ExitCleanly()) 439 Expect(status1.OutputToString()).To(ContainSubstring("Created")) 440 441 ctr1 := podmanTest.Podman([]string{"run", "--pod", podName, "-d", ALPINE, "top"}) 442 ctr1.WaitWithDefaultTimeout() 443 Expect(ctr1).Should(ExitCleanly()) 444 445 status2 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName}) 446 status2.WaitWithDefaultTimeout() 447 Expect(status2).Should(ExitCleanly()) 448 Expect(status2.OutputToString()).To(ContainSubstring("Running")) 449 450 ctr2 := podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"}) 451 ctr2.WaitWithDefaultTimeout() 452 Expect(ctr2).Should(ExitCleanly()) 453 454 status3 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName}) 455 status3.WaitWithDefaultTimeout() 456 Expect(status3).Should(ExitCleanly()) 457 Expect(status3.OutputToString()).To(ContainSubstring("Degraded")) 458 }) 459 460 It("podman create with unsupported network options", func() { 461 podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "container:doesnotmatter"}) 462 podCreate.WaitWithDefaultTimeout() 463 Expect(podCreate).Should(Exit(125)) 464 Expect(podCreate.ErrorToString()).To(ContainSubstring("pods presently do not support network mode container")) 465 }) 466 467 It("podman pod create with namespace path networking", func() { 468 SkipIfRootless("ip netns is not supported for rootless users") 469 SkipIfContainerized("ip netns cannot be run within a container.") 470 471 podName := "netnspod" 472 netNsName := "test1" 473 networkMode := fmt.Sprintf("ns:/var/run/netns/%s", netNsName) 474 475 addNetns := SystemExec("ip", []string{"netns", "add", netNsName}) 476 Expect(addNetns).Should(ExitCleanly()) 477 defer func() { 478 delNetns := SystemExec("ip", []string{"netns", "delete", netNsName}) 479 Expect(delNetns).Should(ExitCleanly()) 480 }() 481 482 podCreate := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--network", networkMode}) 483 podCreate.WaitWithDefaultTimeout() 484 Expect(podCreate).Should(ExitCleanly()) 485 486 podStart := podmanTest.Podman([]string{"pod", "start", podName}) 487 podStart.WaitWithDefaultTimeout() 488 Expect(podStart).Should(ExitCleanly()) 489 490 inspectPod := podmanTest.Podman([]string{"pod", "inspect", podName}) 491 inspectPod.WaitWithDefaultTimeout() 492 Expect(inspectPod).Should(ExitCleanly()) 493 inspectPodJSON := inspectPod.InspectPodToJSON() 494 495 inspectInfraContainer := podmanTest.Podman([]string{"inspect", inspectPodJSON.InfraContainerID}) 496 inspectInfraContainer.WaitWithDefaultTimeout() 497 Expect(inspectInfraContainer).Should(ExitCleanly()) 498 inspectInfraContainerJSON := inspectInfraContainer.InspectContainerToJSON() 499 500 Expect(inspectInfraContainerJSON[0].HostConfig.NetworkMode).To(Equal(networkMode)) 501 }) 502 503 It("podman pod create with --net=none", func() { 504 podName := "testPod" 505 podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "none", "--name", podName}) 506 podCreate.WaitWithDefaultTimeout() 507 Expect(podCreate).Should(ExitCleanly()) 508 509 session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "ip", "-o", "-4", "addr"}) 510 session.WaitWithDefaultTimeout() 511 Expect(session).Should(ExitCleanly()) 512 Expect(session.OutputToString()).To(ContainSubstring("inet 127.0.0.1/8 scope host lo")) 513 Expect(session.OutputToStringArray()).To(HaveLen(1)) 514 }) 515 516 It("podman pod create --infra-image w/untagged image", func() { 517 podmanTest.AddImageToRWStore(ALPINE) 518 dockerfile := `FROM quay.io/libpod/alpine:latest 519 ENTRYPOINT ["sleep","99999"] 520 ` 521 // This builds a none/none image 522 iid := podmanTest.BuildImage(dockerfile, "", "true") 523 524 create := podmanTest.Podman([]string{"pod", "create", "--infra-image", iid}) 525 create.WaitWithDefaultTimeout() 526 Expect(create).Should(ExitCleanly()) 527 }) 528 529 It("podman pod create --cpus", func() { 530 podName := "testPod" 531 numCPU := float64(sysinfo.NumCPU()) 532 period, quota := util.CoresToPeriodAndQuota(numCPU) 533 numCPUStr := strconv.Itoa(int(numCPU)) 534 podCreate := podmanTest.Podman([]string{"pod", "create", "--cpus", numCPUStr, "--name", podName}) 535 podCreate.WaitWithDefaultTimeout() 536 Expect(podCreate).Should(ExitCleanly()) 537 538 contCreate := podmanTest.Podman([]string{"container", "create", "--pod", podName, "alpine"}) 539 contCreate.WaitWithDefaultTimeout() 540 Expect(podCreate).Should(ExitCleanly()) 541 542 podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) 543 podInspect.WaitWithDefaultTimeout() 544 Expect(podInspect).Should(ExitCleanly()) 545 podJSON := podInspect.InspectPodToJSON() 546 Expect(podJSON).To(HaveField("CPUPeriod", period)) 547 Expect(podJSON).To(HaveField("CPUQuota", quota)) 548 }) 549 550 It("podman pod create --cpuset-cpus", func() { 551 podName := "testPod" 552 ctrName := "testCtr" 553 numCPU := float64(sysinfo.NumCPU()) - 1 554 numCPUStr := strconv.Itoa(int(numCPU)) 555 in := "0-" + numCPUStr 556 podCreate := podmanTest.Podman([]string{"pod", "create", "--cpuset-cpus", in, "--name", podName}) 557 podCreate.WaitWithDefaultTimeout() 558 Expect(podCreate).Should(ExitCleanly()) 559 560 contCreate := podmanTest.Podman([]string{"container", "create", "--name", ctrName, "--pod", podName, "alpine"}) 561 contCreate.WaitWithDefaultTimeout() 562 Expect(podCreate).Should(ExitCleanly()) 563 564 podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) 565 podInspect.WaitWithDefaultTimeout() 566 Expect(podInspect).Should(ExitCleanly()) 567 podJSON := podInspect.InspectPodToJSON() 568 Expect(podJSON).To(HaveField("CPUSetCPUs", in)) 569 }) 570 571 It("podman pod create --pid", func() { 572 podName := "pidPod" 573 ns := "ns:/proc/self/ns/" 574 podCreate := podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"}) 575 podCreate.WaitWithDefaultTimeout() 576 Expect(podCreate).Should(ExitCleanly()) 577 578 podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) 579 podInspect.WaitWithDefaultTimeout() 580 Expect(podInspect).Should(ExitCleanly()) 581 podJSON := podInspect.InspectPodToJSON() 582 Expect(podJSON.InfraConfig).To(HaveField("PidNS", ns)) 583 584 podName = "pidPod2" 585 ns = "pod" 586 587 podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"}) 588 podCreate.WaitWithDefaultTimeout() 589 Expect(podCreate).Should(ExitWithError()) 590 591 podName = "pidPod3" 592 ns = "host" 593 594 podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"}) 595 podCreate.WaitWithDefaultTimeout() 596 Expect(podCreate).Should(ExitCleanly()) 597 598 podInspect = podmanTest.Podman([]string{"pod", "inspect", podName}) 599 podInspect.WaitWithDefaultTimeout() 600 Expect(podInspect).Should(ExitCleanly()) 601 podJSON = podInspect.InspectPodToJSON() 602 Expect(podJSON.InfraConfig).To(HaveField("PidNS", "host")) 603 604 podName = "pidPod4" 605 ns = "private" 606 607 podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"}) 608 podCreate.WaitWithDefaultTimeout() 609 Expect(podCreate).Should(ExitCleanly()) 610 611 podInspect = podmanTest.Podman([]string{"pod", "inspect", podName}) 612 podInspect.WaitWithDefaultTimeout() 613 Expect(podInspect).Should(ExitCleanly()) 614 podJSON = podInspect.InspectPodToJSON() 615 Expect(podJSON.InfraConfig).To(HaveField("PidNS", "private")) 616 617 podName = "pidPod5" 618 ns = "container:randomfakeid" 619 620 podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"}) 621 podCreate.WaitWithDefaultTimeout() 622 Expect(podCreate).Should(ExitWithError()) 623 624 }) 625 626 It("podman pod create with --userns=keep-id", func() { 627 if !isRootless() { 628 Skip("Test only runs without root") 629 } 630 631 podName := "testPod" 632 podCreate := podmanTest.Podman([]string{"pod", "create", "--userns", "keep-id", "--name", podName}) 633 podCreate.WaitWithDefaultTimeout() 634 Expect(podCreate).Should(ExitCleanly()) 635 636 session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "id", "-u"}) 637 session.WaitWithDefaultTimeout() 638 Expect(session).Should(ExitCleanly()) 639 uid := strconv.Itoa(os.Geteuid()) 640 Expect(session.OutputToString()).To(ContainSubstring(uid)) 641 642 // Check passwd 643 session = podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "id", "-un"}) 644 session.WaitWithDefaultTimeout() 645 Expect(session).Should(ExitCleanly()) 646 u, err := user.Current() 647 Expect(err).ToNot(HaveOccurred()) 648 Expect(session.OutputToString()).To(Equal(u.Username)) 649 650 // root owns /usr 651 session = podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "stat", "-c%u", "/usr"}) 652 session.WaitWithDefaultTimeout() 653 Expect(session).Should(ExitCleanly()) 654 Expect(session.OutputToString()).To(Equal("0")) 655 656 // fail if --pod and --userns set together 657 session = podmanTest.Podman([]string{"run", "--pod", podName, "--userns", "keep-id", ALPINE, "id", "-u"}) 658 session.WaitWithDefaultTimeout() 659 Expect(session).Should(Exit(125)) 660 }) 661 662 It("podman pod create with --userns=keep-id can add users", func() { 663 if !isRootless() { 664 Skip("Test only runs without root") 665 } 666 667 podName := "testPod" 668 podCreate := podmanTest.Podman([]string{"pod", "create", "--userns", "keep-id", "--name", podName}) 669 podCreate.WaitWithDefaultTimeout() 670 Expect(podCreate).Should(ExitCleanly()) 671 672 // NOTE: we need to use a Fedora image here since the 673 // alpine/busybox versions are not capable of dealing with 674 // --userns=keep-id and will just error out when not running as 675 // "root" 676 ctrName := "ctr-name" 677 session := podmanTest.Podman([]string{"run", "--pod", podName, "-d", "--stop-signal", "9", "--name", ctrName, fedoraMinimal, "sleep", "600"}) 678 session.WaitWithDefaultTimeout() 679 Expect(session).Should(ExitCleanly()) 680 681 u, err := user.Current() 682 Expect(err).ToNot(HaveOccurred()) 683 // container inside pod inherits user from infra container if --user is not set 684 // etc/passwd entry will look like USERNAME:*:1000:1000:Full User Name:/:/bin/sh 685 exec1 := podmanTest.Podman([]string{"exec", ctrName, "id", "-un"}) 686 exec1.WaitWithDefaultTimeout() 687 Expect(exec1).Should(ExitCleanly()) 688 Expect(exec1.OutputToString()).To(Equal(u.Username)) 689 690 exec2 := podmanTest.Podman([]string{"exec", ctrName, "useradd", "testuser"}) 691 exec2.WaitWithDefaultTimeout() 692 Expect(exec2).Should(ExitCleanly()) 693 694 exec3 := podmanTest.Podman([]string{"exec", ctrName, "cat", "/etc/passwd"}) 695 exec3.WaitWithDefaultTimeout() 696 Expect(exec3).Should(ExitCleanly()) 697 Expect(exec3.OutputToString()).To(ContainSubstring("testuser")) 698 }) 699 700 It("podman pod create with --userns=auto", func() { 701 u, err := user.Current() 702 Expect(err).ToNot(HaveOccurred()) 703 name := u.Username 704 if name == "root" { 705 name = "containers" 706 } 707 708 content, err := os.ReadFile("/etc/subuid") 709 if err != nil { 710 Skip("cannot read /etc/subuid") 711 } 712 if !strings.Contains(string(content), name) { 713 Skip("cannot find mappings for the current user") 714 } 715 716 m := make(map[string]string) 717 for i := 0; i < 5; i++ { 718 podName := "testPod" + strconv.Itoa(i) 719 podCreate := podmanTest.Podman([]string{"pod", "create", "--userns=auto", "--name", podName}) 720 podCreate.WaitWithDefaultTimeout() 721 Expect(podCreate).Should(ExitCleanly()) 722 723 session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/uid_map"}) 724 session.WaitWithDefaultTimeout() 725 Expect(session).Should(ExitCleanly()) 726 l := session.OutputToString() 727 Expect(l).To(ContainSubstring("1024")) 728 m[l] = l 729 } 730 // check for no duplicates 731 Expect(m).To(HaveLen(5)) 732 }) 733 734 It("podman pod create --userns=auto:size=%d", func() { 735 u, err := user.Current() 736 Expect(err).ToNot(HaveOccurred()) 737 738 name := u.Username 739 if name == "root" { 740 name = "containers" 741 } 742 743 content, err := os.ReadFile("/etc/subuid") 744 if err != nil { 745 Skip("cannot read /etc/subuid") 746 } 747 if !strings.Contains(string(content), name) { 748 Skip("cannot find mappings for the current user") 749 } 750 751 podName := "testPod" 752 podCreate := podmanTest.Podman([]string{"pod", "create", "--userns=auto:size=500", "--name", podName}) 753 podCreate.WaitWithDefaultTimeout() 754 Expect(podCreate).Should(ExitCleanly()) 755 session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/uid_map"}) 756 session.WaitWithDefaultTimeout() 757 Expect(session).Should(ExitCleanly()) 758 Expect(session.OutputToString()).To(ContainSubstring("500")) 759 760 podName = "testPod-1" 761 podCreate = podmanTest.Podman([]string{"pod", "create", "--userns=auto:size=3000", "--name", podName}) 762 podCreate.WaitWithDefaultTimeout() 763 Expect(podCreate).Should(ExitCleanly()) 764 session = podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/uid_map"}) 765 session.WaitWithDefaultTimeout() 766 Expect(session).Should(ExitCleanly()) 767 Expect(session.OutputToString()).To(ContainSubstring("3000")) 768 }) 769 770 It("podman pod create --userns=auto:uidmapping=", func() { 771 u, err := user.Current() 772 Expect(err).ToNot(HaveOccurred()) 773 774 name := u.Username 775 if name == "root" { 776 name = "containers" 777 } 778 779 content, err := os.ReadFile("/etc/subuid") 780 if err != nil { 781 Skip("cannot read /etc/subuid") 782 } 783 if !strings.Contains(string(content), name) { 784 Skip("cannot find mappings for the current user") 785 } 786 787 podName := "testPod" 788 podCreate := podmanTest.Podman([]string{"pod", "create", "--userns=auto:uidmapping=0:0:1", "--name", podName}) 789 podCreate.WaitWithDefaultTimeout() 790 Expect(podCreate).Should(ExitCleanly()) 791 session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/uid_map"}) 792 session.WaitWithDefaultTimeout() 793 Expect(session).Should(ExitCleanly()) 794 output := session.OutputToString() 795 Expect(output).To(MatchRegexp("\\s0\\s0\\s1")) 796 797 podName = "testPod-1" 798 podCreate = podmanTest.Podman([]string{"pod", "create", "--userns=auto:size=8192,uidmapping=0:0:1", "--name", podName}) 799 podCreate.WaitWithDefaultTimeout() 800 Expect(podCreate).Should(ExitCleanly()) 801 session = podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/uid_map"}) 802 session.WaitWithDefaultTimeout() 803 Expect(session).Should(ExitCleanly()) 804 Expect(session.OutputToString()).To(ContainSubstring("8191")) 805 }) 806 807 It("podman pod create --userns=auto:gidmapping=", func() { 808 u, err := user.Current() 809 Expect(err).ToNot(HaveOccurred()) 810 811 name := u.Username 812 if name == "root" { 813 name = "containers" 814 } 815 816 content, err := os.ReadFile("/etc/subuid") 817 if err != nil { 818 Skip("cannot read /etc/subuid") 819 } 820 if !strings.Contains(string(content), name) { 821 Skip("cannot find mappings for the current user") 822 } 823 824 podName := "testPod" 825 podCreate := podmanTest.Podman([]string{"pod", "create", "--userns=auto:gidmapping=0:0:1", "--name", podName}) 826 podCreate.WaitWithDefaultTimeout() 827 Expect(podCreate).Should(ExitCleanly()) 828 session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/gid_map"}) 829 session.WaitWithDefaultTimeout() 830 Expect(session).Should(ExitCleanly()) 831 output := session.OutputToString() 832 Expect(output).To(MatchRegexp("\\s0\\s0\\s1")) 833 834 podName = "testPod-1" 835 podCreate = podmanTest.Podman([]string{"pod", "create", "--userns=auto:size=8192,gidmapping=0:0:1", "--name", podName}) 836 podCreate.WaitWithDefaultTimeout() 837 Expect(podCreate).Should(ExitCleanly()) 838 session = podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/gid_map"}) 839 session.WaitWithDefaultTimeout() 840 Expect(session).Should(ExitCleanly()) 841 Expect(session.OutputToString()).To(ContainSubstring("8191")) 842 }) 843 844 It("podman pod create --volume", func() { 845 volName := "testVol" 846 volCreate := podmanTest.Podman([]string{"volume", "create", volName}) 847 volCreate.WaitWithDefaultTimeout() 848 Expect(volCreate).Should(ExitCleanly()) 849 podName := "testPod" 850 podCreate := podmanTest.Podman([]string{"pod", "create", "--volume", volName + ":/tmp1", "--name", podName}) 851 podCreate.WaitWithDefaultTimeout() 852 Expect(podCreate).Should(ExitCleanly()) 853 podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) 854 podInspect.WaitWithDefaultTimeout() 855 Expect(podInspect).Should(ExitCleanly()) 856 data := podInspect.InspectPodToJSON() 857 Expect(data.Mounts[0]).To(HaveField("Name", volName)) 858 ctrName := "testCtr" 859 ctrCreate := podmanTest.Podman([]string{"create", "--pod", podName, "--name", ctrName, ALPINE}) 860 ctrCreate.WaitWithDefaultTimeout() 861 Expect(ctrCreate).Should(ExitCleanly()) 862 ctrInspect := podmanTest.Podman([]string{"inspect", ctrName}) 863 ctrInspect.WaitWithDefaultTimeout() 864 Expect(ctrInspect).Should(ExitCleanly()) 865 ctrData := ctrInspect.InspectContainerToJSON() 866 Expect(ctrData[0].Mounts[0]).To(HaveField("Name", volName)) 867 868 ctr2 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "sh", "-c", "echo hello >> " + "/tmp1/test"}) 869 ctr2.WaitWithDefaultTimeout() 870 Expect(ctr2).Should(ExitCleanly()) 871 872 ctr3 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/tmp1/test"}) 873 ctr3.WaitWithDefaultTimeout() 874 Expect(ctr3.OutputToString()).To(ContainSubstring("hello")) 875 876 ctr4 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "touch", "/tmp1/testing.txt"}) 877 ctr4.WaitWithDefaultTimeout() 878 Expect(ctr4).Should(ExitCleanly()) 879 }) 880 881 It("podman pod create --device", func() { 882 SkipIfRootless("Cannot create devices in /dev in rootless mode") 883 // path must be unique to this test, not used anywhere else 884 devdir := "/dev/devdirpodcreate" 885 Expect(os.MkdirAll(devdir, os.ModePerm)).To(Succeed()) 886 defer os.RemoveAll(devdir) 887 888 mknod := SystemExec("mknod", []string{devdir + "/null", "c", "1", "3"}) 889 mknod.WaitWithDefaultTimeout() 890 Expect(mknod).Should(ExitCleanly()) 891 892 podName := "testPod" 893 session := podmanTest.Podman([]string{"pod", "create", "--device", devdir + ":/dev/bar", "--name", podName}) 894 session.WaitWithDefaultTimeout() 895 Expect(session).Should(ExitCleanly()) 896 session = podmanTest.Podman([]string{"run", "-q", "--pod", podName, ALPINE, "stat", "-c%t:%T", "/dev/bar/null"}) 897 session.WaitWithDefaultTimeout() 898 Expect(session).Should(ExitCleanly()) 899 Expect(session.OutputToString()).To(Equal("1:3")) 900 901 }) 902 903 It("podman pod create --volumes-from", func() { 904 volName := "testVol" 905 volCreate := podmanTest.Podman([]string{"volume", "create", volName}) 906 volCreate.WaitWithDefaultTimeout() 907 Expect(volCreate).Should(ExitCleanly()) 908 ctrName := "testCtr" 909 ctrCreate := podmanTest.Podman([]string{"create", "--volume", volName + ":/tmp1", "--name", ctrName, ALPINE}) 910 ctrCreate.WaitWithDefaultTimeout() 911 Expect(ctrCreate).Should(ExitCleanly()) 912 ctrInspect := podmanTest.Podman([]string{"inspect", ctrName}) 913 ctrInspect.WaitWithDefaultTimeout() 914 Expect(ctrInspect).Should(ExitCleanly()) 915 data := ctrInspect.InspectContainerToJSON() 916 Expect(data[0].Mounts[0]).To(HaveField("Name", volName)) 917 podName := "testPod" 918 podCreate := podmanTest.Podman([]string{"pod", "create", "--volumes-from", ctrName, "--name", podName}) 919 podCreate.WaitWithDefaultTimeout() 920 Expect(podCreate).Should(ExitCleanly()) 921 podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) 922 podInspect.WaitWithDefaultTimeout() 923 Expect(podInspect).Should(ExitCleanly()) 924 podData := podInspect.InspectPodToJSON() 925 Expect(podData.Mounts[0]).To(HaveField("Name", volName)) 926 927 ctr2 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "sh", "-c", "echo hello >> " + "/tmp1/test"}) 928 ctr2.WaitWithDefaultTimeout() 929 Expect(ctr2).Should(ExitCleanly()) 930 931 ctr3 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/tmp1/test"}) 932 ctr3.WaitWithDefaultTimeout() 933 Expect(ctr3.OutputToString()).To(ContainSubstring("hello")) 934 }) 935 936 It("podman pod create read network mode from config", func() { 937 confPath, err := filepath.Abs("config/containers-netns.conf") 938 Expect(err).ToNot(HaveOccurred()) 939 os.Setenv("CONTAINERS_CONF", confPath) 940 if IsRemote() { 941 podmanTest.RestartRemoteService() 942 } 943 944 pod := podmanTest.Podman([]string{"pod", "create", "--name", "test", "--infra-name", "test-infra"}) 945 pod.WaitWithDefaultTimeout() 946 Expect(pod).Should(ExitCleanly()) 947 948 inspect := podmanTest.Podman([]string{"inspect", "--format", "{{.HostConfig.NetworkMode}}", "test-infra"}) 949 inspect.WaitWithDefaultTimeout() 950 Expect(inspect).Should(ExitCleanly()) 951 Expect(inspect.OutputToString()).Should(Equal("host")) 952 }) 953 954 It("podman pod create --security-opt", func() { 955 if !selinux.GetEnabled() { 956 Skip("SELinux not enabled") 957 } 958 podCreate := podmanTest.Podman([]string{"pod", "create", "--security-opt", "label=type:spc_t", "--security-opt", "seccomp=unconfined"}) 959 podCreate.WaitWithDefaultTimeout() 960 Expect(podCreate).Should(ExitCleanly()) 961 962 ctrCreate := podmanTest.Podman([]string{"container", "create", "--pod", podCreate.OutputToString(), ALPINE}) 963 ctrCreate.WaitWithDefaultTimeout() 964 Expect(ctrCreate).Should(ExitCleanly()) 965 966 ctrInspect := podmanTest.InspectContainer(ctrCreate.OutputToString()) 967 Expect(ctrInspect[0].HostConfig).To(HaveField("SecurityOpt", []string{"label=type:spc_t", "seccomp=unconfined"})) 968 969 podCreate = podmanTest.Podman([]string{"pod", "create", "--security-opt", "label=disable"}) 970 podCreate.WaitWithDefaultTimeout() 971 Expect(podCreate).Should(ExitCleanly()) 972 973 ctrCreate = podmanTest.Podman([]string{"container", "run", "--pod", podCreate.OutputToString(), ALPINE, "cat", "/proc/self/attr/current"}) 974 ctrCreate.WaitWithDefaultTimeout() 975 Expect(ctrCreate).Should(ExitCleanly()) 976 Expect(ctrCreate.OutputToString()).To(ContainSubstring("spc_t")) 977 }) 978 979 It("podman pod create --security-opt seccomp", func() { 980 if !seccomp.IsEnabled() { 981 Skip("seccomp is not enabled") 982 } 983 podCreate := podmanTest.Podman([]string{"pod", "create", "--security-opt", "seccomp=unconfined"}) 984 podCreate.WaitWithDefaultTimeout() 985 Expect(podCreate).Should(ExitCleanly()) 986 987 ctrCreate := podmanTest.Podman([]string{"container", "create", "--pod", podCreate.OutputToString(), ALPINE}) 988 ctrCreate.WaitWithDefaultTimeout() 989 Expect(ctrCreate).Should(ExitCleanly()) 990 991 ctrInspect := podmanTest.InspectContainer(ctrCreate.OutputToString()) 992 Expect(ctrInspect[0].HostConfig).To(HaveField("SecurityOpt", []string{"seccomp=unconfined"})) 993 }) 994 995 It("podman pod create --security-opt apparmor test", func() { 996 if !apparmor.IsEnabled() { 997 Skip("Apparmor is not enabled") 998 } 999 podCreate := podmanTest.Podman([]string{"pod", "create", "--security-opt", fmt.Sprintf("apparmor=%s", apparmor.Profile)}) 1000 podCreate.WaitWithDefaultTimeout() 1001 Expect(podCreate).Should(ExitCleanly()) 1002 1003 ctrCreate := podmanTest.Podman([]string{"container", "create", "--pod", podCreate.OutputToString(), ALPINE}) 1004 ctrCreate.WaitWithDefaultTimeout() 1005 Expect(ctrCreate).Should(ExitCleanly()) 1006 1007 inspect := podmanTest.InspectContainer(ctrCreate.OutputToString()) 1008 Expect(inspect[0]).To(HaveField("AppArmorProfile", apparmor.Profile)) 1009 1010 }) 1011 1012 It("podman pod create --sysctl test", func() { 1013 SkipIfRootless("Network sysctls are not available root rootless") 1014 podCreate := podmanTest.Podman([]string{"pod", "create", "--sysctl", "net.core.somaxconn=65535"}) 1015 podCreate.WaitWithDefaultTimeout() 1016 Expect(podCreate).Should(ExitCleanly()) 1017 session := podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "net.core.somaxconn"}) 1018 session.WaitWithDefaultTimeout() 1019 Expect(session).Should(ExitCleanly()) 1020 Expect(session.OutputToString()).To(ContainSubstring("net.core.somaxconn = 65535")) 1021 1022 // if not sharing the net NS, nothing should fail, but the sysctl should not be passed 1023 podCreate = podmanTest.Podman([]string{"pod", "create", "--share", "pid", "--sysctl", "net.core.somaxconn=65535"}) 1024 podCreate.WaitWithDefaultTimeout() 1025 Expect(podCreate).Should(ExitCleanly()) 1026 session = podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "net.core.somaxconn"}) 1027 session.WaitWithDefaultTimeout() 1028 Expect(session).Should(ExitCleanly()) 1029 Expect(session.OutputToString()).NotTo(ContainSubstring("net.core.somaxconn = 65535")) 1030 1031 // one other misc option 1032 podCreate = podmanTest.Podman([]string{"pod", "create", "--sysctl", "kernel.msgmax=65535"}) 1033 podCreate.WaitWithDefaultTimeout() 1034 Expect(podCreate).Should(ExitCleanly()) 1035 session = podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "kernel.msgmax"}) 1036 session.WaitWithDefaultTimeout() 1037 Expect(session).Should(ExitCleanly()) 1038 Expect(session.OutputToString()).To(ContainSubstring("kernel.msgmax = 65535")) 1039 1040 podCreate = podmanTest.Podman([]string{"pod", "create", "--share", "pid", "--sysctl", "kernel.msgmax=65535"}) 1041 podCreate.WaitWithDefaultTimeout() 1042 Expect(podCreate).Should(ExitCleanly()) 1043 session = podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "kernel.msgmax"}) 1044 session.WaitWithDefaultTimeout() 1045 Expect(session).Should(ExitCleanly()) 1046 Expect(session.OutputToString()).NotTo(ContainSubstring("kernel.msgmax = 65535")) 1047 1048 }) 1049 1050 It("podman pod create --share-parent test", func() { 1051 SkipIfRootlessCgroupsV1("rootless cannot use cgroups with cgroupsv1") 1052 SkipIfCgroupV1("CgroupMode shows 'host' on CGv1, not CID (issue 15013, wontfix") 1053 podCreate := podmanTest.Podman([]string{"pod", "create", "--share-parent=false"}) 1054 podCreate.WaitWithDefaultTimeout() 1055 Expect(podCreate).Should(ExitCleanly()) 1056 1057 ctrCreate := podmanTest.Podman([]string{"run", "-dt", "--pod", podCreate.OutputToString(), ALPINE}) 1058 ctrCreate.WaitWithDefaultTimeout() 1059 Expect(ctrCreate).Should(ExitCleanly()) 1060 1061 inspectPod := podmanTest.Podman([]string{"pod", "inspect", podCreate.OutputToString()}) 1062 inspectPod.WaitWithDefaultTimeout() 1063 Expect(inspectPod).Should(ExitCleanly()) 1064 data := inspectPod.InspectPodToJSON() 1065 1066 inspect := podmanTest.InspectContainer(ctrCreate.OutputToString()) 1067 Expect(data.CgroupPath).To(BeEmpty()) 1068 if podmanTest.CgroupManager == "cgroupfs" || !isRootless() { 1069 Expect(inspect[0].HostConfig.CgroupParent).To(BeEmpty()) 1070 } else if podmanTest.CgroupManager == "systemd" { 1071 Expect(inspect[0].HostConfig).To(HaveField("CgroupParent", "user.slice")) 1072 } 1073 1074 podCreate2 := podmanTest.Podman([]string{"pod", "create", "--share", "cgroup,ipc,net,uts", "--share-parent=false", "--infra-name", "cgroupCtr"}) 1075 podCreate2.WaitWithDefaultTimeout() 1076 Expect(podCreate2).Should(ExitCleanly()) 1077 1078 ctrCreate2 := podmanTest.Podman([]string{"run", "-dt", "--pod", podCreate2.OutputToString(), ALPINE}) 1079 ctrCreate2.WaitWithDefaultTimeout() 1080 Expect(ctrCreate2).Should(ExitCleanly()) 1081 1082 inspectInfra := podmanTest.InspectContainer("cgroupCtr") 1083 1084 inspect2 := podmanTest.InspectContainer(ctrCreate2.OutputToString()) 1085 1086 Expect(inspect2[0].HostConfig.CgroupMode).To(ContainSubstring(inspectInfra[0].ID)) 1087 1088 podCreate3 := podmanTest.Podman([]string{"pod", "create", "--share", "cgroup"}) 1089 podCreate3.WaitWithDefaultTimeout() 1090 Expect(podCreate3).ShouldNot(ExitCleanly()) 1091 1092 }) 1093 1094 It("podman pod create infra inheritance test", func() { 1095 volName := "testVol1" 1096 volCreate := podmanTest.Podman([]string{"volume", "create", volName}) 1097 volCreate.WaitWithDefaultTimeout() 1098 Expect(volCreate).Should(ExitCleanly()) 1099 1100 session := podmanTest.Podman([]string{"pod", "create", "-v", volName + ":/vol1"}) 1101 session.WaitWithDefaultTimeout() 1102 Expect(session).Should(ExitCleanly()) 1103 1104 volName2 := "testVol2" 1105 volCreate = podmanTest.Podman([]string{"volume", "create", volName2}) 1106 volCreate.WaitWithDefaultTimeout() 1107 Expect(volCreate).Should(ExitCleanly()) 1108 1109 session = podmanTest.Podman([]string{"run", "--pod", session.OutputToString(), "-v", volName2 + ":/vol2", ALPINE, "mount"}) 1110 session.WaitWithDefaultTimeout() 1111 Expect(session).Should(ExitCleanly()) 1112 Expect(session.OutputToString()).Should(ContainSubstring("/vol1")) 1113 Expect(session.OutputToString()).Should(ContainSubstring("/vol2")) 1114 }) 1115 1116 It("podman pod create --shm-size", func() { 1117 podCreate := podmanTest.Podman([]string{"pod", "create", "--shm-size", "10mb"}) 1118 podCreate.WaitWithDefaultTimeout() 1119 Expect(podCreate).Should(ExitCleanly()) 1120 1121 run := podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), ALPINE, "mount"}) 1122 run.WaitWithDefaultTimeout() 1123 Expect(run).Should(ExitCleanly()) 1124 t, strings := run.GrepString("shm on /dev/shm type tmpfs") 1125 Expect(t).To(BeTrue(), "found /dev/shm") 1126 Expect(strings[0]).Should(ContainSubstring("size=10240k")) 1127 }) 1128 1129 It("podman pod create --shm-size and --ipc=host conflict", func() { 1130 podCreate := podmanTest.Podman([]string{"pod", "create", "--shm-size", "10mb"}) 1131 podCreate.WaitWithDefaultTimeout() 1132 Expect(podCreate).Should(ExitCleanly()) 1133 1134 run := podmanTest.Podman([]string{"run", "-dt", "--pod", podCreate.OutputToString(), "--ipc", "host", ALPINE}) 1135 run.WaitWithDefaultTimeout() 1136 Expect(run).ShouldNot(ExitCleanly()) 1137 }) 1138 1139 It("podman pod create --uts test", func() { 1140 session := podmanTest.Podman([]string{"pod", "create", "--uts", "host"}) 1141 session.WaitWithDefaultTimeout() 1142 Expect(session).Should(ExitCleanly()) 1143 1144 session = podmanTest.Podman([]string{"run", "--pod", session.OutputToString(), ALPINE, "printenv", "HOSTNAME"}) 1145 session.WaitWithDefaultTimeout() 1146 Expect(session).Should(ExitCleanly()) 1147 Expect(session.OutputToString()).To(ContainSubstring(hostname)) 1148 1149 podName := "utsPod" 1150 ns := "ns:/proc/self/ns/" 1151 1152 // just share uts with a custom path 1153 podCreate := podmanTest.Podman([]string{"pod", "create", "--uts", ns, "--name", podName, "--share", "uts"}) 1154 podCreate.WaitWithDefaultTimeout() 1155 Expect(podCreate).Should(ExitCleanly()) 1156 1157 podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) 1158 podInspect.WaitWithDefaultTimeout() 1159 Expect(podInspect).Should(ExitCleanly()) 1160 podJSON := podInspect.InspectPodToJSON() 1161 Expect(podJSON.InfraConfig).To(HaveField("UtsNS", ns)) 1162 }) 1163 1164 It("podman pod create --shm-size-systemd", func() { 1165 podName := "testShmSizeSystemd" 1166 session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--shm-size-systemd", "10mb"}) 1167 session.WaitWithDefaultTimeout() 1168 Expect(session).Should(ExitCleanly()) 1169 1170 // add container to pod 1171 ctrRun := podmanTest.Podman([]string{"run", "-d", "--pod", podName, SYSTEMD_IMAGE, "/sbin/init"}) 1172 ctrRun.WaitWithDefaultTimeout() 1173 Expect(ctrRun).Should(ExitCleanly()) 1174 1175 run := podmanTest.Podman([]string{"exec", ctrRun.OutputToString(), "mount"}) 1176 run.WaitWithDefaultTimeout() 1177 Expect(run).Should(ExitCleanly()) 1178 t, strings := run.GrepString("tmpfs on /run/lock") 1179 Expect(t).To(BeTrue(), "found /run/lock") 1180 Expect(strings[0]).Should(ContainSubstring("size=10240k")) 1181 }) 1182 1183 It("create pod with name subset of existing ID", func() { 1184 create1 := podmanTest.Podman([]string{"pod", "create"}) 1185 create1.WaitWithDefaultTimeout() 1186 Expect(create1).Should(ExitCleanly()) 1187 pod1ID := create1.OutputToString() 1188 1189 pod2Name := pod1ID[:5] 1190 create2 := podmanTest.Podman([]string{"pod", "create", pod2Name}) 1191 create2.WaitWithDefaultTimeout() 1192 Expect(create2).Should(ExitCleanly()) 1193 1194 inspect := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{.Name}}", pod2Name}) 1195 inspect.WaitWithDefaultTimeout() 1196 Expect(inspect).Should(ExitCleanly()) 1197 Expect(inspect.OutputToString()).Should(Equal(pod2Name)) 1198 }) 1199 1200 It("podman pod create --restart set to default", func() { 1201 // When the --restart flag is not set, the default value is No 1202 // TODO: v5.0 change this so that the default value is Always 1203 podName := "mypod" 1204 testCtr := "ctr1" 1205 session := podmanTest.Podman([]string{"pod", "create", podName}) 1206 session.WaitWithDefaultTimeout() 1207 Expect(session).Should(ExitCleanly()) 1208 // add container to pod 1209 ctrRun := podmanTest.Podman([]string{"run", "--name", testCtr, "-d", "--pod", podName, ALPINE, "echo", "hello"}) 1210 ctrRun.WaitWithDefaultTimeout() 1211 Expect(ctrRun).Should(ExitCleanly()) 1212 // Wait about 1 second, so we can check the number of restarts as default restart policy is set to No 1213 time.Sleep(1 * time.Second) 1214 ps := podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Restarts}}"}) 1215 ps.WaitWithDefaultTimeout() 1216 Expect(ps).Should(ExitCleanly()) 1217 restarts, err := strconv.Atoi(ps.OutputToString()) 1218 Expect(err).ToNot(HaveOccurred()) 1219 Expect(restarts).To(BeNumerically("==", 0)) 1220 ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Status}}"}) 1221 ps.WaitWithDefaultTimeout() 1222 Expect(ps).Should(ExitCleanly()) 1223 Expect(ps.OutputToString()).To(ContainSubstring("Exited")) 1224 }) 1225 1226 It("podman pod create --restart=on-failure", func() { 1227 // Restart policy set to on-failure with max 2 retries 1228 podName := "mypod" 1229 runningCtr := "ctr1" 1230 testCtr := "ctr2" 1231 session := podmanTest.Podman([]string{"pod", "create", "--restart", "on-failure:2", podName}) 1232 session.WaitWithDefaultTimeout() 1233 Expect(session).Should(ExitCleanly()) 1234 // add container to pod 1235 ctrRun := podmanTest.Podman([]string{"run", "--name", runningCtr, "-d", "--pod", podName, ALPINE, "sleep", "100"}) 1236 ctrRun.WaitWithDefaultTimeout() 1237 Expect(ctrRun).Should(ExitCleanly()) 1238 ctrRun = podmanTest.Podman([]string{"run", "--name", testCtr, "-d", "--pod", podName, ALPINE, "sh", "-c", "echo hello && exit 1"}) 1239 ctrRun.WaitWithDefaultTimeout() 1240 Expect(ctrRun).Should(ExitCleanly()) 1241 // Wait about 2 seconds, so we can check the number of restarts after failure 1242 time.Sleep(2 * time.Second) 1243 ps := podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Restarts}}"}) 1244 ps.WaitWithDefaultTimeout() 1245 Expect(ps).Should(ExitCleanly()) 1246 restarts, err := strconv.Atoi(ps.OutputToString()) 1247 Expect(err).ToNot(HaveOccurred()) 1248 Expect(restarts).To(BeNumerically("==", 2)) 1249 ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Status}}"}) 1250 ps.WaitWithDefaultTimeout() 1251 Expect(ps).Should(ExitCleanly()) 1252 Expect(ps.OutputToString()).To(ContainSubstring("Exited")) 1253 ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + runningCtr, "--format", "{{.Status}}"}) 1254 ps.WaitWithDefaultTimeout() 1255 Expect(ps).Should(ExitCleanly()) 1256 Expect(ps.OutputToString()).To(ContainSubstring("Up")) 1257 }) 1258 1259 It("podman pod create --restart=no/never", func() { 1260 // never and no are the same, just different words to do the same thing 1261 policy := []string{"no", "never"} 1262 for _, p := range policy { 1263 podName := "mypod-" + p 1264 runningCtr := "ctr1-" + p 1265 testCtr := "ctr2-" + p 1266 testCtr2 := "ctr3-" + p 1267 session := podmanTest.Podman([]string{"pod", "create", "--restart", p, podName}) 1268 session.WaitWithDefaultTimeout() 1269 Expect(session).Should(ExitCleanly()) 1270 // add container to pod 1271 ctrRun := podmanTest.Podman([]string{"run", "--name", runningCtr, "-d", "--pod", podName, ALPINE, "sleep", "100"}) 1272 ctrRun.WaitWithDefaultTimeout() 1273 Expect(ctrRun).Should(ExitCleanly()) 1274 ctrRun = podmanTest.Podman([]string{"run", "--name", testCtr, "-d", "--pod", podName, ALPINE, "echo", "hello"}) 1275 ctrRun.WaitWithDefaultTimeout() 1276 Expect(ctrRun).Should(ExitCleanly()) 1277 ctrRun = podmanTest.Podman([]string{"run", "--name", testCtr2, "-d", "--pod", podName, ALPINE, "sh", "-c", "echo hello && exit 1"}) 1278 ctrRun.WaitWithDefaultTimeout() 1279 Expect(ctrRun).Should(ExitCleanly()) 1280 // Wait 1 second, so we can check the number of restarts and make sure the container has actually ran 1281 time.Sleep(1 * time.Second) 1282 // check first test container - container exits with exit code 0 1283 ps := podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Restarts}}"}) 1284 ps.WaitWithDefaultTimeout() 1285 Expect(ps).Should(ExitCleanly()) 1286 restarts, err := strconv.Atoi(ps.OutputToString()) 1287 Expect(err).ToNot(HaveOccurred()) 1288 Expect(restarts).To(BeNumerically("==", 0)) 1289 ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Status}}"}) 1290 ps.WaitWithDefaultTimeout() 1291 Expect(ps).Should(ExitCleanly()) 1292 Expect(ps.OutputToString()).To(ContainSubstring("Exited")) 1293 // Check second test container - container exits with non-zero exit code 1294 ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr2, "--format", "{{.Restarts}}"}) 1295 ps.WaitWithDefaultTimeout() 1296 Expect(ps).Should(ExitCleanly()) 1297 restarts, err = strconv.Atoi(ps.OutputToString()) 1298 Expect(err).ToNot(HaveOccurred()) 1299 Expect(restarts).To(BeNumerically("==", 0)) 1300 ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr2, "--format", "{{.Status}}"}) 1301 ps.WaitWithDefaultTimeout() 1302 Expect(ps).Should(ExitCleanly()) 1303 Expect(ps.OutputToString()).To(ContainSubstring("Exited")) 1304 ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + runningCtr, "--format", "{{.Status}}"}) 1305 ps.WaitWithDefaultTimeout() 1306 Expect(ps).Should(ExitCleanly()) 1307 Expect(ps.OutputToString()).To(ContainSubstring("Up")) 1308 } 1309 }) 1310 })