github.com/AbhinandanKurakure/podman/v3@v3.4.10/test/e2e/run_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net" 7 "os" 8 "path/filepath" 9 "strconv" 10 "strings" 11 "syscall" 12 "time" 13 14 "github.com/containers/podman/v3/pkg/cgroups" 15 . "github.com/containers/podman/v3/test/utils" 16 "github.com/containers/storage/pkg/stringid" 17 "github.com/mrunalp/fileutils" 18 . "github.com/onsi/ginkgo" 19 . "github.com/onsi/gomega" 20 . "github.com/onsi/gomega/gexec" 21 ) 22 23 var _ = Describe("Podman run", func() { 24 var ( 25 tempdir string 26 err error 27 podmanTest *PodmanTestIntegration 28 ) 29 30 BeforeEach(func() { 31 tempdir, err = CreateTempDirInTempDir() 32 if err != nil { 33 os.Exit(1) 34 } 35 podmanTest = PodmanTestCreate(tempdir) 36 podmanTest.Setup() 37 podmanTest.SeedImages() 38 }) 39 40 AfterEach(func() { 41 podmanTest.Cleanup() 42 f := CurrentGinkgoTestDescription() 43 processTestResult(f) 44 }) 45 46 It("podman run a container based on local image", func() { 47 session := podmanTest.Podman([]string{"run", ALPINE, "ls"}) 48 session.WaitWithDefaultTimeout() 49 Expect(session).Should(Exit(0)) 50 }) 51 52 It("podman run check /run/.containerenv", func() { 53 session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/run/.containerenv"}) 54 session.WaitWithDefaultTimeout() 55 Expect(session).Should(Exit(0)) 56 Expect(session.OutputToString()).To(Equal("")) 57 58 session = podmanTest.Podman([]string{"run", "--privileged", "--name=test1", ALPINE, "cat", "/run/.containerenv"}) 59 session.WaitWithDefaultTimeout() 60 Expect(session).Should(Exit(0)) 61 Expect(session.OutputToString()).To(ContainSubstring("name=\"test1\"")) 62 Expect(session.OutputToString()).To(ContainSubstring("image=\"" + ALPINE + "\"")) 63 64 session = podmanTest.Podman([]string{"run", "-v", "/:/host", ALPINE, "cat", "/run/.containerenv"}) 65 session.WaitWithDefaultTimeout() 66 Expect(session).Should(Exit(0)) 67 Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1")) 68 69 session = podmanTest.Podman([]string{"run", "-v", "/:/host", "--privileged", ALPINE, "cat", "/run/.containerenv"}) 70 session.WaitWithDefaultTimeout() 71 Expect(session).Should(Exit(0)) 72 Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1")) 73 }) 74 75 It("podman run a container based on a complex local image name", func() { 76 imageName := strings.TrimPrefix(nginx, "quay.io/") 77 session := podmanTest.Podman([]string{"run", imageName, "ls"}) 78 session.WaitWithDefaultTimeout() 79 Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull")) 80 Expect(session).Should(Exit(0)) 81 }) 82 83 It("podman run --signature-policy", func() { 84 SkipIfRemote("SigPolicy not handled by remote") 85 session := podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/no/such/file", ALPINE}) 86 session.WaitWithDefaultTimeout() 87 Expect(session).To(ExitWithError()) 88 89 session = podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/etc/containers/policy.json", ALPINE}) 90 session.WaitWithDefaultTimeout() 91 Expect(session).Should(Exit(0)) 92 }) 93 94 It("podman run --rm with --restart", func() { 95 session := podmanTest.Podman([]string{"run", "--rm", "--restart", "", ALPINE}) 96 session.WaitWithDefaultTimeout() 97 Expect(session).Should(Exit(0)) 98 99 session = podmanTest.Podman([]string{"run", "--rm", "--restart", "no", ALPINE}) 100 session.WaitWithDefaultTimeout() 101 Expect(session).Should(Exit(0)) 102 103 session = podmanTest.Podman([]string{"run", "--rm", "--restart", "on-failure", ALPINE}) 104 session.WaitWithDefaultTimeout() 105 Expect(session).Should(Exit(0)) 106 107 session = podmanTest.Podman([]string{"run", "--rm", "--restart", "always", ALPINE}) 108 session.WaitWithDefaultTimeout() 109 Expect(session).To(ExitWithError()) 110 111 session = podmanTest.Podman([]string{"run", "--rm", "--restart", "unless-stopped", ALPINE}) 112 session.WaitWithDefaultTimeout() 113 Expect(session).To(ExitWithError()) 114 }) 115 116 It("podman run a container based on on a short name with localhost", func() { 117 tag := podmanTest.Podman([]string{"tag", nginx, "localhost/libpod/alpine_nginx:latest"}) 118 tag.WaitWithDefaultTimeout() 119 120 rmi := podmanTest.Podman([]string{"rmi", nginx}) 121 rmi.WaitWithDefaultTimeout() 122 123 session := podmanTest.Podman([]string{"run", "libpod/alpine_nginx:latest", "ls"}) 124 session.WaitWithDefaultTimeout() 125 Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull")) 126 Expect(session).Should(Exit(0)) 127 }) 128 129 It("podman container run a container based on on a short name with localhost", func() { 130 tag := podmanTest.Podman([]string{"image", "tag", nginx, "localhost/libpod/alpine_nginx:latest"}) 131 tag.WaitWithDefaultTimeout() 132 133 rmi := podmanTest.Podman([]string{"image", "rm", nginx}) 134 rmi.WaitWithDefaultTimeout() 135 136 session := podmanTest.Podman([]string{"container", "run", "libpod/alpine_nginx:latest", "ls"}) 137 session.WaitWithDefaultTimeout() 138 Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull")) 139 Expect(session).Should(Exit(0)) 140 }) 141 142 It("podman run a container based on local image with short options", func() { 143 session := podmanTest.Podman([]string{"run", "-dt", ALPINE, "ls"}) 144 session.WaitWithDefaultTimeout() 145 Expect(session).Should(Exit(0)) 146 }) 147 148 It("podman run a container based on local image with short options and args", func() { 149 // regression test for #714 150 session := podmanTest.Podman([]string{"run", ALPINE, "find", "/etc", "-name", "hosts"}) 151 session.WaitWithDefaultTimeout() 152 Expect(session).Should(Exit(0)) 153 match, _ := session.GrepString("/etc/hosts") 154 Expect(match).Should(BeTrue()) 155 }) 156 157 It("podman create pod with name in /etc/hosts", func() { 158 name := "test_container" 159 hostname := "test_hostname" 160 session := podmanTest.Podman([]string{"run", "-ti", "--rm", "--name", name, "--hostname", hostname, ALPINE, "cat", "/etc/hosts"}) 161 session.WaitWithDefaultTimeout() 162 Expect(session).Should(Exit(0)) 163 match, _ := session.GrepString(name) 164 Expect(match).Should(BeTrue()) 165 match, _ = session.GrepString(hostname) 166 Expect(match).Should(BeTrue()) 167 }) 168 169 It("podman run a container based on remote image", func() { 170 // Changing session to rsession 171 rsession := podmanTest.Podman([]string{"run", "-dt", ALPINE, "ls"}) 172 rsession.WaitWithDefaultTimeout() 173 Expect(rsession).Should(Exit(0)) 174 175 lock := GetPortLock("5000") 176 defer lock.Unlock() 177 session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) 178 session.WaitWithDefaultTimeout() 179 Expect(session).Should(Exit(0)) 180 181 if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { 182 Skip("Cannot start docker registry.") 183 } 184 185 run := podmanTest.Podman([]string{"run", "--tls-verify=false", ALPINE}) 186 run.WaitWithDefaultTimeout() 187 Expect(run).Should(Exit(0)) 188 Expect(podmanTest.NumberOfContainers()).To(Equal(3)) 189 190 // Now registries.conf will be consulted where localhost:5000 191 // is set to be insecure. 192 run = podmanTest.Podman([]string{"run", ALPINE}) 193 run.WaitWithDefaultTimeout() 194 Expect(run).Should(Exit(0)) 195 }) 196 197 It("podman run a container with a --rootfs", func() { 198 rootfs := filepath.Join(tempdir, "rootfs") 199 uls := filepath.Join("/", "usr", "local", "share") 200 uniqueString := stringid.GenerateNonCryptoID() 201 testFilePath := filepath.Join(uls, uniqueString) 202 tarball := filepath.Join(tempdir, "rootfs.tar") 203 204 err := os.Mkdir(rootfs, 0770) 205 Expect(err).Should(BeNil()) 206 207 // Change image in predictable way to validate export 208 csession := podmanTest.Podman([]string{"run", "--name", uniqueString, ALPINE, 209 "/bin/sh", "-c", fmt.Sprintf("echo %s > %s", uniqueString, testFilePath)}) 210 csession.WaitWithDefaultTimeout() 211 Expect(csession).Should(Exit(0)) 212 213 // Export from working container image guarantees working root 214 esession := podmanTest.Podman([]string{"export", "--output", tarball, uniqueString}) 215 esession.WaitWithDefaultTimeout() 216 Expect(esession).Should(Exit(0)) 217 Expect(tarball).Should(BeARegularFile()) 218 219 // N/B: This will loose any extended attributes like SELinux types 220 fmt.Fprintf(os.Stderr, "Extracting container root tarball\n") 221 tarsession := SystemExec("tar", []string{"xf", tarball, "-C", rootfs}) 222 Expect(tarsession).Should(Exit(0)) 223 Expect(filepath.Join(rootfs, uls)).Should(BeADirectory()) 224 225 // Other tests confirm SELinux types, just confirm --rootfs is working. 226 session := podmanTest.Podman([]string{"run", "-i", "--security-opt", "label=disable", 227 "--rootfs", rootfs, "cat", testFilePath}) 228 session.WaitWithDefaultTimeout() 229 Expect(session).Should(Exit(0)) 230 231 // Validate changes made in original container and export 232 stdoutLines := session.OutputToStringArray() 233 Expect(stdoutLines).Should(HaveLen(1)) 234 Expect(stdoutLines[0]).Should(Equal(uniqueString)) 235 }) 236 237 It("podman run a container with --init", func() { 238 session := podmanTest.Podman([]string{"run", "--name", "test", "--init", ALPINE, "ls"}) 239 session.WaitWithDefaultTimeout() 240 Expect(session).Should(Exit(0)) 241 result := podmanTest.Podman([]string{"inspect", "test"}) 242 result.WaitWithDefaultTimeout() 243 Expect(result).Should(Exit(0)) 244 conData := result.InspectContainerToJSON() 245 Expect(conData[0].Path).To(Equal("/dev/init")) 246 Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("TRUE")) 247 }) 248 249 It("podman run a container with --init and --init-path", func() { 250 session := podmanTest.Podman([]string{"run", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"}) 251 session.WaitWithDefaultTimeout() 252 Expect(session).Should(Exit(0)) 253 result := podmanTest.Podman([]string{"inspect", "test"}) 254 result.WaitWithDefaultTimeout() 255 Expect(result).Should(Exit(0)) 256 conData := result.InspectContainerToJSON() 257 Expect(conData[0].Path).To(Equal("/dev/init")) 258 Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("TRUE")) 259 }) 260 261 It("podman run a container without --init", func() { 262 session := podmanTest.Podman([]string{"run", "--name", "test", ALPINE, "ls"}) 263 session.WaitWithDefaultTimeout() 264 Expect(session).Should(Exit(0)) 265 result := podmanTest.Podman([]string{"inspect", "test"}) 266 result.WaitWithDefaultTimeout() 267 Expect(result).Should(Exit(0)) 268 conData := result.InspectContainerToJSON() 269 Expect(conData[0].Path).To(Equal("ls")) 270 Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("FALSE")) 271 }) 272 273 forbidGetCWDSeccompProfile := func() string { 274 in := []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`) 275 jsonFile, err := podmanTest.CreateSeccompJson(in) 276 if err != nil { 277 fmt.Println(err) 278 Skip("Failed to prepare seccomp.json for test.") 279 } 280 return jsonFile 281 } 282 283 It("podman run mask and unmask path test", func() { 284 session := podmanTest.Podman([]string{"run", "-d", "--name=maskCtr1", "--security-opt", "unmask=ALL", "--security-opt", "mask=/proc/acpi", ALPINE, "sleep", "200"}) 285 session.WaitWithDefaultTimeout() 286 Expect(session).Should(Exit(0)) 287 session = podmanTest.Podman([]string{"exec", "maskCtr1", "ls", "/sys/firmware"}) 288 session.WaitWithDefaultTimeout() 289 Expect(session.OutputToString()).To(Not(BeEmpty())) 290 Expect(session).Should(Exit(0)) 291 session = podmanTest.Podman([]string{"exec", "maskCtr1", "ls", "/proc/acpi"}) 292 session.WaitWithDefaultTimeout() 293 Expect(session.OutputToString()).To(BeEmpty()) 294 295 session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr2", "--security-opt", "unmask=/proc/acpi:/sys/firmware", ALPINE, "sleep", "200"}) 296 session.WaitWithDefaultTimeout() 297 Expect(session).Should(Exit(0)) 298 session = podmanTest.Podman([]string{"exec", "maskCtr2", "ls", "/sys/firmware"}) 299 session.WaitWithDefaultTimeout() 300 Expect(session.OutputToString()).To(Not(BeEmpty())) 301 Expect(session).Should(Exit(0)) 302 session = podmanTest.Podman([]string{"exec", "maskCtr2", "ls", "/proc/acpi"}) 303 session.WaitWithDefaultTimeout() 304 Expect(session.OutputToString()).To(Not(BeEmpty())) 305 Expect(session).Should(Exit(0)) 306 307 session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr3", "--security-opt", "mask=/sys/power/disk", ALPINE, "sleep", "200"}) 308 session.WaitWithDefaultTimeout() 309 Expect(session).Should(Exit(0)) 310 session = podmanTest.Podman([]string{"exec", "maskCtr3", "cat", "/sys/power/disk"}) 311 session.WaitWithDefaultTimeout() 312 Expect(session.OutputToString()).To(BeEmpty()) 313 Expect(session).Should(Exit(0)) 314 315 session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr4", "--security-opt", "systempaths=unconfined", ALPINE, "sleep", "200"}) 316 session.WaitWithDefaultTimeout() 317 Expect(session).Should(Exit(0)) 318 session = podmanTest.Podman([]string{"exec", "maskCtr4", "ls", "/sys/firmware"}) 319 session.WaitWithDefaultTimeout() 320 Expect(session.OutputToString()).To(Not(BeEmpty())) 321 Expect(session).Should(Exit(0)) 322 323 session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr5", "--security-opt", "systempaths=unconfined", ALPINE, "grep", "/proc", "/proc/self/mounts"}) 324 session.WaitWithDefaultTimeout() 325 Expect(session).Should(Exit(0)) 326 Expect(session.OutputToStringArray()).Should(HaveLen(1)) 327 328 session = podmanTest.Podman([]string{"run", "-d", "--security-opt", "unmask=/proc/*", ALPINE, "grep", "/proc", "/proc/self/mounts"}) 329 session.WaitWithDefaultTimeout() 330 Expect(session).Should(Exit(0)) 331 Expect(session.OutputToStringArray()).Should(HaveLen(1)) 332 333 session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/proc/a*", ALPINE, "ls", "/proc/acpi"}) 334 session.WaitWithDefaultTimeout() 335 Expect(session).Should(Exit(0)) 336 Expect(session.OutputToString()).To(Not(BeEmpty())) 337 }) 338 339 It("podman run security-opt unmask on /sys/fs/cgroup", func() { 340 341 SkipIfCgroupV1("podman umask on /sys/fs/cgroup will fail with cgroups V1") 342 SkipIfRootless("/sys/fs/cgroup rw access is needed") 343 rwOnCGroups := "/sys/fs/cgroup cgroup2 rw" 344 session := podmanTest.Podman([]string{"run", "--security-opt", "unmask=ALL", "--security-opt", "mask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"}) 345 session.WaitWithDefaultTimeout() 346 Expect(session).Should(Exit(0)) 347 Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups)) 348 349 session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"}) 350 session.WaitWithDefaultTimeout() 351 Expect(session).Should(Exit(0)) 352 Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups)) 353 354 session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup///", ALPINE, "cat", "/proc/mounts"}) 355 session.WaitWithDefaultTimeout() 356 Expect(session).Should(Exit(0)) 357 Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups)) 358 359 session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=ALL", ALPINE, "cat", "/proc/mounts"}) 360 session.WaitWithDefaultTimeout() 361 Expect(session).Should(Exit(0)) 362 Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups)) 363 364 session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", "--security-opt", "mask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"}) 365 session.WaitWithDefaultTimeout() 366 Expect(session).Should(Exit(0)) 367 Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups)) 368 369 session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", ALPINE, "ls", "/sys/fs/cgroup"}) 370 session.WaitWithDefaultTimeout() 371 Expect(session).Should(Exit(0)) 372 Expect(session.OutputToString()).ToNot(BeEmpty()) 373 }) 374 375 It("podman run seccomp test", func() { 376 session := podmanTest.Podman([]string{"run", "-it", "--security-opt", strings.Join([]string{"seccomp=", forbidGetCWDSeccompProfile()}, ""), ALPINE, "pwd"}) 377 session.WaitWithDefaultTimeout() 378 Expect(session).To(ExitWithError()) 379 match, _ := session.GrepString("Operation not permitted") 380 Expect(match).Should(BeTrue()) 381 }) 382 383 It("podman run seccomp test --privileged", func() { 384 session := podmanTest.Podman([]string{"run", "-it", "--privileged", "--security-opt", strings.Join([]string{"seccomp=", forbidGetCWDSeccompProfile()}, ""), ALPINE, "pwd"}) 385 session.WaitWithDefaultTimeout() 386 Expect(session).To(ExitWithError()) 387 match, _ := session.GrepString("Operation not permitted") 388 Expect(match).Should(BeTrue()) 389 }) 390 391 It("podman run seccomp test --privileged no profile should be unconfined", func() { 392 session := podmanTest.Podman([]string{"run", "-it", "--privileged", ALPINE, "grep", "Seccomp", "/proc/self/status"}) 393 session.WaitWithDefaultTimeout() 394 Expect(session.OutputToString()).To(ContainSubstring("0")) 395 Expect(session).Should(Exit(0)) 396 }) 397 398 It("podman run seccomp test no profile should be default", func() { 399 session := podmanTest.Podman([]string{"run", "-it", ALPINE, "grep", "Seccomp", "/proc/self/status"}) 400 session.WaitWithDefaultTimeout() 401 Expect(session.OutputToString()).To(ContainSubstring("2")) 402 Expect(session).Should(Exit(0)) 403 }) 404 405 It("podman run capabilities test", func() { 406 session := podmanTest.Podman([]string{"run", "--rm", "--cap-add", "all", ALPINE, "cat", "/proc/self/status"}) 407 session.WaitWithDefaultTimeout() 408 Expect(session).Should(Exit(0)) 409 410 session = podmanTest.Podman([]string{"run", "--rm", "--cap-add", "sys_admin", ALPINE, "cat", "/proc/self/status"}) 411 session.WaitWithDefaultTimeout() 412 Expect(session).Should(Exit(0)) 413 414 session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "all", ALPINE, "cat", "/proc/self/status"}) 415 session.WaitWithDefaultTimeout() 416 Expect(session).Should(Exit(0)) 417 418 session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "setuid", ALPINE, "cat", "/proc/self/status"}) 419 session.WaitWithDefaultTimeout() 420 Expect(session).Should(Exit(0)) 421 }) 422 423 It("podman run user capabilities test", func() { 424 // We need to ignore the containers.conf on the test distribution for this test 425 os.Setenv("CONTAINERS_CONF", "/dev/null") 426 if IsRemote() { 427 podmanTest.RestartRemoteService() 428 } 429 session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapBnd", "/proc/self/status"}) 430 session.WaitWithDefaultTimeout() 431 Expect(session).Should(Exit(0)) 432 Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) 433 434 session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapEff", "/proc/self/status"}) 435 session.WaitWithDefaultTimeout() 436 Expect(session).Should(Exit(0)) 437 Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) 438 439 session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapInh", "/proc/self/status"}) 440 session.WaitWithDefaultTimeout() 441 Expect(session).Should(Exit(0)) 442 Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) 443 444 session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapBnd", "/proc/self/status"}) 445 session.WaitWithDefaultTimeout() 446 Expect(session).Should(Exit(0)) 447 Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) 448 449 session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapEff", "/proc/self/status"}) 450 session.WaitWithDefaultTimeout() 451 Expect(session).Should(Exit(0)) 452 Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) 453 454 session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapInh", "/proc/self/status"}) 455 session.WaitWithDefaultTimeout() 456 Expect(session).Should(Exit(0)) 457 Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) 458 459 session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapBnd", "/proc/self/status"}) 460 session.WaitWithDefaultTimeout() 461 Expect(session).Should(Exit(0)) 462 Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) 463 464 session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapEff", "/proc/self/status"}) 465 session.WaitWithDefaultTimeout() 466 Expect(session).Should(Exit(0)) 467 Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) 468 469 session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"}) 470 session.WaitWithDefaultTimeout() 471 Expect(session).Should(Exit(0)) 472 Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) 473 474 session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) 475 session.WaitWithDefaultTimeout() 476 Expect(session).Should(Exit(0)) 477 Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) 478 479 session = podmanTest.Podman([]string{"run", "--user=0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"}) 480 session.WaitWithDefaultTimeout() 481 Expect(session).Should(Exit(0)) 482 Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) 483 484 session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"}) 485 session.WaitWithDefaultTimeout() 486 Expect(session).Should(Exit(0)) 487 Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) 488 489 session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) 490 session.WaitWithDefaultTimeout() 491 Expect(session).Should(Exit(0)) 492 Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) 493 494 if os.Geteuid() > 0 { 495 if os.Getenv("SKIP_USERNS") != "" { 496 Skip("Skip userns tests.") 497 } 498 if _, err := os.Stat("/proc/self/uid_map"); err != nil { 499 Skip("User namespaces not supported.") 500 } 501 session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"}) 502 session.WaitWithDefaultTimeout() 503 Expect(session).Should(Exit(0)) 504 Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) 505 506 session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--privileged", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) 507 session.WaitWithDefaultTimeout() 508 Expect(session).Should(Exit(0)) 509 Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) 510 511 session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"}) 512 session.WaitWithDefaultTimeout() 513 Expect(session).Should(Exit(0)) 514 Expect(session.OutputToString()).To(ContainSubstring("0000000000000002")) 515 } 516 }) 517 518 It("podman run user capabilities test with image", func() { 519 // We need to ignore the containers.conf on the test distribution for this test 520 os.Setenv("CONTAINERS_CONF", "/dev/null") 521 if IsRemote() { 522 podmanTest.RestartRemoteService() 523 } 524 dockerfile := fmt.Sprintf(`FROM %s 525 USER bin`, BB) 526 podmanTest.BuildImage(dockerfile, "test", "false") 527 session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapBnd", "/proc/self/status"}) 528 session.WaitWithDefaultTimeout() 529 Expect(session).Should(Exit(0)) 530 Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb")) 531 532 session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapEff", "/proc/self/status"}) 533 session.WaitWithDefaultTimeout() 534 Expect(session).Should(Exit(0)) 535 Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) 536 }) 537 538 It("podman run limits test", func() { 539 SkipIfRootlessCgroupsV1("Setting limits not supported on cgroupv1 for rootless users") 540 541 if !isRootless() { 542 session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "rtprio=99", "--cap-add=sys_nice", fedoraMinimal, "cat", "/proc/self/sched"}) 543 session.WaitWithDefaultTimeout() 544 Expect(session).Should(Exit(0)) 545 } 546 547 session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=2048:2048", fedoraMinimal, "ulimit", "-n"}) 548 session.WaitWithDefaultTimeout() 549 Expect(session).Should(Exit(0)) 550 Expect(session.OutputToString()).To(ContainSubstring("2048")) 551 552 session = podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=1024:1028", fedoraMinimal, "ulimit", "-n"}) 553 session.WaitWithDefaultTimeout() 554 Expect(session).Should(Exit(0)) 555 Expect(session.OutputToString()).To(ContainSubstring("1024")) 556 557 if !CGROUPSV2 { 558 // --oom-kill-disable not supported on cgroups v2. 559 session = podmanTest.Podman([]string{"run", "--rm", "--oom-kill-disable=true", fedoraMinimal, "echo", "memory-hog"}) 560 session.WaitWithDefaultTimeout() 561 Expect(session).Should(Exit(0)) 562 } 563 564 session = podmanTest.Podman([]string{"run", "--rm", "--oom-score-adj=111", fedoraMinimal, "cat", "/proc/self/oom_score_adj"}) 565 session.WaitWithDefaultTimeout() 566 Expect(session).Should(Exit(0)) 567 Expect(session.OutputToString()).To(Equal("111")) 568 }) 569 570 It("podman run limits host test", func() { 571 SkipIfRemote("This can only be used for local tests") 572 573 var l syscall.Rlimit 574 575 err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l) 576 Expect(err).To(BeNil()) 577 578 session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "host", fedoraMinimal, "ulimit", "-Hn"}) 579 session.WaitWithDefaultTimeout() 580 Expect(session).Should(Exit(0)) 581 582 ulimitCtrStr := strings.TrimSpace(session.OutputToString()) 583 ulimitCtr, err := strconv.ParseUint(ulimitCtrStr, 10, 0) 584 Expect(err).To(BeNil()) 585 586 Expect(ulimitCtr).Should(BeNumerically(">=", l.Max)) 587 }) 588 589 It("podman run with cidfile", func() { 590 session := podmanTest.Podman([]string{"run", "--cidfile", tempdir + "cidfile", ALPINE, "ls"}) 591 session.WaitWithDefaultTimeout() 592 Expect(session).Should(Exit(0)) 593 err := os.Remove(tempdir + "cidfile") 594 Expect(err).To(BeNil()) 595 }) 596 597 It("podman run sysctl test", func() { 598 SkipIfRootless("Network sysctls are not available root rootless") 599 session := podmanTest.Podman([]string{"run", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"}) 600 session.WaitWithDefaultTimeout() 601 Expect(session).Should(Exit(0)) 602 Expect(session.OutputToString()).To(ContainSubstring("net.core.somaxconn = 65535")) 603 604 // network sysctls should fail if --net=host is set 605 session = podmanTest.Podman([]string{"run", "--net", "host", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"}) 606 session.WaitWithDefaultTimeout() 607 Expect(session).Should(Exit(125)) 608 }) 609 610 It("podman run blkio-weight test", func() { 611 SkipIfRootlessCgroupsV1("Setting blkio-weight not supported on cgroupv1 for rootless users") 612 SkipIfRootless("By default systemd doesn't delegate io to rootless users") 613 if CGROUPSV2 { 614 if _, err := os.Stat("/sys/fs/cgroup/io.stat"); os.IsNotExist(err) { 615 Skip("Kernel does not have io.stat") 616 } 617 if _, err := os.Stat("/sys/fs/cgroup/system.slice/io.bfq.weight"); os.IsNotExist(err) { 618 Skip("Kernel does not support BFQ IO scheduler") 619 } 620 session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/io.bfq.weight"}) 621 session.WaitWithDefaultTimeout() 622 Expect(session).Should(Exit(0)) 623 // there was a documentation issue in the kernel that reported a different range [1-10000] for the io controller. 624 // older versions of crun/runc used it. For the time being allow both versions to pass the test. 625 // FIXME: drop "|51" once all the runtimes we test have the fix in place. 626 Expect(strings.Replace(session.OutputToString(), "default ", "", 1)).To(MatchRegexp("15|51")) 627 } else { 628 if _, err := os.Stat("/sys/fs/cgroup/blkio/blkio.weight"); os.IsNotExist(err) { 629 Skip("Kernel does not support blkio.weight") 630 } 631 session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.weight"}) 632 session.WaitWithDefaultTimeout() 633 Expect(session).Should(Exit(0)) 634 Expect(session.OutputToString()).To(ContainSubstring("15")) 635 } 636 }) 637 638 It("podman run device-read-bps test", func() { 639 SkipIfRootless("FIXME: Missing /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control") 640 SkipIfRootlessCgroupsV1("Setting device-read-bps not supported on cgroupv1 for rootless users") 641 642 var session *PodmanSessionIntegration 643 644 if CGROUPSV2 { 645 session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"}) 646 } else { 647 session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"}) 648 } 649 650 session.WaitWithDefaultTimeout() 651 Expect(session).Should(Exit(0)) 652 if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2 653 Expect(session.OutputToString()).To(ContainSubstring("1048576")) 654 } 655 }) 656 657 It("podman run device-write-bps test", func() { 658 SkipIfRootless("FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist") 659 SkipIfRootlessCgroupsV1("Setting device-write-bps not supported on cgroupv1 for rootless users") 660 661 var session *PodmanSessionIntegration 662 663 if CGROUPSV2 { 664 session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"}) 665 } else { 666 session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"}) 667 } 668 session.WaitWithDefaultTimeout() 669 Expect(session).Should(Exit(0)) 670 if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2 671 Expect(session.OutputToString()).To(ContainSubstring("1048576")) 672 } 673 }) 674 675 It("podman run device-read-iops test", func() { 676 SkipIfRootless("FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist") 677 SkipIfRootlessCgroupsV1("Setting device-read-iops not supported on cgroupv1 for rootless users") 678 var session *PodmanSessionIntegration 679 680 if CGROUPSV2 { 681 session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"}) 682 } else { 683 session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"}) 684 } 685 686 session.WaitWithDefaultTimeout() 687 Expect(session).Should(Exit(0)) 688 if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2 689 Expect(session.OutputToString()).To(ContainSubstring("100")) 690 } 691 }) 692 693 It("podman run device-write-iops test", func() { 694 SkipIfRootless("FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist") 695 SkipIfRootlessCgroupsV1("Setting device-write-iops not supported on cgroupv1 for rootless users") 696 var session *PodmanSessionIntegration 697 698 if CGROUPSV2 { 699 session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"}) 700 } else { 701 session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"}) 702 } 703 704 session.WaitWithDefaultTimeout() 705 Expect(session).Should(Exit(0)) 706 if !CGROUPSV2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2 707 Expect(session.OutputToString()).To(ContainSubstring("100")) 708 } 709 }) 710 711 It("podman run notify_socket", func() { 712 SkipIfRemote("This can only be used for local tests") 713 714 host := GetHostDistributionInfo() 715 if host.Distribution != "rhel" && host.Distribution != "centos" && host.Distribution != "fedora" { 716 Skip("this test requires a working runc") 717 } 718 sock := filepath.Join(podmanTest.TempDir, "notify") 719 addr := net.UnixAddr{ 720 Name: sock, 721 Net: "unixgram", 722 } 723 socket, err := net.ListenUnixgram("unixgram", &addr) 724 Expect(err).To(BeNil()) 725 defer os.Remove(sock) 726 defer socket.Close() 727 728 os.Setenv("NOTIFY_SOCKET", sock) 729 defer os.Unsetenv("NOTIFY_SOCKET") 730 731 session := podmanTest.Podman([]string{"run", ALPINE, "printenv", "NOTIFY_SOCKET"}) 732 session.WaitWithDefaultTimeout() 733 Expect(session).Should(Exit(0)) 734 Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0)) 735 }) 736 737 It("podman run log-opt", func() { 738 log := filepath.Join(podmanTest.TempDir, "/container.log") 739 session := podmanTest.Podman([]string{"run", "--rm", "--log-driver", "k8s-file", "--log-opt", fmt.Sprintf("path=%s", log), ALPINE, "ls"}) 740 session.WaitWithDefaultTimeout() 741 Expect(session).Should(Exit(0)) 742 _, err := os.Stat(log) 743 Expect(err).To(BeNil()) 744 _ = os.Remove(log) 745 }) 746 747 It("podman run tagged image", func() { 748 podmanTest.AddImageToRWStore(BB) 749 tag := podmanTest.Podman([]string{"tag", BB, "bb"}) 750 tag.WaitWithDefaultTimeout() 751 Expect(tag).Should(Exit(0)) 752 753 session := podmanTest.Podman([]string{"run", "--rm", "bb", "ls"}) 754 session.WaitWithDefaultTimeout() 755 Expect(session).Should(Exit(0)) 756 }) 757 758 It("podman test hooks", func() { 759 hcheck := "/run/hookscheck" 760 hooksDir := tempdir + "/hooks" 761 os.Mkdir(hooksDir, 0755) 762 fileutils.CopyFile("hooks/hooks.json", hooksDir) 763 os.Setenv("HOOK_OPTION", fmt.Sprintf("--hooks-dir=%s", hooksDir)) 764 os.Remove(hcheck) 765 session := podmanTest.Podman([]string{"run", ALPINE, "ls"}) 766 session.Wait(10) 767 os.Unsetenv("HOOK_OPTION") 768 Expect(session).Should(Exit(0)) 769 }) 770 771 It("podman run with subscription secrets", func() { 772 SkipIfRemote("--default-mount-file option is not supported in podman-remote") 773 containersDir := filepath.Join(podmanTest.TempDir, "containers") 774 err := os.MkdirAll(containersDir, 0755) 775 Expect(err).To(BeNil()) 776 777 secretsDir := filepath.Join(podmanTest.TempDir, "rhel", "secrets") 778 err = os.MkdirAll(secretsDir, 0755) 779 Expect(err).To(BeNil()) 780 781 mountsFile := filepath.Join(containersDir, "mounts.conf") 782 mountString := secretsDir + ":/run/secrets" 783 err = ioutil.WriteFile(mountsFile, []byte(mountString), 0755) 784 Expect(err).To(BeNil()) 785 786 secretsFile := filepath.Join(secretsDir, "test.txt") 787 secretsString := "Testing secrets mount. I am mounted!" 788 err = ioutil.WriteFile(secretsFile, []byte(secretsString), 0755) 789 Expect(err).To(BeNil()) 790 791 targetDir := tempdir + "/symlink/target" 792 err = os.MkdirAll(targetDir, 0755) 793 Expect(err).To(BeNil()) 794 keyFile := filepath.Join(targetDir, "key.pem") 795 err = ioutil.WriteFile(keyFile, []byte(mountString), 0755) 796 Expect(err).To(BeNil()) 797 execSession := SystemExec("ln", []string{"-s", targetDir, filepath.Join(secretsDir, "mysymlink")}) 798 Expect(execSession).Should(Exit(0)) 799 800 session := podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "cat", "/run/secrets/test.txt"}) 801 session.WaitWithDefaultTimeout() 802 Expect(session).Should(Exit(0)) 803 Expect(session.OutputToString()).To(Equal(secretsString)) 804 805 session = podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "ls", "/run/secrets/mysymlink"}) 806 session.WaitWithDefaultTimeout() 807 Expect(session).Should(Exit(0)) 808 Expect(session.OutputToString()).To(ContainSubstring("key.pem")) 809 }) 810 811 It("podman run with FIPS mode secrets", func() { 812 SkipIfRootless("rootless can not manipulate system-fips file") 813 fipsFile := "/etc/system-fips" 814 err = ioutil.WriteFile(fipsFile, []byte{}, 0755) 815 Expect(err).To(BeNil()) 816 817 session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls", "/run/secrets"}) 818 session.WaitWithDefaultTimeout() 819 Expect(session).Should(Exit(0)) 820 Expect(session.OutputToString()).To(ContainSubstring("system-fips")) 821 822 err = os.Remove(fipsFile) 823 Expect(err).To(BeNil()) 824 }) 825 826 It("podman run without group-add", func() { 827 session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"}) 828 session.WaitWithDefaultTimeout() 829 Expect(session).Should(Exit(0)) 830 Expect(session.LineInOutputContains("27(video),777,65533(nogroup)")).To(BeFalse()) 831 }) 832 833 It("podman run with group-add", func() { 834 session := podmanTest.Podman([]string{"run", "--rm", "--group-add=audio", "--group-add=nogroup", "--group-add=777", ALPINE, "id"}) 835 session.WaitWithDefaultTimeout() 836 Expect(session).Should(Exit(0)) 837 Expect(session.LineInOutputContains("777,65533(nogroup)")).To(BeTrue()) 838 }) 839 840 It("podman run with user (default)", func() { 841 session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"}) 842 session.WaitWithDefaultTimeout() 843 Expect(session).Should(Exit(0)) 844 Expect(session.LineInOutputContains("uid=0(root) gid=0(root)")).To(BeTrue()) 845 }) 846 847 It("podman run with user (integer, not in /etc/passwd)", func() { 848 session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "id"}) 849 session.WaitWithDefaultTimeout() 850 Expect(session).Should(Exit(0)) 851 Expect(session.OutputToString()).To(Equal("uid=1234(1234) gid=0(root)")) 852 }) 853 854 It("podman run with user (integer, in /etc/passwd)", func() { 855 session := podmanTest.Podman([]string{"run", "--rm", "--user=8", ALPINE, "id"}) 856 session.WaitWithDefaultTimeout() 857 Expect(session).Should(Exit(0)) 858 Expect(session.LineInOutputContains("uid=8(mail) gid=12(mail)")).To(BeTrue()) 859 }) 860 861 It("podman run with user (username)", func() { 862 session := podmanTest.Podman([]string{"run", "--rm", "--user=mail", ALPINE, "id"}) 863 session.WaitWithDefaultTimeout() 864 Expect(session).Should(Exit(0)) 865 Expect(session.LineInOutputContains("uid=8(mail) gid=12(mail)")).To(BeTrue()) 866 }) 867 868 It("podman run with user:group (username:integer)", func() { 869 session := podmanTest.Podman([]string{"run", "--rm", "--user=mail:21", ALPINE, "id"}) 870 session.WaitWithDefaultTimeout() 871 Expect(session).Should(Exit(0)) 872 Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp)")) 873 }) 874 875 It("podman run with user:group (integer:groupname)", func() { 876 session := podmanTest.Podman([]string{"run", "--rm", "--user=8:ftp", ALPINE, "id"}) 877 session.WaitWithDefaultTimeout() 878 Expect(session).Should(Exit(0)) 879 Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp)")) 880 }) 881 882 It("podman run with user, verify caps dropped", func() { 883 session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "grep", "CapEff", "/proc/self/status"}) 884 session.WaitWithDefaultTimeout() 885 Expect(session).Should(Exit(0)) 886 capEff := strings.Split(session.OutputToString(), " ") 887 Expect("0000000000000000").To(Equal(capEff[1])) 888 }) 889 890 It("podman run with attach stdin outputs container ID", func() { 891 session := podmanTest.Podman([]string{"run", "--attach", "stdin", ALPINE, "printenv"}) 892 session.WaitWithDefaultTimeout() 893 Expect(session).Should(Exit(0)) 894 ps := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc"}) 895 ps.WaitWithDefaultTimeout() 896 Expect(ps).Should(Exit(0)) 897 Expect(ps.LineInOutputContains(session.OutputToString())).To(BeTrue()) 898 }) 899 900 It("podman run with attach stdout does not print stderr", func() { 901 session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stdout", ALPINE, "ls", "/doesnotexist"}) 902 session.WaitWithDefaultTimeout() 903 Expect(session.OutputToString()).To(Equal("")) 904 }) 905 906 It("podman run with attach stderr does not print stdout", func() { 907 session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stderr", ALPINE, "ls", "/"}) 908 session.WaitWithDefaultTimeout() 909 Expect(session).Should(Exit(0)) 910 Expect(session.OutputToString()).To(Equal("")) 911 }) 912 913 It("podman run attach nonsense errors", func() { 914 session := podmanTest.Podman([]string{"run", "--rm", "--attach", "asdfasdf", ALPINE, "ls", "/"}) 915 session.WaitWithDefaultTimeout() 916 Expect(session).Should(Exit(125)) 917 }) 918 919 It("podman run exit code on failure to exec", func() { 920 session := podmanTest.Podman([]string{"run", ALPINE, "/etc"}) 921 session.WaitWithDefaultTimeout() 922 Expect(session).Should(Exit(126)) 923 }) 924 925 It("podman run error on exec", func() { 926 session := podmanTest.Podman([]string{"run", ALPINE, "sh", "-c", "exit 100"}) 927 session.WaitWithDefaultTimeout() 928 Expect(session).Should(Exit(100)) 929 }) 930 931 It("podman run with named volume", func() { 932 session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "stat", "-c", "%a %Y", "/var/tmp"}) 933 session.WaitWithDefaultTimeout() 934 Expect(session).Should(Exit(0)) 935 perms := session.OutputToString() 936 937 session = podmanTest.Podman([]string{"run", "--rm", "-v", "test:/var/tmp", ALPINE, "stat", "-c", "%a %Y", "/var/tmp"}) 938 session.WaitWithDefaultTimeout() 939 Expect(session).Should(Exit(0)) 940 Expect(session.OutputToString()).To(Equal(perms)) 941 }) 942 943 It("podman run with built-in volume image", func() { 944 session := podmanTest.Podman([]string{"run", "--rm", redis, "ls"}) 945 session.WaitWithDefaultTimeout() 946 Expect(session).Should(Exit(0)) 947 948 dockerfile := fmt.Sprintf(`FROM %s 949 RUN mkdir -p /myvol/data && chown -R mail.0 /myvol 950 VOLUME ["/myvol/data"] 951 USER mail`, BB) 952 953 podmanTest.BuildImage(dockerfile, "test", "false") 954 session = podmanTest.Podman([]string{"run", "--rm", "test", "ls", "-al", "/myvol/data"}) 955 session.WaitWithDefaultTimeout() 956 Expect(session).Should(Exit(0)) 957 Expect(session.OutputToString()).To(ContainSubstring("mail root")) 958 }) 959 960 It("podman run --volumes-from flag", func() { 961 vol := filepath.Join(podmanTest.TempDir, "vol-test") 962 err := os.MkdirAll(vol, 0755) 963 Expect(err).To(BeNil()) 964 965 filename := "test.txt" 966 volFile := filepath.Join(vol, filename) 967 data := "Testing --volumes-from!!!" 968 err = ioutil.WriteFile(volFile, []byte(data), 0755) 969 Expect(err).To(BeNil()) 970 mountpoint := "/myvol/" 971 972 session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint + ":z", ALPINE, "cat", mountpoint + filename}) 973 session.WaitWithDefaultTimeout() 974 Expect(session).Should(Exit(0)) 975 ctrID := session.OutputToString() 976 977 session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "cat", mountpoint + filename}) 978 session.WaitWithDefaultTimeout() 979 Expect(session).Should(Exit(0)) 980 Expect(session.OutputToString()).To(Equal(data)) 981 982 session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "sh", "-c", "echo test >> " + mountpoint + filename}) 983 session.WaitWithDefaultTimeout() 984 Expect(session).Should(Exit(0)) 985 986 session = podmanTest.Podman([]string{"start", "--attach", ctrID}) 987 session.WaitWithDefaultTimeout() 988 Expect(session).Should(Exit(0)) 989 Expect(session.OutputToString()).To(Equal(data + "test")) 990 }) 991 992 It("podman run --volumes-from flag options", func() { 993 vol := filepath.Join(podmanTest.TempDir, "vol-test") 994 err := os.MkdirAll(vol, 0755) 995 Expect(err).To(BeNil()) 996 997 filename := "test.txt" 998 volFile := filepath.Join(vol, filename) 999 data := "Testing --volumes-from!!!" 1000 err = ioutil.WriteFile(volFile, []byte(data), 0755) 1001 Expect(err).To(BeNil()) 1002 mountpoint := "/myvol/" 1003 1004 session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint, ALPINE, "cat", mountpoint + filename}) 1005 session.WaitWithDefaultTimeout() 1006 Expect(session).Should(Exit(0)) 1007 ctrID := session.OutputToString() 1008 1009 // check that the read only option works 1010 session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro", ALPINE, "touch", mountpoint + "abc.txt"}) 1011 session.WaitWithDefaultTimeout() 1012 Expect(session).Should(Exit(1)) 1013 Expect(session.ErrorToString()).To(ContainSubstring("Read-only file system")) 1014 1015 // check that both z and ro options work 1016 session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro,z", ALPINE, "cat", mountpoint + filename}) 1017 session.WaitWithDefaultTimeout() 1018 Expect(session).Should(Exit(0)) 1019 Expect(session.OutputToString()).To(Equal(data)) 1020 1021 // check that multiple ro/rw are not working 1022 session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro,rw", ALPINE, "cat", mountpoint + filename}) 1023 session.WaitWithDefaultTimeout() 1024 Expect(session).Should(Exit(125)) 1025 Expect(session.ErrorToString()).To(ContainSubstring("cannot set ro or rw options more than once")) 1026 1027 // check that multiple z options are not working 1028 session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":z,z,ro", ALPINE, "cat", mountpoint + filename}) 1029 session.WaitWithDefaultTimeout() 1030 Expect(session).Should(Exit(125)) 1031 Expect(session.ErrorToString()).To(ContainSubstring("cannot set :z more than once in mount options")) 1032 1033 // create new read only volume 1034 session = podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint + ":ro", ALPINE, "cat", mountpoint + filename}) 1035 session.WaitWithDefaultTimeout() 1036 Expect(session).Should(Exit(0)) 1037 ctrID = session.OutputToString() 1038 1039 // check if the original volume was mounted as read only that --volumes-from also mount it as read only 1040 session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "touch", mountpoint + "abc.txt"}) 1041 session.WaitWithDefaultTimeout() 1042 Expect(session).Should(Exit(1)) 1043 Expect(session.ErrorToString()).To(ContainSubstring("Read-only file system")) 1044 }) 1045 1046 It("podman run --volumes-from flag with built-in volumes", func() { 1047 session := podmanTest.Podman([]string{"create", redis, "sh"}) 1048 session.WaitWithDefaultTimeout() 1049 Expect(session).Should(Exit(0)) 1050 ctrID := session.OutputToString() 1051 1052 session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "ls"}) 1053 session.WaitWithDefaultTimeout() 1054 Expect(session).Should(Exit(0)) 1055 Expect(session.OutputToString()).To(ContainSubstring("data")) 1056 }) 1057 1058 It("podman run --volumes flag with multiple volumes", func() { 1059 vol1 := filepath.Join(podmanTest.TempDir, "vol-test1") 1060 err := os.MkdirAll(vol1, 0755) 1061 Expect(err).To(BeNil()) 1062 vol2 := filepath.Join(podmanTest.TempDir, "vol-test2") 1063 err = os.MkdirAll(vol2, 0755) 1064 Expect(err).To(BeNil()) 1065 1066 session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", ALPINE, "touch", "/myvol2/foo.txt"}) 1067 session.WaitWithDefaultTimeout() 1068 Expect(session).Should(Exit(0)) 1069 }) 1070 1071 It("podman run --volumes flag with empty host dir", func() { 1072 vol1 := filepath.Join(podmanTest.TempDir, "vol-test1") 1073 err := os.MkdirAll(vol1, 0755) 1074 Expect(err).To(BeNil()) 1075 1076 session := podmanTest.Podman([]string{"run", "--volume", ":/myvol1:z", ALPINE, "touch", "/myvol2/foo.txt"}) 1077 session.WaitWithDefaultTimeout() 1078 Expect(session).To(ExitWithError()) 1079 Expect(session.ErrorToString()).To(ContainSubstring("directory cannot be empty")) 1080 session = podmanTest.Podman([]string{"run", "--volume", vol1 + ":", ALPINE, "touch", "/myvol2/foo.txt"}) 1081 session.WaitWithDefaultTimeout() 1082 Expect(session).To(ExitWithError()) 1083 Expect(session.ErrorToString()).To(ContainSubstring("directory cannot be empty")) 1084 }) 1085 1086 It("podman run --mount flag with multiple mounts", func() { 1087 vol1 := filepath.Join(podmanTest.TempDir, "vol-test1") 1088 err := os.MkdirAll(vol1, 0755) 1089 Expect(err).To(BeNil()) 1090 vol2 := filepath.Join(podmanTest.TempDir, "vol-test2") 1091 err = os.MkdirAll(vol2, 0755) 1092 Expect(err).To(BeNil()) 1093 1094 session := podmanTest.Podman([]string{"run", "--mount", "type=bind,src=" + vol1 + ",target=/myvol1,z", "--mount", "type=bind,src=" + vol2 + ",target=/myvol2,z", ALPINE, "touch", "/myvol2/foo.txt"}) 1095 session.WaitWithDefaultTimeout() 1096 Expect(session).Should(Exit(0)) 1097 }) 1098 1099 It("podman run findmnt nothing shared", func() { 1100 vol1 := filepath.Join(podmanTest.TempDir, "vol-test1") 1101 err := os.MkdirAll(vol1, 0755) 1102 Expect(err).To(BeNil()) 1103 vol2 := filepath.Join(podmanTest.TempDir, "vol-test2") 1104 err = os.MkdirAll(vol2, 0755) 1105 Expect(err).To(BeNil()) 1106 1107 session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"}) 1108 session.WaitWithDefaultTimeout() 1109 Expect(session).Should(Exit(0)) 1110 match, _ := session.GrepString("shared") 1111 Expect(match).Should(BeFalse()) 1112 }) 1113 1114 It("podman run findmnt shared", func() { 1115 vol1 := filepath.Join(podmanTest.TempDir, "vol-test1") 1116 err := os.MkdirAll(vol1, 0755) 1117 Expect(err).To(BeNil()) 1118 vol2 := filepath.Join(podmanTest.TempDir, "vol-test2") 1119 err = os.MkdirAll(vol2, 0755) 1120 Expect(err).To(BeNil()) 1121 1122 session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:shared,z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"}) 1123 session.WaitWithDefaultTimeout() 1124 Expect(session).Should(Exit(0)) 1125 match, shared := session.GrepString("shared") 1126 Expect(match).Should(BeTrue()) 1127 // make sure it's only shared (and not 'shared,slave') 1128 isSharedOnly := !strings.Contains(shared[0], "shared,") 1129 Expect(isSharedOnly).Should(BeTrue()) 1130 }) 1131 1132 It("podman run --security-opts proc-opts=", func() { 1133 session := podmanTest.Podman([]string{"run", "--security-opt", "proc-opts=nosuid,exec", fedoraMinimal, "findmnt", "-noOPTIONS", "/proc"}) 1134 session.WaitWithDefaultTimeout() 1135 Expect(session).Should(Exit(0)) 1136 output := session.OutputToString() 1137 Expect(output).To(ContainSubstring("nosuid")) 1138 Expect(output).To(Not(ContainSubstring("exec"))) 1139 }) 1140 1141 It("podman run --mount type=bind,bind-nonrecursive", func() { 1142 SkipIfRootless("FIXME: rootless users are not allowed to mount bind-nonrecursive (Could this be a Kernel bug?") 1143 session := podmanTest.Podman([]string{"run", "--mount", "type=bind,bind-nonrecursive,slave,src=/,target=/host", fedoraMinimal, "findmnt", "-nR", "/host"}) 1144 session.WaitWithDefaultTimeout() 1145 Expect(session).Should(Exit(0)) 1146 Expect(len(session.OutputToStringArray())).To(Equal(1)) 1147 }) 1148 1149 It("podman run --mount type=devpts,target=/foo/bar", func() { 1150 session := podmanTest.Podman([]string{"run", "--mount", "type=devpts,target=/foo/bar", fedoraMinimal, "stat", "-f", "-c%T", "/foo/bar"}) 1151 session.WaitWithDefaultTimeout() 1152 Expect(session).Should(Exit(0)) 1153 Expect(session.OutputToString()).To(ContainSubstring("devpts")) 1154 }) 1155 1156 It("podman run --pod automatically", func() { 1157 session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:foobar", ALPINE, "nc", "-l", "-p", "8686"}) 1158 session.WaitWithDefaultTimeout() 1159 Expect(session).Should(Exit(0)) 1160 1161 session = podmanTest.Podman([]string{"run", "--pod", "foobar", ALPINE, "/bin/sh", "-c", "echo test | nc -w 1 127.0.0.1 8686"}) 1162 session.WaitWithDefaultTimeout() 1163 Expect(session).Should(Exit(0)) 1164 1165 check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"}) 1166 check.WaitWithDefaultTimeout() 1167 match, _ := check.GrepString("foobar") 1168 Expect(match).To(BeTrue()) 1169 }) 1170 1171 It("podman run --pod new with hostname", func() { 1172 hostname := "abc" 1173 session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", "--hostname", hostname, ALPINE, "cat", "/etc/hostname"}) 1174 session.WaitWithDefaultTimeout() 1175 Expect(session).Should(Exit(0)) 1176 Expect(session.OutputToString()).To(ContainSubstring(hostname)) 1177 }) 1178 1179 It("podman run --rm should work", func() { 1180 session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "ls"}) 1181 session.WaitWithDefaultTimeout() 1182 Expect(session).Should(Exit(0)) 1183 session = podmanTest.Podman([]string{"wait", "test"}) 1184 session.WaitWithDefaultTimeout() 1185 Expect(session).To(ExitWithError()) 1186 1187 numContainers := podmanTest.NumberOfContainers() 1188 Expect(numContainers).To(Equal(0)) 1189 }) 1190 1191 It("podman run --rm failed container should delete itself", func() { 1192 session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "foo"}) 1193 session.WaitWithDefaultTimeout() 1194 Expect(session).To(ExitWithError()) 1195 session = podmanTest.Podman([]string{"wait", "test"}) 1196 session.WaitWithDefaultTimeout() 1197 Expect(session).To(ExitWithError()) 1198 1199 numContainers := podmanTest.NumberOfContainers() 1200 Expect(numContainers).To(Equal(0)) 1201 }) 1202 1203 It("podman run failed container should NOT delete itself", func() { 1204 session := podmanTest.Podman([]string{"run", ALPINE, "foo"}) 1205 session.WaitWithDefaultTimeout() 1206 Expect(session).To(ExitWithError()) 1207 // If remote we could have a race condition 1208 session = podmanTest.Podman([]string{"wait", "test"}) 1209 session.WaitWithDefaultTimeout() 1210 Expect(session).To(ExitWithError()) 1211 1212 numContainers := podmanTest.NumberOfContainers() 1213 Expect(numContainers).To(Equal(1)) 1214 }) 1215 It("podman run readonly container should NOT mount /dev/shm read/only", func() { 1216 session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "mount"}) 1217 session.WaitWithDefaultTimeout() 1218 Expect(session).Should(Exit(0)) 1219 1220 Expect(session.OutputToString()).To(Not(ContainSubstring("/dev/shm type tmpfs (ro,"))) 1221 }) 1222 1223 It("podman run readonly container should NOT mount /run noexec", func() { 1224 session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "sh", "-c", "mount | grep \"/run \""}) 1225 session.WaitWithDefaultTimeout() 1226 Expect(session).Should(Exit(0)) 1227 1228 Expect(session.OutputToString()).To(Not(ContainSubstring("noexec"))) 1229 }) 1230 1231 It("podman run with bad healthcheck retries", func() { 1232 session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-retries", "0", ALPINE, "top"}) 1233 session.Wait() 1234 Expect(session).To(ExitWithError()) 1235 Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-retries must be greater than 0")) 1236 }) 1237 1238 It("podman run with bad healthcheck timeout", func() { 1239 session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "foo", "--health-timeout", "0s", ALPINE, "top"}) 1240 session.WaitWithDefaultTimeout() 1241 Expect(session).To(ExitWithError()) 1242 Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-timeout must be at least 1 second")) 1243 }) 1244 1245 It("podman run with bad healthcheck start-period", func() { 1246 session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "foo", "--health-start-period", "-1s", ALPINE, "top"}) 1247 session.WaitWithDefaultTimeout() 1248 Expect(session).To(ExitWithError()) 1249 Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-start-period must be 0 seconds or greater")) 1250 }) 1251 1252 It("podman run with --add-host and --no-hosts fails", func() { 1253 session := podmanTest.Podman([]string{"run", "-dt", "--add-host", "test1:127.0.0.1", "--no-hosts", ALPINE, "top"}) 1254 session.WaitWithDefaultTimeout() 1255 Expect(session).To(ExitWithError()) 1256 }) 1257 1258 It("podman run with restart-policy always restarts containers", func() { 1259 testDir := filepath.Join(podmanTest.RunRoot, "restart-test") 1260 err := os.MkdirAll(testDir, 0755) 1261 Expect(err).To(BeNil()) 1262 1263 aliveFile := filepath.Join(testDir, "running") 1264 file, err := os.Create(aliveFile) 1265 Expect(err).To(BeNil()) 1266 file.Close() 1267 1268 session := podmanTest.Podman([]string{"run", "-dt", "--restart", "always", "-v", fmt.Sprintf("%s:/tmp/runroot:Z", testDir), ALPINE, "sh", "-c", "date +%N > /tmp/runroot/ran && while test -r /tmp/runroot/running; do sleep 0.1s; done"}) 1269 1270 found := false 1271 testFile := filepath.Join(testDir, "ran") 1272 for i := 0; i < 30; i++ { 1273 time.Sleep(1 * time.Second) 1274 if _, err := os.Stat(testFile); err == nil { 1275 found = true 1276 err = os.Remove(testFile) 1277 Expect(err).To(BeNil()) 1278 break 1279 } 1280 } 1281 Expect(found).To(BeTrue()) 1282 1283 err = os.Remove(aliveFile) 1284 Expect(err).To(BeNil()) 1285 1286 session.WaitWithDefaultTimeout() 1287 1288 // 10 seconds to restart the container 1289 found = false 1290 for i := 0; i < 10; i++ { 1291 time.Sleep(1 * time.Second) 1292 if _, err := os.Stat(testFile); err == nil { 1293 found = true 1294 break 1295 } 1296 } 1297 Expect(found).To(BeTrue()) 1298 }) 1299 1300 It("podman run with cgroups=split", func() { 1301 SkipIfNotSystemd(podmanTest.CgroupManager, "do not test --cgroups=split if not running on systemd") 1302 SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users") 1303 SkipIfRemote("--cgroups=split cannot be used in remote mode") 1304 1305 checkLines := func(lines []string) { 1306 cgroup := "" 1307 for _, line := range lines { 1308 parts := strings.SplitN(line, ":", 3) 1309 if len(parts) < 2 { 1310 continue 1311 } 1312 if !CGROUPSV2 { 1313 // ignore unified on cgroup v1. 1314 // both runc and crun do not set it. 1315 // crun does not set named hierarchies. 1316 if parts[1] == "" || strings.Contains(parts[1], "name=") { 1317 continue 1318 } 1319 } 1320 if parts[2] == "/" { 1321 continue 1322 } 1323 if cgroup == "" { 1324 cgroup = parts[2] 1325 continue 1326 } 1327 Expect(cgroup).To(Equal(parts[2])) 1328 } 1329 } 1330 1331 container := podmanTest.PodmanSystemdScope([]string{"run", "--rm", "--cgroups=split", ALPINE, "cat", "/proc/self/cgroup"}) 1332 container.WaitWithDefaultTimeout() 1333 Expect(container).Should(Exit(0)) 1334 checkLines(container.OutputToStringArray()) 1335 1336 // check that --cgroups=split is honored also when a container runs in a pod 1337 container = podmanTest.PodmanSystemdScope([]string{"run", "--rm", "--pod", "new:split-test-pod", "--cgroups=split", ALPINE, "cat", "/proc/self/cgroup"}) 1338 container.WaitWithDefaultTimeout() 1339 Expect(container).Should(Exit(0)) 1340 checkLines(container.OutputToStringArray()) 1341 }) 1342 1343 It("podman run with cgroups=disabled runs without cgroups", func() { 1344 SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users") 1345 // Only works on crun 1346 if !strings.Contains(podmanTest.OCIRuntime, "crun") { 1347 Skip("Test only works on crun") 1348 } 1349 1350 ownsCgroup, err := cgroups.UserOwnsCurrentSystemdCgroup() 1351 Expect(err).ShouldNot(HaveOccurred()) 1352 if !ownsCgroup { 1353 // Podman moves itself to a new cgroup if it doesn't own the current cgroup 1354 Skip("Test only works when Podman owns the current cgroup") 1355 } 1356 1357 trim := func(i string) string { 1358 return strings.TrimSuffix(i, "\n") 1359 } 1360 1361 curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup") 1362 Expect(err).ShouldNot(HaveOccurred()) 1363 curCgroups := trim(string(curCgroupsBytes)) 1364 fmt.Printf("Output:\n%s\n", curCgroups) 1365 Expect(curCgroups).ToNot(Equal("")) 1366 1367 container := podmanTest.Podman([]string{"run", "--cgroupns=host", "--cgroups=disabled", ALPINE, "cat", "/proc/self/cgroup"}) 1368 container.WaitWithDefaultTimeout() 1369 Expect(container).Should(Exit(0)) 1370 1371 ctrCgroups := trim(container.OutputToString()) 1372 fmt.Printf("Output\n:%s\n", ctrCgroups) 1373 1374 Expect(ctrCgroups).To(Equal(curCgroups)) 1375 }) 1376 1377 It("podman run with cgroups=enabled makes cgroups", func() { 1378 SkipIfRootlessCgroupsV1("Enable cgroups not supported on cgroupv1 for rootless users") 1379 // Only works on crun 1380 if !strings.Contains(podmanTest.OCIRuntime, "crun") { 1381 Skip("Test only works on crun") 1382 } 1383 1384 curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup") 1385 Expect(err).To(BeNil()) 1386 var curCgroups string = string(curCgroupsBytes) 1387 fmt.Printf("Output:\n%s\n", curCgroups) 1388 Expect(curCgroups).To(Not(Equal(""))) 1389 1390 ctrName := "testctr" 1391 container := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--cgroups=enabled", ALPINE, "top"}) 1392 container.WaitWithDefaultTimeout() 1393 Expect(container).Should(Exit(0)) 1394 1395 // Get PID and get cgroups of that PID 1396 inspectOut := podmanTest.InspectContainer(ctrName) 1397 Expect(len(inspectOut)).To(Equal(1)) 1398 pid := inspectOut[0].State.Pid 1399 Expect(pid).To(Not(Equal(0))) 1400 1401 ctrCgroupsBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid)) 1402 Expect(err).To(BeNil()) 1403 var ctrCgroups string = string(ctrCgroupsBytes) 1404 fmt.Printf("Output\n:%s\n", ctrCgroups) 1405 Expect(curCgroups).To(Not(Equal(ctrCgroups))) 1406 }) 1407 1408 It("podman run with cgroups=garbage errors", func() { 1409 session := podmanTest.Podman([]string{"run", "-d", "--cgroups=garbage", ALPINE, "top"}) 1410 session.WaitWithDefaultTimeout() 1411 Expect(session).To(ExitWithError()) 1412 }) 1413 1414 It("podman run should fail with nonexistent authfile", func() { 1415 session := podmanTest.Podman([]string{"run", "--authfile", "/tmp/nonexistent", ALPINE, "ls"}) 1416 session.WaitWithDefaultTimeout() 1417 Expect(session).To(ExitWithError()) 1418 }) 1419 1420 It("podman run --device-cgroup-rule", func() { 1421 SkipIfRootless("rootless users are not allowed to mknod") 1422 deviceCgroupRule := "c 42:* rwm" 1423 session := podmanTest.Podman([]string{"run", "--cap-add", "mknod", "--name", "test", "-d", "--device-cgroup-rule", deviceCgroupRule, ALPINE, "top"}) 1424 session.WaitWithDefaultTimeout() 1425 Expect(session).Should(Exit(0)) 1426 session = podmanTest.Podman([]string{"exec", "test", "mknod", "newDev", "c", "42", "1"}) 1427 session.WaitWithDefaultTimeout() 1428 Expect(session).Should(Exit(0)) 1429 }) 1430 1431 It("podman run --replace", func() { 1432 // Make sure we error out with --name. 1433 session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"}) 1434 session.WaitWithDefaultTimeout() 1435 Expect(session).Should(Exit(125)) 1436 1437 // Run and replace 5 times in a row the "same" container. 1438 ctrName := "testCtr" 1439 for i := 0; i < 5; i++ { 1440 session := podmanTest.Podman([]string{"run", "--detach", "--replace", "--name", ctrName, ALPINE, "/bin/sh"}) 1441 session.WaitWithDefaultTimeout() 1442 Expect(session).Should(Exit(0)) 1443 } 1444 }) 1445 1446 It("podman run --preserve-fds", func() { 1447 devNull, err := os.Open("/dev/null") 1448 Expect(err).To(BeNil()) 1449 defer devNull.Close() 1450 files := []*os.File{ 1451 devNull, 1452 } 1453 session := podmanTest.PodmanExtraFiles([]string{"run", "--preserve-fds", "1", ALPINE, "ls"}, files) 1454 session.WaitWithDefaultTimeout() 1455 Expect(session).Should(Exit(0)) 1456 }) 1457 1458 It("podman run --preserve-fds invalid fd", func() { 1459 session := podmanTest.Podman([]string{"run", "--preserve-fds", "2", ALPINE}) 1460 session.WaitWithDefaultTimeout() 1461 Expect(session).To(ExitWithError()) 1462 Expect(session.ErrorToString()).To(ContainSubstring("file descriptor 3 is not available")) 1463 }) 1464 1465 It("podman run --privileged and --group-add", func() { 1466 groupName := "mail" 1467 session := podmanTest.Podman([]string{"run", "-t", "-i", "--group-add", groupName, "--privileged", fedoraMinimal, "groups"}) 1468 session.WaitWithDefaultTimeout() 1469 Expect(session).Should(Exit(0)) 1470 Expect(strings.Contains(session.OutputToString(), groupName)).To(BeTrue()) 1471 }) 1472 1473 It("podman run --tz", func() { 1474 testDir := filepath.Join(podmanTest.RunRoot, "tz-test") 1475 err := os.MkdirAll(testDir, 0755) 1476 Expect(err).To(BeNil()) 1477 1478 tzFile := filepath.Join(testDir, "tzfile.txt") 1479 file, err := os.Create(tzFile) 1480 Expect(err).To(BeNil()) 1481 1482 _, err = file.WriteString("Hello") 1483 Expect(err).To(BeNil()) 1484 file.Close() 1485 1486 badTZFile := fmt.Sprintf("../../../%s", tzFile) 1487 session := podmanTest.Podman([]string{"run", "--tz", badTZFile, "--rm", ALPINE, "date"}) 1488 session.WaitWithDefaultTimeout() 1489 Expect(session).To(ExitWithError()) 1490 Expect(session.ErrorToString()).To(ContainSubstring("error finding timezone for container")) 1491 1492 err = os.Remove(tzFile) 1493 Expect(err).To(BeNil()) 1494 1495 session = podmanTest.Podman([]string{"run", "--tz", "foo", "--rm", ALPINE, "date"}) 1496 session.WaitWithDefaultTimeout() 1497 Expect(session).To(ExitWithError()) 1498 1499 session = podmanTest.Podman([]string{"run", "--tz", "America", "--rm", ALPINE, "date"}) 1500 session.WaitWithDefaultTimeout() 1501 Expect(session).To(ExitWithError()) 1502 1503 session = podmanTest.Podman([]string{"run", "--tz", "Pacific/Honolulu", "--rm", ALPINE, "date", "+'%H %Z'"}) 1504 session.WaitWithDefaultTimeout() 1505 Expect(session).Should(Exit(0)) 1506 Expect(session.OutputToString()).To(ContainSubstring("HST")) 1507 1508 session = podmanTest.Podman([]string{"run", "--tz", "local", "--rm", ALPINE, "date", "+'%H %Z'"}) 1509 session.WaitWithDefaultTimeout() 1510 Expect(session).Should(Exit(0)) 1511 t := time.Now() 1512 z, _ := t.Zone() 1513 h := strconv.Itoa(t.Hour()) 1514 Expect(session.OutputToString()).To(ContainSubstring(z)) 1515 Expect(session.OutputToString()).To(ContainSubstring(h)) 1516 1517 }) 1518 1519 It("podman run verify pids-limit", func() { 1520 SkipIfCgroupV1("pids-limit not supported on cgroup V1") 1521 limit := "4321" 1522 session := podmanTest.Podman([]string{"run", "--pids-limit", limit, "--net=none", "--rm", ALPINE, "cat", "/sys/fs/cgroup/pids.max"}) 1523 session.WaitWithDefaultTimeout() 1524 Expect(session).Should(Exit(0)) 1525 Expect(session.OutputToString()).To(ContainSubstring(limit)) 1526 }) 1527 1528 It("podman run umask", func() { 1529 if !strings.Contains(podmanTest.OCIRuntime, "crun") { 1530 Skip("Test only works on crun") 1531 } 1532 1533 session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"}) 1534 session.WaitWithDefaultTimeout() 1535 Expect(session).Should(Exit(0)) 1536 Expect(session.OutputToString()).To(Equal("0022")) 1537 1538 session = podmanTest.Podman([]string{"run", "--umask", "0002", "--rm", ALPINE, "sh", "-c", "umask"}) 1539 session.WaitWithDefaultTimeout() 1540 Expect(session).Should(Exit(0)) 1541 Expect(session.OutputToString()).To(Equal("0002")) 1542 1543 session = podmanTest.Podman([]string{"run", "--umask", "0077", "--rm", fedoraMinimal, "umask"}) 1544 session.WaitWithDefaultTimeout() 1545 Expect(session).Should(Exit(0)) 1546 Expect(session.OutputToString()).To(Equal("0077")) 1547 1548 session = podmanTest.Podman([]string{"run", "--umask", "22", "--rm", ALPINE, "sh", "-c", "umask"}) 1549 session.WaitWithDefaultTimeout() 1550 Expect(session).Should(Exit(0)) 1551 Expect(session.OutputToString()).To(Equal("0022")) 1552 1553 session = podmanTest.Podman([]string{"run", "--umask", "9999", "--rm", ALPINE, "sh", "-c", "umask"}) 1554 session.WaitWithDefaultTimeout() 1555 Expect(session).To(ExitWithError()) 1556 Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask")) 1557 }) 1558 1559 It("podman run makes workdir from image", func() { 1560 // BuildImage does not seem to work remote 1561 dockerfile := fmt.Sprintf(`FROM %s 1562 WORKDIR /madethis`, BB) 1563 podmanTest.BuildImage(dockerfile, "test", "false") 1564 session := podmanTest.Podman([]string{"run", "--rm", "test", "pwd"}) 1565 session.WaitWithDefaultTimeout() 1566 Expect(session).Should(Exit(0)) 1567 Expect(session.OutputToString()).To(ContainSubstring("/madethis")) 1568 }) 1569 1570 It("podman run --entrypoint does not use image command", func() { 1571 session := podmanTest.Podman([]string{"run", "--entrypoint", "/bin/echo", ALPINE}) 1572 session.WaitWithDefaultTimeout() 1573 Expect(session).Should(Exit(0)) 1574 // We can't guarantee the output is completely empty, some 1575 // nonprintables seem to work their way in. 1576 Expect(session.OutputToString()).To(Not(ContainSubstring("/bin/sh"))) 1577 }) 1578 1579 It("podman run a container with log-level (lower case)", func() { 1580 session := podmanTest.Podman([]string{"--log-level=info", "run", ALPINE, "ls"}) 1581 session.WaitWithDefaultTimeout() 1582 Expect(session).Should(Exit(0)) 1583 }) 1584 1585 It("podman run a container with log-level (upper case)", func() { 1586 session := podmanTest.Podman([]string{"--log-level=INFO", "run", ALPINE, "ls"}) 1587 session.WaitWithDefaultTimeout() 1588 Expect(session).Should(Exit(0)) 1589 }) 1590 1591 It("podman run a container with --pull never should fail if no local store", func() { 1592 session := podmanTest.Podman([]string{"run", "--pull", "never", "docker.io/library/debian:latest", "ls"}) 1593 session.WaitWithDefaultTimeout() 1594 Expect(session).Should(Exit(125)) 1595 }) 1596 1597 It("podman run container with --pull missing and only pull once", func() { 1598 session := podmanTest.Podman([]string{"run", "--pull", "missing", cirros, "ls"}) 1599 session.WaitWithDefaultTimeout() 1600 Expect(session).Should(Exit(0)) 1601 Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull")) 1602 1603 session = podmanTest.Podman([]string{"run", "--pull", "missing", cirros, "ls"}) 1604 session.WaitWithDefaultTimeout() 1605 Expect(session).Should(Exit(0)) 1606 Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull")) 1607 }) 1608 1609 It("podman run container with --pull missing should pull image multiple times", func() { 1610 session := podmanTest.Podman([]string{"run", "--pull", "always", cirros, "ls"}) 1611 session.WaitWithDefaultTimeout() 1612 Expect(session).Should(Exit(0)) 1613 Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull")) 1614 1615 session = podmanTest.Podman([]string{"run", "--pull", "always", cirros, "ls"}) 1616 session.WaitWithDefaultTimeout() 1617 Expect(session).Should(Exit(0)) 1618 Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull")) 1619 }) 1620 1621 It("podman run container with hostname and hostname environment variable", func() { 1622 hostnameEnv := "test123" 1623 session := podmanTest.Podman([]string{"run", "--hostname", "testctr", "--env", fmt.Sprintf("HOSTNAME=%s", hostnameEnv), ALPINE, "printenv", "HOSTNAME"}) 1624 session.WaitWithDefaultTimeout() 1625 Expect(session).Should(Exit(0)) 1626 Expect(session.OutputToString()).To(ContainSubstring(hostnameEnv)) 1627 }) 1628 1629 It("podman run --secret", func() { 1630 secretsString := "somesecretdata" 1631 secretFilePath := filepath.Join(podmanTest.TempDir, "secret") 1632 err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) 1633 Expect(err).To(BeNil()) 1634 1635 session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) 1636 session.WaitWithDefaultTimeout() 1637 Expect(session).Should(Exit(0)) 1638 1639 session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"}) 1640 session.WaitWithDefaultTimeout() 1641 Expect(session).Should(Exit(0)) 1642 Expect(session.OutputToString()).To(Equal(secretsString)) 1643 1644 session = podmanTest.Podman([]string{"inspect", "secr", "--format", " {{(index .Config.Secrets 0).Name}}"}) 1645 session.WaitWithDefaultTimeout() 1646 Expect(session).Should(Exit(0)) 1647 Expect(session.OutputToString()).To(ContainSubstring("mysecret")) 1648 1649 }) 1650 1651 It("podman run --secret source=mysecret,type=mount", func() { 1652 secretsString := "somesecretdata" 1653 secretFilePath := filepath.Join(podmanTest.TempDir, "secret") 1654 err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) 1655 Expect(err).To(BeNil()) 1656 1657 session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) 1658 session.WaitWithDefaultTimeout() 1659 Expect(session).Should(Exit(0)) 1660 1661 session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"}) 1662 session.WaitWithDefaultTimeout() 1663 Expect(session).Should(Exit(0)) 1664 Expect(session.OutputToString()).To(Equal(secretsString)) 1665 1666 session = podmanTest.Podman([]string{"inspect", "secr", "--format", " {{(index .Config.Secrets 0).Name}}"}) 1667 session.WaitWithDefaultTimeout() 1668 Expect(session).Should(Exit(0)) 1669 Expect(session.OutputToString()).To(ContainSubstring("mysecret")) 1670 1671 }) 1672 1673 It("podman run --secret source=mysecret,type=mount with target", func() { 1674 secretsString := "somesecretdata" 1675 secretFilePath := filepath.Join(podmanTest.TempDir, "secret") 1676 err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) 1677 Expect(err).To(BeNil()) 1678 1679 session := podmanTest.Podman([]string{"secret", "create", "mysecret_target", secretFilePath}) 1680 session.WaitWithDefaultTimeout() 1681 Expect(session).Should(Exit(0)) 1682 1683 session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret_target,type=mount,target=hello", "--name", "secr_target", ALPINE, "cat", "/run/secrets/hello"}) 1684 session.WaitWithDefaultTimeout() 1685 Expect(session).Should(Exit(0)) 1686 Expect(session.OutputToString()).To(Equal(secretsString)) 1687 1688 session = podmanTest.Podman([]string{"inspect", "secr_target", "--format", " {{(index .Config.Secrets 0).Name}}"}) 1689 session.WaitWithDefaultTimeout() 1690 Expect(session).Should(Exit(0)) 1691 Expect(session.OutputToString()).To(ContainSubstring("mysecret_target")) 1692 1693 }) 1694 1695 It("podman run --secret source=mysecret,type=mount with target at /tmp", func() { 1696 secretsString := "somesecretdata" 1697 secretFilePath := filepath.Join(podmanTest.TempDir, "secret") 1698 err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) 1699 Expect(err).To(BeNil()) 1700 1701 session := podmanTest.Podman([]string{"secret", "create", "mysecret_target2", secretFilePath}) 1702 session.WaitWithDefaultTimeout() 1703 Expect(session).Should(Exit(0)) 1704 1705 session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret_target2,type=mount,target=/tmp/hello", "--name", "secr_target2", ALPINE, "cat", "/tmp/hello"}) 1706 session.WaitWithDefaultTimeout() 1707 Expect(session).Should(Exit(0)) 1708 Expect(session.OutputToString()).To(Equal(secretsString)) 1709 1710 session = podmanTest.Podman([]string{"inspect", "secr_target2", "--format", " {{(index .Config.Secrets 0).Name}}"}) 1711 session.WaitWithDefaultTimeout() 1712 Expect(session).Should(Exit(0)) 1713 Expect(session.OutputToString()).To(ContainSubstring("mysecret_target2")) 1714 1715 }) 1716 1717 It("podman run --secret source=mysecret,type=env", func() { 1718 secretsString := "somesecretdata" 1719 secretFilePath := filepath.Join(podmanTest.TempDir, "secret") 1720 err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) 1721 Expect(err).To(BeNil()) 1722 1723 session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) 1724 session.WaitWithDefaultTimeout() 1725 Expect(session).Should(Exit(0)) 1726 1727 session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env", "--name", "secr", ALPINE, "printenv", "mysecret"}) 1728 session.WaitWithDefaultTimeout() 1729 Expect(session).Should(Exit(0)) 1730 Expect(session.OutputToString()).To(Equal(secretsString)) 1731 }) 1732 1733 It("podman run --secret target option", func() { 1734 secretsString := "somesecretdata" 1735 secretFilePath := filepath.Join(podmanTest.TempDir, "secret") 1736 err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) 1737 Expect(err).To(BeNil()) 1738 1739 session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) 1740 session.WaitWithDefaultTimeout() 1741 Expect(session).Should(Exit(0)) 1742 1743 session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env,target=anotherplace", "--name", "secr", ALPINE, "printenv", "anotherplace"}) 1744 session.WaitWithDefaultTimeout() 1745 Expect(session).Should(Exit(0)) 1746 Expect(session.OutputToString()).To(Equal(secretsString)) 1747 }) 1748 1749 It("podman run --secret mount with uid, gid, mode options", func() { 1750 secretsString := "somesecretdata" 1751 secretFilePath := filepath.Join(podmanTest.TempDir, "secret") 1752 err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) 1753 Expect(err).To(BeNil()) 1754 1755 session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) 1756 session.WaitWithDefaultTimeout() 1757 Expect(session).Should(Exit(0)) 1758 1759 // check default permissions 1760 session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "secr", ALPINE, "ls", "-l", "/run/secrets/mysecret"}) 1761 session.WaitWithDefaultTimeout() 1762 Expect(session).Should(Exit(0)) 1763 output := session.OutputToString() 1764 Expect(output).To(ContainSubstring("-r--r--r--")) 1765 Expect(output).To(ContainSubstring("root")) 1766 1767 session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount,uid=1000,gid=1001,mode=777", "--name", "secr2", ALPINE, "ls", "-ln", "/run/secrets/mysecret"}) 1768 session.WaitWithDefaultTimeout() 1769 Expect(session).Should(Exit(0)) 1770 output = session.OutputToString() 1771 Expect(output).To(ContainSubstring("-rwxrwxrwx")) 1772 Expect(output).To(ContainSubstring("1000")) 1773 Expect(output).To(ContainSubstring("1001")) 1774 }) 1775 1776 It("podman run --secret with --user", func() { 1777 secretsString := "somesecretdata" 1778 secretFilePath := filepath.Join(podmanTest.TempDir, "secret") 1779 err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) 1780 Expect(err).To(BeNil()) 1781 1782 session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) 1783 session.WaitWithDefaultTimeout() 1784 Expect(session).Should(Exit(0)) 1785 1786 session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "nonroot", "--user", "200:200", ALPINE, "cat", "/run/secrets/mysecret"}) 1787 session.WaitWithDefaultTimeout() 1788 Expect(session).Should(Exit(0)) 1789 Expect(session.OutputToString()).To(Equal(secretsString)) 1790 }) 1791 1792 It("podman run invalid secret option", func() { 1793 secretsString := "somesecretdata" 1794 secretFilePath := filepath.Join(podmanTest.TempDir, "secret") 1795 err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755) 1796 Expect(err).To(BeNil()) 1797 1798 session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) 1799 session.WaitWithDefaultTimeout() 1800 Expect(session).Should(Exit(0)) 1801 1802 // Invalid type 1803 session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=other", "--name", "secr", ALPINE, "printenv", "mysecret"}) 1804 session.WaitWithDefaultTimeout() 1805 Expect(session).To(ExitWithError()) 1806 1807 // Invalid option 1808 session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,invalid=invalid", "--name", "secr", ALPINE, "printenv", "mysecret"}) 1809 session.WaitWithDefaultTimeout() 1810 Expect(session).To(ExitWithError()) 1811 1812 // Option syntax not valid 1813 session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type", "--name", "secr", ALPINE, "printenv", "mysecret"}) 1814 session.WaitWithDefaultTimeout() 1815 Expect(session).To(ExitWithError()) 1816 1817 // mount option with env type 1818 session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env,uid=1000", "--name", "secr", ALPINE, "printenv", "mysecret"}) 1819 session.WaitWithDefaultTimeout() 1820 Expect(session).To(ExitWithError()) 1821 1822 // No source given 1823 session = podmanTest.Podman([]string{"run", "--secret", "type=env", "--name", "secr", ALPINE, "printenv", "mysecret"}) 1824 session.WaitWithDefaultTimeout() 1825 Expect(session).To(ExitWithError()) 1826 }) 1827 1828 It("podman run --requires", func() { 1829 depName := "ctr1" 1830 depContainer := podmanTest.Podman([]string{"create", "--name", depName, ALPINE, "top"}) 1831 depContainer.WaitWithDefaultTimeout() 1832 Expect(depContainer).Should(Exit(0)) 1833 1834 mainName := "ctr2" 1835 mainContainer := podmanTest.Podman([]string{"run", "--name", mainName, "--requires", depName, "-d", ALPINE, "top"}) 1836 mainContainer.WaitWithDefaultTimeout() 1837 Expect(mainContainer).Should(Exit(0)) 1838 1839 stop := podmanTest.Podman([]string{"stop", "--all"}) 1840 stop.WaitWithDefaultTimeout() 1841 Expect(stop).Should(Exit(0)) 1842 1843 start := podmanTest.Podman([]string{"start", mainName}) 1844 start.WaitWithDefaultTimeout() 1845 Expect(start).Should(Exit(0)) 1846 1847 running := podmanTest.Podman([]string{"ps", "-q"}) 1848 running.WaitWithDefaultTimeout() 1849 Expect(running).Should(Exit(0)) 1850 Expect(len(running.OutputToStringArray())).To(Equal(2)) 1851 }) 1852 1853 It("podman run with pidfile", func() { 1854 SkipIfRemote("pidfile not handled by remote") 1855 pidfile := tempdir + "pidfile" 1856 session := podmanTest.Podman([]string{"run", "--pidfile", pidfile, ALPINE, "ls"}) 1857 session.WaitWithDefaultTimeout() 1858 Expect(session).Should(Exit(0)) 1859 readFirstLine := func(path string) string { 1860 content, err := ioutil.ReadFile(path) 1861 Expect(err).To(BeNil()) 1862 return strings.Split(string(content), "\n")[0] 1863 } 1864 containerPID := readFirstLine(pidfile) 1865 _, err = strconv.Atoi(containerPID) // Make sure it's a proper integer 1866 Expect(err).To(BeNil()) 1867 }) 1868 1869 It("podman run check personality support", func() { 1870 // TODO: Remove this as soon as this is merged and made available in our CI https://github.com/opencontainers/runc/pull/3126. 1871 if !strings.Contains(podmanTest.OCIRuntime, "crun") { 1872 Skip("Test only works on crun") 1873 } 1874 session := podmanTest.Podman([]string{"run", "--personality=LINUX32", "--name=testpersonality", ALPINE, "uname", "-a"}) 1875 session.WaitWithDefaultTimeout() 1876 Expect(session).Should(Exit(0)) 1877 Expect(session.OutputToString()).To(ContainSubstring("i686")) 1878 }) 1879 })