diff options
Diffstat (limited to 'test')
48 files changed, 508 insertions, 146 deletions
diff --git a/test/apiv2/10-images.at b/test/apiv2/10-images.at index f854d38ab..a08393668 100644 --- a/test/apiv2/10-images.at +++ b/test/apiv2/10-images.at @@ -126,6 +126,20 @@ t DELETE libpod/images/test:test 200 t GET images/json?filters='{"label":["xyz"]}' 200 length=0 t GET libpod/images/json?filters='{"label":["xyz"]}' 200 length=0 + +# to be used in prune until filter tests +podman image build -t test1:latest -<<EOF +from alpine +RUN >file3 +EOF + +# image should not be deleted +t GET images/json?filters='{"reference":["test1"]}' 200 length=1 +t POST images/prune?filters='{"until":["500000"]}' 200 +t GET images/json?filters='{"reference":["test1"]}' 200 length=1 + +t DELETE libpod/images/test1:latest 200 + # Export more than one image # FIXME FIXME FIXME, this doesn't work: # not ok 64 [10-images] GET images/get?names=alpine,busybox : status diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index 58b2dff0a..23dd374d6 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -205,10 +205,15 @@ t GET containers/$cid/json 200 \ t POST containers/create Image=$IMAGE Entrypoint='["top"]' 201 \ .Id~[0-9a-f]\\{64\\} cid_top=$(jq -r '.Id' <<<"$output") +network_expect="{}" +if root; then + network_expect='.podman.NetworkID=podman' +fi t GET containers/${cid_top}/json 200 \ .Config.Entrypoint[0]="top" \ .Config.Cmd='[]' \ .Path="top" + .NetworkSettings.Networks="$network_expect" t POST containers/${cid_top}/start 204 # make sure the container is running t GET containers/${cid_top}/json 200 \ @@ -258,7 +263,7 @@ cid=$(jq -r '.Id' <<<"$output") t GET containers/$cid/json 200 \ .Image=${MultiTagName} t DELETE containers/$cid 204 -t DELETE images/${MultiTagName}?force=true 200 +t DELETE images/${MultiTagName} 200 # vim: filetype=sh # Test Volumes field adds an anonymous volume diff --git a/test/apiv2/30-volumes.at b/test/apiv2/30-volumes.at index 623e691e3..ed606134a 100644 --- a/test/apiv2/30-volumes.at +++ b/test/apiv2/30-volumes.at @@ -13,6 +13,13 @@ t POST libpod/volumes/create name=foo1 201 \ .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \ .Labels={} \ .Options={} +t POST volumes/create 201 \ + .Name~[0-9a-f]\\{64\\} + .Driver=local \ + .Mountpoint=$volumepath/~[0-9a-f]\\{64\\}/_data \ + .CreatedAt~[0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}.* \ + .Labels={} \ + .Options={} t POST libpod/volumes/create 201 t POST libpod/volumes/create \ Name=foo2 \ diff --git a/test/apiv2/rest_api/test_rest_v2_0_0.py b/test/apiv2/rest_api/test_rest_v2_0_0.py index 3b089e2f2..f66e2b120 100644 --- a/test/apiv2/rest_api/test_rest_v2_0_0.py +++ b/test/apiv2/rest_api/test_rest_v2_0_0.py @@ -614,7 +614,11 @@ class TestApi(unittest.TestCase): # FIXME need method to determine which image is going to be "pruned" to fix test # TODO should handler be recursive when deleting images? # self.assertIn(img["Id"], prune_payload["ImagesDeleted"][1]["Deleted"]) - self.assertIsNotNone(prune_payload["ImagesDeleted"][1]["Deleted"]) + + # FIXME (@vrothberg): I commented this line out during the `libimage` migration. + # It doesn't make sense to report anything to be deleted if the reclaimed space + # is zero. I think the test needs some rewrite. + # self.assertIsNotNone(prune_payload["ImagesDeleted"][1]["Deleted"]) def test_status_compat(self): r = requests.post( diff --git a/test/buildah-bud/apply-podman-deltas b/test/buildah-bud/apply-podman-deltas index 9f6f38190..ecdb9430c 100755 --- a/test/buildah-bud/apply-podman-deltas +++ b/test/buildah-bud/apply-podman-deltas @@ -137,7 +137,8 @@ skip "podman requires a directory, not a Dockerfile" \ # ...or due to Ed's laziness skip "Too much effort to spin up a local registry" \ - "bud with encrypted FROM image" + "bud with encrypted FROM image" \ + "bud --authfile" # ...or due to a fundamental arg-parsing difference between buildah and podman # which we could and perhaps should fix in the buildah repo via: @@ -146,6 +147,14 @@ skip "Too much effort to spin up a local registry" \ skip "FIXME FIXME FIXME: argument-order incompatible with podman" \ "bud-squash-hardlinks" +skip "FIXME FIXME FIXME we'll figure these out later" \ + "bud-multi-stage-nocache-nocommit" \ + "bud with --cgroup-parent" + +# see https://github.com/containers/podman/pull/10147#issuecomment-832503633 +skip "FIXME FIXME FIXME podman save/load has been fixed (but not yet used in Buildah CI)" \ + "bud with --layers and --no-cache flags" + ############################################################################### # BEGIN tests which are skipped due to actual podman bugs. skip "FIXME: podman #9915" \ diff --git a/test/buildah-bud/buildah-tests.diff b/test/buildah-bud/buildah-tests.diff index bba737848..6cda37723 100644 --- a/test/buildah-bud/buildah-tests.diff +++ b/test/buildah-bud/buildah-tests.diff @@ -1,27 +1,18 @@ -From b948e99cb6cb4765987711e8d8948841f6d3f7e2 Mon Sep 17 00:00:00 2001 +From a51192239fafdb59f26c9ddaab1ca9fcac2bb664 Mon Sep 17 00:00:00 2001 From: Ed Santiago <santiago@redhat.com> Date: Tue, 9 Feb 2021 17:28:05 -0700 Subject: [PATCH] tweaks for running buildah tests under podman Signed-off-by: Ed Santiago <santiago@redhat.com> --- - tests/helpers.bash | 28 ++++++++++++++++++++++++---- - 1 file changed, 24 insertions(+), 4 deletions(-) + tests/helpers.bash | 26 +++++++++++++++++++++++--- + 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/tests/helpers.bash b/tests/helpers.bash -index 99c290af..c5572840 100644 +index 4dc3a7dbda13..003575f48cec 100644 --- a/tests/helpers.bash +++ b/tests/helpers.bash -@@ -70,7 +70,7 @@ function _prefetch() { - mkdir -p ${_BUILDAH_IMAGE_CACHEDIR} - fi - -- local _podman_opts="--root ${TESTDIR}/root --storage-driver ${STORAGE_DRIVER}" -+ local _podman_opts="--root ${TESTDIR}/root --runroot ${TESTDIR}/runroot --storage-driver ${STORAGE_DRIVER}" - - for img in "$@"; do - echo "# [checking for: $img]" >&2 -@@ -138,15 +138,35 @@ function run_buildah() { +@@ -140,15 +140,35 @@ function run_buildah() { --retry) retry=3; shift;; # retry network flakes esac @@ -54,11 +45,11 @@ index 99c290af..c5572840 100644 # stdout is only emitted upon error; this echo is to help a debugger - echo "\$ $BUILDAH_BINARY $*" -- run timeout --foreground --kill=10 $BUILDAH_TIMEOUT ${BUILDAH_BINARY} --registries-conf ${TESTSDIR}/registries.conf --root ${TESTDIR}/root --runroot ${TESTDIR}/runroot --storage-driver ${STORAGE_DRIVER} "$@" +- run timeout --foreground --kill=10 $BUILDAH_TIMEOUT ${BUILDAH_BINARY} ${REGISTRY_OPTS} ${ROOTDIR_OPTS} "$@" + echo "\$ $cmd_basename $*" + run timeout --foreground --kill=10 $BUILDAH_TIMEOUT ${podman_or_buildah} --registries-conf ${TESTSDIR}/registries.conf --root ${TESTDIR}/root --runroot ${TESTDIR}/runroot --storage-driver ${STORAGE_DRIVER} "$@" # without "quotes", multiple lines are glommed together into one if [ -n "$output" ]; then echo "$output" -- -2.30.2 +2.31.1 diff --git a/test/compose/ipam_set_ip/docker-compose.yml b/test/compose/ipam_set_ip/docker-compose.yml new file mode 100644 index 000000000..d220c02c0 --- /dev/null +++ b/test/compose/ipam_set_ip/docker-compose.yml @@ -0,0 +1,17 @@ +version: "3.2" +services: + test: + image: alpine + networks: + net1: + ipv4_address: 10.123.0.253 + tty: true + command: ["top"] + +networks: + net1: + driver: bridge + ipam: + driver: default + config: + - subnet: 10.123.0.0/24 diff --git a/test/compose/ipam_set_ip/tests.sh b/test/compose/ipam_set_ip/tests.sh new file mode 100644 index 000000000..ecaf3167e --- /dev/null +++ b/test/compose/ipam_set_ip/tests.sh @@ -0,0 +1,4 @@ +# -*- bash -*- + +podman container inspect ipam_set_ip_test_1 --format '{{ .NetworkSettings.Networks.ipam_set_ip_net1.IPAddress }}' +like "$output" "10.123.0.253" "$testname : ip address is set" diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 9ae56d7ce..359345096 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -320,7 +320,7 @@ func (p *PodmanTestIntegration) createArtifact(image string) { fmt.Printf("Caching %s at %s...", image, destName) if _, err := os.Stat(destName); os.IsNotExist(err) { pull := p.PodmanNoCache([]string{"pull", image}) - pull.Wait(240) + pull.Wait(440) Expect(pull.ExitCode()).To(Equal(0)) save := p.PodmanNoCache([]string{"save", "-o", destName, image}) @@ -605,13 +605,6 @@ func SkipIfRootlessCgroupsV1(reason string) { } } -func SkipIfUnprivilegedCPULimits() { - info := GetHostDistributionInfo() - if isRootless() && info.Distribution == "fedora" { - ginkgo.Skip("Rootless Fedora doesn't have permission to set CPU limits") - } -} - func SkipIfRootless(reason string) { checkReason(reason) if os.Geteuid() != 0 { diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go index 803124de1..a354de3b2 100644 --- a/test/e2e/containers_conf_test.go +++ b/test/e2e/containers_conf_test.go @@ -353,4 +353,23 @@ var _ = Describe("Podman run", func() { Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("test")) }) + + It("podman info seccomp profile path", func() { + configPath := filepath.Join(podmanTest.TempDir, "containers.conf") + os.Setenv("CONTAINERS_CONF", configPath) + + profile := filepath.Join(podmanTest.TempDir, "seccomp.json") + containersConf := []byte(fmt.Sprintf("[containers]\nseccomp_profile=\"%s\"", profile)) + err = ioutil.WriteFile(configPath, containersConf, os.ModePerm) + Expect(err).To(BeNil()) + + if IsRemote() { + podmanTest.RestartRemoteService() + } + + session := podmanTest.Podman([]string{"info", "--format", "{{.Host.Security.SECCOMPProfilePath}}"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(Equal(profile)) + }) }) diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index c3586d9b6..611e8ddac 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -496,6 +496,29 @@ var _ = Describe("Podman generate kube", func() { Expect(inspect.OutputToString()).To(ContainSubstring(vol1)) }) + It("podman generate kube when bind-mounting '/' and '/root' at the same time ", func() { + // Fixes https://github.com/containers/podman/issues/9764 + + ctrName := "mount-root-ctr" + session1 := podmanTest.Podman([]string{"run", "-d", "--pod", "new:mount-root-conflict", "--name", ctrName, + "-v", "/:/volume1/", + "-v", "/root:/volume2/", + "alpine", "top"}) + session1.WaitWithDefaultTimeout() + Expect(session1.ExitCode()).To(Equal(0)) + + kube := podmanTest.Podman([]string{"generate", "kube", "mount-root-conflict"}) + kube.WaitWithDefaultTimeout() + Expect(kube.ExitCode()).To(Equal(0)) + + pod := new(v1.Pod) + err := yaml.Unmarshal(kube.Out.Contents(), pod) + Expect(err).To(BeNil()) + + Expect(len(pod.Spec.Volumes)).To(Equal(2)) + + }) + It("podman generate kube with persistent volume claim", func() { vol := "vol-test-persistent-volume-claim" diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index 3a1da5d8c..75d778f10 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -242,7 +242,7 @@ var _ = Describe("Podman generate systemd", func() { n.WaitWithDefaultTimeout() Expect(n.ExitCode()).To(Equal(0)) - session := podmanTest.Podman([]string{"generate", "systemd", "--timeout", "42", "--name", "--new", "foo"}) + session := podmanTest.Podman([]string{"generate", "systemd", "--time", "42", "--name", "--new", "foo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/load_test.go b/test/e2e/load_test.go index 267f18b0a..3bd75a8f2 100644 --- a/test/e2e/load_test.go +++ b/test/e2e/load_test.go @@ -286,7 +286,7 @@ var _ = Describe("Podman load", func() { }) It("podman load multi-image archive", func() { - result := podmanTest.Podman([]string{"load", "-i", "./testdata/image/docker-two-images.tar.xz"}) + result := podmanTest.Podman([]string{"load", "-i", "./testdata/docker-two-images.tar.xz"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) Expect(result.LineInOutputContains("example.com/empty:latest")).To(BeTrue()) diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index f89da4c05..dc3913394 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -1717,7 +1717,7 @@ spec: } }) - It("podman play kube --ip", func() { + It("podman play kube --ip and --mac-address", func() { var i, numReplicas int32 numReplicas = 3 deployment := getDeployment(withReplicas(numReplicas)) @@ -1735,6 +1735,10 @@ spec: for _, ip := range ips { playArgs = append(playArgs, "--ip", ip) } + macs := []string{"e8:d8:82:c9:80:40", "e8:d8:82:c9:80:50", "e8:d8:82:c9:80:60"} + for _, mac := range macs { + playArgs = append(playArgs, "--mac-address", mac) + } kube := podmanTest.Podman(append(playArgs, kubeYaml)) kube.WaitWithDefaultTimeout() @@ -1747,6 +1751,13 @@ spec: Expect(inspect.ExitCode()).To(Equal(0)) Expect(inspect.OutputToString()).To(Equal(ips[i])) } + + for i = 0; i < numReplicas; i++ { + inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i]), "--format", "{{ .NetworkSettings.Networks." + net + ".MacAddress }}"}) + inspect.WaitWithDefaultTimeout() + Expect(inspect.ExitCode()).To(Equal(0)) + Expect(inspect.OutputToString()).To(Equal(macs[i])) + } }) It("podman play kube test with network portbindings", func() { @@ -1988,8 +1999,7 @@ VOLUME %s`, ALPINE, hostPathDir+"/") It("podman play kube allows setting resource limits", func() { SkipIfContainerized("Resource limits require a running systemd") - SkipIfRootlessCgroupsV1("Limits require root or cgroups v2") - SkipIfUnprivilegedCPULimits() + SkipIfRootless("CPU limits require root") podmanTest.CgroupManager = "systemd" var ( diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index cbe38fc76..38f893a43 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -104,8 +104,9 @@ var _ = Describe("Podman prune", func() { after := podmanTest.Podman([]string{"images", "-a"}) after.WaitWithDefaultTimeout() Expect(none.ExitCode()).To(Equal(0)) + // Check if all "dangling" images were pruned. hasNoneAfter, _ := after.GrepString("<none>") - Expect(hasNoneAfter).To(BeTrue()) + Expect(hasNoneAfter).To(BeFalse()) Expect(len(after.OutputToStringArray()) > 1).To(BeTrue()) }) @@ -135,12 +136,18 @@ var _ = Describe("Podman prune", func() { It("podman image prune unused images", func() { podmanTest.AddImageToRWStore(ALPINE) podmanTest.AddImageToRWStore(BB) + + images := podmanTest.Podman([]string{"images", "-a"}) + images.WaitWithDefaultTimeout() + Expect(images.ExitCode()).To(Equal(0)) + prune := podmanTest.Podman([]string{"image", "prune", "-af"}) prune.WaitWithDefaultTimeout() Expect(prune.ExitCode()).To(Equal(0)) - images := podmanTest.Podman([]string{"images", "-aq"}) + images = podmanTest.Podman([]string{"images", "-aq"}) images.WaitWithDefaultTimeout() + Expect(images.ExitCode()).To(Equal(0)) // all images are unused, so they all should be deleted! Expect(len(images.OutputToStringArray())).To(Equal(len(CACHE_IMAGES))) }) diff --git a/test/e2e/ps_test.go b/test/e2e/ps_test.go index 37b6516c1..2d7d84005 100644 --- a/test/e2e/ps_test.go +++ b/test/e2e/ps_test.go @@ -269,6 +269,12 @@ var _ = Describe("Podman ps", func() { result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) Expect(result.OutputToString()).To(Equal(cid)) + + // Query by truncated image name should not match ( should return empty output ) + result = podmanTest.Podman([]string{"ps", "-q", "--no-trunc", "-a", "--filter", "ancestor=quay.io/libpod/alpi"}) + result.WaitWithDefaultTimeout() + Expect(result.ExitCode()).To(Equal(0)) + Expect(result.OutputToString()).To(Equal("")) }) It("podman ps id filter flag", func() { diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go index 5308548f1..c60ad9487 100644 --- a/test/e2e/pull_test.go +++ b/test/e2e/pull_test.go @@ -86,7 +86,7 @@ var _ = Describe("Podman pull", func() { session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2:none"}) + session = podmanTest.Podman([]string{"rmi", "testdigest_v2s2"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) }) @@ -256,7 +256,7 @@ var _ = Describe("Podman pull", func() { // Pulling a multi-image archive without further specifying // which image _must_ error out. Pulling is restricted to one // image. - session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz")}) + session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz")}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(125)) expectedError := "Unexpected tar manifest.json: expected 1 item, got 2" @@ -265,31 +265,31 @@ var _ = Describe("Podman pull", func() { // Now pull _one_ image from a multi-image archive via the name // and index syntax. - session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:@0")}) + session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:@0")}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:example.com/empty:latest")}) + session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:example.com/empty:latest")}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:@1")}) + session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:@1")}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:example.com/empty/but:different")}) + session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:example.com/empty/but:different")}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) // Now check for some errors. - session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:foo.com/does/not/exist:latest")}) + session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:foo.com/does/not/exist:latest")}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(125)) expectedError = "Tag \"foo.com/does/not/exist:latest\" not found" found, _ = session.ErrorGrepString(expectedError) Expect(found).To(Equal(true)) - session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/image/docker-two-images.tar.xz:@2")}) + session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:./testdata/docker-two-images.tar.xz:@2")}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(125)) expectedError = "Invalid source index @2, only 2 manifest items available" diff --git a/test/e2e/run_cgroup_parent_test.go b/test/e2e/run_cgroup_parent_test.go index d68b1bb5f..1df4c4033 100644 --- a/test/e2e/run_cgroup_parent_test.go +++ b/test/e2e/run_cgroup_parent_test.go @@ -1,7 +1,10 @@ package integration import ( + "fmt" "os" + "path/filepath" + "strings" . "github.com/containers/podman/v3/test/utils" . "github.com/onsi/ginkgo" @@ -58,6 +61,38 @@ var _ = Describe("Podman run with --cgroup-parent", func() { Expect(ok).To(BeTrue()) }) + Specify("always honor --cgroup-parent", func() { + SkipIfCgroupV1("test not supported in cgroups v1") + if Containerized() || podmanTest.CgroupManager == "cgroupfs" { + Skip("Requires Systemd cgroup manager support") + } + if IsRemote() { + Skip("Not supported for remote") + } + + run := podmanTest.Podman([]string{"run", "-d", "--cgroupns=host", fedoraMinimal, "sleep", "100"}) + run.WaitWithDefaultTimeout() + Expect(run.ExitCode()).To(Equal(0)) + cid := run.OutputToString() + + exec := podmanTest.Podman([]string{"exec", cid, "cat", "/proc/self/cgroup"}) + exec.WaitWithDefaultTimeout() + Expect(exec.ExitCode()).To(Equal(0)) + + cgroup := filepath.Dir(strings.TrimRight(strings.Replace(exec.OutputToString(), "0::", "", -1), "\n")) + + run = podmanTest.Podman([]string{"--cgroup-manager=cgroupfs", "run", "-d", fmt.Sprintf("--cgroup-parent=%s", cgroup), fedoraMinimal, "sleep", "100"}) + run.WaitWithDefaultTimeout() + Expect(run.ExitCode()).To(Equal(0)) + + exec = podmanTest.Podman([]string{"exec", cid, "cat", "/proc/self/cgroup"}) + exec.WaitWithDefaultTimeout() + Expect(exec.ExitCode()).To(Equal(0)) + cgroupEffective := filepath.Dir(strings.TrimRight(strings.Replace(exec.OutputToString(), "0::", "", -1), "\n")) + + Expect(cgroupEffective).To(Equal(cgroup)) + }) + Specify("valid --cgroup-parent using slice", func() { if Containerized() || podmanTest.CgroupManager == "cgroupfs" { Skip("Requires Systemd cgroup manager support") diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 4859db524..59220cf01 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -299,9 +299,17 @@ var _ = Describe("Podman run", func() { session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr5", "--security-opt", "systempaths=unconfined", ALPINE, "grep", "/proc", "/proc/self/mounts"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - stdoutLines := session.OutputToStringArray() - Expect(stdoutLines).Should(HaveLen(1)) + Expect(session.OutputToStringArray()).Should(HaveLen(1)) + + session = podmanTest.Podman([]string{"run", "-d", "--security-opt", "unmask=/proc/*", ALPINE, "grep", "/proc", "/proc/self/mounts"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToStringArray()).Should(HaveLen(1)) + session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/proc/a*", ALPINE, "ls", "/proc/acpi"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(Not(BeEmpty())) }) It("podman run security-opt unmask on /sys/fs/cgroup", func() { @@ -582,6 +590,9 @@ USER bin`, BB) if _, err := os.Stat("/sys/fs/cgroup/io.stat"); os.IsNotExist(err) { Skip("Kernel does not have io.stat") } + if _, err := os.Stat("/sys/fs/cgroup/system.slice/io.bfq.weight"); os.IsNotExist(err) { + Skip("Kernel does not support BFQ IO scheduler") + } session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/io.bfq.weight"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -910,6 +921,17 @@ USER mail`, BB) Expect(session.OutputToString()).To(ContainSubstring("mail root")) }) + It("podman run with incorect VOLUME", func() { + dockerfile := fmt.Sprintf(`FROM %s +VOLUME ['/etc/foo'] +WORKDIR /etc/foo`, BB) + podmanTest.BuildImage(dockerfile, "test", "false") + session := podmanTest.Podman([]string{"run", "--rm", "test", "echo", "test"}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + Expect(session.OutputToString()).To(ContainSubstring("test")) + }) + It("podman run --volumes-from flag", func() { vol := filepath.Join(podmanTest.TempDir, "vol-test") err := os.MkdirAll(vol, 0755) diff --git a/test/e2e/testdata/docker-name-only.tar.xz b/test/e2e/testdata/docker-name-only.tar.xz Binary files differnew file mode 100644 index 000000000..0cad9f108 --- /dev/null +++ b/test/e2e/testdata/docker-name-only.tar.xz diff --git a/test/e2e/testdata/docker-registry-name.tar.xz b/test/e2e/testdata/docker-registry-name.tar.xz Binary files differnew file mode 100644 index 000000000..181816c2e --- /dev/null +++ b/test/e2e/testdata/docker-registry-name.tar.xz diff --git a/test/e2e/testdata/docker-two-images.tar.xz b/test/e2e/testdata/docker-two-images.tar.xz Binary files differnew file mode 100644 index 000000000..148d8a86b --- /dev/null +++ b/test/e2e/testdata/docker-two-images.tar.xz diff --git a/test/e2e/testdata/docker-two-names.tar.xz b/test/e2e/testdata/docker-two-names.tar.xz Binary files differnew file mode 100644 index 000000000..07fbc479c --- /dev/null +++ b/test/e2e/testdata/docker-two-names.tar.xz diff --git a/test/e2e/testdata/docker-unnamed.tar.xz b/test/e2e/testdata/docker-unnamed.tar.xz Binary files differnew file mode 100644 index 000000000..ba6ea1bae --- /dev/null +++ b/test/e2e/testdata/docker-unnamed.tar.xz diff --git a/test/e2e/testdata/image b/test/e2e/testdata/image deleted file mode 120000 index a9e67bf9a..000000000 --- a/test/e2e/testdata/image +++ /dev/null @@ -1 +0,0 @@ -../../../libpod/image/testdata/
\ No newline at end of file diff --git a/test/e2e/testdata/oci-name-only.tar.gz b/test/e2e/testdata/oci-name-only.tar.gz Binary files differnew file mode 100644 index 000000000..57bc07564 --- /dev/null +++ b/test/e2e/testdata/oci-name-only.tar.gz diff --git a/test/e2e/testdata/oci-non-docker-name.tar.gz b/test/e2e/testdata/oci-non-docker-name.tar.gz Binary files differnew file mode 100644 index 000000000..5ffc0eabd --- /dev/null +++ b/test/e2e/testdata/oci-non-docker-name.tar.gz diff --git a/test/e2e/testdata/oci-registry-name.tar.gz b/test/e2e/testdata/oci-registry-name.tar.gz Binary files differnew file mode 100644 index 000000000..e6df87339 --- /dev/null +++ b/test/e2e/testdata/oci-registry-name.tar.gz diff --git a/test/e2e/testdata/oci-unnamed.tar.gz b/test/e2e/testdata/oci-unnamed.tar.gz Binary files differnew file mode 100644 index 000000000..de445fdf8 --- /dev/null +++ b/test/e2e/testdata/oci-unnamed.tar.gz diff --git a/test/e2e/testdata/registries.conf b/test/e2e/testdata/registries.conf new file mode 100644 index 000000000..16622a1ac --- /dev/null +++ b/test/e2e/testdata/registries.conf @@ -0,0 +1,4 @@ +short-name-mode="enforcing" + +[aliases] +"busybox"="docker.io/library/busybox" diff --git a/test/e2e/tree_test.go b/test/e2e/tree_test.go index 184b99dfb..33c69554b 100644 --- a/test/e2e/tree_test.go +++ b/test/e2e/tree_test.go @@ -34,8 +34,7 @@ var _ = Describe("Podman image tree", func() { }) It("podman image tree", func() { - SkipIfRemote("Does not work on remote client") - Skip("don't understand why this fails") + SkipIfRemote("podman-image-tree is not supported for remote clients") podmanTest.AddImageToRWStore(cirros) dockerfile := `FROM quay.io/libpod/cirros:latest RUN mkdir hello diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats index 35107f0a0..5d44c373f 100644 --- a/test/system/001-basic.bats +++ b/test/system/001-basic.bats @@ -10,16 +10,18 @@ function setup() { : } -@test "podman --context emits reasonable output" { - run_podman 125 --context=swarm version - is "$output" "Error: Podman does not support swarm, the only --context value allowed is \"default\"" "--context=default or fail" - - run_podman --context=default version -} +#### DO NOT ADD ANY TESTS HERE! ADD NEW TESTS AT BOTTOM! @test "podman version emits reasonable output" { run_podman version + # FIXME FIXME FIXME: #10248: nasty message on Ubuntu cgroups v1, rootless + if [[ "$output" =~ "overlay test mount with multiple lowers failed" ]]; then + if is_rootless; then + lines=("${lines[@]:1}") + fi + fi + # First line of podman-remote is "Client:<blank>". # Just delete it (i.e. remove the first entry from the 'lines' array) if is_remote; then @@ -41,6 +43,17 @@ function setup() { } +@test "podman --context emits reasonable output" { + # All we care about here is that the command passes + run_podman --context=default version + + # This one must fail + run_podman 125 --context=swarm version + is "$output" \ + "Error: Podman does not support swarm, the only --context value allowed is \"default\"" \ + "--context=default or fail" +} + @test "podman can pull an image" { run_podman pull $IMAGE } diff --git a/test/system/005-info.bats b/test/system/005-info.bats index ed341dd17..83d79221a 100644 --- a/test/system/005-info.bats +++ b/test/system/005-info.bats @@ -67,8 +67,7 @@ store.imageStore.number | 1 # RHEL or CentOS 8. # FIXME: what does 'CentOS 8' even mean? What is $VERSION_ID in CentOS? - run_podman info --format '{{.Host.OCIRuntime.Name}}' - is "$output" "runc" "$osname only supports OCI Runtime = runc" + is "$(podman_runtime)" "runc" "$osname only supports OCI Runtime = runc" else skip "only applicable on RHEL, this is $osname" fi diff --git a/test/system/010-images.bats b/test/system/010-images.bats index e7c88408e..bda331e6b 100644 --- a/test/system/010-images.bats +++ b/test/system/010-images.bats @@ -64,7 +64,7 @@ Labels.created_at | 20[0-9-]\\\+T[0-9:]\\\+Z run_podman commit my-container my-test-image run_podman images my-test-image --format '{{ .History }}' - is "$output" "" "Image has empty history to begin with" + is "$output" "localhost/my-test-image:latest" "image history with initial name" # Generate two randomish tags; 'tr' because they must be all lower-case rand_name1="test-image-history-$(random_string 10 | tr A-Z a-z)" @@ -74,13 +74,13 @@ Labels.created_at | 20[0-9-]\\\+T[0-9:]\\\+Z run_podman tag my-test-image $rand_name1 run_podman rmi $rand_name1 run_podman images my-test-image --format '{{ .History }}' - is "$output" "localhost/${rand_name1}:latest" "image history after one tag" + is "$output" "localhost/my-test-image:latest, localhost/${rand_name1}:latest" "image history after one tag" # Repeat with second tag. Now both tags should be in history run_podman tag my-test-image $rand_name2 run_podman rmi $rand_name2 run_podman images my-test-image --format '{{ .History }}' - is "$output" "localhost/${rand_name2}:latest, localhost/${rand_name1}:latest" \ + is "$output" "localhost/my-test-image:latest, localhost/${rand_name2}:latest, localhost/${rand_name1}:latest" \ "image history after two tags" run_podman rmi my-test-image diff --git a/test/system/020-tag.bats b/test/system/020-tag.bats index 1f5eede39..945781afd 100644 --- a/test/system/020-tag.bats +++ b/test/system/020-tag.bats @@ -29,7 +29,7 @@ function _tag_and_check() { # Test error case. run_podman 125 untag $IMAGE registry.com/foo:bar - is "$output" "Error: \"registry.com/foo:bar\": no such tag" + is "$output" "Error: registry.com/foo:bar: tag not known" } @test "podman untag all" { diff --git a/test/system/030-run.bats b/test/system/030-run.bats index b2999a9e7..9a136ff13 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -142,7 +142,7 @@ echo $rand | 0 | $rand NONLOCAL_IMAGE="$PODMAN_NONLOCAL_IMAGE_FQN" run_podman 125 run --pull=never $NONLOCAL_IMAGE true - is "$output" "Error: unable to find a name and tag match for $NONLOCAL_IMAGE in repotags: no such image" "--pull=never [with image not present]: error" + is "$output" "Error: $NONLOCAL_IMAGE: image not known" "--pull=never [with image not present]: error" run_podman run --pull=missing $NONLOCAL_IMAGE true is "$output" "Trying to pull .*" "--pull=missing [with image NOT PRESENT]: fetches" @@ -153,13 +153,11 @@ echo $rand | 0 | $rand run_podman run --pull=always $NONLOCAL_IMAGE true is "$output" "Trying to pull .*" "--pull=always [with image PRESENT]: re-fetches" - # Very weird corner case fixed by #7770: 'podman run foo' will run 'myfoo' - # if it exists, because the string 'foo' appears in 'myfoo'. This test - # covers that, as well as making sure that our testimage (which is always - # tagged :YYYYMMDD, never :latest) doesn't match either. - run_podman tag $IMAGE my${PODMAN_TEST_IMAGE_NAME}:latest - run_podman 125 run --pull=never $PODMAN_TEST_IMAGE_NAME true - is "$output" "Error: unable to find a name and tag match for $PODMAN_TEST_IMAGE_NAME in repotags: no such image" \ + # NOTE: older version of podman would match "foo" against "myfoo". That + # behaviour was changed with introduction of `containers/common/libimage` + # which will only match at repository boundaries (/). + run_podman 125 run --pull=never my$PODMAN_TEST_IMAGE_NAME true + is "$output" "Error: my$PODMAN_TEST_IMAGE_NAME: image not known" \ "podman run --pull=never with shortname (and implicit :latest)" # ...but if we add a :latest tag (without 'my'), it should now work @@ -169,7 +167,7 @@ echo $rand | 0 | $rand "podman run --pull=never, with shortname, succeeds if img is present" run_podman rm -a - run_podman rmi $NONLOCAL_IMAGE {my,}${PODMAN_TEST_IMAGE_NAME}:latest + run_podman rmi $NONLOCAL_IMAGE ${PODMAN_TEST_IMAGE_NAME}:latest } # 'run --rmi' deletes the image in the end unless it's used by another container @@ -243,7 +241,7 @@ echo $rand | 0 | $rand # Save it as a tar archive run_podman commit myc myi archive=$PODMAN_TMPDIR/archive.tar - run_podman save myi -o $archive + run_podman save --quiet myi -o $archive is "$output" "" "podman save" # Clean up image and container from container storage... @@ -501,6 +499,7 @@ json-file | f run_podman inspect --format '{{.OCIRuntime}}' $cid is "$output" "$new_runtime" "podman inspect shows configured runtime" run_podman kill $cid + run_podman wait $cid run_podman rm $cid rm -f $new_runtime } @@ -668,4 +667,27 @@ json-file | f is "$output" ".*HOME=/.*" } +@test "podman run --timeout - basic test" { + cid=timeouttest + t0=$SECONDS + run_podman 255 run --name $cid --timeout 10 $IMAGE sleep 60 + t1=$SECONDS + # Confirm that container is stopped. Podman-remote unfortunately + # cannot tell the difference between "stopped" and "exited", and + # spits them out interchangeably, so we need to recognize either. + run_podman inspect --format '{{.State.Status}} {{.State.ExitCode}}' $cid + is "$output" "\\(stopped\|exited\\) \-1" \ + "Status and exit code of stopped container" + + # This operation should take + # exactly 10 seconds. Give it some leeway. + delta_t=$(( $t1 - $t0 )) + [ $delta_t -gt 8 ] ||\ + die "podman stop: ran too quickly! ($delta_t seconds; expected >= 10)" + [ $delta_t -le 14 ] ||\ + die "podman stop: took too long ($delta_t seconds; expected ~10)" + + run_podman rm $cid +} + # vim: filetype=sh diff --git a/test/system/045-start.bats b/test/system/045-start.bats new file mode 100644 index 000000000..542f9d1c2 --- /dev/null +++ b/test/system/045-start.bats @@ -0,0 +1,60 @@ +#!/usr/bin/env bats -*- bats -*- + +load helpers + +@test "podman start --all - start all containers" { + # Run a bunch of short-lived containers, with different --restart settings + run_podman run -d $IMAGE /bin/true + cid_none_implicit="$output" + run_podman run -d --restart=no $IMAGE /bin/false + cid_none_explicit="$output" + run_podman run -d --restart=on-failure $IMAGE /bin/true + cid_on_failure="$output" + + # Run one longer-lived one. + run_podman run -d --restart=always $IMAGE sleep 20 + cid_always="$output" + + run_podman wait $cid_none_implicit $cid_none_explicit $cid_on_failure + + run_podman start --all + is "$output" ".*$cid_none_implicit" "started: container with no --restart" + is "$output" ".*$cid_none_explicit" "started: container with --restart=no" + is "$output" ".*$cid_on_failure" "started: container with --restart=on-failure" + if [[ $output =~ $cid_always ]]; then + die "podman start --all restarted a running container" + fi + + run_podman rm $cid_none_implicit $cid_none_explicit $cid_on_failure + run_podman stop -t 1 $cid_always + run_podman rm $cid_always +} + +@test "podman start --all with incompatible options" { + expected="Error: either start all containers or the container(s) provided in the arguments" + run_podman 125 start --all 12333 + is "$output" "$expected" "start --all, with args, throws error" + if ! is_remote; then + run_podman 125 start --all --latest + is "$output" "$expected" "podman start --all --latest" + fi +} + +@test "podman start --filter - start only containers that match the filter" { + run_podman run -d $IMAGE /bin/true + cid="$output" + run_podman start --filter restart-policy=always $cid "CID of restart-policy=always container" + is "$output" "" + + run_podman start --filter restart-policy=none $cid "CID of restart-policy=none container" + is "$output" "$cid" +} + +@test "podman start --filter invalid-restart-policy - return error" { + run_podman run -d $IMAGE /bin/true + cid="$output" + run_podman 125 start --filter restart-policy=fakepolicy $cid "CID of restart-policy=<not-exists> container" + is "$output" "Error: fakepolicy invalid restart policy" +} + +# vim: filetype=sh diff --git a/test/system/060-mount.bats b/test/system/060-mount.bats index f04f34bf6..63a93e13b 100644 --- a/test/system/060-mount.bats +++ b/test/system/060-mount.bats @@ -70,7 +70,7 @@ load helpers is "$output" "" "podman image umount: does not re-umount" run_podman 125 image umount no-such-container - is "$output" "Error: unable to find a name and tag match for no-such-container in repotags: no such image" \ + is "$output" "Error: no-such-container: image not known" \ "error message from image umount no-such-container" run_podman image mount diff --git a/test/system/070-build.bats b/test/system/070-build.bats index 6ae78de2e..a2c8ae588 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -393,9 +393,9 @@ Labels.$label_name | $label_value "image tree: third line" is "${lines[3]}" "Image Layers" \ "image tree: fourth line" - is "${lines[4]}" "... ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[$IMAGE]" \ + is "${lines[4]}" ".* ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[localhost/build_test:latest]" \ "image tree: first layer line" - is "${lines[-1]}" "... ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[localhost/build_test:latest]" \ + is "${lines[-1]}" ".* ID: [0-9a-f]\{12\} Size: .* Top Layer of: \[$IMAGE]" \ "image tree: last layer line" # FIXME: 'image tree --whatrequires' does not work via remote @@ -553,6 +553,7 @@ STEP 2: RUN echo x${random2}y x${random2}y${remote_extra} STEP 3: COMMIT build_test${remote_extra} --> [0-9a-f]\{11\} +Successfully tagged localhost/build_test:latest [0-9a-f]\{64\} a${random3}z" @@ -698,7 +699,7 @@ EOF # we're happy. if ! is_remote; then is "$output" \ - ".* pull policy is .never. but .* could not be found locally" \ + ".*Error: error creating build container: quay.io/libpod/nosuchimage:nosuchtag: image not known" \ "--pull-never fails with expected error message" fi } diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats index 98992f973..9a852db89 100644 --- a/test/system/160-volumes.bats +++ b/test/system/160-volumes.bats @@ -123,8 +123,7 @@ EOF # ARGH. Unfortunately, runc (used for cgroups v1) produces a different error local expect_rc=126 local expect_msg='.* OCI permission denied.*' - run_podman info --format '{{ .Host.OCIRuntime.Path }}' - if expr "$output" : ".*/runc"; then + if [[ $(podman_runtime) = "runc" ]]; then expect_rc=1 expect_msg='.* exec user process caused.*permission denied' fi diff --git a/test/system/170-run-userns.bats b/test/system/170-run-userns.bats index 2dc5b078f..eb6c4e259 100644 --- a/test/system/170-run-userns.bats +++ b/test/system/170-run-userns.bats @@ -6,22 +6,31 @@ load helpers +function _require_crun() { + runtime=$(podman_runtime) + if [[ $runtime != "crun" ]]; then + skip "runtime is $runtime; keep-groups requires crun" + fi +} + @test "podman --group-add keep-groups while in a userns" { - skip_if_rootless "choot is not allowed in rootless mode" + skip_if_rootless "chroot is not allowed in rootless mode" skip_if_remote "--group-add keep-groups not supported in remote mode" + _require_crun run chroot --groups 1234 / ${PODMAN} run --uidmap 0:200000:5000 --group-add keep-groups $IMAGE id is "$output" ".*65534(nobody)" "Check group leaked into user namespace" } @test "podman --group-add keep-groups while not in a userns" { - skip_if_rootless "choot is not allowed in rootless mode" + skip_if_rootless "chroot is not allowed in rootless mode" skip_if_remote "--group-add keep-groups not supported in remote mode" + _require_crun run chroot --groups 1234,5678 / ${PODMAN} run --group-add keep-groups $IMAGE id is "$output" ".*1234" "Check group leaked into container" } @test "podman --group-add without keep-groups while in a userns" { - skip_if_rootless "choot is not allowed in rootless mode" + skip_if_rootless "chroot is not allowed in rootless mode" skip_if_remote "--group-add keep-groups not supported in remote mode" run chroot --groups 1234,5678 / ${PODMAN} run --uidmap 0:200000:5000 --group-add 457 $IMAGE id is "$output" ".*457" "Check group leaked into container" diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index ac3ae2f98..b42769409 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -27,23 +27,23 @@ function teardown() { run '?' $SYSTEMCTL stop "$SERVICE_NAME" rm -f "$UNIT_FILE" $SYSTEMCTL daemon-reload + run_podman rmi -a + basic_teardown } -# This test can fail in dev. environment because of SELinux. -# quick fix: chcon -t container_runtime_exec_t ./bin/podman -@test "podman generate - systemd - basic" { +# Helper to setup xdg runtime for rootless +function xdg_rootless() { # podman initializes this if unset, but systemctl doesn't if is_rootless; then if [ -z "$XDG_RUNTIME_DIR" ]; then export XDG_RUNTIME_DIR=/run/user/$(id -u) fi fi +} - cname=$(random_string) - # See #7407 for --pull=always. - run_podman create --pull=always --name $cname --label "io.containers.autoupdate=image" $IMAGE top - +# Helper to start a systemd service running a container +function service_setup() { run_podman generate systemd --new $cname echo "$output" > "$UNIT_FILE" run_podman rm $cname @@ -59,6 +59,30 @@ function teardown() { if [ $status -ne 0 ]; then die "Non-zero status of systemd unit $SERVICE_NAME, output: $output" fi +} + +# Helper to stop a systemd service running a container +function service_cleanup() { + run $SYSTEMCTL stop "$SERVICE_NAME" + if [ $status -ne 0 ]; then + die "Error stopping systemd unit $SERVICE_NAME, output: $output" + fi + + rm -f "$UNIT_FILE" + $SYSTEMCTL daemon-reload +} + +# These tests can fail in dev. environment because of SELinux. +# quick fix: chcon -t container_runtime_exec_t ./bin/podman +@test "podman generate - systemd - basic" { + xdg_rootless + + cname=$(random_string) + # See #7407 for --pull=always. + run_podman create --pull=always --name $cname --label "io.containers.autoupdate=registry" $IMAGE top + + # Start systemd service to run this container + service_setup # Give container time to start; make sure output looks top-like sleep 2 @@ -72,13 +96,33 @@ function teardown() { run_podman auto-update # All good. Stop service, clean up. - run $SYSTEMCTL stop "$SERVICE_NAME" - if [ $status -ne 0 ]; then - die "Error stopping systemd unit $SERVICE_NAME, output: $output" - fi + service_cleanup +} - rm -f "$UNIT_FILE" - $SYSTEMCTL daemon-reload +@test "podman autoupdate local" { + xdg_rootless + + cname=$(random_string) + run_podman create --name $cname --label "io.containers.autoupdate=local" $IMAGE top + + # Start systemd service to run this container + service_setup + + # Give container time to start; make sure output looks top-like + sleep 2 + run_podman logs $cname + is "$output" ".*Load average:.*" "running container 'top'-like output" + + # Save the container id before updating + run_podman ps --format '{{.ID}}' + + # Run auto-update and check that it restarted the container + run_podman commit --change "CMD=/bin/bash" $cname $IMAGE + run_podman auto-update + is $output $SERVICE_NAME "autoupdate local restarted container" + + # All good. Stop service, clean up. + service_cleanup } # vim: filetype=sh diff --git a/test/system/260-sdnotify.bats b/test/system/260-sdnotify.bats index 8bf49eb1d..acb30de47 100644 --- a/test/system/260-sdnotify.bats +++ b/test/system/260-sdnotify.bats @@ -17,9 +17,9 @@ function setup() { # sdnotify fails with runc 1.0.0-3-dev2 on Ubuntu. Let's just # assume that we work only with crun, nothing else. - run_podman info --format '{{ .Host.OCIRuntime.Name }}' - if [[ "$output" != "crun" ]]; then - skip "this test only works with crun, not '$output'" + runtime=$(podman_runtime) + if [[ "$runtime" != "crun" ]]; then + skip "this test only works with crun, not $runtime" fi basic_setup diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats index 8a690fb48..f8cee0e59 100644 --- a/test/system/410-selinux.bats +++ b/test/system/410-selinux.bats @@ -51,18 +51,13 @@ function check_label() { } @test "podman selinux: pid=host" { - # FIXME FIXME FIXME: Remove these lines once all VMs have >= 2.146.0 - # (this is ugly, but better than an unconditional skip) - skip_if_no_selinux + # FIXME this test fails when run rootless with runc: + # Error: container_linux.go:367: starting container process caused: process_linux.go:495: container init caused: readonly path /proc/asound: operation not permitted: OCI permission denied if is_rootless; then - if [ -x /usr/bin/rpm ]; then - cs_version=$(rpm -q --qf '%{version}' container-selinux) - else - # SELinux not enabled on Ubuntu, so we should never get here - die "WHOA! SELinux enabled, but no /usr/bin/rpm!" - fi + runtime=$(podman_runtime) + test "$runtime" == "crun" \ + || skip "runtime is $runtime; this test requires crun" fi - # FIXME FIXME FIXME: delete up to here, leaving just check_label check_label "--pid=host" "spc_t" } @@ -185,30 +180,41 @@ function check_label() { @test "podman with nonexistent labels" { skip_if_no_selinux + # runc and crun emit different diagnostics + runtime=$(podman_runtime) + case "$runtime" in + crun) expect="\`/proc/thread-self/attr/exec\`: OCI runtime error: unable to assign security attribute" ;; + runc) expect="OCI runtime error: .*: failed to set /proc/self/attr/keycreate on procfs" ;; + *) skip "Unknown runtime '$runtime'";; + esac + # The '.*' in the error below is for dealing with podman-remote, which # includes "error preparing container <sha> for attach" in output. run_podman 126 run --security-opt label=type:foo.bar $IMAGE true - is "$output" "Error.*: \`/proc/thread-self/attr/exec\`: OCI runtime error: unable to assign security attribute" "useful diagnostic" + is "$output" "Error.*: $expect" "podman emits useful diagnostic on failure" } @test "podman selinux: check relabel" { skip_if_no_selinux LABEL="system_u:object_r:tmp_t:s0" + RELABEL="system_u:object_r:container_file_t:s0" tmpdir=$PODMAN_TMPDIR/vol touch $tmpdir chcon -vR ${LABEL} $tmpdir ls -Z $tmpdir run_podman run -v $tmpdir:/test $IMAGE cat /proc/self/attr/current - level=$(secon -l $output) run ls -dZ ${tmpdir} is "$output" ${LABEL} "No Relabel Correctly" - run_podman run -v $tmpdir:/test:Z --security-opt label=disable $IMAGE cat /proc/self/attr/current - level=$(secon -l $output) + run_podman run -v $tmpdir:/test:z --security-opt label=disable $IMAGE cat /proc/self/attr/current + run ls -dZ $tmpdir + is "$output" ${RELABEL} "Privileged Relabel Correctly" + + run_podman run -v $tmpdir:/test:z --privileged $IMAGE cat /proc/self/attr/current run ls -dZ $tmpdir - is "$output" ${LABEL} "No Privileged Relabel Correctly" + is "$output" ${RELABEL} "Privileged Relabel Correctly" run_podman run -v $tmpdir:/test:Z $IMAGE cat /proc/self/attr/current level=$(secon -l $output) @@ -217,7 +223,7 @@ function check_label() { run_podman run -v $tmpdir:/test:z $IMAGE cat /proc/self/attr/current run ls -dZ $tmpdir - is "$output" "system_u:object_r:container_file_t:s0" "Shared Relabel Correctly" + is "$output" ${RELABEL} "Shared Relabel Correctly" } # vim: filetype=sh diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index 8da864798..788dc4cd1 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -77,35 +77,48 @@ load helpers # FIXME: randomize port, and create second random host port myport=54321 - # Container will exit as soon as 'nc' receives input - # We use '-n -v' to give us log messages showing an incoming connection - # and its IP address; the purpose of that is guaranteeing that the - # remote IP is not 127.0.0.1 (podman PR #9052). - # We could get more parseable output by using $NCAT_REMOTE_ADDR, - # but busybox nc doesn't support that. - run_podman run -d --userns=keep-id -p 127.0.0.1:$myport:$myport \ - $IMAGE nc -l -n -v -p $myport - cid="$output" - - # emit random string, and check it - teststring=$(random_string 30) - echo "$teststring" | nc 127.0.0.1 $myport - - run_podman logs $cid - # Sigh. We can't check line-by-line, because 'nc' output order is - # unreliable. We usually get the 'connect to' line before the random - # string, but sometimes we get it after. So, just do substring checks. - is "$output" ".*listening on \[::\]:$myport .*" "nc -v shows right port" - - # This is the truly important check: make sure the remote IP is - # in the 10.X range, not 127.X. - is "$output" \ - ".*connect to \[::ffff:10\..*\]:$myport from \[::ffff:10\..*\]:.*" \ - "nc -v shows remote IP address in 10.X space (not 127.0.0.1)" - is "$output" ".*${teststring}.*" "test string received on container" - - # Clean up - run_podman rm $cid + for cidr in "" "$(random_rfc1918_subnet).0/24"; do + myport=$(( myport + 1 )) + if [[ -z $cidr ]]; then + # regex to match that we are in 10.X subnet + match="10\..*" + else + # Issue #9828 make sure a custom slir4netns cidr also works + network_arg="--network slirp4netns:cidr=$cidr" + # slirp4netns interface ip is always .100 + match="${cidr%.*}.100" + fi + + # Container will exit as soon as 'nc' receives input + # We use '-n -v' to give us log messages showing an incoming connection + # and its IP address; the purpose of that is guaranteeing that the + # remote IP is not 127.0.0.1 (podman PR #9052). + # We could get more parseable output by using $NCAT_REMOTE_ADDR, + # but busybox nc doesn't support that. + run_podman run -d --userns=keep-id $network_arg -p 127.0.0.1:$myport:$myport \ + $IMAGE nc -l -n -v -p $myport + cid="$output" + + # emit random string, and check it + teststring=$(random_string 30) + echo "$teststring" | nc 127.0.0.1 $myport + + run_podman logs $cid + # Sigh. We can't check line-by-line, because 'nc' output order is + # unreliable. We usually get the 'connect to' line before the random + # string, but sometimes we get it after. So, just do substring checks. + is "$output" ".*listening on \[::\]:$myport .*" "nc -v shows right port" + + # This is the truly important check: make sure the remote IP is not 127.X. + is "$output" \ + ".*connect to \[::ffff:$match*\]:$myport from \[::ffff:$match\]:.*" \ + "nc -v shows remote IP address is not 127.0.0.1" + is "$output" ".*${teststring}.*" "test string received on container" + + # Clean up + run_podman wait $cid + run_podman rm $cid + done } # "network create" now works rootless, with the help of a special container @@ -128,7 +141,7 @@ load helpers is "$output" ".* inet ${mysubnet}\.2/24 brd ${mysubnet}\.255 " \ "sdfsdf" - run_podman run --rm -d --network $mynetname -p 127.0.0.1:$myport:$myport \ + run_podman run -d --network $mynetname -p 127.0.0.1:$myport:$myport \ $IMAGE nc -l -n -v -p $myport cid="$output" @@ -154,6 +167,7 @@ load helpers is "$output" "Error: the network name $mynetname is already used" \ "Trying to create an already-existing network" + run_podman rm $cid run_podman network rm $mynetname run_podman 1 network rm $mynetname } diff --git a/test/system/build-testimage b/test/system/build-testimage index aac08e307..3e5b982ce 100755 --- a/test/system/build-testimage +++ b/test/system/build-testimage @@ -78,7 +78,7 @@ podman rmi -f testimage &> /dev/null || true # and because Dan says arch emulation is not currently working on podman # (no further details). # Arch emulation on Fedora requires the qemu-user-static package. -for arch in amd64 ppc64le s390x;do +for arch in amd64 arm64v8 ppc64le s390x;do ${BUILDAH} bud \ --arch=$arch \ --build-arg ARCH=$arch \ @@ -106,9 +106,9 @@ ${BUILDAH} manifest push --all ${remote_tag} docker://${remote_tag} # As of 2021-02-24 it is simply busybox, because it is super small, # but it's complicated because of multiarch: # -# img=quay.io/libpod/testimage:00000001 +# img=quay.io/libpod/testimage:0000000<current+1> # buildah manifest create $img -# for arch in amd64 ppc64le s390x;do +# for arch in amd64 arm64v8 ppc64le s390x;do # buildah pull --arch $arch docker.io/$arch/busybox:1.32.0 # buildah manifest add $img docker.io/$arch/busybox:1.32.0 # done diff --git a/test/system/helpers.bash b/test/system/helpers.bash index b9eacfd0b..e0c208f57 100644 --- a/test/system/helpers.bash +++ b/test/system/helpers.bash @@ -7,14 +7,14 @@ PODMAN=${PODMAN:-podman} PODMAN_TEST_IMAGE_REGISTRY=${PODMAN_TEST_IMAGE_REGISTRY:-"quay.io"} PODMAN_TEST_IMAGE_USER=${PODMAN_TEST_IMAGE_USER:-"libpod"} PODMAN_TEST_IMAGE_NAME=${PODMAN_TEST_IMAGE_NAME:-"testimage"} -PODMAN_TEST_IMAGE_TAG=${PODMAN_TEST_IMAGE_TAG:-"20210223"} +PODMAN_TEST_IMAGE_TAG=${PODMAN_TEST_IMAGE_TAG:-"20210427"} PODMAN_TEST_IMAGE_FQN="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:$PODMAN_TEST_IMAGE_TAG" PODMAN_TEST_IMAGE_ID= # Remote image that we *DO NOT* fetch or keep by default; used for testing pull # This changed from 0 to 1 on 2021-02-24 due to multiarch considerations; it # should change only very rarely. -PODMAN_NONLOCAL_IMAGE_FQN="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:00000001" +PODMAN_NONLOCAL_IMAGE_FQN="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:00000002" # Because who wants to spell that out each time? IMAGE=$PODMAN_TEST_IMAGE_FQN @@ -35,6 +35,23 @@ fi # That way individual tests can override with their own setup/teardown, # while retaining the ability to include these if they so desire. +# Some CI systems set this to runc, overriding the default crun. +# Although it would be more elegant to override options in run_podman(), +# we instead override $PODMAN itself because some tests (170-run-userns) +# have to invoke $PODMAN directly. +if [[ -n $OCI_RUNTIME ]]; then + if [[ -z $CONTAINERS_CONF ]]; then + # FIXME: BATS provides no mechanism for end-of-run cleanup[1]; how + # can we avoid leaving this file behind when we finish? + # [1] https://github.com/bats-core/bats-core/issues/39 + export CONTAINERS_CONF=$(mktemp --tmpdir=${BATS_TMPDIR:-/tmp} podman-bats-XXXXXXX.containers.conf) + cat >$CONTAINERS_CONF <<EOF +[engine] +runtime="$OCI_RUNTIME" +EOF + fi +fi + # Setup helper: establish a test environment with exactly the images needed function basic_setup() { # Clean up all containers @@ -284,6 +301,16 @@ function is_cgroupsv2() { test "$cgroup_type" = "cgroup2fs" } +# Returns the OCI runtime *basename* (typically crun or runc). Much as we'd +# love to cache this result, we probably shouldn't. +function podman_runtime() { + # This function is intended to be used as '$(podman_runtime)', i.e. + # our caller wants our output. run_podman() messes with output because + # it emits the command invocation to stdout, hence the redirection. + run_podman info --format '{{ .Host.OCIRuntime.Name }}' >/dev/null + basename "${output:-[null]}" +} + # rhbz#1895105: rootless journald is unavailable except to users in # certain magic groups; which our testuser account does not belong to # (intentional: that is the RHEL default, so that's the setup we test). diff --git a/test/upgrade/README.md b/test/upgrade/README.md index 2979a66d7..6e5005134 100644 --- a/test/upgrade/README.md +++ b/test/upgrade/README.md @@ -84,4 +84,4 @@ Where To Go From Here * Figuring out how/if to run variations with different config files (e.g. running OLD-PODMAN that creates a user libpod.conf, tweaking - that in the test, then running NEW-PODMAN upgrate tests) + that in the test, then running NEW-PODMAN upgrade tests) |