summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/e2e/create_test.go12
-rw-r--r--test/e2e/inspect_test.go18
-rw-r--r--test/e2e/network_connect_disconnect_test.go123
-rw-r--r--test/e2e/network_test.go7
-rw-r--r--test/e2e/run_networking_test.go14
-rw-r--r--test/e2e/run_test.go5
-rw-r--r--test/e2e/run_volume_test.go53
-rw-r--r--test/system/030-run.bats4
-rw-r--r--test/system/055-rm.bats7
-rw-r--r--test/system/065-cp.bats12
-rw-r--r--test/system/070-build.bats4
-rwxr-xr-xtest/system/build-testimage52
-rw-r--r--test/system/helpers.bash7
13 files changed, 288 insertions, 30 deletions
diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go
index 43da95a9d..1f1786dbe 100644
--- a/test/e2e/create_test.go
+++ b/test/e2e/create_test.go
@@ -9,6 +9,7 @@ import (
"strings"
. "github.com/containers/podman/v3/test/utils"
+ "github.com/containers/storage/pkg/stringid"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
@@ -576,15 +577,20 @@ var _ = Describe("Podman create", func() {
Expect(session.ExitCode()).ToNot(BeZero())
})
- It("create container in pod with network should fail", func() {
+ It("create container in pod with network should not fail", func() {
name := "createwithnetwork"
pod := podmanTest.RunTopContainerInPod("", "new:"+name)
pod.WaitWithDefaultTimeout()
Expect(pod.ExitCode()).To(BeZero())
- session := podmanTest.Podman([]string{"create", "--pod", name, "--network", "foobar", ALPINE, "top"})
+ netName := "pod" + stringid.GenerateNonCryptoID()
+ session := podmanTest.Podman([]string{"network", "create", netName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ defer podmanTest.removeCNINetwork(netName)
+
+ session = podmanTest.Podman([]string{"create", "--pod", name, "--network", netName, ALPINE, "top"})
session.WaitWithDefaultTimeout()
- //Expect(session.ExitCode()).ToNot(BeZero())
Expect(session.ExitCode()).To(BeZero())
})
diff --git a/test/e2e/inspect_test.go b/test/e2e/inspect_test.go
index d417fc49d..772ebed05 100644
--- a/test/e2e/inspect_test.go
+++ b/test/e2e/inspect_test.go
@@ -490,4 +490,22 @@ var _ = Describe("Podman inspect", func() {
}
Expect(found).To(BeTrue())
})
+
+ It("Dropped capabilities are sorted", func() {
+ ctrName := "testCtr"
+ session := podmanTest.Podman([]string{"run", "-d", "--cap-drop", "CAP_AUDIT_WRITE", "--cap-drop", "CAP_MKNOD", "--cap-drop", "CAP_NET_RAW", "--name", ctrName, ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+
+ inspect := podmanTest.Podman([]string{"inspect", ctrName})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(BeZero())
+
+ data := inspect.InspectContainerToJSON()
+ Expect(len(data)).To(Equal(1))
+ Expect(len(data[0].HostConfig.CapDrop)).To(Equal(3))
+ Expect(data[0].HostConfig.CapDrop[0]).To(Equal("CAP_AUDIT_WRITE"))
+ Expect(data[0].HostConfig.CapDrop[1]).To(Equal("CAP_MKNOD"))
+ Expect(data[0].HostConfig.CapDrop[2]).To(Equal("CAP_NET_RAW"))
+ })
})
diff --git a/test/e2e/network_connect_disconnect_test.go b/test/e2e/network_connect_disconnect_test.go
index ab42a592f..eb8ad7181 100644
--- a/test/e2e/network_connect_disconnect_test.go
+++ b/test/e2e/network_connect_disconnect_test.go
@@ -37,7 +37,6 @@ var _ = Describe("Podman network connect and disconnect", func() {
dis := podmanTest.Podman([]string{"network", "disconnect", "foobar", "test"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).ToNot(BeZero())
-
})
It("bad container name in network disconnect should result in error", func() {
@@ -51,7 +50,25 @@ var _ = Describe("Podman network connect and disconnect", func() {
dis := podmanTest.Podman([]string{"network", "disconnect", netName, "foobar"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).ToNot(BeZero())
+ })
+
+ It("network disconnect with net mode slirp4netns should result in error", func() {
+ SkipIfRootless("network connect and disconnect are only rootful")
+ netName := "slirp" + stringid.GenerateNonCryptoID()
+ session := podmanTest.Podman([]string{"network", "create", netName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ defer podmanTest.removeCNINetwork(netName)
+
+ session = podmanTest.Podman([]string{"create", "--name", "test", "--network", "slirp4netns", ALPINE})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ defer podmanTest.removeCNINetwork(netName)
+ con := podmanTest.Podman([]string{"network", "disconnect", netName, "test"})
+ con.WaitWithDefaultTimeout()
+ Expect(con.ExitCode()).ToNot(BeZero())
+ Expect(con.ErrorToString()).To(ContainSubstring(`network mode "slirp4netns" is not supported`))
})
It("podman network disconnect", func() {
@@ -89,7 +106,6 @@ var _ = Describe("Podman network connect and disconnect", func() {
dis := podmanTest.Podman([]string{"network", "connect", "foobar", "test"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).ToNot(BeZero())
-
})
It("bad container name in network connect should result in error", func() {
@@ -103,7 +119,25 @@ var _ = Describe("Podman network connect and disconnect", func() {
dis := podmanTest.Podman([]string{"network", "connect", netName, "foobar"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).ToNot(BeZero())
+ })
+
+ It("network connect with net mode slirp4netns should result in error", func() {
+ SkipIfRootless("network connect and disconnect are only rootful")
+ netName := "slirp" + stringid.GenerateNonCryptoID()
+ session := podmanTest.Podman([]string{"network", "create", netName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ defer podmanTest.removeCNINetwork(netName)
+
+ session = podmanTest.Podman([]string{"create", "--name", "test", "--network", "slirp4netns", ALPINE})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ defer podmanTest.removeCNINetwork(netName)
+ con := podmanTest.Podman([]string{"network", "connect", netName, "test"})
+ con.WaitWithDefaultTimeout()
+ Expect(con.ExitCode()).ToNot(BeZero())
+ Expect(con.ErrorToString()).To(ContainSubstring(`network mode "slirp4netns" is not supported`))
})
It("podman connect on a container that already is connected to the network should error", func() {
@@ -195,6 +229,55 @@ var _ = Describe("Podman network connect and disconnect", func() {
Expect(exec.ExitCode()).To(BeZero())
})
+ It("podman network connect and run with network ID", func() {
+ SkipIfRemote("remote flakes to much I will fix this in another PR")
+ SkipIfRootless("network connect and disconnect are only rootful")
+ netName := "ID" + stringid.GenerateNonCryptoID()
+ session := podmanTest.Podman([]string{"network", "create", netName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ defer podmanTest.removeCNINetwork(netName)
+
+ session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + netName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ netID := session.OutputToString()
+
+ ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netID, ALPINE, "top"})
+ ctr.WaitWithDefaultTimeout()
+ Expect(ctr.ExitCode()).To(BeZero())
+
+ exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
+ exec.WaitWithDefaultTimeout()
+ Expect(exec.ExitCode()).To(BeZero())
+
+ // Create a second network
+ newNetName := "ID2" + stringid.GenerateNonCryptoID()
+ session = podmanTest.Podman([]string{"network", "create", newNetName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ defer podmanTest.removeCNINetwork(newNetName)
+
+ session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + newNetName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ newNetID := session.OutputToString()
+
+ connect := podmanTest.Podman([]string{"network", "connect", newNetID, "test"})
+ connect.WaitWithDefaultTimeout()
+ Expect(connect.ExitCode()).To(BeZero())
+
+ inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{.NetworkSettings.Networks}}"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(BeZero())
+ Expect(inspect.OutputToString()).To(ContainSubstring(netName))
+ Expect(inspect.OutputToString()).To(ContainSubstring(newNetName))
+
+ exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth1"})
+ exec.WaitWithDefaultTimeout()
+ Expect(exec.ExitCode()).To(BeZero())
+ })
+
It("podman network disconnect when not running", func() {
SkipIfRootless("network connect and disconnect are only rootful")
netName1 := "aliasTest" + stringid.GenerateNonCryptoID()
@@ -234,4 +317,40 @@ var _ = Describe("Podman network connect and disconnect", func() {
exec.WaitWithDefaultTimeout()
Expect(exec.ExitCode()).ToNot(BeZero())
})
+
+ It("podman network disconnect and run with network ID", func() {
+ SkipIfRemote("remote flakes to much I will fix this in another PR")
+ SkipIfRootless("network connect and disconnect are only rootful")
+ netName := "aliasTest" + stringid.GenerateNonCryptoID()
+ session := podmanTest.Podman([]string{"network", "create", netName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ defer podmanTest.removeCNINetwork(netName)
+
+ session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + netName})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ netID := session.OutputToString()
+
+ ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netID, ALPINE, "top"})
+ ctr.WaitWithDefaultTimeout()
+ Expect(ctr.ExitCode()).To(BeZero())
+
+ exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
+ exec.WaitWithDefaultTimeout()
+ Expect(exec.ExitCode()).To(BeZero())
+
+ dis := podmanTest.Podman([]string{"network", "disconnect", netID, "test"})
+ dis.WaitWithDefaultTimeout()
+ Expect(dis.ExitCode()).To(BeZero())
+
+ inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(BeZero())
+ Expect(inspect.OutputToString()).To(Equal("0"))
+
+ exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
+ exec.WaitWithDefaultTimeout()
+ Expect(exec.ExitCode()).ToNot(BeZero())
+ })
})
diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go
index a7eb6e629..53521cdc4 100644
--- a/test/e2e/network_test.go
+++ b/test/e2e/network_test.go
@@ -150,6 +150,13 @@ var _ = Describe("Podman network", func() {
defer podmanTest.removeCNINetwork(net)
Expect(session.ExitCode()).To(BeZero())
+ // Tests Default Table Output
+ session = podmanTest.Podman([]string{"network", "ls", "--filter", "id=" + netID})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ expectedTable := "NETWORK ID NAME VERSION PLUGINS"
+ Expect(session.OutputToString()).To(ContainSubstring(expectedTable))
+
session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.Name}} {{.ID}}", "--filter", "id=" + netID})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeZero())
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index a6237a49a..0e6e636bc 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -766,4 +766,18 @@ var _ = Describe("Podman run networking", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeZero())
})
+
+ It("podman run check dnsname adds dns search domain", func() {
+ Skip("needs dnsname#57")
+ net := "dnsname" + stringid.GenerateNonCryptoID()
+ session := podmanTest.Podman([]string{"network", "create", net})
+ session.WaitWithDefaultTimeout()
+ defer podmanTest.removeCNINetwork(net)
+ Expect(session.ExitCode()).To(BeZero())
+
+ session = podmanTest.Podman([]string{"run", "--network", net, ALPINE, "cat", "/etc/resolv.conf"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(BeZero())
+ Expect(session.OutputToString()).To(ContainSubstring("search dns.podman"))
+ })
})
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index c28086fe8..f0ba9d1d9 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -1228,9 +1228,10 @@ USER mail`
for _, line := range lines {
parts := strings.SplitN(line, ":", 3)
if !CGROUPSV2 {
- // ignore unified on cgroup v1
+ // ignore unified on cgroup v1.
// both runc and crun do not set it.
- if parts[1] == "" {
+ // crun does not set named hierarchies.
+ if parts[1] == "" || strings.Contains(parts[1], "name=") {
continue
}
}
diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go
index 20c43bf4a..454dfdc83 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -2,8 +2,10 @@ package integration
import (
"fmt"
+ "io/ioutil"
"os"
"os/exec"
+ "os/user"
"path/filepath"
"strings"
@@ -590,4 +592,55 @@ VOLUME /test/`
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(2))
})
+
+ It("podman run with U volume flag", func() {
+ SkipIfRemote("Overlay volumes only work locally")
+
+ u, err := user.Current()
+ Expect(err).To(BeNil())
+ name := u.Username
+ if name == "root" {
+ name = "containers"
+ }
+
+ content, err := ioutil.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")
+ }
+
+ if os.Getenv("container") != "" {
+ Skip("Overlay mounts not supported when running in a container")
+ }
+ if rootless.IsRootless() {
+ if _, err := exec.LookPath("fuse_overlay"); err != nil {
+ Skip("Fuse-Overlayfs required for rootless overlay mount test")
+ }
+ }
+
+ mountPath := filepath.Join(podmanTest.TempDir, "secrets")
+ os.Mkdir(mountPath, 0755)
+ vol := mountPath + ":" + dest + ":U"
+
+ session := podmanTest.Podman([]string{"run", "--rm", "--user", "888:888", "-v", vol, ALPINE, "stat", "-c", "%u:%g", dest})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ found, _ := session.GrepString("888:888")
+ Expect(found).Should(BeTrue())
+
+ session = podmanTest.Podman([]string{"run", "--rm", "--user", "888:888", "--userns", "auto", "-v", vol, ALPINE, "stat", "-c", "%u:%g", dest})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ found, _ = session.GrepString("888:888")
+ Expect(found).Should(BeTrue())
+
+ vol = vol + ",O"
+ session = podmanTest.Podman([]string{"run", "--rm", "--user", "888:888", "--userns", "keep-id", "-v", vol, ALPINE, "stat", "-c", "%u:%g", dest})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ found, _ = session.GrepString("888:888")
+ Expect(found).Should(BeTrue())
+ })
})
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index 93449ece9..b2999a9e7 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -139,7 +139,7 @@ echo $rand | 0 | $rand
is "$output" "" "--pull=never [present]: no output"
# Now test with a remote image which we don't have present (the 00 tag)
- NONLOCAL_IMAGE="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:00000000"
+ 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"
@@ -175,7 +175,7 @@ echo $rand | 0 | $rand
# 'run --rmi' deletes the image in the end unless it's used by another container
@test "podman run --rmi" {
# Name of a nonlocal image. It should be pulled in by the first 'run'
- NONLOCAL_IMAGE="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:00000000"
+ NONLOCAL_IMAGE="$PODMAN_NONLOCAL_IMAGE_FQN"
run_podman 1 image exists $NONLOCAL_IMAGE
# Run a container, without --rm; this should block subsequent --rmi
diff --git a/test/system/055-rm.bats b/test/system/055-rm.bats
index 0107114b5..a5770f20f 100644
--- a/test/system/055-rm.bats
+++ b/test/system/055-rm.bats
@@ -51,6 +51,13 @@ load helpers
run_podman rm $rand $external_cid
}
+@test "podman rm <-> run --rm race" {
+ # A container's lock is released before attempting to stop it. This opens
+ # the window for race conditions that led to #9479.
+ run_podman run --rm -d $IMAGE sleep infinity
+ run_podman rm -af
+}
+
# I'm sorry! This test takes 13 seconds. There's not much I can do about it,
# please know that I think it's justified: podman 1.5.0 had a strange bug
# in with exit status was not preserved on some code paths with 'rm -f'
diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats
index 0fcc437d4..312106b36 100644
--- a/test/system/065-cp.bats
+++ b/test/system/065-cp.bats
@@ -475,9 +475,9 @@ load helpers
run_podman exec cpcontainer rm -rf /tmp/$srcdir
# Now for "/dev/stdin".
+ # Note: while this works, the content ends up in Nirvana.
+ # Same for Docker.
run_podman cp /dev/stdin cpcontainer:/tmp < $tar_file
- run_podman exec cpcontainer cat /tmp/$srcdir/$rand_filename
- is "$output" "$rand_content"
# Error checks below ...
@@ -487,11 +487,11 @@ load helpers
# Destination must be a directory (on an existing file).
run_podman exec cpcontainer touch /tmp/file.txt
- run_podman 125 cp /dev/stdin cpcontainer:/tmp/file.txt < $tar_file
+ run_podman 125 cp - cpcontainer:/tmp/file.txt < $tar_file
is "$output" 'Error: destination must be a directory when copying from stdin'
# Destination must be a directory (on an absent path).
- run_podman 125 cp /dev/stdin cpcontainer:/tmp/IdoNotExist < $tar_file
+ run_podman 125 cp - cpcontainer:/tmp/IdoNotExist < $tar_file
is "$output" 'Error: destination must be a directory when copying from stdin'
run_podman rm -f cpcontainer
@@ -508,6 +508,10 @@ load helpers
run_podman exec cpcontainer sh -c "echo '$rand_content' > /tmp/file.txt"
run_podman exec cpcontainer touch /tmp/empty.txt
+ # Make sure that only "-" gets special treatment. "/dev/stdout"
+ run_podman 125 cp cpcontainer:/tmp/file.txt /dev/stdout
+ is "$output" 'Error: invalid destination: "/dev/stdout" must be a directory or a regular file'
+
# Copying from stdout will always compress. So let's copy the previously
# created file from the container via stdout, untar the archive and make
# sure the file exists with the expected content.
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index 89f3f5c64..1e7d366a1 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -305,8 +305,10 @@ Cmd[0] | /bin/mydefaultcmd
Cmd[1] | $s_echo
WorkingDir | $workdir
Labels.$label_name | $label_value
-Labels.\"io.buildah.version\" | $buildah_version
"
+ # FIXME: 2021-02-24: Fixed in buildah #3036; reenable this once podman
+ # vendors in a newer buildah!
+ # Labels.\"io.buildah.version\" | $buildah_version
parse_table "$tests" | while read field expect; do
actual=$(jq -r ".[0].Config.$field" <<<"$output")
diff --git a/test/system/build-testimage b/test/system/build-testimage
index 53ade57f0..aac08e307 100755
--- a/test/system/build-testimage
+++ b/test/system/build-testimage
@@ -12,6 +12,9 @@
# still need a fedora image for that.
#
+# Buildah binary
+BUILDAH=${BUILDAH:-buildah}
+
# Tag for this new image
YMD=$(date +%Y%m%d)
@@ -58,7 +61,8 @@ chmod 755 pause
# - check for updates @ https://hub.docker.com/_/alpine
# busybox-extras provides httpd needed in 500-networking.bats
cat >Containerfile <<EOF
-FROM docker.io/library/alpine:3.12.0
+ARG ARCH=please-override-arch
+FROM docker.io/\${ARCH}/alpine:3.12.0
RUN apk add busybox-extras
ADD testimage-id pause /home/podman/
LABEL created_by=$create_script
@@ -69,26 +73,44 @@ EOF
# --squash-all : needed by 'tree' test in 070-build.bats
podman rmi -f testimage &> /dev/null || true
-podman build --squash-all -t testimage .
+
+# We need to use buildah because (as of 2021-02-23) only buildah has --manifest
+# 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
+ ${BUILDAH} bud \
+ --arch=$arch \
+ --build-arg ARCH=$arch \
+ --manifest=testimage \
+ --squash \
+ .
+done
# Clean up
cd /tmp
rm -rf $tmpdir
-# Tag and push to quay.
-podman tag testimage quay.io/libpod/testimage:$YMD
-podman push quay.io/libpod/testimage:$YMD
+# Tag image and push (all arches) to quay.
+remote_tag=quay.io/libpod/testimage:$YMD
+podman tag testimage ${remote_tag}
+${BUILDAH} manifest push --all ${remote_tag} docker://${remote_tag}
-# Side note: there should always be a testimage tagged ':00000000'
-# (eight zeroes) in the same location; this is used by tests which
-# need to pull a non-locally-cached image. This image will rarely
-# if ever need to change, nor in fact does it even have to be a
-# copy of this testimage since all we use it for is 'true'.
+# Side note: there should always be a testimage tagged ':0000000<X>'
+# (eight digits, zero-padded sequence ID) in the same location; this is
+# used by tests which need to pull a non-locally-cached image. This
+# image will rarely if ever need to change, nor in fact does it even
+# have to be a copy of this testimage since all we use it for is 'true'.
+# However, it does need to be multiarch :-(
#
-# As of 2020-09-02 it is simply busybox, because it is super small:
+# As of 2021-02-24 it is simply busybox, because it is super small,
+# but it's complicated because of multiarch:
#
-# podman pull docker.io/library/busybox:1.32.0
-# podman tag docker.io/library/busybox:1.32.0 \
-# quay.io/libpod/testimage:00000000
-# podman push quay.io/libpod/testimage:00000000
+# img=quay.io/libpod/testimage:00000001
+# buildah manifest create $img
+# for arch in amd64 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
+# buildah manifest push --all $img docker://$img
#
diff --git a/test/system/helpers.bash b/test/system/helpers.bash
index 4a7823852..38e317709 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -7,9 +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:-"20200929"}
+PODMAN_TEST_IMAGE_TAG=${PODMAN_TEST_IMAGE_TAG:-"20210223"}
PODMAN_TEST_IMAGE_FQN="$PODMAN_TEST_IMAGE_REGISTRY/$PODMAN_TEST_IMAGE_USER/$PODMAN_TEST_IMAGE_NAME:$PODMAN_TEST_IMAGE_TAG"
+# 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"
+
# Because who wants to spell that out each time?
IMAGE=$PODMAN_TEST_IMAGE_FQN