Files
podman/test/e2e/pod_create_test.go
Daniel J Walsh 6565bde6e8 Add --no-hostname option
Fixes: https://github.com/containers/podman/issues/25002

Also add the ability to inspect containers for
UseImageHosts and UseImageHostname.

Finally fixed some bugs in handling of --no-hosts for Pods,
which I descovered.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
2025-01-15 06:51:32 -05:00

1458 lines
62 KiB
Go

//go:build linux || freebsd
package integration
import (
"fmt"
"os"
"os/user"
"path/filepath"
"strconv"
"strings"
"time"
"github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/seccomp"
"github.com/containers/common/pkg/sysinfo"
"github.com/containers/podman/v5/pkg/util"
. "github.com/containers/podman/v5/test/utils"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/opencontainers/selinux/go-selinux"
)
var _ = Describe("Podman pod create", func() {
hostname, _ := os.Hostname()
It("podman create pod", func() {
_, ec, podID := podmanTest.CreatePod(nil)
Expect(ec).To(Equal(0))
check := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc"})
check.WaitWithDefaultTimeout()
Expect(check.OutputToString()).To(ContainSubstring(podID))
Expect(check.OutputToStringArray()).To(HaveLen(1))
})
It("podman create pod with name", func() {
name := "test"
_, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}})
Expect(ec).To(Equal(0))
check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"})
check.WaitWithDefaultTimeout()
Expect(check.OutputToString()).To(ContainSubstring(name))
})
It("podman create pod with doubled name", func() {
name := "test"
_, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}})
Expect(ec).To(Equal(0))
_, ec2, _ := podmanTest.CreatePod(map[string][]string{"--name": {name}})
Expect(ec2).To(Not(Equal(0)))
check := podmanTest.Podman([]string{"pod", "ps", "-q"})
check.WaitWithDefaultTimeout()
Expect(check.OutputToStringArray()).To(HaveLen(1))
})
It("podman create pod without network portbindings", func() {
name := "test"
session := podmanTest.Podman([]string{"pod", "create", "--name", name})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
pod := session.OutputToString()
webserver := podmanTest.Podman([]string{"run", "--pod", pod, "-dt", NGINX_IMAGE})
webserver.WaitWithDefaultTimeout()
Expect(webserver).Should(ExitCleanly())
check := SystemExec("nc", []string{"-z", "localhost", "80"})
Expect(check).Should(ExitWithError(1, ""))
})
It("podman create pod with network portbindings", func() {
name := "test"
port := GetPort()
session := podmanTest.Podman([]string{"pod", "create", "--name", name, "-p", fmt.Sprintf("%d:80", port)})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
pod := session.OutputToString()
webserver := podmanTest.Podman([]string{"run", "--pod", pod, "-dt", NGINX_IMAGE})
webserver.WaitWithDefaultTimeout()
Expect(webserver).Should(ExitCleanly())
Expect(ncz(port)).To(BeTrue(), "port %d is up", port)
})
It("podman create pod with id file with network portbindings", func() {
file := filepath.Join(podmanTest.TempDir, "pod.id")
name := "test"
port := GetPort()
session := podmanTest.Podman([]string{"pod", "create", "--name", name, "--pod-id-file", file, "-p", fmt.Sprintf("%d:80", port)})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
webserver := podmanTest.Podman([]string{"run", "--pod-id-file", file, "-dt", NGINX_IMAGE})
webserver.WaitWithDefaultTimeout()
Expect(webserver).Should(ExitCleanly())
Expect(ncz(port)).To(BeTrue(), "port %d is up", port)
})
It("podman create pod with no infra but portbindings should fail", func() {
name := "test"
session := podmanTest.Podman([]string{"pod", "create", "--infra=false", "--name", name, "-p", "80:80"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitWithError(125, "you must have an infra container to publish port bindings to the host"))
})
It("podman create pod with --no-hosts", func() {
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--no-hosts", "--name", name})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
alpineResolvConf := podmanTest.Podman([]string{"run", "--rm", "--no-hosts", ALPINE, "cat", "/etc/hosts"})
alpineResolvConf.WaitWithDefaultTimeout()
Expect(alpineResolvConf).Should(ExitCleanly())
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/hosts"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf).Should(ExitCleanly())
Expect(podResolvConf.OutputToString()).To(Equal(alpineResolvConf.OutputToString()))
})
It("podman create pod with --no-hostname", func() {
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--no-hostname", "--name", name})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
alpineHostname := podmanTest.Podman([]string{"run", "--rm", "--no-hostname", ALPINE, "cat", "/etc/hostname"})
alpineHostname.WaitWithDefaultTimeout()
Expect(alpineHostname).Should(ExitCleanly())
podHostname := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/hostname"})
podHostname.WaitWithDefaultTimeout()
Expect(podHostname).Should(ExitCleanly())
Expect(podHostname.OutputToString()).To(Equal(alpineHostname.OutputToString()))
})
It("podman create pod with --no-hosts and no infra should fail", func() {
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--no-hosts", "--name", name, "--infra=false"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "cannot specify --no-hosts without an infra container"))
})
It("podman create pod with --add-host", func() {
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--add-host", "test.example.com:12.34.56.78", "--name", name})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/hosts"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf).Should(ExitCleanly())
Expect(podResolvConf.OutputToString()).To(ContainSubstring("12.34.56.78 test.example.com"))
})
It("podman create pod with --add-host and no infra should fail", func() {
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--add-host", "test.example.com:12.34.56.78", "--name", name, "--infra=false"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "NoInfra and HostAdd are mutually exclusive pod options: invalid pod spec"))
})
It("podman create pod with --add-host and --no-hosts should fail", func() {
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--add-host", "test.example.com:12.34.56.78", "--name", name, "--no-hosts"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "--no-hosts and --add-host cannot be set together"))
})
Describe("podman create pod with --hosts-file", func() {
BeforeEach(func() {
imageHosts := filepath.Join(podmanTest.TempDir, "pause_hosts")
err := os.WriteFile(imageHosts, []byte("56.78.12.34 image.example.com"), 0755)
Expect(err).ToNot(HaveOccurred())
configHosts := filepath.Join(podmanTest.TempDir, "hosts")
err = os.WriteFile(configHosts, []byte("12.34.56.78 config.example.com"), 0755)
Expect(err).ToNot(HaveOccurred())
confFile := filepath.Join(podmanTest.TempDir, "containers.conf")
err = os.WriteFile(confFile, []byte(fmt.Sprintf("[containers]\nbase_hosts_file=\"%s\"\n", configHosts)), 0755)
Expect(err).ToNot(HaveOccurred())
os.Setenv("CONTAINERS_CONF_OVERRIDE", confFile)
if IsRemote() {
podmanTest.RestartRemoteService()
}
dockerfile := strings.Join([]string{
`FROM ` + INFRA_IMAGE,
`COPY pause_hosts /etc/hosts`,
}, "\n")
podmanTest.BuildImage(dockerfile, "foobar.com/hosts_test_pause:latest", "false", "--no-hosts")
})
It("--hosts-file=path", func() {
hostsPath := filepath.Join(podmanTest.TempDir, "hosts")
err := os.WriteFile(hostsPath, []byte("23.45.67.89 file.example.com"), 0755)
Expect(err).ToNot(HaveOccurred())
podCreate := podmanTest.Podman([]string{"pod", "create", "--hostname", "hosts_test.dev", "--hosts-file=" + hostsPath, "--add-host=add.example.com:34.56.78.90", "--infra-image=foobar.com/hosts_test_pause:latest", "--infra-name=hosts_test_infra", "--name", "hosts_test_pod"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", "hosts_test_pod", "--name", "hosts_test", "--rm", ALPINE, "cat", "/etc/hosts"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).ToNot(ContainSubstring("56.78.12.34 image.example.com"))
Expect(session.OutputToString()).ToNot(ContainSubstring("12.34.56.78 config.example.com"))
Expect(session.OutputToString()).To(ContainSubstring("23.45.67.89 file.example.com"))
Expect(session.OutputToString()).To(ContainSubstring("34.56.78.90 add.example.com"))
Expect(session.OutputToString()).To(ContainSubstring("127.0.0.1 localhost"))
Expect(session.OutputToString()).To(ContainSubstring("::1 localhost"))
Expect(session.OutputToString()).To(ContainSubstring("host.containers.internal host.docker.internal"))
Expect(session.OutputToString()).To(ContainSubstring("hosts_test.dev hosts_test_infra"))
Expect(session.OutputToString()).To(ContainSubstring("127.0.0.1 hosts_test"))
})
It("--hosts-file=image", func() {
podCreate := podmanTest.Podman([]string{"pod", "create", "--hostname", "hosts_test.dev", "--hosts-file=image", "--add-host=add.example.com:34.56.78.90", "--infra-image=foobar.com/hosts_test_pause:latest", "--infra-name=hosts_test_infra", "--name", "hosts_test_pod"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", "hosts_test_pod", "--name", "hosts_test", "--rm", ALPINE, "cat", "/etc/hosts"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("56.78.12.34 image.example.com"))
Expect(session.OutputToString()).ToNot(ContainSubstring("12.34.56.78 config.example.com"))
Expect(session.OutputToString()).To(ContainSubstring("34.56.78.90 add.example.com"))
Expect(session.OutputToString()).To(ContainSubstring("127.0.0.1 localhost"))
Expect(session.OutputToString()).To(ContainSubstring("::1 localhost"))
Expect(session.OutputToString()).To(ContainSubstring("host.containers.internal host.docker.internal"))
Expect(session.OutputToString()).To(ContainSubstring("hosts_test.dev hosts_test_infra"))
Expect(session.OutputToString()).To(ContainSubstring("127.0.0.1 hosts_test"))
})
It("--hosts-file=none", func() {
podCreate := podmanTest.Podman([]string{"pod", "create", "--hostname", "hosts_test.dev", "--hosts-file=none", "--add-host=add.example.com:34.56.78.90", "--infra-image=foobar.com/hosts_test_pause:latest", "--infra-name=hosts_test_infra", "--name", "hosts_test_pod"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", "hosts_test_pod", "--name", "hosts_test", "--rm", ALPINE, "cat", "/etc/hosts"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).ToNot(ContainSubstring("56.78.12.34 image.example.com"))
Expect(session.OutputToString()).ToNot(ContainSubstring("12.34.56.78 config.example.com"))
Expect(session.OutputToString()).To(ContainSubstring("34.56.78.90 add.example.com"))
Expect(session.OutputToString()).To(ContainSubstring("127.0.0.1 localhost"))
Expect(session.OutputToString()).To(ContainSubstring("::1 localhost"))
Expect(session.OutputToString()).To(ContainSubstring("host.containers.internal host.docker.internal"))
Expect(session.OutputToString()).To(ContainSubstring("hosts_test.dev hosts_test_infra"))
Expect(session.OutputToString()).To(ContainSubstring("127.0.0.1 hosts_test"))
})
It("--hosts-file= falls back to containers.conf", func() {
podCreate := podmanTest.Podman([]string{"pod", "create", "--hostname", "hosts_test.dev", "--hosts-file=", "--add-host=add.example.com:34.56.78.90", "--infra-image=foobar.com/hosts_test_pause:latest", "--infra-name=hosts_test_infra", "--name", "hosts_test_pod"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", "hosts_test_pod", "--name", "hosts_test", "--rm", ALPINE, "cat", "/etc/hosts"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).ToNot(ContainSubstring("56.78.12.34 image.example.com"))
Expect(session.OutputToString()).To(ContainSubstring("12.34.56.78 config.example.com"))
Expect(session.OutputToString()).To(ContainSubstring("34.56.78.90 add.example.com"))
Expect(session.OutputToString()).To(ContainSubstring("127.0.0.1 localhost"))
Expect(session.OutputToString()).To(ContainSubstring("::1 localhost"))
Expect(session.OutputToString()).To(ContainSubstring("host.containers.internal host.docker.internal"))
Expect(session.OutputToString()).To(ContainSubstring("hosts_test.dev hosts_test_infra"))
Expect(session.OutputToString()).To(ContainSubstring("127.0.0.1 hosts_test"))
})
})
It("podman create pod with --hosts-file and no infra should fail", func() {
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--hosts-file=image", "--name", name, "--infra=false"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "NoInfra and HostsFile are mutually exclusive pod options: invalid pod spec"))
})
It("podman create pod with --hosts-file and --no-hosts should fail", func() {
name := "test"
podCreate := podmanTest.Podman([]string{"pod", "create", "--hosts-file=image", "--name", name, "--no-hosts"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "--no-hosts and --hosts-file cannot be set together"))
})
It("podman create pod with DNS server set", func() {
name := "test"
server := "12.34.56.78"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns", server, "--name", name})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/resolv.conf"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf).Should(ExitCleanly())
Expect(podResolvConf.OutputToString()).To(ContainSubstring("nameserver %s", server))
})
It("podman create pod with DNS server set and no infra should fail", func() {
name := "test"
server := "12.34.56.78"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns", server, "--name", name, "--infra=false"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "NoInfra and DNSServer are mutually exclusive pod options: invalid pod spec"))
})
It("podman create pod with DNS option set", func() {
name := "test"
option := "attempts:5"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-opt", option, "--name", name})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/resolv.conf"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf).Should(ExitCleanly())
Expect(podResolvConf.OutputToString()).To(ContainSubstring(fmt.Sprintf("options %s", option)))
})
It("podman create pod with DNS option set and no infra should fail", func() {
name := "test"
option := "attempts:5"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-opt", option, "--name", name, "--infra=false"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "NoInfra and DNSOption are mutually exclusive pod options: invalid pod spec"))
})
It("podman create pod with DNS search domain set", func() {
name := "test"
search := "example.com"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-search", search, "--name", name})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "cat", "/etc/resolv.conf"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf).Should(ExitCleanly())
Expect(podResolvConf.OutputToString()).To(ContainSubstring(fmt.Sprintf("search %s", search)))
})
It("podman create pod with DNS search domain set and no infra should fail", func() {
name := "test"
search := "example.com"
podCreate := podmanTest.Podman([]string{"pod", "create", "--dns-search", search, "--name", name, "--infra=false"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "NoInfo and DNSSearch are mutually exclusive pod options: invalid pod spec"))
})
It("podman create pod with IP address", func() {
name := "test"
ip := GetSafeIPAddress()
podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", name})
podCreate.WaitWithDefaultTimeout()
// Rootless should error without network
if isRootless() {
Expect(podCreate).Should(ExitWithError(125, "invalid config provided: networks and static ip/mac address can only be used with Bridge mode networking"))
} else {
Expect(podCreate).Should(ExitCleanly())
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "ip", "addr"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf).Should(ExitCleanly())
Expect(podResolvConf.OutputToString()).To(ContainSubstring(ip))
}
})
It("podman container in pod with IP address shares IP address", func() {
SkipIfRootless("Rootless does not support --ip without network")
podName := "test"
ctrName := "testCtr"
ip := GetSafeIPAddress()
podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podCtr := podmanTest.Podman([]string{"run", "--name", ctrName, "--pod", podName, "-d", "-t", ALPINE, "top"})
podCtr.WaitWithDefaultTimeout()
Expect(podCtr).Should(ExitCleanly())
ctrInspect := podmanTest.Podman([]string{"inspect", ctrName})
ctrInspect.WaitWithDefaultTimeout()
Expect(ctrInspect).Should(ExitCleanly())
ctrJSON := ctrInspect.InspectContainerToJSON()
Expect(ctrJSON[0].NetworkSettings).To(HaveField("IPAddress", ip))
})
It("podman create pod with IP address and no infra should fail", func() {
name := "test"
ip := GetSafeIPAddress()
podCreate := podmanTest.Podman([]string{"pod", "create", "--ip", ip, "--name", name, "--infra=false"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "cannot set --ip without infra container: invalid argument"))
})
It("podman create pod with MAC address", func() {
name := "test"
mac := "92:d0:c6:0a:29:35"
podCreate := podmanTest.Podman([]string{"pod", "create", "--mac-address", mac, "--name", name})
podCreate.WaitWithDefaultTimeout()
// Rootless should error
if isRootless() {
Expect(podCreate).Should(ExitWithError(125, "invalid config provided: networks and static ip/mac address can only be used with Bridge mode networking"))
} else {
Expect(podCreate).Should(ExitCleanly())
podResolvConf := podmanTest.Podman([]string{"run", "--pod", name, "--rm", ALPINE, "ip", "addr"})
podResolvConf.WaitWithDefaultTimeout()
Expect(podResolvConf).Should(ExitCleanly())
Expect(podResolvConf.OutputToString()).To(ContainSubstring(mac))
}
})
It("podman create pod with MAC address and no infra should fail", func() {
name := "test"
mac := "92:d0:c6:0a:29:35"
podCreate := podmanTest.Podman([]string{"pod", "create", "--mac-address", mac, "--name", name, "--infra=false"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "cannot set --mac without infra container: invalid argument"))
})
It("podman create pod and print id to external file", func() {
// Switch to temp dir and restore it afterwards
cwd, err := os.Getwd()
Expect(err).ToNot(HaveOccurred())
Expect(os.Chdir(os.TempDir())).To(Succeed())
targetFile := filepath.Join(podmanTest.TempDir, "idFile")
defer Expect(os.RemoveAll(targetFile)).To(BeNil())
defer Expect(os.Chdir(cwd)).To(BeNil())
session := podmanTest.Podman([]string{"pod", "create", "--name=abc", "--pod-id-file", targetFile})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
id, _ := os.ReadFile(targetFile)
check := podmanTest.Podman([]string{"pod", "inspect", "abc"})
check.WaitWithDefaultTimeout()
data := check.InspectPodToJSON()
Expect(data).To(HaveField("ID", string(id)))
})
It("podman pod create --replace", func() {
// Make sure we error out with --name.
session := podmanTest.Podman([]string{"pod", "create", "--replace"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitWithError(125, "cannot replace pod without --name being set"))
// Create and replace 5 times in a row the "same" pod.
podName := "testCtr"
for i := 0; i < 5; i++ {
session = podmanTest.Podman([]string{"pod", "create", "--replace", "--name", podName})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
}
})
It("podman create pod with defaults", func() {
name := "test"
session := podmanTest.Podman([]string{"pod", "create", "--name", name})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
check := podmanTest.Podman([]string{"pod", "inspect", name})
check.WaitWithDefaultTimeout()
Expect(check).Should(ExitCleanly())
data := check.InspectPodToJSON()
check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID})
check1.WaitWithDefaultTimeout()
Expect(check1).Should(ExitCleanly())
Expect(check1.OutputToString()).To(Equal("[/catatonit -P]"))
// check the Path and Args
check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID})
check2.WaitWithDefaultTimeout()
Expect(check2).Should(ExitCleanly())
Expect(check2.OutputToString()).To(Equal("/catatonit:[-P]"))
})
It("podman create pod with --infra-command", func() {
name := "test"
session := podmanTest.Podman([]string{"pod", "create", "--infra-command", "/pause1", "--name", name})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
check := podmanTest.Podman([]string{"pod", "inspect", name})
check.WaitWithDefaultTimeout()
Expect(check).Should(ExitCleanly())
data := check.InspectPodToJSON()
check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID})
check1.WaitWithDefaultTimeout()
Expect(check1).Should(ExitCleanly())
Expect(check1.OutputToString()).To(Equal("[/pause1]"))
// check the Path and Args
check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID})
check2.WaitWithDefaultTimeout()
Expect(check2).Should(ExitCleanly())
Expect(check2.OutputToString()).To(Equal("/pause1:[/pause1]"))
})
It("podman create pod with --infra-image", func() {
dockerfile := `FROM quay.io/libpod/alpine:latest
entrypoint ["/fromimage"]
`
podmanTest.BuildImage(dockerfile, "localhost/infra", "false")
name := "test"
session := podmanTest.Podman([]string{"pod", "create", "--infra-image", "localhost/infra", "--name", name})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
check := podmanTest.Podman([]string{"pod", "inspect", name})
check.WaitWithDefaultTimeout()
Expect(check).Should(ExitCleanly())
data := check.InspectPodToJSON()
check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID})
check1.WaitWithDefaultTimeout()
Expect(check1).Should(ExitCleanly())
Expect(check1.OutputToString()).To(Equal("[/fromimage]"))
// check the Path and Args
check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID})
check2.WaitWithDefaultTimeout()
Expect(check2).Should(ExitCleanly())
Expect(check2.OutputToString()).To(Equal("/fromimage:[/fromimage]"))
})
It("podman create pod with --infra-command --infra-image", func() {
dockerfile := `FROM quay.io/libpod/alpine:latest
entrypoint ["/fromimage"]
`
podmanTest.BuildImage(dockerfile, "localhost/infra", "false")
name := "test"
session := podmanTest.Podman([]string{"pod", "create", "--infra-image", "localhost/infra", "--infra-command", "/fromcommand", "--name", name})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
check := podmanTest.Podman([]string{"pod", "inspect", name})
check.WaitWithDefaultTimeout()
Expect(check).Should(ExitCleanly())
data := check.InspectPodToJSON()
check1 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Config.Entrypoint}}", data.Containers[0].ID})
check1.WaitWithDefaultTimeout()
Expect(check1).Should(ExitCleanly())
Expect(check1.OutputToString()).To(Equal("[/fromcommand]"))
// check the Path and Args
check2 := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.Path}}:{{.Args}}", data.Containers[0].ID})
check2.WaitWithDefaultTimeout()
Expect(check2).Should(ExitCleanly())
Expect(check2.OutputToString()).To(Equal("/fromcommand:[/fromcommand]"))
})
It("podman create pod with slirp network option", func() {
name := "test"
session := podmanTest.Podman([]string{"pod", "create", "--name", name, "--network", "slirp4netns:port_handler=slirp4netns", "-p", "8082:8000"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
check := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{.InfraConfig.NetworkOptions.slirp4netns}}", name})
check.WaitWithDefaultTimeout()
Expect(check).Should(ExitCleanly())
Expect(check.OutputToString()).To(Equal("[port_handler=slirp4netns]"))
})
It("podman pod status test", func() {
podName := "testpod"
create := podmanTest.Podman([]string{"pod", "create", "--name", podName})
create.WaitWithDefaultTimeout()
Expect(create).Should(ExitCleanly())
status1 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName})
status1.WaitWithDefaultTimeout()
Expect(status1).Should(ExitCleanly())
Expect(status1.OutputToString()).To(ContainSubstring("Created"))
ctr1 := podmanTest.Podman([]string{"run", "--pod", podName, "-d", ALPINE, "top"})
ctr1.WaitWithDefaultTimeout()
Expect(ctr1).Should(ExitCleanly())
status2 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName})
status2.WaitWithDefaultTimeout()
Expect(status2).Should(ExitCleanly())
Expect(status2.OutputToString()).To(ContainSubstring("Running"))
ctr2 := podmanTest.Podman([]string{"create", "--pod", podName, ALPINE, "top"})
ctr2.WaitWithDefaultTimeout()
Expect(ctr2).Should(ExitCleanly())
status3 := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{ .State }}", podName})
status3.WaitWithDefaultTimeout()
Expect(status3).Should(ExitCleanly())
Expect(status3.OutputToString()).To(ContainSubstring("Degraded"))
})
It("podman create with unsupported network options", func() {
podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "container:doesnotmatter"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "pods presently do not support network mode container"))
Expect(podCreate.ErrorToString()).To(ContainSubstring("pods presently do not support network mode container"))
})
It("podman pod create with namespace path networking", func() {
SkipIfRootless("ip netns is not supported for rootless users")
SkipIfContainerized("ip netns cannot be run within a container.")
podName := "netnspod"
netNsName := "test1"
networkMode := fmt.Sprintf("ns:/var/run/netns/%s", netNsName)
addNetns := SystemExec("ip", []string{"netns", "add", netNsName})
Expect(addNetns).Should(ExitCleanly())
defer func() {
delNetns := SystemExec("ip", []string{"netns", "delete", netNsName})
Expect(delNetns).Should(ExitCleanly())
}()
podCreate := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--network", networkMode})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podStart := podmanTest.Podman([]string{"pod", "start", podName})
podStart.WaitWithDefaultTimeout()
Expect(podStart).Should(ExitCleanly())
inspectPod := podmanTest.Podman([]string{"pod", "inspect", podName})
inspectPod.WaitWithDefaultTimeout()
Expect(inspectPod).Should(ExitCleanly())
inspectPodJSON := inspectPod.InspectPodToJSON()
inspectInfraContainer := podmanTest.Podman([]string{"inspect", inspectPodJSON.InfraContainerID})
inspectInfraContainer.WaitWithDefaultTimeout()
Expect(inspectInfraContainer).Should(ExitCleanly())
inspectInfraContainerJSON := inspectInfraContainer.InspectContainerToJSON()
Expect(inspectInfraContainerJSON[0].HostConfig.NetworkMode).To(Equal(networkMode))
})
It("podman pod create with --net=none", func() {
podName := "testPod"
podCreate := podmanTest.Podman([]string{"pod", "create", "--network", "none", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "ip", "-o", "-4", "addr"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("inet 127.0.0.1/8 scope host lo"))
Expect(session.OutputToStringArray()).To(HaveLen(1))
})
It("podman pod create --infra-image w/untagged image", func() {
podmanTest.AddImageToRWStore(ALPINE)
dockerfile := `FROM quay.io/libpod/alpine:latest
ENTRYPOINT ["sleep","99999"]
`
// This builds a none/none image
iid := podmanTest.BuildImage(dockerfile, "", "true")
create := podmanTest.Podman([]string{"pod", "create", "--infra-image", iid})
create.WaitWithDefaultTimeout()
Expect(create).Should(ExitCleanly())
})
It("podman pod create --cpus", func() {
podName := "testPod"
numCPU := float64(sysinfo.NumCPU())
period, quota := util.CoresToPeriodAndQuota(numCPU)
numCPUStr := strconv.Itoa(int(numCPU))
podCreate := podmanTest.Podman([]string{"pod", "create", "--cpus", numCPUStr, "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
contCreate := podmanTest.Podman([]string{"container", "create", "--pod", podName, "alpine"})
contCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
podInspect.WaitWithDefaultTimeout()
Expect(podInspect).Should(ExitCleanly())
podJSON := podInspect.InspectPodToJSON()
Expect(podJSON).To(HaveField("CPUPeriod", period))
Expect(podJSON).To(HaveField("CPUQuota", quota))
})
It("podman pod create --cpuset-cpus", func() {
podName := "testPod"
ctrName := "testCtr"
numCPU := float64(sysinfo.NumCPU()) - 1
numCPUStr := strconv.Itoa(int(numCPU))
in := "0-" + numCPUStr
podCreate := podmanTest.Podman([]string{"pod", "create", "--cpuset-cpus", in, "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
contCreate := podmanTest.Podman([]string{"container", "create", "--name", ctrName, "--pod", podName, "alpine"})
contCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
podInspect.WaitWithDefaultTimeout()
Expect(podInspect).Should(ExitCleanly())
podJSON := podInspect.InspectPodToJSON()
Expect(podJSON).To(HaveField("CPUSetCPUs", in))
})
It("podman pod create --pid", func() {
podName := "pidPod"
ns := "ns:/proc/self/ns/"
podCreate := podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
podInspect.WaitWithDefaultTimeout()
Expect(podInspect).Should(ExitCleanly())
podJSON := podInspect.InspectPodToJSON()
Expect(podJSON.InfraConfig).To(HaveField("PidNS", ns))
podName = "pidPod2"
ns = "pod"
podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitWithError(125, "cannot use pod namespace as container is not joining a pod or pod has no infra container: invalid argument"))
podName = "pidPod3"
ns = "host"
podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podInspect = podmanTest.Podman([]string{"pod", "inspect", podName})
podInspect.WaitWithDefaultTimeout()
Expect(podInspect).Should(ExitCleanly())
podJSON = podInspect.InspectPodToJSON()
Expect(podJSON.InfraConfig).To(HaveField("PidNS", "host"))
podName = "pidPod4"
ns = "private"
podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podInspect = podmanTest.Podman([]string{"pod", "inspect", podName})
podInspect.WaitWithDefaultTimeout()
Expect(podInspect).Should(ExitCleanly())
podJSON = podInspect.InspectPodToJSON()
Expect(podJSON.InfraConfig).To(HaveField("PidNS", "private"))
podName = "pidPod5"
ns = "container:randomfakeid"
podCreate = podmanTest.Podman([]string{"pod", "create", "--pid", ns, "--name", podName, "--share", "pid"})
podCreate.WaitWithDefaultTimeout()
// This can fail in two ways, depending on intricate SELinux specifics:
// There are actually two different failure messages:
// container "randomfakeid" not found: no container with name ...
// looking up container to share pid namespace with: no container with name ...
// Too complicated to differentiate in test context, so we ignore the first part
// and just check for the "no container" substring, which is common to both.
Expect(podCreate).Should(ExitWithError(125, `no container with name or ID "randomfakeid" found: no such container`))
})
It("podman pod create with --userns=keep-id", func() {
if !isRootless() {
Skip("Test only runs without root")
}
podName := "testPod"
podCreate := podmanTest.Podman([]string{"pod", "create", "--userns", "keep-id", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "id", "-u"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
uid := strconv.Itoa(os.Geteuid())
Expect(session.OutputToString()).To(ContainSubstring(uid))
// Check passwd
session = podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "id", "-un"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
u, err := user.Current()
Expect(err).ToNot(HaveOccurred())
Expect(session.OutputToString()).To(Equal(u.Username))
// root owns /usr
session = podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "stat", "-c%u", "/usr"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(Equal("0"))
// fail if --pod and --userns set together
session = podmanTest.Podman([]string{"run", "--pod", podName, "--userns", "keep-id", ALPINE, "id", "-u"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitWithError(125, "--userns and --pod cannot be set together"))
})
It("podman pod create with --userns=keep-id can add users", func() {
if !isRootless() {
Skip("Test only runs without root")
}
podName := "testPod"
podCreate := podmanTest.Podman([]string{"pod", "create", "--userns", "keep-id", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
// NOTE: we need to use a Fedora image here since the
// alpine/busybox versions are not capable of dealing with
// --userns=keep-id and will just error out when not running as
// "root"
ctrName := "ctr-name"
session := podmanTest.Podman([]string{"run", "--pod", podName, "-d", "--stop-signal", "9", "--name", ctrName, fedoraMinimal, "sleep", "600"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
u, err := user.Current()
Expect(err).ToNot(HaveOccurred())
// container inside pod inherits user from infra container if --user is not set
// etc/passwd entry will look like USERNAME:*:1000:1000:Full User Name:/:/bin/sh
exec1 := podmanTest.Podman([]string{"exec", ctrName, "id", "-un"})
exec1.WaitWithDefaultTimeout()
Expect(exec1).Should(ExitCleanly())
Expect(exec1.OutputToString()).To(Equal(u.Username))
exec2 := podmanTest.Podman([]string{"exec", ctrName, "useradd", "testuser"})
exec2.WaitWithDefaultTimeout()
Expect(exec2).Should(ExitCleanly())
exec3 := podmanTest.Podman([]string{"exec", ctrName, "cat", "/etc/passwd"})
exec3.WaitWithDefaultTimeout()
Expect(exec3).Should(ExitCleanly())
Expect(exec3.OutputToString()).To(ContainSubstring("testuser"))
})
It("podman pod create with --userns=auto", func() {
u, err := user.Current()
Expect(err).ToNot(HaveOccurred())
name := u.Username
if name == "root" {
name = "containers"
}
content, err := os.ReadFile("/etc/subuid")
if err != nil {
Skip("cannot read /etc/subuid")
}
if !strings.Contains(string(content), name) {
Skip("cannot find mappings for the current user")
}
m := make(map[string]string)
for i := 0; i < 5; i++ {
podName := "testPod" + strconv.Itoa(i)
podCreate := podmanTest.Podman([]string{"pod", "create", "--userns=auto", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/uid_map"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
l := session.OutputToString()
Expect(l).To(ContainSubstring("1024"))
m[l] = l
}
// check for no duplicates
Expect(m).To(HaveLen(5))
})
It("podman pod create --userns=auto:size=%d", func() {
u, err := user.Current()
Expect(err).ToNot(HaveOccurred())
name := u.Username
if name == "root" {
name = "containers"
}
content, err := os.ReadFile("/etc/subuid")
if err != nil {
Skip("cannot read /etc/subuid")
}
if !strings.Contains(string(content), name) {
Skip("cannot find mappings for the current user")
}
podName := "testPod"
podCreate := podmanTest.Podman([]string{"pod", "create", "--userns=auto:size=500", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/uid_map"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("500"))
podName = "testPod-1"
podCreate = podmanTest.Podman([]string{"pod", "create", "--userns=auto:size=3000", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session = podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/uid_map"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("3000"))
})
It("podman pod create --userns=auto:uidmapping=", func() {
u, err := user.Current()
Expect(err).ToNot(HaveOccurred())
name := u.Username
if name == "root" {
name = "containers"
}
content, err := os.ReadFile("/etc/subuid")
if err != nil {
Skip("cannot read /etc/subuid")
}
if !strings.Contains(string(content), name) {
Skip("cannot find mappings for the current user")
}
podName := "testPod"
podCreate := podmanTest.Podman([]string{"pod", "create", "--userns=auto:uidmapping=0:0:1", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/uid_map"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
output := session.OutputToString()
Expect(output).To(MatchRegexp(`(^|\s)0\s+0\s+1(\s|$)`))
podName = "testPod-1"
podCreate = podmanTest.Podman([]string{"pod", "create", "--userns=auto:size=8192,uidmapping=0:0:1", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session = podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/uid_map"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("8191"))
})
It("podman pod create --userns=auto:gidmapping=", func() {
u, err := user.Current()
Expect(err).ToNot(HaveOccurred())
name := u.Username
if name == "root" {
name = "containers"
}
content, err := os.ReadFile("/etc/subuid")
if err != nil {
Skip("cannot read /etc/subuid")
}
if !strings.Contains(string(content), name) {
Skip("cannot find mappings for the current user")
}
podName := "testPod"
podCreate := podmanTest.Podman([]string{"pod", "create", "--userns=auto:gidmapping=0:0:1", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/gid_map"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
output := session.OutputToString()
Expect(output).To(MatchRegexp(`(^|\s)0\s+0\s+1(\s|$)`))
podName = "testPod-1"
podCreate = podmanTest.Podman([]string{"pod", "create", "--userns=auto:size=8192,gidmapping=0:0:1", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session = podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/proc/self/gid_map"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("8191"))
})
It("podman pod create --volume", func() {
volName := "testVol"
volCreate := podmanTest.Podman([]string{"volume", "create", volName})
volCreate.WaitWithDefaultTimeout()
Expect(volCreate).Should(ExitCleanly())
podName := "testPod"
podCreate := podmanTest.Podman([]string{"pod", "create", "--volume", volName + ":/tmp1", "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
podInspect.WaitWithDefaultTimeout()
Expect(podInspect).Should(ExitCleanly())
data := podInspect.InspectPodToJSON()
Expect(data.Mounts[0]).To(HaveField("Name", volName))
ctrName := "testCtr"
ctrCreate := podmanTest.Podman([]string{"create", "--pod", podName, "--name", ctrName, ALPINE})
ctrCreate.WaitWithDefaultTimeout()
Expect(ctrCreate).Should(ExitCleanly())
ctrInspect := podmanTest.Podman([]string{"inspect", ctrName})
ctrInspect.WaitWithDefaultTimeout()
Expect(ctrInspect).Should(ExitCleanly())
ctrData := ctrInspect.InspectContainerToJSON()
Expect(ctrData[0].Mounts[0]).To(HaveField("Name", volName))
ctr2 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "sh", "-c", "echo hello >> " + "/tmp1/test"})
ctr2.WaitWithDefaultTimeout()
Expect(ctr2).Should(ExitCleanly())
ctr3 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/tmp1/test"})
ctr3.WaitWithDefaultTimeout()
Expect(ctr3.OutputToString()).To(ContainSubstring("hello"))
ctr4 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "touch", "/tmp1/testing.txt"})
ctr4.WaitWithDefaultTimeout()
Expect(ctr4).Should(ExitCleanly())
})
It("podman pod create --device", func() {
SkipIfRootless("Cannot create devices in /dev in rootless mode")
// path must be unique to this test, not used anywhere else
devdir := "/dev/devdirpodcreate"
Expect(os.MkdirAll(devdir, os.ModePerm)).To(Succeed())
defer os.RemoveAll(devdir)
mknod := SystemExec("mknod", []string{devdir + "/null", "c", "1", "3"})
mknod.WaitWithDefaultTimeout()
Expect(mknod).Should(ExitCleanly())
podName := "testPod"
session := podmanTest.Podman([]string{"pod", "create", "--device", devdir + ":/dev/bar", "--name", podName})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
session = podmanTest.Podman([]string{"run", "-q", "--pod", podName, ALPINE, "stat", "-c%t:%T", "/dev/bar/null"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(Equal("1:3"))
})
It("podman pod create --volumes-from", func() {
volName := "testVol"
volCreate := podmanTest.Podman([]string{"volume", "create", volName})
volCreate.WaitWithDefaultTimeout()
Expect(volCreate).Should(ExitCleanly())
ctrName := "testCtr"
ctrCreate := podmanTest.Podman([]string{"create", "--volume", volName + ":/tmp1", "--name", ctrName, ALPINE})
ctrCreate.WaitWithDefaultTimeout()
Expect(ctrCreate).Should(ExitCleanly())
ctrInspect := podmanTest.Podman([]string{"inspect", ctrName})
ctrInspect.WaitWithDefaultTimeout()
Expect(ctrInspect).Should(ExitCleanly())
data := ctrInspect.InspectContainerToJSON()
Expect(data[0].Mounts[0]).To(HaveField("Name", volName))
podName := "testPod"
podCreate := podmanTest.Podman([]string{"pod", "create", "--volumes-from", ctrName, "--name", podName})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
podInspect.WaitWithDefaultTimeout()
Expect(podInspect).Should(ExitCleanly())
podData := podInspect.InspectPodToJSON()
Expect(podData.Mounts[0]).To(HaveField("Name", volName))
ctr2 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "sh", "-c", "echo hello >> " + "/tmp1/test"})
ctr2.WaitWithDefaultTimeout()
Expect(ctr2).Should(ExitCleanly())
ctr3 := podmanTest.Podman([]string{"run", "--pod", podName, ALPINE, "cat", "/tmp1/test"})
ctr3.WaitWithDefaultTimeout()
Expect(ctr3.OutputToString()).To(ContainSubstring("hello"))
})
It("podman pod create read network mode from config", func() {
confPath, err := filepath.Abs("config/containers-netns.conf")
Expect(err).ToNot(HaveOccurred())
os.Setenv("CONTAINERS_CONF", confPath)
if IsRemote() {
podmanTest.RestartRemoteService()
}
pod := podmanTest.Podman([]string{"pod", "create", "--name", "test", "--infra-name", "test-infra"})
pod.WaitWithDefaultTimeout()
Expect(pod).Should(ExitCleanly())
inspect := podmanTest.Podman([]string{"inspect", "--format", "{{.HostConfig.NetworkMode}}", "test-infra"})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).Should(Equal("host"))
})
It("podman pod create --security-opt", func() {
if !selinux.GetEnabled() {
Skip("SELinux not enabled")
}
podCreate := podmanTest.Podman([]string{"pod", "create", "--security-opt", "label=type:spc_t", "--security-opt", "seccomp=unconfined"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
ctrCreate := podmanTest.Podman([]string{"container", "create", "--pod", podCreate.OutputToString(), ALPINE})
ctrCreate.WaitWithDefaultTimeout()
Expect(ctrCreate).Should(ExitCleanly())
ctrInspect := podmanTest.InspectContainer(ctrCreate.OutputToString())
Expect(ctrInspect[0].HostConfig).To(HaveField("SecurityOpt", []string{"label=type:spc_t", "seccomp=unconfined"}))
podCreate = podmanTest.Podman([]string{"pod", "create", "--security-opt", "label=disable"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
ctrCreate = podmanTest.Podman([]string{"container", "run", "--pod", podCreate.OutputToString(), ALPINE, "cat", "/proc/self/attr/current"})
ctrCreate.WaitWithDefaultTimeout()
Expect(ctrCreate).Should(ExitCleanly())
Expect(ctrCreate.OutputToString()).To(ContainSubstring("spc_t"))
})
It("podman pod create --security-opt seccomp", func() {
if !seccomp.IsEnabled() {
Skip("seccomp is not enabled")
}
podCreate := podmanTest.Podman([]string{"pod", "create", "--security-opt", "seccomp=unconfined"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
ctrCreate := podmanTest.Podman([]string{"container", "create", "--pod", podCreate.OutputToString(), ALPINE})
ctrCreate.WaitWithDefaultTimeout()
Expect(ctrCreate).Should(ExitCleanly())
ctrInspect := podmanTest.InspectContainer(ctrCreate.OutputToString())
Expect(ctrInspect[0].HostConfig).To(HaveField("SecurityOpt", []string{"seccomp=unconfined"}))
})
It("podman pod create --security-opt apparmor test", func() {
if !apparmor.IsEnabled() {
Skip("Apparmor is not enabled")
}
podCreate := podmanTest.Podman([]string{"pod", "create", "--security-opt", fmt.Sprintf("apparmor=%s", apparmor.Profile)})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
ctrCreate := podmanTest.Podman([]string{"container", "create", "--pod", podCreate.OutputToString(), ALPINE})
ctrCreate.WaitWithDefaultTimeout()
Expect(ctrCreate).Should(ExitCleanly())
inspect := podmanTest.InspectContainer(ctrCreate.OutputToString())
Expect(inspect[0]).To(HaveField("AppArmorProfile", apparmor.Profile))
})
It("podman pod create --sysctl test", func() {
SkipIfRootless("Network sysctls are not available root rootless")
podCreate := podmanTest.Podman([]string{"pod", "create", "--sysctl", "net.core.somaxconn=65535"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "net.core.somaxconn"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("net.core.somaxconn = 65535"))
// if not sharing the net NS, nothing should fail, but the sysctl should not be passed
podCreate = podmanTest.Podman([]string{"pod", "create", "--share", "pid", "--sysctl", "net.core.somaxconn=65535"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session = podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "net.core.somaxconn"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).NotTo(ContainSubstring("net.core.somaxconn = 65535"))
// one other misc option
podCreate = podmanTest.Podman([]string{"pod", "create", "--sysctl", "kernel.msgmax=65535"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session = podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "kernel.msgmax"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("kernel.msgmax = 65535"))
podCreate = podmanTest.Podman([]string{"pod", "create", "--share", "pid", "--sysctl", "kernel.msgmax=65535"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
session = podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), "--rm", ALPINE, "sysctl", "kernel.msgmax"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).NotTo(ContainSubstring("kernel.msgmax = 65535"))
})
It("podman pod create --share-parent test", func() {
SkipIfRootlessCgroupsV1("rootless cannot use cgroups with cgroupsv1")
SkipIfCgroupV1("CgroupMode shows 'host' on CGv1, not CID (issue 15013, wontfix")
podCreate := podmanTest.Podman([]string{"pod", "create", "--share-parent=false"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
ctrCreate := podmanTest.Podman([]string{"run", "-dt", "--pod", podCreate.OutputToString(), ALPINE})
ctrCreate.WaitWithDefaultTimeout()
Expect(ctrCreate).Should(ExitCleanly())
inspectPod := podmanTest.Podman([]string{"pod", "inspect", podCreate.OutputToString()})
inspectPod.WaitWithDefaultTimeout()
Expect(inspectPod).Should(ExitCleanly())
data := inspectPod.InspectPodToJSON()
inspect := podmanTest.InspectContainer(ctrCreate.OutputToString())
Expect(data.CgroupPath).To(BeEmpty())
if podmanTest.CgroupManager == "cgroupfs" || !isRootless() {
Expect(inspect[0].HostConfig.CgroupParent).To(BeEmpty())
} else if podmanTest.CgroupManager == "systemd" {
Expect(inspect[0].HostConfig).To(HaveField("CgroupParent", "user.slice"))
}
podCreate2 := podmanTest.Podman([]string{"pod", "create", "--share", "cgroup,ipc,net,uts", "--share-parent=false", "--infra-name", "cgroupCtr"})
podCreate2.WaitWithDefaultTimeout()
Expect(podCreate2).Should(ExitCleanly())
ctrCreate2 := podmanTest.Podman([]string{"run", "-dt", "--pod", podCreate2.OutputToString(), ALPINE})
ctrCreate2.WaitWithDefaultTimeout()
Expect(ctrCreate2).Should(ExitCleanly())
inspectInfra := podmanTest.InspectContainer("cgroupCtr")
inspect2 := podmanTest.InspectContainer(ctrCreate2.OutputToString())
Expect(inspect2[0].HostConfig.CgroupMode).To(ContainSubstring(inspectInfra[0].ID))
podCreate3 := podmanTest.Podman([]string{"pod", "create", "--share", "cgroup"})
podCreate3.WaitWithDefaultTimeout()
Expect(podCreate3).ShouldNot(ExitCleanly())
})
It("podman pod create infra inheritance test", func() {
volName := "testVol1"
volCreate := podmanTest.Podman([]string{"volume", "create", volName})
volCreate.WaitWithDefaultTimeout()
Expect(volCreate).Should(ExitCleanly())
session := podmanTest.Podman([]string{"pod", "create", "-v", volName + ":/vol1"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
volName2 := "testVol2"
volCreate = podmanTest.Podman([]string{"volume", "create", volName2})
volCreate.WaitWithDefaultTimeout()
Expect(volCreate).Should(ExitCleanly())
session = podmanTest.Podman([]string{"run", "--pod", session.OutputToString(), "-v", volName2 + ":/vol2", ALPINE, "mount"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).Should(ContainSubstring("/vol1"))
Expect(session.OutputToString()).Should(ContainSubstring("/vol2"))
})
It("podman pod create --shm-size", func() {
podCreate := podmanTest.Podman([]string{"pod", "create", "--shm-size", "10mb"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
run := podmanTest.Podman([]string{"run", "--pod", podCreate.OutputToString(), ALPINE, "mount"})
run.WaitWithDefaultTimeout()
Expect(run).Should(ExitCleanly())
t, strings := run.GrepString("shm on /dev/shm type tmpfs")
Expect(t).To(BeTrue(), "found /dev/shm")
Expect(strings[0]).Should(ContainSubstring("size=10240k"))
})
It("podman pod create --shm-size and --ipc=host conflict", func() {
podCreate := podmanTest.Podman([]string{"pod", "create", "--shm-size", "10mb"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
run := podmanTest.Podman([]string{"run", "-dt", "--pod", podCreate.OutputToString(), "--ipc", "host", ALPINE})
run.WaitWithDefaultTimeout()
Expect(run).ShouldNot(ExitCleanly())
})
It("podman pod create --uts test", func() {
session := podmanTest.Podman([]string{"pod", "create", "--uts", "host"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
session = podmanTest.Podman([]string{"run", "--pod", session.OutputToString(), ALPINE, "printenv", "HOSTNAME"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring(hostname))
podName := "utsPod"
ns := "ns:/proc/self/ns/"
// just share uts with a custom path
podCreate := podmanTest.Podman([]string{"pod", "create", "--uts", ns, "--name", podName, "--share", "uts"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(ExitCleanly())
podInspect := podmanTest.Podman([]string{"pod", "inspect", podName})
podInspect.WaitWithDefaultTimeout()
Expect(podInspect).Should(ExitCleanly())
podJSON := podInspect.InspectPodToJSON()
Expect(podJSON.InfraConfig).To(HaveField("UtsNS", ns))
})
It("podman pod create --shm-size-systemd", func() {
podName := "testShmSizeSystemd"
session := podmanTest.Podman([]string{"pod", "create", "--name", podName, "--shm-size-systemd", "10mb"})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
// add container to pod
ctrRun := podmanTest.Podman([]string{"run", "-d", "--pod", podName, SYSTEMD_IMAGE, "/sbin/init"})
ctrRun.WaitWithDefaultTimeout()
Expect(ctrRun).Should(ExitCleanly())
run := podmanTest.Podman([]string{"exec", ctrRun.OutputToString(), "mount"})
run.WaitWithDefaultTimeout()
Expect(run).Should(ExitCleanly())
t, strings := run.GrepString("tmpfs on /run/lock")
Expect(t).To(BeTrue(), "found /run/lock")
Expect(strings[0]).Should(ContainSubstring("size=10240k"))
})
It("create pod with name subset of existing ID", func() {
create1 := podmanTest.Podman([]string{"pod", "create"})
create1.WaitWithDefaultTimeout()
Expect(create1).Should(ExitCleanly())
pod1ID := create1.OutputToString()
pod2Name := pod1ID[:5]
create2 := podmanTest.Podman([]string{"pod", "create", pod2Name})
create2.WaitWithDefaultTimeout()
Expect(create2).Should(ExitCleanly())
inspect := podmanTest.Podman([]string{"pod", "inspect", "--format", "{{.Name}}", pod2Name})
inspect.WaitWithDefaultTimeout()
Expect(inspect).Should(ExitCleanly())
Expect(inspect.OutputToString()).Should(Equal(pod2Name))
})
It("podman pod create --restart set to default", func() {
// When the --restart flag is not set, the default value is No
// TODO: v5.0 change this so that the default value is Always
podName := "mypod"
testCtr := "ctr1"
session := podmanTest.Podman([]string{"pod", "create", podName})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
// add container to pod
ctrRun := podmanTest.Podman([]string{"run", "--name", testCtr, "-d", "--pod", podName, ALPINE, "echo", "hello"})
ctrRun.WaitWithDefaultTimeout()
Expect(ctrRun).Should(ExitCleanly())
// Wait about 1 second, so we can check the number of restarts as default restart policy is set to No
time.Sleep(1 * time.Second)
ps := podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Restarts}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(ExitCleanly())
restarts, err := strconv.Atoi(ps.OutputToString())
Expect(err).ToNot(HaveOccurred())
Expect(restarts).To(BeNumerically("==", 0))
ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Status}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(ExitCleanly())
Expect(ps.OutputToString()).To(ContainSubstring("Exited"))
})
It("podman pod create --restart=on-failure", func() {
// Restart policy set to on-failure with max 2 retries
podName := "mypod"
runningCtr := "ctr1"
testCtr := "ctr2"
session := podmanTest.Podman([]string{"pod", "create", "--restart", "on-failure:2", podName})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
// add container to pod
ctrRun := podmanTest.Podman([]string{"run", "--name", runningCtr, "-d", "--pod", podName, ALPINE, "sleep", "100"})
ctrRun.WaitWithDefaultTimeout()
Expect(ctrRun).Should(ExitCleanly())
ctrRun = podmanTest.Podman([]string{"run", "--name", testCtr, "-d", "--pod", podName, ALPINE, "sh", "-c", "echo hello && exit 1"})
ctrRun.WaitWithDefaultTimeout()
Expect(ctrRun).Should(ExitCleanly())
// Wait about 2 seconds, so we can check the number of restarts after failure
time.Sleep(2 * time.Second)
ps := podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Restarts}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(ExitCleanly())
restarts, err := strconv.Atoi(ps.OutputToString())
Expect(err).ToNot(HaveOccurred())
Expect(restarts).To(BeNumerically("==", 2))
ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Status}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(ExitCleanly())
Expect(ps.OutputToString()).To(ContainSubstring("Exited"))
ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + runningCtr, "--format", "{{.Status}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(ExitCleanly())
Expect(ps.OutputToString()).To(ContainSubstring("Up"))
})
It("podman pod create --restart=no/never", func() {
// never and no are the same, just different words to do the same thing
policy := []string{"no", "never"}
for _, p := range policy {
podName := "mypod-" + p
runningCtr := "ctr1-" + p
testCtr := "ctr2-" + p
testCtr2 := "ctr3-" + p
session := podmanTest.Podman([]string{"pod", "create", "--restart", p, podName})
session.WaitWithDefaultTimeout()
Expect(session).Should(ExitCleanly())
// add container to pod
ctrRun := podmanTest.Podman([]string{"run", "--name", runningCtr, "-d", "--pod", podName, ALPINE, "sleep", "100"})
ctrRun.WaitWithDefaultTimeout()
Expect(ctrRun).Should(ExitCleanly())
ctrRun = podmanTest.Podman([]string{"run", "--name", testCtr, "-d", "--pod", podName, ALPINE, "echo", "hello"})
ctrRun.WaitWithDefaultTimeout()
Expect(ctrRun).Should(ExitCleanly())
ctrRun = podmanTest.Podman([]string{"run", "--name", testCtr2, "-d", "--pod", podName, ALPINE, "sh", "-c", "echo hello && exit 1"})
ctrRun.WaitWithDefaultTimeout()
Expect(ctrRun).Should(ExitCleanly())
// Wait 1 second, so we can check the number of restarts and make sure the container has actually ran
time.Sleep(1 * time.Second)
// check first test container - container exits with exit code 0
ps := podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Restarts}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(ExitCleanly())
restarts, err := strconv.Atoi(ps.OutputToString())
Expect(err).ToNot(HaveOccurred())
Expect(restarts).To(BeNumerically("==", 0))
ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr, "--format", "{{.Status}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(ExitCleanly())
Expect(ps.OutputToString()).To(ContainSubstring("Exited"))
// Check second test container - container exits with non-zero exit code
ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr2, "--format", "{{.Restarts}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(ExitCleanly())
restarts, err = strconv.Atoi(ps.OutputToString())
Expect(err).ToNot(HaveOccurred())
Expect(restarts).To(BeNumerically("==", 0))
ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + testCtr2, "--format", "{{.Status}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(ExitCleanly())
Expect(ps.OutputToString()).To(ContainSubstring("Exited"))
ps = podmanTest.Podman([]string{"ps", "-a", "--filter", "name=" + runningCtr, "--format", "{{.Status}}"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(ExitCleanly())
Expect(ps.OutputToString()).To(ContainSubstring("Up"))
}
})
})