Files
podman/test/e2e/run_test.go
Matthew Heon 39c493b3fc Do not use image CMD if user gave ENTRYPOINT
This matches Docker behavior, and seems to make sense - the CMD
may have been specific to the original entrypoint and probably
does not make sense if it was changed.

While we're in here, greatly simplify the logic for populating
the SpecGen's Command. We create the full command when making the
OCI spec, so the client should not be doing any more than setting
it to the Command the user passed in, and completely ignoring
ENTRYPOINT.

Fixes #7115

Signed-off-by: Matthew Heon <mheon@redhat.com>
2020-08-10 10:18:43 -04:00

1167 lines
45 KiB
Go

package integration
import (
"fmt"
"io/ioutil"
"net"
"os"
"path/filepath"
"strconv"
"strings"
"syscall"
"time"
"github.com/containers/podman/v2/pkg/cgroups"
. "github.com/containers/podman/v2/test/utils"
"github.com/containers/storage/pkg/stringid"
"github.com/mrunalp/fileutils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Podman run", func() {
var (
tempdir string
err error
podmanTest *PodmanTestIntegration
)
BeforeEach(func() {
tempdir, err = CreateTempDirInTempDir()
if err != nil {
os.Exit(1)
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
podmanTest.SeedImages()
})
AfterEach(func() {
podmanTest.Cleanup()
f := CurrentGinkgoTestDescription()
processTestResult(f)
})
It("podman run a container based on local image", func() {
session := podmanTest.Podman([]string{"run", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run a container based on a complex local image name", func() {
SkipIfRootless()
imageName := strings.TrimPrefix(nginx, "quay.io/")
session := podmanTest.Podman([]string{"run", imageName, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run a container based on on a short name with localhost", func() {
tag := podmanTest.Podman([]string{"tag", nginx, "localhost/libpod/alpine_nginx:latest"})
tag.WaitWithDefaultTimeout()
rmi := podmanTest.Podman([]string{"rmi", nginx})
rmi.WaitWithDefaultTimeout()
session := podmanTest.Podman([]string{"run", "libpod/alpine_nginx:latest", "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
Expect(session.ExitCode()).To(Equal(0))
})
It("podman container run a container based on on a short name with localhost", func() {
tag := podmanTest.Podman([]string{"image", "tag", nginx, "localhost/libpod/alpine_nginx:latest"})
tag.WaitWithDefaultTimeout()
rmi := podmanTest.Podman([]string{"image", "rm", nginx})
rmi.WaitWithDefaultTimeout()
session := podmanTest.Podman([]string{"container", "run", "libpod/alpine_nginx:latest", "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run a container based on local image with short options", func() {
session := podmanTest.Podman([]string{"run", "-dt", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run a container based on local image with short options and args", func() {
// regression test for #714
session := podmanTest.Podman([]string{"run", ALPINE, "find", "/etc", "-name", "hosts"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
match, _ := session.GrepString("/etc/hosts")
Expect(match).Should(BeTrue())
})
It("podman create pod with name in /etc/hosts", func() {
name := "test_container"
hostname := "test_hostname"
session := podmanTest.Podman([]string{"run", "-ti", "--rm", "--name", name, "--hostname", hostname, ALPINE, "cat", "/etc/hosts"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
match, _ := session.GrepString(name)
Expect(match).Should(BeTrue())
match, _ = session.GrepString(hostname)
Expect(match).Should(BeTrue())
})
It("podman run a container based on remote image", func() {
session := podmanTest.Podman([]string{"run", "-dt", BB_GLIBC, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run a container with a --rootfs", func() {
rootfs := filepath.Join(tempdir, "rootfs")
uls := filepath.Join("/", "usr", "local", "share")
uniqueString := stringid.GenerateNonCryptoID()
testFilePath := filepath.Join(uls, uniqueString)
tarball := filepath.Join(tempdir, "rootfs.tar")
err := os.Mkdir(rootfs, 0770)
Expect(err).Should(BeNil())
// Change image in predictable way to validate export
csession := podmanTest.Podman([]string{"run", "--name", uniqueString, ALPINE,
"/bin/sh", "-c", fmt.Sprintf("echo %s > %s", uniqueString, testFilePath)})
csession.WaitWithDefaultTimeout()
Expect(csession.ExitCode()).To(Equal(0))
// Export from working container image guarantees working root
esession := podmanTest.Podman([]string{"export", "--output", tarball, uniqueString})
esession.WaitWithDefaultTimeout()
Expect(esession.ExitCode()).To(Equal(0))
Expect(tarball).Should(BeARegularFile())
// N/B: This will loose any extended attributes like SELinux types
fmt.Fprintf(os.Stderr, "Extracting container root tarball\n")
tarsession := SystemExec("tar", []string{"xf", tarball, "-C", rootfs})
Expect(tarsession.ExitCode()).To(Equal(0))
Expect(filepath.Join(rootfs, uls)).Should(BeADirectory())
// Other tests confirm SELinux types, just confirm --rootfs is working.
session := podmanTest.Podman([]string{"run", "-i", "--security-opt", "label=disable",
"--rootfs", rootfs, "cat", testFilePath})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
// Validate changes made in original container and export
stdoutLines := session.OutputToStringArray()
Expect(stdoutLines).Should(HaveLen(1))
Expect(stdoutLines[0]).Should(Equal(uniqueString))
})
It("podman run a container with --init", func() {
session := podmanTest.Podman([]string{"run", "--name", "test", "--init", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
result := podmanTest.Podman([]string{"inspect", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
conData := result.InspectContainerToJSON()
Expect(conData[0].Path).To(Equal("/dev/init"))
Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("TRUE"))
})
It("podman run a container with --init and --init-path", func() {
session := podmanTest.Podman([]string{"run", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
result := podmanTest.Podman([]string{"inspect", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
conData := result.InspectContainerToJSON()
Expect(conData[0].Path).To(Equal("/dev/init"))
Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("TRUE"))
})
It("podman run a container without --init", func() {
session := podmanTest.Podman([]string{"run", "--name", "test", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
result := podmanTest.Podman([]string{"inspect", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
conData := result.InspectContainerToJSON()
Expect(conData[0].Path).To(Equal("ls"))
Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("FALSE"))
})
It("podman run seccomp test", func() {
in := []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`)
jsonFile, err := podmanTest.CreateSeccompJson(in)
if err != nil {
fmt.Println(err)
Skip("Failed to prepare seccomp.json for test.")
}
session := podmanTest.Podman([]string{"run", "-it", "--security-opt", strings.Join([]string{"seccomp=", jsonFile}, ""), ALPINE, "pwd"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
match, _ := session.GrepString("Operation not permitted")
Expect(match).Should(BeTrue())
})
It("podman run capabilities test", func() {
session := podmanTest.Podman([]string{"run", "--rm", "--cap-add", "all", ALPINE, "cat", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"run", "--rm", "--cap-add", "sys_admin", ALPINE, "cat", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "all", ALPINE, "cat", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "setuid", ALPINE, "cat", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run user capabilities test", func() {
session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapBnd", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapEff", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapBnd", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapEff", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapBnd", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapEff", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
})
It("podman run user capabilities test with image", func() {
SkipIfRemote()
dockerfile := `FROM busybox
USER bin`
podmanTest.BuildImage(dockerfile, "test", "false")
session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapBnd", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapEff", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
})
It("podman run limits test", func() {
SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "rtprio=99", "--cap-add=sys_nice", fedoraMinimal, "cat", "/proc/self/sched"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=2048:2048", fedoraMinimal, "ulimit", "-n"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("2048"))
session = podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=1024:1028", fedoraMinimal, "ulimit", "-n"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("1024"))
cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
Expect(err).To(BeNil())
if !cgroupsv2 {
// --oom-kill-disable not supported on cgroups v2.
session = podmanTest.Podman([]string{"run", "--rm", "--oom-kill-disable=true", fedoraMinimal, "echo", "memory-hog"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
}
session = podmanTest.Podman([]string{"run", "--rm", "--oom-score-adj=100", fedoraMinimal, "cat", "/proc/self/oom_score_adj"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("100"))
})
It("podman run limits host test", func() {
SkipIfRemote()
var l syscall.Rlimit
err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l)
Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "host", fedoraMinimal, "ulimit", "-Hn"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
ulimitCtrStr := strings.TrimSpace(session.OutputToString())
ulimitCtr, err := strconv.ParseUint(ulimitCtrStr, 10, 0)
Expect(err).To(BeNil())
Expect(ulimitCtr).Should(BeNumerically(">=", l.Max))
})
It("podman run with cidfile", func() {
session := podmanTest.Podman([]string{"run", "--cidfile", tempdir + "cidfile", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
err := os.Remove(tempdir + "cidfile")
Expect(err).To(BeNil())
})
It("podman run sysctl test", func() {
SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("net.core.somaxconn = 65535"))
})
It("podman run blkio-weight test", func() {
SkipIfRootless()
cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
Expect(err).To(BeNil())
if !cgroupsv2 {
if _, err := os.Stat("/sys/fs/cgroup/blkio/blkio.weight"); os.IsNotExist(err) {
Skip("Kernel does not support blkio.weight")
}
}
if cgroupsv2 {
// convert linearly from [10-1000] to [1-10000]
session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.bfq.weight"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("51"))
} else {
session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.weight"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("15"))
}
})
It("podman run device-read-bps test", func() {
SkipIfRootless()
cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
Expect(err).To(BeNil())
var session *PodmanSessionIntegration
if cgroupsv2 {
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"})
} else {
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"})
}
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
if !cgroupsv2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
Expect(session.OutputToString()).To(ContainSubstring("1048576"))
}
})
It("podman run device-write-bps test", func() {
SkipIfRootless()
cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
Expect(err).To(BeNil())
var session *PodmanSessionIntegration
if cgroupsv2 {
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"})
} else {
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"})
}
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
if !cgroupsv2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
Expect(session.OutputToString()).To(ContainSubstring("1048576"))
}
})
It("podman run device-read-iops test", func() {
SkipIfRootless()
cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
Expect(err).To(BeNil())
var session *PodmanSessionIntegration
if cgroupsv2 {
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"})
} else {
session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"})
}
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
if !cgroupsv2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
Expect(session.OutputToString()).To(ContainSubstring("100"))
}
})
It("podman run device-write-iops test", func() {
SkipIfRootless()
cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
Expect(err).To(BeNil())
var session *PodmanSessionIntegration
if cgroupsv2 {
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"})
} else {
session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"})
}
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
if !cgroupsv2 { // TODO: Test Simplification. For now, we only care about exit(0) w/ cgroupsv2
Expect(session.OutputToString()).To(ContainSubstring("100"))
}
})
It("podman run notify_socket", func() {
SkipIfRemote()
host := GetHostDistributionInfo()
if host.Distribution != "rhel" && host.Distribution != "centos" && host.Distribution != "fedora" {
Skip("this test requires a working runc")
}
sock := filepath.Join(podmanTest.TempDir, "notify")
addr := net.UnixAddr{
Name: sock,
Net: "unixgram",
}
socket, err := net.ListenUnixgram("unixgram", &addr)
Expect(err).To(BeNil())
defer os.Remove(sock)
defer socket.Close()
os.Setenv("NOTIFY_SOCKET", sock)
defer os.Unsetenv("NOTIFY_SOCKET")
session := podmanTest.Podman([]string{"run", ALPINE, "printenv", "NOTIFY_SOCKET"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0))
})
It("podman run log-opt", func() {
log := filepath.Join(podmanTest.TempDir, "/container.log")
session := podmanTest.Podman([]string{"run", "--rm", "--log-opt", fmt.Sprintf("path=%s", log), ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
_, err := os.Stat(log)
Expect(err).To(BeNil())
_ = os.Remove(log)
})
It("podman run tagged image", func() {
podmanTest.RestoreArtifact(BB)
tag := podmanTest.PodmanNoCache([]string{"tag", "busybox", "bb"})
tag.WaitWithDefaultTimeout()
Expect(tag.ExitCode()).To(Equal(0))
session := podmanTest.PodmanNoCache([]string{"run", "--rm", "bb", "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman test hooks", func() {
hcheck := "/run/hookscheck"
hooksDir := tempdir + "/hooks"
os.Mkdir(hooksDir, 0755)
fileutils.CopyFile("hooks/hooks.json", hooksDir)
os.Setenv("HOOK_OPTION", fmt.Sprintf("--hooks-dir=%s", hooksDir))
os.Remove(hcheck)
session := podmanTest.Podman([]string{"run", ALPINE, "ls"})
session.Wait(10)
os.Unsetenv("HOOK_OPTION")
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run with secrets", func() {
SkipIfRemote()
containersDir := filepath.Join(podmanTest.TempDir, "containers")
err := os.MkdirAll(containersDir, 0755)
Expect(err).To(BeNil())
secretsDir := filepath.Join(podmanTest.TempDir, "rhel", "secrets")
err = os.MkdirAll(secretsDir, 0755)
Expect(err).To(BeNil())
mountsFile := filepath.Join(containersDir, "mounts.conf")
mountString := secretsDir + ":/run/secrets"
err = ioutil.WriteFile(mountsFile, []byte(mountString), 0755)
Expect(err).To(BeNil())
secretsFile := filepath.Join(secretsDir, "test.txt")
secretsString := "Testing secrets mount. I am mounted!"
err = ioutil.WriteFile(secretsFile, []byte(secretsString), 0755)
Expect(err).To(BeNil())
targetDir := tempdir + "/symlink/target"
err = os.MkdirAll(targetDir, 0755)
Expect(err).To(BeNil())
keyFile := filepath.Join(targetDir, "key.pem")
err = ioutil.WriteFile(keyFile, []byte(mountString), 0755)
Expect(err).To(BeNil())
execSession := SystemExec("ln", []string{"-s", targetDir, filepath.Join(secretsDir, "mysymlink")})
Expect(execSession.ExitCode()).To(Equal(0))
session := podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "cat", "/run/secrets/test.txt"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal(secretsString))
session = podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "ls", "/run/secrets/mysymlink"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("key.pem"))
})
It("podman run with FIPS mode secrets", func() {
SkipIfRootless()
fipsFile := "/etc/system-fips"
err = ioutil.WriteFile(fipsFile, []byte{}, 0755)
Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls", "/run/secrets"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("system-fips"))
err = os.Remove(fipsFile)
Expect(err).To(BeNil())
})
It("podman run without group-add", func() {
SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)"))
})
It("podman run with group-add", func() {
SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", "--group-add=audio", "--group-add=nogroup", "--group-add=777", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),18(audio),20(dialout),26(tape),27(video),777,65533(nogroup)"))
})
It("podman run with user (default)", func() {
SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video)"))
})
It("podman run with user (integer, not in /etc/passwd)", func() {
session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("uid=1234(1234) gid=0(root)"))
})
It("podman run with user (integer, in /etc/passwd)", func() {
SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", "--user=8", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=12(mail) groups=12(mail)"))
})
It("podman run with user (username)", func() {
SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--rm", "--user=mail", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=12(mail) groups=12(mail)"))
})
It("podman run with user:group (username:integer)", func() {
session := podmanTest.Podman([]string{"run", "--rm", "--user=mail:21", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp)"))
})
It("podman run with user:group (integer:groupname)", func() {
session := podmanTest.Podman([]string{"run", "--rm", "--user=8:ftp", ALPINE, "id"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp)"))
})
It("podman run with user, verify caps dropped", func() {
session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "grep", "CapEff", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
capEff := strings.Split(session.OutputToString(), " ")
Expect("0000000000000000").To(Equal(capEff[1]))
})
It("podman run with attach stdin outputs container ID", func() {
session := podmanTest.Podman([]string{"run", "--attach", "stdin", ALPINE, "printenv"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
ps := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc"})
ps.WaitWithDefaultTimeout()
Expect(ps.ExitCode()).To(Equal(0))
Expect(ps.LineInOutputContains(session.OutputToString())).To(BeTrue())
})
It("podman run with attach stdout does not print stderr", func() {
session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stdout", ALPINE, "ls", "/doesnotexist"})
session.WaitWithDefaultTimeout()
Expect(session.OutputToString()).To(Equal(""))
})
It("podman run with attach stderr does not print stdout", func() {
session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stderr", ALPINE, "ls", "/"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal(""))
})
It("podman run attach nonsense errors", func() {
session := podmanTest.Podman([]string{"run", "--rm", "--attach", "asdfasdf", ALPINE, "ls", "/"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(125))
})
It("podman run exit code on failure to exec", func() {
session := podmanTest.Podman([]string{"run", ALPINE, "/etc"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(126))
})
It("podman run error on exec", func() {
session := podmanTest.Podman([]string{"run", ALPINE, "sh", "-c", "exit 100"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(100))
})
It("podman run with built-in volume image", func() {
SkipIfRemote()
session := podmanTest.Podman([]string{"run", "--rm", redis, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
dockerfile := `FROM busybox
RUN mkdir -p /myvol/data && chown -R mail.0 /myvol
VOLUME ["/myvol/data"]
USER mail`
podmanTest.BuildImage(dockerfile, "test", "false")
session = podmanTest.Podman([]string{"run", "--rm", "test", "ls", "-al", "/myvol/data"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("mail root"))
})
It("podman run --volumes-from flag", func() {
vol := filepath.Join(podmanTest.TempDir, "vol-test")
err := os.MkdirAll(vol, 0755)
Expect(err).To(BeNil())
volFile := filepath.Join(vol, "test.txt")
data := "Testing --volumes-from!!!"
err = ioutil.WriteFile(volFile, []byte(data), 0755)
Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"create", "--volume", vol + ":/myvol", redis, "sh"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
ctrID := session.OutputToString()
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "echo", "'testing read-write!' >> myvol/test.txt"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":z", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run --volumes-from flag with built-in volumes", func() {
session := podmanTest.Podman([]string{"create", redis, "sh"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
ctrID := session.OutputToString()
session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("data"))
})
It("podman run --volumes flag with multiple volumes", func() {
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
err := os.MkdirAll(vol1, 0755)
Expect(err).To(BeNil())
vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
err = os.MkdirAll(vol2, 0755)
Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", ALPINE, "touch", "/myvol2/foo.txt"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run --volumes flag with empty host dir", func() {
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
err := os.MkdirAll(vol1, 0755)
Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"run", "--volume", ":/myvol1:z", ALPINE, "touch", "/myvol2/foo.txt"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
Expect(session.ErrorToString()).To(ContainSubstring("directory cannot be empty"))
session = podmanTest.Podman([]string{"run", "--volume", vol1 + ":", ALPINE, "touch", "/myvol2/foo.txt"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
Expect(session.ErrorToString()).To(ContainSubstring("directory cannot be empty"))
})
It("podman run --mount flag with multiple mounts", func() {
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
err := os.MkdirAll(vol1, 0755)
Expect(err).To(BeNil())
vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
err = os.MkdirAll(vol2, 0755)
Expect(err).To(BeNil())
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"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run findmnt nothing shared", func() {
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
err := os.MkdirAll(vol1, 0755)
Expect(err).To(BeNil())
vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
err = os.MkdirAll(vol2, 0755)
Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
match, _ := session.GrepString("shared")
Expect(match).Should(BeFalse())
})
It("podman run findmnt shared", func() {
vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
err := os.MkdirAll(vol1, 0755)
Expect(err).To(BeNil())
vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
err = os.MkdirAll(vol2, 0755)
Expect(err).To(BeNil())
session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:shared,z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
match, shared := session.GrepString("shared")
Expect(match).Should(BeTrue())
// make sure it's only shared (and not 'shared,slave')
isSharedOnly := !strings.Contains(shared[0], "shared,")
Expect(isSharedOnly).Should(BeTrue())
})
It("podman run --mount type=bind,bind-nonrecursive", func() {
SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--mount", "type=bind,bind-nonrecursive,slave,src=/,target=/host", fedoraMinimal, "findmnt", "-nR", "/host"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(1))
})
It("podman run --mount type=devpts,target=/foo/bar", func() {
SkipIfRootless()
session := podmanTest.Podman([]string{"run", "--mount", "type=devpts,target=/foo/bar", fedoraMinimal, "stat", "-f", "-c%T", "/foo/bar"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("devpts"))
})
It("podman run --pod automatically", func() {
session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:foobar", ALPINE, "nc", "-l", "-p", "8080"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"run", "--pod", "foobar", ALPINE, "/bin/sh", "-c", "echo test | nc -w 1 127.0.0.1 8080"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"})
check.WaitWithDefaultTimeout()
match, _ := check.GrepString("foobar")
Expect(match).To(BeTrue())
})
It("podman run --rm should work", func() {
session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"wait", "test"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
numContainers := podmanTest.NumberOfContainers()
Expect(numContainers).To(Equal(0))
})
It("podman run --rm failed container should delete itself", func() {
session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "foo"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
session = podmanTest.Podman([]string{"wait", "test"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
numContainers := podmanTest.NumberOfContainers()
Expect(numContainers).To(Equal(0))
})
It("podman run failed container should NOT delete itself", func() {
session := podmanTest.Podman([]string{"run", ALPINE, "foo"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
// If remote we could have a race condition
session = podmanTest.Podman([]string{"wait", "test"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
numContainers := podmanTest.NumberOfContainers()
Expect(numContainers).To(Equal(1))
})
It("podman run readonly container should NOT mount /dev/shm read/only", func() {
session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "mount"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Not(ContainSubstring("/dev/shm type tmpfs (ro,")))
})
It("podman run with bad healthcheck retries", func() {
session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-retries", "0", ALPINE, "top"})
session.Wait()
Expect(session).To(ExitWithError())
Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-retries must be greater than 0"))
})
It("podman run with bad healthcheck timeout", func() {
session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-timeout", "0s", ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-timeout must be at least 1 second"))
})
It("podman run with bad healthcheck start-period", func() {
session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-start-period", "-1s", ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-start-period must be 0 seconds or greater"))
})
It("podman run with --add-host and --no-hosts fails", func() {
session := podmanTest.Podman([]string{"run", "-dt", "--add-host", "test1:127.0.0.1", "--no-hosts", ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
})
It("podman run with restart-policy always restarts containers", func() {
SkipIfRemote()
testDir := filepath.Join(podmanTest.RunRoot, "restart-test")
err := os.MkdirAll(testDir, 0755)
Expect(err).To(BeNil())
aliveFile := filepath.Join(testDir, "running")
file, err := os.Create(aliveFile)
Expect(err).To(BeNil())
file.Close()
session := podmanTest.Podman([]string{"run", "-dt", "--restart", "always", "-v", fmt.Sprintf("%s:/tmp/runroot:Z", testDir), fedoraMinimal, "bash", "-c", "date +%N > /tmp/runroot/ran && while test -r /tmp/runroot/running; do sleep 0.1s; done"})
found := false
testFile := filepath.Join(testDir, "ran")
for i := 0; i < 10; i++ {
time.Sleep(1 * time.Second)
if _, err := os.Stat(testFile); err == nil {
found = true
err = os.Remove(testFile)
Expect(err).To(BeNil())
break
}
}
Expect(found).To(BeTrue())
err = os.Remove(aliveFile)
Expect(err).To(BeNil())
session.WaitWithDefaultTimeout()
// 10 seconds to restart the container
found = false
for i := 0; i < 10; i++ {
time.Sleep(1 * time.Second)
if _, err := os.Stat(testFile); err == nil {
found = true
break
}
}
Expect(found).To(BeTrue())
})
It("podman run with cgroups=disabled runs without cgroups", func() {
SkipIfRemote()
SkipIfRootless()
// Only works on crun
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
Skip("Test only works on crun")
}
curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup")
Expect(err).To(BeNil())
var curCgroups string = string(curCgroupsBytes)
fmt.Printf("Output:\n%s\n", curCgroups)
Expect(curCgroups).To(Not(Equal("")))
ctrName := "testctr"
container := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--cgroups=disabled", ALPINE, "top"})
container.WaitWithDefaultTimeout()
Expect(container.ExitCode()).To(Equal(0))
// Get PID and get cgroups of that PID
inspectOut := podmanTest.InspectContainer(ctrName)
Expect(len(inspectOut)).To(Equal(1))
pid := inspectOut[0].State.Pid
Expect(pid).To(Not(Equal(0)))
Expect(inspectOut[0].HostConfig.CgroupParent).To(Equal(""))
ctrCgroupsBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid))
Expect(err).To(BeNil())
var ctrCgroups string = string(ctrCgroupsBytes)
fmt.Printf("Output\n:%s\n", ctrCgroups)
Expect(curCgroups).To(Equal(ctrCgroups))
})
It("podman run with cgroups=enabled makes cgroups", func() {
SkipIfRemote()
SkipIfRootless()
// Only works on crun
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
Skip("Test only works on crun")
}
curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup")
Expect(err).To(BeNil())
var curCgroups string = string(curCgroupsBytes)
fmt.Printf("Output:\n%s\n", curCgroups)
Expect(curCgroups).To(Not(Equal("")))
ctrName := "testctr"
container := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--cgroups=enabled", ALPINE, "top"})
container.WaitWithDefaultTimeout()
Expect(container.ExitCode()).To(Equal(0))
// Get PID and get cgroups of that PID
inspectOut := podmanTest.InspectContainer(ctrName)
Expect(len(inspectOut)).To(Equal(1))
pid := inspectOut[0].State.Pid
Expect(pid).To(Not(Equal(0)))
ctrCgroupsBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid))
Expect(err).To(BeNil())
var ctrCgroups string = string(ctrCgroupsBytes)
fmt.Printf("Output\n:%s\n", ctrCgroups)
Expect(curCgroups).To(Not(Equal(ctrCgroups)))
})
It("podman run with cgroups=garbage errors", func() {
session := podmanTest.Podman([]string{"run", "-d", "--cgroups=garbage", ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
})
It("podman run should fail with nonexist authfile", func() {
session := podmanTest.Podman([]string{"run", "--authfile", "/tmp/nonexist", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
})
It("podman run --device-cgroup-rule", func() {
SkipIfRootless()
deviceCgroupRule := "c 42:* rwm"
session := podmanTest.Podman([]string{"run", "--name", "test", "-d", "--device-cgroup-rule", deviceCgroupRule, ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"exec", "test", "mknod", "newDev", "c", "42", "1"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run --replace", func() {
// Make sure we error out with --name.
session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(125))
// Run and replace 5 times in a row the "same" container.
ctrName := "testCtr"
for i := 0; i < 5; i++ {
session := podmanTest.Podman([]string{"run", "--detach", "--replace", "--name", ctrName, ALPINE, "/bin/sh"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
}
})
It("podman run --preserve-fds", func() {
devNull, err := os.Open("/dev/null")
Expect(err).To(BeNil())
defer devNull.Close()
files := []*os.File{
devNull,
}
session := podmanTest.PodmanExtraFiles([]string{"run", "--preserve-fds", "1", ALPINE, "ls"}, files)
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
})
It("podman run --preserve-fds invalid fd", func() {
session := podmanTest.Podman([]string{"run", "--preserve-fds", "2", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
Expect(session.ErrorToString()).To(ContainSubstring("file descriptor 3 is not available"))
})
It("podman run --privileged and --group-add", func() {
groupName := "kvm"
session := podmanTest.Podman([]string{"run", "-t", "-i", "--group-add", groupName, "--privileged", fedoraMinimal, "groups"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(strings.Contains(session.OutputToString(), groupName)).To(BeTrue())
})
It("podman run --tz", func() {
session := podmanTest.Podman([]string{"run", "--tz", "foo", "--rm", ALPINE, "date"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
session = podmanTest.Podman([]string{"run", "--tz", "America", "--rm", ALPINE, "date"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
session = podmanTest.Podman([]string{"run", "--tz", "Pacific/Honolulu", "--rm", ALPINE, "date", "+'%H %Z'"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("HST"))
session = podmanTest.Podman([]string{"run", "--tz", "local", "--rm", ALPINE, "date", "+'%H %Z'"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
t := time.Now()
z, _ := t.Zone()
h := strconv.Itoa(t.Hour())
Expect(session.OutputToString()).To(ContainSubstring(z))
Expect(session.OutputToString()).To(ContainSubstring(h))
})
It("podman run verify pids-limit", func() {
SkipIfCgroupV1()
limit := "4321"
session := podmanTest.Podman([]string{"run", "--pids-limit", limit, "--rm", ALPINE, "cat", "/sys/fs/cgroup/pids.max"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring(limit))
})
It("podman run umask", func() {
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
Skip("Test only works on crun")
}
session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("0022"))
session = podmanTest.Podman([]string{"run", "--umask", "0002", "--rm", ALPINE, "sh", "-c", "umask"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("0002"))
session = podmanTest.Podman([]string{"run", "--umask", "0077", "--rm", fedoraMinimal, "umask"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("0077"))
session = podmanTest.Podman([]string{"run", "--umask", "22", "--rm", ALPINE, "sh", "-c", "umask"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(Equal("0022"))
session = podmanTest.Podman([]string{"run", "--umask", "9999", "--rm", ALPINE, "sh", "-c", "umask"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask"))
})
It("podman run makes workdir from image", func() {
// BuildImage does not seem to work remote
SkipIfRemote()
dockerfile := `FROM busybox
WORKDIR /madethis`
podmanTest.BuildImage(dockerfile, "test", "false")
session := podmanTest.Podman([]string{"run", "--rm", "test", "pwd"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("/madethis"))
})
It("podman run --entrypoint does not use image command", func() {
session := podmanTest.Podman([]string{"run", "--entrypoint", "/bin/echo", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
// We can't guarantee the output is completely empty, some
// nonprintables seem to work their way in.
Expect(session.OutputToString()).To(Not(ContainSubstring("/bin/sh")))
})
})