mirror of
https://github.com/containers/podman.git
synced 2025-07-15 03:02:52 +08:00

The initial version of libimage changed the order of layers which has now been restored to remain backwards compatible. Further changes: * Fix a bug in the journald logging which requires to strip trailing new lines from the message. The system tests did not pass due to empty new lines. Triggered by changing the default logger to journald in containers/common. * Fix another bug in the journald logging which embedded the container ID inside the message rather than the specifid field. That surfaced in a preceeding whitespace of each log line which broke the system tests. * Alter the system tests to make sure that the k8s-file and the journald logging drivers are executed. * A number of e2e tests have been changed to force the k8s-file driver to make them pass when running inside a root container. * Increase the timeout in a kill test which seems to take longer now. Reasons are unknown. Tests passed earlier and no signal-related changes happend. It may be CI VM flake since some system tests but other flaked. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
397 lines
14 KiB
Go
397 lines
14 KiB
Go
package integration
|
|
|
|
/*
|
|
toolbox_test.go is under the care of the Toolbox Team.
|
|
|
|
The tests are trying to stress parts of Podman that Toolbox[0] needs for
|
|
its functionality.
|
|
|
|
[0] https://github.com/containers/toolbox
|
|
|
|
Info about test cases:
|
|
- some tests rely on a certain configuration of a container that is done by
|
|
executing several commands in the entry-point of a container. To make
|
|
sure the initialization had enough time to be executed,
|
|
WaitContainerReady() after the container is started.
|
|
|
|
- in several places there's an invocation of 'podman logs' It is there mainly
|
|
to ease debugging when a test goes wrong (during the initialization of a
|
|
container) but sometimes it is also used in the test case itself.
|
|
|
|
Maintainers (Toolbox Team):
|
|
- Ondřej Míchal <harrymichal@fedoraproject.org>
|
|
- Debarshi Ray <rishi@fedoraproject.org>
|
|
|
|
Also available on Freenode IRC on #silverblue or #podman
|
|
*/
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"os/user"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/containers/podman/v3/pkg/rootless"
|
|
. "github.com/containers/podman/v3/test/utils"
|
|
. "github.com/onsi/ginkgo"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("Toolbox-specific testing", 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 --dns=none - allows self-management of /etc/resolv.conf", func() {
|
|
var session *PodmanSessionIntegration
|
|
|
|
session = podmanTest.Podman([]string{"run", "--dns", "none", ALPINE, "sh", "-c",
|
|
"rm -f /etc/resolv.conf; touch -d '1970-01-01 00:02:03' /etc/resolv.conf; stat -c %s:%Y /etc/resolv.conf"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring("0:123"))
|
|
})
|
|
|
|
It("podman run --no-hosts - allows self-management of /etc/hosts", func() {
|
|
var session *PodmanSessionIntegration
|
|
|
|
session = podmanTest.Podman([]string{"run", "--no-hosts", ALPINE, "sh", "-c",
|
|
"rm -f /etc/hosts; touch -d '1970-01-01 00:02:03' /etc/hosts; stat -c %s:%Y /etc/hosts"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring("0:123"))
|
|
})
|
|
|
|
It("podman create --ulimit host + podman exec - correctly mirrors hosts ulimits", func() {
|
|
if podmanTest.RemoteTest {
|
|
Skip("Ulimit check does not work with a remote client")
|
|
}
|
|
var session *PodmanSessionIntegration
|
|
var containerHardLimit int
|
|
var rlimit syscall.Rlimit
|
|
var err error
|
|
|
|
err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit)
|
|
Expect(err).To(BeNil())
|
|
fmt.Printf("Expected value: %d", rlimit.Max)
|
|
|
|
session = podmanTest.Podman([]string{"create", "--name", "test", "--ulimit", "host", ALPINE,
|
|
"sleep", "1000"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
session = podmanTest.Podman([]string{"start", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test", "sh", "-c",
|
|
"ulimit -H -n"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
containerHardLimit, err = strconv.Atoi(strings.Trim(session.OutputToString(), "\n"))
|
|
Expect(err).To(BeNil())
|
|
Expect(containerHardLimit).To(BeNumerically(">=", rlimit.Max))
|
|
})
|
|
|
|
It("podman create --ipc=host --pid=host + podman exec - correct shared memory limit size", func() {
|
|
// Comparison of the size of /dev/shm on the host being equal to the one in
|
|
// a container
|
|
if podmanTest.RemoteTest {
|
|
Skip("Shm size check does not work with a remote client")
|
|
}
|
|
SkipIfRootlessCgroupsV1("Not supported for rootless + CGroupsV1")
|
|
var session *PodmanSessionIntegration
|
|
var cmd *exec.Cmd
|
|
var hostShmSize, containerShmSize int
|
|
var err error
|
|
|
|
// Because Alpine uses busybox, most commands don't offer advanced options
|
|
// like "--output" in df. Therefore the value of the field 'Size' (or
|
|
// ('1K-blocks') needs to be extracted manually.
|
|
cmd = exec.Command("df", "/dev/shm")
|
|
res, err := cmd.Output()
|
|
Expect(err).To(BeNil())
|
|
lines := strings.SplitN(string(res), "\n", 2)
|
|
fields := strings.Fields(lines[len(lines)-1])
|
|
hostShmSize, err = strconv.Atoi(fields[1])
|
|
Expect(err).To(BeNil())
|
|
|
|
session = podmanTest.Podman([]string{"create", "--name", "test", "--ipc=host", "--pid=host", ALPINE,
|
|
"sleep", "1000"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
session = podmanTest.Podman([]string{"start", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test",
|
|
"df", "/dev/shm"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
lines = session.OutputToStringArray()
|
|
fields = strings.Fields(lines[len(lines)-1])
|
|
containerShmSize, err = strconv.Atoi(fields[1])
|
|
Expect(err).To(BeNil())
|
|
|
|
// In some cases it may happen that the size of /dev/shm is not exactly
|
|
// equal. Therefore it's fine if there's a slight tolerance between the
|
|
// compared values.
|
|
Expect(hostShmSize).To(BeNumerically("~", containerShmSize, 100))
|
|
})
|
|
|
|
It("podman create --userns=keep-id --user root:root - entrypoint - entrypoint is executed as root", func() {
|
|
var session *PodmanSessionIntegration
|
|
|
|
session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", ALPINE,
|
|
"id"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring("uid=0(root) gid=0(root)"))
|
|
})
|
|
|
|
It("podman create --userns=keep-id + podman exec - correct names of user and group", func() {
|
|
var session *PodmanSessionIntegration
|
|
var err error
|
|
|
|
currentUser, err := user.Current()
|
|
Expect(err).To(BeNil())
|
|
|
|
currentGroup, err := user.LookupGroupId(currentUser.Gid)
|
|
Expect(err).To(BeNil())
|
|
|
|
session = podmanTest.Podman([]string{"create", "--name", "test", "--userns=keep-id", ALPINE,
|
|
"sleep", "1000"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(err).To(BeNil())
|
|
|
|
session = podmanTest.Podman([]string{"start", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
expectedOutput := fmt.Sprintf("uid=%s(%s) gid=%s(%s)",
|
|
currentUser.Uid, currentUser.Username,
|
|
currentGroup.Gid, currentGroup.Name)
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test",
|
|
"id"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring(expectedOutput))
|
|
})
|
|
|
|
It("podman create --userns=keep-id - entrypoint - adding user with useradd and then removing their password", func() {
|
|
var session *PodmanSessionIntegration
|
|
|
|
var username string = "testuser"
|
|
var homeDir string = "/home/testuser"
|
|
var shell string = "/bin/sh"
|
|
var uid string = "1001"
|
|
var gid string = "1001"
|
|
|
|
useradd := fmt.Sprintf("useradd --home-dir %s --shell %s --uid %s %s",
|
|
homeDir, shell, uid, username)
|
|
passwd := fmt.Sprintf("passwd --delete %s", username)
|
|
session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c",
|
|
fmt.Sprintf("%s; %s; echo READY; sleep 1000", useradd, passwd)})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
session = podmanTest.Podman([]string{"start", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue())
|
|
|
|
expectedOutput := fmt.Sprintf("%s:x:%s:%s::%s:%s",
|
|
username, uid, gid, homeDir, shell)
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test", "cat", "/etc/passwd"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring(expectedOutput))
|
|
|
|
expectedOutput = "passwd: Note: deleting a password also unlocks the password."
|
|
|
|
session = podmanTest.Podman([]string{"logs", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.ErrorToString()).To(ContainSubstring(expectedOutput))
|
|
})
|
|
|
|
It("podman create --userns=keep-id + podman exec - adding group with groupadd", func() {
|
|
var session *PodmanSessionIntegration
|
|
|
|
var groupName string = "testgroup"
|
|
var gid string = "1001"
|
|
|
|
groupadd := fmt.Sprintf("groupadd --gid %s %s", gid, groupName)
|
|
|
|
session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c",
|
|
fmt.Sprintf("%s; echo READY; sleep 1000", groupadd)})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
session = podmanTest.Podman([]string{"start", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue())
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test", "cat", "/etc/group"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring(groupName))
|
|
|
|
session = podmanTest.Podman([]string{"logs", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring("READY"))
|
|
})
|
|
|
|
It("podman create --userns=keep-id - entrypoint - modifying existing user with usermod - add to new group, change home/shell/uid", func() {
|
|
var session *PodmanSessionIntegration
|
|
var badHomeDir string = "/home/badtestuser"
|
|
var badShell string = "/bin/sh"
|
|
var badUID string = "1001"
|
|
var username string = "testuser"
|
|
var homeDir string = "/home/testuser"
|
|
var shell string = "/bin/bash"
|
|
var uid string = "2000"
|
|
var groupName string = "testgroup"
|
|
var gid string = "2000"
|
|
|
|
// The use of bad* in the name of variables does not imply the invocation
|
|
// of useradd should fail The user is supposed to be created successfully
|
|
// but later his information (uid, home, shell,..) is changed via usermod.
|
|
useradd := fmt.Sprintf("useradd --home-dir %s --shell %s --uid %s %s",
|
|
badHomeDir, badShell, badUID, username)
|
|
groupadd := fmt.Sprintf("groupadd --gid %s %s",
|
|
gid, groupName)
|
|
usermod := fmt.Sprintf("usermod --append --groups wheel --home %s --shell %s --uid %s --gid %s %s",
|
|
homeDir, shell, uid, gid, username)
|
|
|
|
session = podmanTest.Podman([]string{"create", "--log-driver", "k8s-file", "--name", "test", "--userns=keep-id", "--user", "root:root", fedoraToolbox, "sh", "-c",
|
|
fmt.Sprintf("%s; %s; %s; echo READY; sleep 1000", useradd, groupadd, usermod)})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
session = podmanTest.Podman([]string{"start", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue())
|
|
|
|
expectedUser := fmt.Sprintf("%s:x:%s:%s::%s:%s",
|
|
username, uid, gid, homeDir, shell)
|
|
|
|
session = podmanTest.Podman([]string{"exec", "test", "cat", "/etc/passwd"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring(expectedUser))
|
|
|
|
session = podmanTest.Podman([]string{"logs", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring("READY"))
|
|
})
|
|
|
|
It("podman run --privileged --userns=keep-id --user root:root - entrypoint - (bind)mounting", func() {
|
|
var session *PodmanSessionIntegration
|
|
|
|
session = podmanTest.Podman([]string{"run", "--privileged", "--userns=keep-id", "--user", "root:root", ALPINE,
|
|
"mount", "-t", "tmpfs", "tmpfs", "/tmp"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
session = podmanTest.Podman([]string{"run", "--privileged", "--userns=keep-id", "--user", "root:root", ALPINE,
|
|
"mount", "--rbind", "/tmp", "/var/tmp"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
})
|
|
|
|
It("podman create + start - with all needed switches for create - sleep as entry-point", func() {
|
|
var session *PodmanSessionIntegration
|
|
|
|
// These should be most of the switches that Toolbox uses to create a "toolbox" container
|
|
// https://github.com/containers/toolbox/blob/master/src/cmd/create.go
|
|
session = podmanTest.Podman([]string{"create",
|
|
"--log-driver", "k8s-file",
|
|
"--dns", "none",
|
|
"--hostname", "toolbox",
|
|
"--ipc", "host",
|
|
"--label", "com.github.containers.toolbox=true",
|
|
"--name", "test",
|
|
"--network", "host",
|
|
"--no-hosts",
|
|
"--pid", "host",
|
|
"--privileged",
|
|
"--security-opt", "label=disable",
|
|
"--ulimit", "host",
|
|
"--userns=keep-id",
|
|
"--user", "root:root",
|
|
fedoraToolbox, "sh", "-c", "echo READY; sleep 1000"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
session = podmanTest.Podman([]string{"start", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
|
|
Expect(WaitContainerReady(podmanTest, "test", "READY", 5, 1)).To(BeTrue())
|
|
|
|
session = podmanTest.Podman([]string{"logs", "test"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring("READY"))
|
|
})
|
|
|
|
It("podman run --userns=keep-id check $HOME", func() {
|
|
var session *PodmanSessionIntegration
|
|
|
|
currentUser, err := user.Current()
|
|
Expect(err).To(BeNil())
|
|
|
|
session = podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:%s", currentUser.HomeDir, currentUser.HomeDir), "--userns=keep-id", fedoraToolbox, "sh", "-c", "echo $HOME"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring(currentUser.HomeDir))
|
|
|
|
if rootless.IsRootless() {
|
|
location := path.Dir(currentUser.HomeDir)
|
|
volumeArg := fmt.Sprintf("%s:%s", location, location)
|
|
session = podmanTest.Podman([]string{"run",
|
|
"--userns=keep-id",
|
|
"--volume", volumeArg,
|
|
fedoraToolbox, "sh", "-c", "echo $HOME"})
|
|
session.WaitWithDefaultTimeout()
|
|
Expect(session.ExitCode()).To(Equal(0))
|
|
Expect(session.OutputToString()).To(ContainSubstring(currentUser.HomeDir))
|
|
}
|
|
})
|
|
|
|
})
|