mirror of
https://github.com/containers/podman.git
synced 2025-10-25 02:04:43 +08:00
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>
1167 lines
45 KiB
Go
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")))
|
|
})
|
|
})
|