github.com/containers/podman/v5@v5.1.0-rc1/test/e2e/exec_test.go (about) 1 package integration 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 . "github.com/containers/podman/v5/test/utils" 10 . "github.com/onsi/ginkgo/v2" 11 . "github.com/onsi/gomega" 12 . "github.com/onsi/gomega/gexec" 13 ) 14 15 var _ = Describe("Podman exec", func() { 16 17 It("podman exec into bogus container", func() { 18 session := podmanTest.Podman([]string{"exec", "foobar", "ls"}) 19 session.WaitWithDefaultTimeout() 20 Expect(session).Should(ExitWithError(125, `no container with name or ID "foobar" found: no such container`)) 21 }) 22 23 It("podman exec simple command", func() { 24 setup := podmanTest.RunTopContainer("test1") 25 setup.WaitWithDefaultTimeout() 26 Expect(setup).Should(ExitCleanly()) 27 28 session := podmanTest.Podman([]string{"exec", "test1", "ls"}) 29 session.WaitWithDefaultTimeout() 30 Expect(session).Should(ExitCleanly()) 31 32 // With no command 33 session = podmanTest.Podman([]string{"exec", "test1"}) 34 session.WaitWithDefaultTimeout() 35 Expect(session).Should(ExitWithError(125, "must provide a non-empty command to start an exec session: invalid argument")) 36 }) 37 38 It("podman container exec simple command", func() { 39 setup := podmanTest.RunTopContainer("test1") 40 setup.WaitWithDefaultTimeout() 41 Expect(setup).Should(ExitCleanly()) 42 43 session := podmanTest.Podman([]string{"container", "exec", "test1", "ls"}) 44 session.WaitWithDefaultTimeout() 45 Expect(session).Should(ExitCleanly()) 46 }) 47 48 It("podman exec simple command using latest", func() { 49 setup := podmanTest.RunTopContainer("test1") 50 setup.WaitWithDefaultTimeout() 51 Expect(setup).Should(ExitCleanly()) 52 cid := "-l" 53 if IsRemote() { 54 cid = "test1" 55 } 56 session := podmanTest.Podman([]string{"exec", cid, "ls"}) 57 session.WaitWithDefaultTimeout() 58 Expect(session).Should(ExitCleanly()) 59 }) 60 61 It("podman exec environment test", func() { 62 setup := podmanTest.RunTopContainer("test1") 63 setup.WaitWithDefaultTimeout() 64 Expect(setup).Should(ExitCleanly()) 65 66 session := podmanTest.Podman([]string{"exec", "--env", "FOO=BAR", "test1", "printenv", "FOO"}) 67 session.WaitWithDefaultTimeout() 68 Expect(session).Should(ExitCleanly()) 69 Expect(session.OutputToString()).To(Equal("BAR")) 70 71 session = podmanTest.Podman([]string{"exec", "--env", "PATH=/bin", "test1", "printenv", "PATH"}) 72 session.WaitWithDefaultTimeout() 73 Expect(session).Should(ExitCleanly()) 74 Expect(session.OutputToString()).To(Equal("/bin")) 75 }) 76 77 It("podman exec os.Setenv env", func() { 78 // remote doesn't properly interpret os.Setenv 79 setup := podmanTest.RunTopContainer("test1") 80 setup.WaitWithDefaultTimeout() 81 Expect(setup).Should(ExitCleanly()) 82 83 os.Setenv("FOO", "BAR") 84 session := podmanTest.Podman([]string{"exec", "--env", "FOO", "test1", "printenv", "FOO"}) 85 session.WaitWithDefaultTimeout() 86 Expect(session).Should(ExitCleanly()) 87 Expect(session.OutputToString()).To(Equal("BAR")) 88 os.Unsetenv("FOO") 89 }) 90 91 It("podman exec exit code", func() { 92 setup := podmanTest.RunTopContainer("test1") 93 setup.WaitWithDefaultTimeout() 94 Expect(setup).Should(ExitCleanly()) 95 96 session := podmanTest.Podman([]string{"exec", "test1", "sh", "-c", "exit 100"}) 97 session.WaitWithDefaultTimeout() 98 Expect(session).Should(Exit(100)) 99 }) 100 101 It("podman exec in keep-id container drops privileges", func() { 102 SkipIfNotRootless("This function is not enabled for rootful podman") 103 ctrName := "testctr1" 104 testCtr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--userns=keep-id", ALPINE, "top"}) 105 testCtr.WaitWithDefaultTimeout() 106 Expect(testCtr).Should(ExitCleanly()) 107 108 session := podmanTest.Podman([]string{"exec", ctrName, "grep", "CapEff", "/proc/self/status"}) 109 session.WaitWithDefaultTimeout() 110 Expect(session).Should(ExitCleanly()) 111 Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) 112 }) 113 114 It("podman exec --privileged", func() { 115 session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 116 session.WaitWithDefaultTimeout() 117 Expect(session).Should(ExitCleanly()) 118 bndPerms := session.OutputToString() 119 120 session = podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 121 session.WaitWithDefaultTimeout() 122 Expect(session).Should(ExitCleanly()) 123 effPerms := session.OutputToString() 124 125 setup := podmanTest.RunTopContainer("test-privileged") 126 setup.WaitWithDefaultTimeout() 127 Expect(setup).Should(ExitCleanly()) 128 129 session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 130 session.WaitWithDefaultTimeout() 131 Expect(session).Should(ExitCleanly()) 132 Expect(session.OutputToString()).To(ContainSubstring(effPerms)) 133 134 session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 135 session.WaitWithDefaultTimeout() 136 Expect(session).Should(ExitCleanly()) 137 Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) 138 }) 139 140 It("podman exec --privileged", func() { 141 session := podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 142 session.WaitWithDefaultTimeout() 143 Expect(session).Should(ExitCleanly()) 144 bndPerms := session.OutputToString() 145 146 session = podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 147 session.WaitWithDefaultTimeout() 148 Expect(session).Should(ExitCleanly()) 149 effPerms := session.OutputToString() 150 151 setup := podmanTest.RunTopContainer("test-privileged") 152 setup.WaitWithDefaultTimeout() 153 Expect(setup).Should(ExitCleanly()) 154 155 session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 156 session.WaitWithDefaultTimeout() 157 Expect(session).Should(ExitCleanly()) 158 Expect(session.OutputToString()).To(ContainSubstring(effPerms)) 159 160 session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 161 session.WaitWithDefaultTimeout() 162 Expect(session).Should(ExitCleanly()) 163 Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) 164 165 }) 166 167 It("podman exec --privileged", func() { 168 session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 169 session.WaitWithDefaultTimeout() 170 Expect(session).Should(ExitCleanly()) 171 bndPerms := session.OutputToString() 172 173 setup := podmanTest.RunTopContainer("test-privileged") 174 setup.WaitWithDefaultTimeout() 175 Expect(setup).Should(ExitCleanly()) 176 177 session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 178 session.WaitWithDefaultTimeout() 179 Expect(session).Should(ExitCleanly()) 180 Expect(session.OutputToString()).To(ContainSubstring("00000000")) 181 182 session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 183 session.WaitWithDefaultTimeout() 184 Expect(session).Should(ExitCleanly()) 185 Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) 186 }) 187 188 It("podman exec --privileged container not running as root", func() { 189 session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 190 session.WaitWithDefaultTimeout() 191 Expect(session).Should(ExitCleanly()) 192 bndPerms := session.OutputToString() 193 194 setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin"}) 195 setup.WaitWithDefaultTimeout() 196 Expect(setup).Should(ExitCleanly()) 197 198 session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 199 session.WaitWithDefaultTimeout() 200 Expect(session).Should(ExitCleanly()) 201 Expect(session.OutputToString()).To(ContainSubstring("00000000")) 202 203 session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 204 session.WaitWithDefaultTimeout() 205 Expect(session).Should(ExitCleanly()) 206 Expect(session.OutputToString()).To(ContainSubstring("00000000")) 207 208 session = podmanTest.Podman([]string{"exec", "--privileged", "--user=root", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 209 session.WaitWithDefaultTimeout() 210 Expect(session).Should(ExitCleanly()) 211 Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) 212 213 session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 214 session.WaitWithDefaultTimeout() 215 Expect(session).Should(ExitCleanly()) 216 Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) 217 }) 218 219 It("podman exec with user with cap-add", func() { 220 capAdd := "--cap-add=net_bind_service" 221 session := podmanTest.Podman([]string{"run", "--user=bin", capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 222 session.WaitWithDefaultTimeout() 223 Expect(session).Should(ExitCleanly()) 224 bndPerms := session.OutputToString() 225 226 session = podmanTest.Podman([]string{"run", "--user=bin", capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 227 session.WaitWithDefaultTimeout() 228 Expect(session).Should(ExitCleanly()) 229 effPerms := session.OutputToString() 230 231 setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin", capAdd}) 232 setup.WaitWithDefaultTimeout() 233 Expect(setup).Should(ExitCleanly()) 234 235 session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 236 session.WaitWithDefaultTimeout() 237 Expect(session).Should(ExitCleanly()) 238 Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) 239 240 session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 241 session.WaitWithDefaultTimeout() 242 Expect(session).Should(ExitCleanly()) 243 Expect(session.OutputToString()).To(ContainSubstring(effPerms)) 244 }) 245 246 It("podman exec with user with and cap-drop cap-add", func() { 247 capAdd := "--cap-add=net_bind_service" 248 capDrop := "--cap-drop=all" 249 session := podmanTest.Podman([]string{"run", "--user=bin", capDrop, capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 250 session.WaitWithDefaultTimeout() 251 Expect(session).Should(ExitCleanly()) 252 bndPerms := session.OutputToString() 253 254 session = podmanTest.Podman([]string{"run", "--user=bin", capDrop, capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 255 session.WaitWithDefaultTimeout() 256 Expect(session).Should(ExitCleanly()) 257 effPerms := session.OutputToString() 258 259 setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin", capDrop, capAdd}) 260 setup.WaitWithDefaultTimeout() 261 Expect(setup).Should(ExitCleanly()) 262 263 session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 264 session.WaitWithDefaultTimeout() 265 Expect(session).Should(ExitCleanly()) 266 Expect(session.OutputToString()).To(ContainSubstring(bndPerms)) 267 268 session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapInh /proc/self/status | cut -f 2"}) 269 session.WaitWithDefaultTimeout() 270 Expect(session).Should(ExitCleanly()) 271 Expect(session.OutputToString()).To(ContainSubstring(effPerms)) 272 273 session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 274 session.WaitWithDefaultTimeout() 275 Expect(session).Should(ExitCleanly()) 276 Expect(session.OutputToString()).To(ContainSubstring(effPerms)) 277 278 session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapPrm /proc/self/status | cut -f 2"}) 279 session.WaitWithDefaultTimeout() 280 Expect(session).Should(ExitCleanly()) 281 Expect(session.OutputToString()).To(ContainSubstring(effPerms)) 282 283 session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapAmb /proc/self/status | cut -f 2"}) 284 session.WaitWithDefaultTimeout() 285 Expect(session).Should(ExitCleanly()) 286 Expect(session.OutputToString()).To(ContainSubstring(effPerms)) 287 }) 288 289 It("podman exec --privileged with user", func() { 290 session := podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 291 session.WaitWithDefaultTimeout() 292 Expect(session).Should(ExitCleanly()) 293 bindPerms := session.OutputToString() 294 295 setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--privileged", "--user=bin"}) 296 setup.WaitWithDefaultTimeout() 297 Expect(setup).Should(ExitCleanly()) 298 299 session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"}) 300 session.WaitWithDefaultTimeout() 301 Expect(session).Should(ExitCleanly()) 302 Expect(session.OutputToString()).To(ContainSubstring(bindPerms)) 303 304 session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"}) 305 session.WaitWithDefaultTimeout() 306 Expect(session).Should(ExitCleanly()) 307 Expect(session.OutputToString()).To(ContainSubstring("0000000000000000")) 308 }) 309 310 // #10927 ("no logs from conmon"), one of our nastiest flakes 311 It("podman exec terminal doesn't hang", FlakeAttempts(3), func() { 312 setup := podmanTest.Podman([]string{"run", "-dti", "--name", "test1", fedoraMinimal, "sleep", "+Inf"}) 313 setup.WaitWithDefaultTimeout() 314 Expect(setup).Should(Exit(0)) 315 Expect(setup.ErrorToString()).To(ContainSubstring("The input device is not a TTY. The --tty and --interactive flags might not work properly")) 316 317 for i := 0; i < 5; i++ { 318 session := podmanTest.Podman([]string{"exec", "-ti", "test1", "true"}) 319 session.WaitWithDefaultTimeout() 320 Expect(session).Should(ExitCleanly()) 321 } 322 }) 323 324 It("podman exec pseudo-terminal sanity check", func() { 325 setup := podmanTest.Podman([]string{"run", "--detach", "--name", "test1", fedoraMinimal, "sleep", "+Inf"}) 326 setup.WaitWithDefaultTimeout() 327 Expect(setup).Should(ExitCleanly()) 328 329 session := podmanTest.Podman([]string{"exec", "--interactive", "--tty", "test1", "/usr/bin/stty", "--all"}) 330 session.WaitWithDefaultTimeout() 331 Expect(session).Should(ExitCleanly()) 332 Expect(session.OutputToString()).To(ContainSubstring(" onlcr")) 333 }) 334 335 It("podman exec simple command with user", func() { 336 setup := podmanTest.RunTopContainer("test1") 337 setup.WaitWithDefaultTimeout() 338 Expect(setup).Should(ExitCleanly()) 339 340 session := podmanTest.Podman([]string{"exec", "--user", "root", "test1", "ls"}) 341 session.WaitWithDefaultTimeout() 342 Expect(session).Should(ExitCleanly()) 343 }) 344 345 It("podman exec with user only in container", func() { 346 testUser := "test123" 347 setup := podmanTest.Podman([]string{"run", "--name", "test1", "-d", CITEST_IMAGE, "sleep", "60"}) 348 setup.WaitWithDefaultTimeout() 349 Expect(setup).Should(ExitCleanly()) 350 351 session := podmanTest.Podman([]string{"exec", "test1", "adduser", "-D", testUser}) 352 session.WaitWithDefaultTimeout() 353 Expect(session).Should(ExitCleanly()) 354 355 session2 := podmanTest.Podman([]string{"exec", "--user", testUser, "test1", "whoami"}) 356 session2.WaitWithDefaultTimeout() 357 Expect(session2).Should(ExitCleanly()) 358 Expect(session2.OutputToString()).To(Equal(testUser)) 359 }) 360 361 It("podman exec with user from run", func() { 362 testUser := "guest" 363 setup := podmanTest.Podman([]string{"run", "--user", testUser, "-d", ALPINE, "top"}) 364 setup.WaitWithDefaultTimeout() 365 Expect(setup).Should(ExitCleanly()) 366 ctrID := setup.OutputToString() 367 368 session := podmanTest.Podman([]string{"exec", ctrID, "whoami"}) 369 session.WaitWithDefaultTimeout() 370 Expect(session).Should(ExitCleanly()) 371 Expect(session.OutputToString()).To(ContainSubstring(testUser)) 372 373 overrideUser := "root" 374 session = podmanTest.Podman([]string{"exec", "--user", overrideUser, ctrID, "whoami"}) 375 session.WaitWithDefaultTimeout() 376 Expect(session).Should(ExitCleanly()) 377 Expect(session.OutputToString()).To(ContainSubstring(overrideUser)) 378 }) 379 380 It("podman exec simple working directory test", func() { 381 setup := podmanTest.RunTopContainer("test1") 382 setup.WaitWithDefaultTimeout() 383 Expect(setup).Should(ExitCleanly()) 384 385 session := podmanTest.Podman([]string{"exec", "--workdir", "/tmp", "test1", "pwd"}) 386 session.WaitWithDefaultTimeout() 387 Expect(session).Should(ExitCleanly()) 388 Expect(session.OutputToString()).To(Equal("/tmp")) 389 390 session = podmanTest.Podman([]string{"exec", "-w", "/tmp", "test1", "pwd"}) 391 session.WaitWithDefaultTimeout() 392 Expect(session).Should(ExitCleanly()) 393 Expect(session.OutputToString()).To(Equal("/tmp")) 394 }) 395 396 It("podman exec missing working directory test", func() { 397 setup := podmanTest.RunTopContainer("test1") 398 setup.WaitWithDefaultTimeout() 399 Expect(setup).Should(ExitCleanly()) 400 401 expect := "chdir to `/missing`: No such file or directory" 402 if podmanTest.OCIRuntime == "runc" { 403 expect = "chdir to cwd" 404 } 405 session := podmanTest.Podman([]string{"exec", "--workdir", "/missing", "test1", "pwd"}) 406 session.WaitWithDefaultTimeout() 407 Expect(session).To(ExitWithError(127, expect)) 408 409 session = podmanTest.Podman([]string{"exec", "-w", "/missing", "test1", "pwd"}) 410 session.WaitWithDefaultTimeout() 411 Expect(session).To(ExitWithError(127, expect)) 412 }) 413 414 It("podman exec cannot be invoked", func() { 415 setup := podmanTest.RunTopContainer("test1") 416 setup.WaitWithDefaultTimeout() 417 Expect(setup).Should(ExitCleanly()) 418 419 session := podmanTest.Podman([]string{"exec", "test1", "/etc"}) 420 session.WaitWithDefaultTimeout() 421 422 // crun (and, we hope, any other future runtimes) 423 expectedStatus := 126 424 expectedMessage := "open executable: Operation not permitted: OCI permission denied" 425 426 // ...but it's much more complicated under runc (#19552) 427 if podmanTest.OCIRuntime == "runc" { 428 expectedMessage = `exec failed: unable to start container process: exec: "/etc": is a directory` 429 expectedStatus = 255 430 if IsRemote() { 431 expectedStatus = 125 432 } 433 } 434 Expect(session).Should(ExitWithError(expectedStatus, expectedMessage)) 435 }) 436 437 It("podman exec command not found", func() { 438 setup := podmanTest.RunTopContainer("test1") 439 setup.WaitWithDefaultTimeout() 440 Expect(setup).Should(ExitCleanly()) 441 442 session := podmanTest.Podman([]string{"exec", "test1", "notthere"}) 443 session.WaitWithDefaultTimeout() 444 Expect(session).Should(ExitWithError(127, "OCI runtime attempted to invoke a command that was not found")) 445 }) 446 447 It("podman exec preserve fds sanity check", func() { 448 setup := podmanTest.RunTopContainer("test1") 449 setup.WaitWithDefaultTimeout() 450 Expect(setup).Should(ExitCleanly()) 451 452 devNull, err := os.Open("/dev/null") 453 Expect(err).ToNot(HaveOccurred()) 454 defer devNull.Close() 455 files := []*os.File{ 456 devNull, 457 } 458 session := podmanTest.PodmanExtraFiles([]string{"exec", "--preserve-fds", "1", "test1", "ls"}, files) 459 session.WaitWithDefaultTimeout() 460 Expect(session).Should(ExitCleanly()) 461 }) 462 463 It("podman exec preserves --group-add groups", func() { 464 groupName := "group1" 465 gid := "4444" 466 ctrName1 := "ctr1" 467 ctr1 := podmanTest.Podman([]string{"run", "--name", ctrName1, fedoraMinimal, "groupadd", "-g", gid, groupName}) 468 ctr1.WaitWithDefaultTimeout() 469 Expect(ctr1).Should(ExitCleanly()) 470 471 imgName := "img1" 472 commit := podmanTest.Podman([]string{"commit", "-q", ctrName1, imgName}) 473 commit.WaitWithDefaultTimeout() 474 Expect(commit).Should(ExitCleanly()) 475 476 ctrName2 := "ctr2" 477 ctr2 := podmanTest.Podman([]string{"run", "-d", "--name", ctrName2, "--group-add", groupName, imgName, "sleep", "300"}) 478 ctr2.WaitWithDefaultTimeout() 479 Expect(ctr2).Should(ExitCleanly()) 480 481 exec := podmanTest.Podman([]string{"exec", ctrName2, "id"}) 482 exec.WaitWithDefaultTimeout() 483 Expect(exec).Should(ExitCleanly()) 484 Expect(exec.OutputToString()).To(ContainSubstring(fmt.Sprintf("%s(%s)", gid, groupName))) 485 }) 486 487 It("podman exec preserves container groups with --user and --group-add", func() { 488 dockerfile := fmt.Sprintf(`FROM %s 489 RUN groupadd -g 4000 first 490 RUN groupadd -g 4001 second 491 RUN useradd -u 1000 auser`, fedoraMinimal) 492 imgName := "testimg" 493 podmanTest.BuildImage(dockerfile, imgName, "false") 494 495 ctrName := "testctr" 496 ctr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--user", "auser:first", "--group-add", "second", imgName, "sleep", "300"}) 497 ctr.WaitWithDefaultTimeout() 498 Expect(ctr).Should(ExitCleanly()) 499 500 exec := podmanTest.Podman([]string{"exec", ctrName, "id"}) 501 exec.WaitWithDefaultTimeout() 502 Expect(exec).Should(ExitCleanly()) 503 output := exec.OutputToString() 504 Expect(output).To(ContainSubstring("4000(first)")) 505 Expect(output).To(ContainSubstring("4001(second)")) 506 Expect(output).To(ContainSubstring("1000(auser)")) 507 508 // Kill the container just so the test does not take 15 seconds to stop. 509 kill := podmanTest.Podman([]string{"kill", ctrName}) 510 kill.WaitWithDefaultTimeout() 511 Expect(kill).Should(ExitCleanly()) 512 }) 513 514 It("podman exec --detach", func() { 515 ctrName := "testctr" 516 ctr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, ALPINE, "top"}) 517 ctr.WaitWithDefaultTimeout() 518 Expect(ctr).Should(ExitCleanly()) 519 520 exec1 := podmanTest.Podman([]string{"exec", "-d", ctrName, "top"}) 521 exec1.WaitWithDefaultTimeout() 522 Expect(ctr).Should(ExitCleanly()) 523 524 data := podmanTest.InspectContainer(ctrName) 525 Expect(data).To(HaveLen(1)) 526 Expect(data[0].ExecIDs).To(HaveLen(1)) 527 Expect(exec1.OutputToString()).To(ContainSubstring(data[0].ExecIDs[0])) 528 529 exec2 := podmanTest.Podman([]string{"exec", ctrName, "ps", "-a"}) 530 exec2.WaitWithDefaultTimeout() 531 Expect(ctr).Should(ExitCleanly()) 532 Expect(strings.Count(exec2.OutputToString(), "top")).To(Equal(2)) 533 534 // Ensure that stop with a running detached exec session is 535 // clean. 536 podmanTest.StopContainer(ctrName) 537 }) 538 539 It("podman exec with env var secret", func() { 540 secretsString := "somesecretdata" 541 secretFilePath := filepath.Join(podmanTest.TempDir, "secret") 542 err := os.WriteFile(secretFilePath, []byte(secretsString), 0755) 543 Expect(err).ToNot(HaveOccurred()) 544 545 session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath}) 546 session.WaitWithDefaultTimeout() 547 Expect(session).Should(ExitCleanly()) 548 549 session = podmanTest.Podman([]string{"run", "-d", "--secret", "source=mysecret,type=env", "--name", "secr", ALPINE, "top"}) 550 session.WaitWithDefaultTimeout() 551 Expect(session).Should(ExitCleanly()) 552 553 session = podmanTest.Podman([]string{"exec", "secr", "printenv", "mysecret"}) 554 session.WaitWithDefaultTimeout() 555 Expect(session).Should(ExitCleanly()) 556 Expect(session.OutputToString()).To(ContainSubstring(secretsString)) 557 558 session = podmanTest.Podman([]string{"commit", "-q", "secr", "foobar.com/test1-image:latest"}) 559 session.WaitWithDefaultTimeout() 560 Expect(session).Should(ExitCleanly()) 561 562 session = podmanTest.Podman([]string{"run", "foobar.com/test1-image:latest", "printenv", "mysecret"}) 563 session.WaitWithDefaultTimeout() 564 Expect(session.OutputToString()).To(Not(ContainSubstring(secretsString))) 565 }) 566 567 It("podman exec --wait 2 seconds on bogus container", func() { 568 SkipIfRemote("not supported for --wait") 569 session := podmanTest.Podman([]string{"exec", "--wait", "2", "1234"}) 570 session.WaitWithDefaultTimeout() 571 Expect(session).Should(ExitWithError(125, "timed out waiting for container: 1234")) 572 }) 573 574 It("podman exec --wait 5 seconds for started container", func() { 575 SkipIfRemote("not supported for --wait") 576 ctrName := "waitCtr" 577 578 session := podmanTest.Podman([]string{"exec", "--wait", "5", ctrName, "whoami"}) 579 580 session2 := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, ALPINE, "top"}) 581 session2.WaitWithDefaultTimeout() 582 583 session.Wait(6) 584 585 Expect(session2).Should(ExitCleanly()) 586 Expect(session).Should(ExitCleanly()) 587 Expect(session.OutputToString()).To(Equal("root")) 588 }) 589 })