mirror of
https://github.com/containers/podman.git
synced 2026-07-09 14:54:59 -04:00
I do not understand this condition in the code, not passing the log file to the runtime when run with log level debug makes no sense. It means we do not get the proper error message from the runtime so debug logging shows a much worse error: "container create failed (no logs from conmon)..." When the actual error is the command is not in $PATH for example. So to fix this just remove the log level check. Also not the support json flag condition is done inside execOCILog(). Signed-off-by: Paul Holzinger <pholzing@redhat.com>
690 lines
28 KiB
Go
690 lines
28 KiB
Go
//go:build linux || freebsd
|
|
|
|
package integration
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
. "github.com/onsi/gomega/gexec"
|
|
. "go.podman.io/podman/v6/test/utils"
|
|
)
|
|
|
|
var _ = Describe("Podman exec", func() {
|
|
It("podman exec into bogus container", func() {
|
|
session := podmanTest.Podman([]string{"exec", "foobar", "ls"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitWithError(125, `no container with name or ID "foobar" found: no such container`))
|
|
})
|
|
|
|
It("podman exec simple command", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"exec", "test1", "ls"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
// With no command
|
|
session = podmanTest.Podman([]string{"exec", "test1"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitWithError(125, "must provide a non-empty command to start an exec session: invalid argument"))
|
|
})
|
|
|
|
It("podman container exec simple command", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"container", "exec", "test1", "ls"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
})
|
|
|
|
It("podman exec simple command using latest", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
cid := "-l"
|
|
if IsRemote() {
|
|
cid = "test1"
|
|
}
|
|
session := podmanTest.Podman([]string{"exec", cid, "ls"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
})
|
|
|
|
It("podman exec simple command using cidfile", func() {
|
|
cidFile := filepath.Join(tempdir, "cid")
|
|
session := podmanTest.RunTopContainerWithArgs("test1", []string{"--cidfile", cidFile})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(podmanTest.NumberOfContainers()).To(Equal(1))
|
|
|
|
result := podmanTest.Podman([]string{"exec", "--cidfile", cidFile, "ls"})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitCleanly())
|
|
})
|
|
|
|
It("podman exec latest and cidfile", func() {
|
|
SkipIfRemote("--latest flag n/a")
|
|
|
|
cidFile := filepath.Join(tempdir, "cid")
|
|
session := podmanTest.RunTopContainerWithArgs("test1", []string{"--cidfile", cidFile})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(podmanTest.NumberOfContainers()).To(Equal(1))
|
|
|
|
result := podmanTest.Podman([]string{"exec", "--cidfile", cidFile, "--latest", "ls"})
|
|
result.WaitWithDefaultTimeout()
|
|
Expect(result).Should(ExitWithError(125, `--latest and --cidfile can not be used together`))
|
|
})
|
|
|
|
It("podman exec nonextant cidfile", func() {
|
|
session := podmanTest.Podman([]string{"exec", "--cidfile", "foobar", "ls"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitWithError(125, `reading CIDFile: open foobar: no such file or directory`))
|
|
})
|
|
|
|
It("podman exec environment test", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"exec", "--env", "FOO=BAR", "test1", "printenv", "FOO"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(Equal("BAR"))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--env", "PATH=/bin", "test1", "printenv", "PATH"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(Equal("/bin"))
|
|
})
|
|
|
|
It("podman exec os.Setenv env", func() {
|
|
// remote doesn't properly interpret os.Setenv
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
os.Setenv("FOO", "BAR")
|
|
session := podmanTest.Podman([]string{"exec", "--env", "FOO", "test1", "printenv", "FOO"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(Equal("BAR"))
|
|
os.Unsetenv("FOO")
|
|
})
|
|
|
|
It("podman exec exit code", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"exec", "test1", "sh", "-c", "exit 100"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitWithError(100, ""))
|
|
})
|
|
|
|
It("podman exec in keep-id container drops privileges", func() {
|
|
SkipIfNotRootless("This function is not enabled for rootful podman")
|
|
ctrName := "testctr1"
|
|
testCtr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--userns=keep-id", ALPINE, "top"})
|
|
testCtr.WaitWithDefaultTimeout()
|
|
Expect(testCtr).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"exec", ctrName, "grep", "CapEff", "/proc/self/status"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
|
|
})
|
|
|
|
It("podman exec --privileged", func() {
|
|
session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
bndPerms := session.OutputToString()
|
|
|
|
session = podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
effPerms := session.OutputToString()
|
|
|
|
setup := podmanTest.RunTopContainer("test-privileged")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(effPerms))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(bndPerms))
|
|
})
|
|
|
|
It("podman exec --privileged", func() {
|
|
session := podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
bndPerms := session.OutputToString()
|
|
|
|
session = podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
effPerms := session.OutputToString()
|
|
|
|
setup := podmanTest.RunTopContainer("test-privileged")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(effPerms))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(bndPerms))
|
|
})
|
|
|
|
It("podman exec --privileged", func() {
|
|
session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
bndPerms := session.OutputToString()
|
|
|
|
setup := podmanTest.RunTopContainer("test-privileged")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring("00000000"))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(bndPerms))
|
|
})
|
|
|
|
It("podman exec --privileged container not running as root", func() {
|
|
session := podmanTest.Podman([]string{"run", "--privileged", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
bndPerms := session.OutputToString()
|
|
|
|
setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin"})
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring("00000000"))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring("00000000"))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "--user=root", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(bndPerms))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "--user=bin", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(bndPerms))
|
|
})
|
|
|
|
It("podman exec with user with cap-add", func() {
|
|
capAdd := "--cap-add=net_bind_service"
|
|
session := podmanTest.Podman([]string{"run", "--user=bin", capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
bndPerms := session.OutputToString()
|
|
|
|
session = podmanTest.Podman([]string{"run", "--user=bin", capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
effPerms := session.OutputToString()
|
|
|
|
setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin", capAdd})
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(bndPerms))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(effPerms))
|
|
})
|
|
|
|
It("podman exec with user with and cap-drop cap-add", func() {
|
|
capAdd := "--cap-add=net_bind_service"
|
|
capDrop := "--cap-drop=all"
|
|
session := podmanTest.Podman([]string{"run", "--user=bin", capDrop, capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
bndPerms := session.OutputToString()
|
|
|
|
session = podmanTest.Podman([]string{"run", "--user=bin", capDrop, capAdd, "--rm", ALPINE, "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
effPerms := session.OutputToString()
|
|
|
|
setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--user=bin", capDrop, capAdd})
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(bndPerms))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapInh /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(effPerms))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(effPerms))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapPrm /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(effPerms))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test-privileged", "sh", "-c", "grep ^CapAmb /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(effPerms))
|
|
})
|
|
|
|
It("podman exec --privileged with user", func() {
|
|
session := podmanTest.Podman([]string{"run", "--privileged", "--user=bin", "--rm", ALPINE, "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
bindPerms := session.OutputToString()
|
|
|
|
setup := podmanTest.RunTopContainerWithArgs("test-privileged", []string{"--privileged", "--user=bin"})
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapBnd /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(bindPerms))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "--privileged", "test-privileged", "sh", "-c", "grep ^CapEff /proc/self/status | cut -f 2"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
|
|
})
|
|
|
|
// #10927 ("no logs from conmon"), one of our nastiest flakes
|
|
It("podman exec terminal doesn't hang", FlakeAttempts(3), func() {
|
|
setup := podmanTest.Podman([]string{"run", "-ti", "--rm", "--name", "test1", FEDORA_MINIMAL, "true"})
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(Exit(0))
|
|
Expect(setup.ErrorToString()).To(ContainSubstring("The input device is not a TTY. The --tty and --interactive flags might not work properly"))
|
|
|
|
podmanTest.PodmanExitCleanly("run", "-dti", "--name", "test1", FEDORA_MINIMAL, "sleep", "+Inf")
|
|
for range 5 {
|
|
session := podmanTest.Podman([]string{"exec", "-ti", "test1", "true"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
}
|
|
})
|
|
|
|
It("podman exec pseudo-terminal sanity check", func() {
|
|
setup := podmanTest.Podman([]string{"run", "--detach", "--name", "test1", FEDORA_MINIMAL, "sleep", "+Inf"})
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"exec", "--interactive", "--tty", "test1", "/usr/bin/stty", "--all"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(" onlcr"))
|
|
})
|
|
|
|
It("podman exec simple command with user", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"exec", "--user", "root", "test1", "ls"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
})
|
|
|
|
It("podman exec with user only in container", func() {
|
|
testUser := "test123"
|
|
setup := podmanTest.Podman([]string{"run", "--name", "test1", "-d", CITEST_IMAGE, "sleep", "60"})
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"exec", "test1", "adduser", "-D", testUser})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
session2 := podmanTest.Podman([]string{"exec", "--user", testUser, "test1", "whoami"})
|
|
session2.WaitWithDefaultTimeout()
|
|
Expect(session2).Should(ExitCleanly())
|
|
Expect(session2.OutputToString()).To(Equal(testUser))
|
|
})
|
|
|
|
It("podman exec with user from run", func() {
|
|
testUser := "guest"
|
|
setup := podmanTest.Podman([]string{"run", "--user", testUser, "-d", ALPINE, "top"})
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
ctrID := setup.OutputToString()
|
|
|
|
session := podmanTest.Podman([]string{"exec", ctrID, "whoami"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(testUser))
|
|
|
|
overrideUser := "root"
|
|
session = podmanTest.Podman([]string{"exec", "--user", overrideUser, ctrID, "whoami"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(overrideUser))
|
|
})
|
|
|
|
It("podman exec simple working directory test", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"exec", "--workdir", "/tmp", "test1", "pwd"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(Equal("/tmp"))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "-w", "/tmp", "test1", "pwd"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(Equal("/tmp"))
|
|
})
|
|
|
|
It("podman exec missing working directory test", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
expect := ".*(chdir to cwd|chdir to `/missing`: No such file or directory).*"
|
|
session := podmanTest.Podman([]string{"exec", "--workdir", "/missing", "test1", "pwd"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).To(ExitWithErrorRegex(127, expect))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "-w", "/missing", "test1", "pwd"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).To(ExitWithErrorRegex(127, expect))
|
|
})
|
|
|
|
It("podman exec cannot be invoked", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"exec", "test1", "/etc"})
|
|
session.WaitWithDefaultTimeout()
|
|
|
|
// ...but it's much more complicated under runc (#19552)
|
|
if podmanTest.OCIRuntime == "runc" {
|
|
expectedMessage := `exec failed: unable to start container process: exec: "/etc": is a directory`
|
|
expectedStatus := 255
|
|
if IsRemote() {
|
|
expectedStatus = 125
|
|
}
|
|
Expect(session).Should(ExitWithError(expectedStatus, expectedMessage))
|
|
} else {
|
|
// crun (and, we hope, any other future runtimes)
|
|
expectedStatus := 126
|
|
expectedMessage := ".*(open executable|the path `/etc` is not a regular file): Operation not permitted: OCI permission denied.*"
|
|
Expect(session).Should(ExitWithErrorRegex(expectedStatus, expectedMessage))
|
|
}
|
|
})
|
|
|
|
It("podman exec command not found", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
session := podmanTest.Podman([]string{"exec", "test1", "notthere"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitWithError(127, "OCI runtime attempted to invoke a command that was not found"))
|
|
})
|
|
|
|
It("podman exec preserve fds sanity check", func() {
|
|
setup := podmanTest.RunTopContainer("test1")
|
|
setup.WaitWithDefaultTimeout()
|
|
Expect(setup).Should(ExitCleanly())
|
|
|
|
devNull, err := os.Open("/dev/null")
|
|
Expect(err).ToNot(HaveOccurred())
|
|
defer devNull.Close()
|
|
files := []*os.File{
|
|
devNull,
|
|
}
|
|
podmanTest.PodmanExitCleanlyWithOptions(PodmanExecOptions{
|
|
ExtraFiles: files,
|
|
}, "exec", "--preserve-fds", "1", "test1", "ls")
|
|
})
|
|
|
|
It("podman exec preserves --group-add groups", func() {
|
|
groupName := "group1"
|
|
gid := "4444"
|
|
ctrName1 := "ctr1"
|
|
ctr1 := podmanTest.Podman([]string{"run", "--name", ctrName1, FEDORA_MINIMAL, "groupadd", "-g", gid, groupName})
|
|
ctr1.WaitWithDefaultTimeout()
|
|
Expect(ctr1).Should(ExitCleanly())
|
|
|
|
imgName := "img1"
|
|
commit := podmanTest.Podman([]string{"commit", "-q", ctrName1, imgName})
|
|
commit.WaitWithDefaultTimeout()
|
|
Expect(commit).Should(ExitCleanly())
|
|
|
|
ctrName2 := "ctr2"
|
|
ctr2 := podmanTest.Podman([]string{"run", "-d", "--name", ctrName2, "--group-add", groupName, imgName, "sleep", "300"})
|
|
ctr2.WaitWithDefaultTimeout()
|
|
Expect(ctr2).Should(ExitCleanly())
|
|
|
|
exec := podmanTest.Podman([]string{"exec", ctrName2, "id"})
|
|
exec.WaitWithDefaultTimeout()
|
|
Expect(exec).Should(ExitCleanly())
|
|
Expect(exec.OutputToString()).To(ContainSubstring(fmt.Sprintf("%s(%s)", gid, groupName)))
|
|
})
|
|
|
|
It("podman exec preserves container groups with --user and --group-add", func() {
|
|
dockerfile := fmt.Sprintf(`FROM %s
|
|
RUN groupadd -g 4000 first
|
|
RUN groupadd -g 4001 second
|
|
RUN useradd -u 1000 auser`, FEDORA_MINIMAL)
|
|
imgName := "testimg"
|
|
podmanTest.BuildImage(dockerfile, imgName, "false")
|
|
|
|
ctrName := "testctr"
|
|
ctr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--user", "auser:first", "--group-add", "second", imgName, "sleep", "300"})
|
|
ctr.WaitWithDefaultTimeout()
|
|
Expect(ctr).Should(ExitCleanly())
|
|
|
|
exec := podmanTest.Podman([]string{"exec", ctrName, "id"})
|
|
exec.WaitWithDefaultTimeout()
|
|
Expect(exec).Should(ExitCleanly())
|
|
output := exec.OutputToString()
|
|
Expect(output).To(ContainSubstring("4000(first)"))
|
|
Expect(output).To(ContainSubstring("4001(second)"))
|
|
Expect(output).To(ContainSubstring("1000(auser)"))
|
|
|
|
// Kill the container just so the test does not take 15 seconds to stop.
|
|
kill := podmanTest.Podman([]string{"kill", ctrName})
|
|
kill.WaitWithDefaultTimeout()
|
|
Expect(kill).Should(ExitCleanly())
|
|
})
|
|
|
|
It("podman exec --detach", func() {
|
|
ctrName := "testctr"
|
|
ctr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, ALPINE, "top"})
|
|
ctr.WaitWithDefaultTimeout()
|
|
Expect(ctr).Should(ExitCleanly())
|
|
|
|
exec1 := podmanTest.Podman([]string{"exec", "-d", ctrName, "top"})
|
|
exec1.WaitWithDefaultTimeout()
|
|
Expect(ctr).Should(ExitCleanly())
|
|
|
|
data := podmanTest.InspectContainer(ctrName)
|
|
Expect(data).To(HaveLen(1))
|
|
Expect(data[0].ExecIDs).To(HaveLen(1))
|
|
Expect(exec1.OutputToString()).To(ContainSubstring(data[0].ExecIDs[0]))
|
|
|
|
exec2 := podmanTest.Podman([]string{"exec", ctrName, "ps", "-a"})
|
|
exec2.WaitWithDefaultTimeout()
|
|
Expect(ctr).Should(ExitCleanly())
|
|
Expect(strings.Count(exec2.OutputToString(), "top")).To(Equal(2))
|
|
|
|
// Ensure that stop with a running detached exec session is
|
|
// clean.
|
|
podmanTest.StopContainer(ctrName)
|
|
})
|
|
|
|
It("podman exec with env var secret", func() {
|
|
secretsString := "somesecretdata"
|
|
secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
|
|
err := os.WriteFile(secretFilePath, []byte(secretsString), 0o755)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
session = podmanTest.Podman([]string{"run", "-d", "--secret", "source=mysecret,type=env", "--name", "secr", ALPINE, "top"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
session = podmanTest.Podman([]string{"exec", "secr", "printenv", "mysecret"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(ContainSubstring(secretsString))
|
|
|
|
session = podmanTest.Podman([]string{"commit", "-q", "secr", "foobar.com/test1-image:latest"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
session = podmanTest.Podman([]string{"run", "foobar.com/test1-image:latest", "printenv", "mysecret"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.OutputToString()).To(Not(ContainSubstring(secretsString)))
|
|
})
|
|
|
|
It("podman exec --wait 2 seconds on bogus container", func() {
|
|
SkipIfRemote("not supported for --wait")
|
|
session := podmanTest.Podman([]string{"exec", "--wait", "2", "1234"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitWithError(125, "timed out waiting for container: 1234"))
|
|
})
|
|
|
|
It("podman exec --wait 5 seconds for started container", func() {
|
|
SkipIfRemote("not supported for --wait")
|
|
ctrName := "waitCtr"
|
|
|
|
session := podmanTest.Podman([]string{"exec", "--wait", "5", ctrName, "whoami"})
|
|
|
|
session2 := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, ALPINE, "top"})
|
|
session2.WaitWithDefaultTimeout()
|
|
|
|
session.Wait(6)
|
|
|
|
Expect(session2).Should(ExitCleanly())
|
|
Expect(session).Should(ExitCleanly())
|
|
Expect(session.OutputToString()).To(Equal("root"))
|
|
})
|
|
|
|
It("podman exec with --no-session flag", func() {
|
|
SkipIfRemote("The --no-session flag is not supported for remote clients")
|
|
session := podmanTest.RunTopContainer("no_session_test")
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
execResult := podmanTest.Podman([]string{"exec", "--no-session", "no_session_test", "echo", "hello"})
|
|
execResult.WaitWithDefaultTimeout()
|
|
Expect(execResult).Should(ExitCleanly())
|
|
Expect(execResult.OutputToString()).To(Equal("hello"))
|
|
})
|
|
|
|
It("podman stop is not blocked by a long-running --no-session exec", func() {
|
|
SkipIfRemote("The --no-session flag is not supported for remote clients")
|
|
|
|
ctrName := "no_session_lock_test"
|
|
session := podmanTest.RunTopContainer(ctrName)
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
execSession := podmanTest.Podman([]string{"exec", "--no-session", ctrName, "sleep", "30"})
|
|
stopSession := podmanTest.Podman([]string{"stop", "-t", "5", ctrName})
|
|
stopSession.WaitWithDefaultTimeout()
|
|
Expect(stopSession).Should(ExitCleanly())
|
|
Eventually(execSession, "5s").Should(Not(Exit(0)))
|
|
})
|
|
|
|
It("podman exec --no-session exit codes", func() {
|
|
SkipIfRemote("The --no-session flag is not supported for remote clients")
|
|
|
|
ctrName := "no_session_exit_code_test"
|
|
session := podmanTest.RunTopContainer(ctrName)
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
execResult := podmanTest.Podman([]string{"exec", "--no-session", ctrName, "sh", "-c", "exit 42"})
|
|
execResult.WaitWithDefaultTimeout()
|
|
Expect(execResult).Should(ExitWithError(42, ""))
|
|
|
|
execResult = podmanTest.Podman([]string{"exec", "--no-session", ctrName, "nonexistentcommand"})
|
|
execResult.WaitWithDefaultTimeout()
|
|
Expect(execResult).Should(ExitWithError(127, "OCI runtime attempted to invoke a command that was not found"))
|
|
|
|
execSession := podmanTest.Podman([]string{"exec", "--no-session", ctrName, "sleep", "30"})
|
|
time.Sleep(2 * time.Second) // Give time for the first exec to start (CI is slow)
|
|
killSession := podmanTest.Podman([]string{"exec", ctrName, "sh", "-c", "kill -9 $(pgrep sleep)"})
|
|
killSession.WaitWithDefaultTimeout()
|
|
Expect(killSession).Should(ExitCleanly())
|
|
|
|
execSession.WaitWithDefaultTimeout()
|
|
Expect(execSession).Should(ExitWithError(137, ""))
|
|
})
|
|
|
|
It("podman exec command not in $PATH error", func() {
|
|
session := podmanTest.RunTopContainer("testctr")
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session).Should(ExitCleanly())
|
|
|
|
execResult := podmanTest.Podman([]string{"exec", "testctr", "kjhasdf"})
|
|
execResult.WaitWithDefaultTimeout()
|
|
Expect(execResult).Should(ExitWithError(127, "not found in $PATH"))
|
|
|
|
// Test again with log level debug, this must produce the same error
|
|
execResult = podmanTest.Podman([]string{"--log-level=debug", "exec", "testctr", "kjhasdf"})
|
|
execResult.WaitWithDefaultTimeout()
|
|
Expect(execResult).Should(ExitWithError(127, "not found in $PATH"))
|
|
})
|
|
})
|