diff options
Diffstat (limited to 'test')
72 files changed, 1221 insertions, 317 deletions
diff --git a/test/apiv2/12-imagesMore.at b/test/apiv2/12-imagesMore.at index 57d5e114d..fc18dd2d7 100644 --- a/test/apiv2/12-imagesMore.at +++ b/test/apiv2/12-imagesMore.at @@ -56,4 +56,17 @@ t GET libpod/images/$IMAGE/json 200 \ t DELETE libpod/images/$IMAGE 200 \ .ExitCode=0 +podman pull -q $IMAGE + +# test podman image SCP +# ssh needs to work so we can validate that the failure is past argument parsing +podman system connection add --default test ssh://$USER@localhost/run/user/$UID/podman/podman.sock +# should fail but need to check the output... +# status 125 here means that the save/load fails due to +# cirrus weirdness with exec.Command. All of the args have been parsed sucessfully. +t POST "libpod/images/scp/$IMAGE?destination=QA::" 500 \ + .cause="exit status 125" +t DELETE libpod/images/$IMAGE 200 \ + .ExitCode=0 + stop_registry diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index 383c527b4..6ef4ef917 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -16,7 +16,12 @@ podman pull $ENV_WORKDIR_IMG &>/dev/null # Ensure clean slate podman rm -a -f &>/dev/null -t GET "libpod/containers/json (at start: clean slate)" 200 length=0 +t GET "libpod/containers/json (at start: clean slate)" 200 \ + "[]" \ + length=0 +# check content type: https://github.com/containers/podman/issues/14647 +response_headers=$(cat "$WORKDIR/curl.headers.out") +like "$response_headers" ".*Content-Type: application/json.*" "header does not contain application/json" # Regression test for #12904 (race condition in logging code) mytext="hi-there-$(random_string 15)" @@ -95,6 +100,17 @@ fi t DELETE libpod/containers/$cid 200 .[0].Id=$cid +# Issue #14676: make sure the stats show the memory limit specified for the container +if root; then + CTRNAME=ctr-with-limit + podman run --name $CTRNAME -d -m 512m -v /tmp:/tmp $IMAGE top + + t GET libpod/containers/$CTRNAME/stats?stream=false 200 \ + .memory_stats.limit=536870912 + + podman rm -f $CTRNAME +fi + # Issue #6799: it should be possible to start a container, even w/o args. t POST libpod/containers/create?name=test_noargs Image=${IMAGE} 201 \ .Id~[0-9a-f]\\{64\\} @@ -486,3 +502,27 @@ done stop_service start_service + +# Our states are different from Docker's. +# Regression test for #14700 (Docker compat returning unknown "initialized" for status.status) to ensure the stay compatible +podman create --name status-test $IMAGE sh -c "sleep 3" +t GET containers/status-test/json 200 .State.Status="created" + +podman init status-test +t GET containers/status-test/json 200 .State.Status="created" + +podman start status-test +t GET containers/status-test/json 200 .State.Status="running" + +podman pause status-test +t GET containers/status-test/json 200 .State.Status="paused" + +podman unpause status-test +t GET containers/status-test/json 200 .State.Status="running" + +podman stop status-test & +sleep 1 +t GET containers/status-test/json 200 .State.Status="stopping" + +sleep 3 +t GET containers/status-test/json 200 .State.Status="exited" diff --git a/test/apiv2/27-containersEvents.at b/test/apiv2/27-containersEvents.at index a86f2e353..e0a66e0ac 100644 --- a/test/apiv2/27-containersEvents.at +++ b/test/apiv2/27-containersEvents.at @@ -18,6 +18,10 @@ t GET "libpod/events?stream=false&since=$START" 200 \ 'select(.status | contains("died")).Action=died' \ 'select(.status | contains("died")).Actor.Attributes.containerExitCode=1' +t GET "libpod/events?stream=false&since=$START" 200 \ + 'select(.status | contains("start")).Action=start' \ + 'select(.status | contains("start")).HealthStatus='\ + # compat api, uses status=die (#12643) t GET "events?stream=false&since=$START" 200 \ 'select(.status | contains("start")).Action=start' \ diff --git a/test/apiv2/35-networks.at b/test/apiv2/35-networks.at index 4aad4563d..fcff26521 100644 --- a/test/apiv2/35-networks.at +++ b/test/apiv2/35-networks.at @@ -78,8 +78,8 @@ t GET networks?filters="{\"id\":[\"$network1_id\"]}" 200 \ .[0].Name=network1 \ .[0].Id=$network1_id # invalid filter -t GET networks?filters='{"dangling":["1"]}' 500 \ - .cause='invalid filter "dangling"' +t GET networks?filters='{"dangling":["true","0"]}' 500 \ + .cause="got more than one value for filter key \"dangling\"" # (#9293 with no networks the endpoint should return empty array instead of null) t GET networks?filters='{"name":["doesnotexists"]}' 200 \ "[]" diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2 index 25f648d93..8548d84e5 100755 --- a/test/apiv2/test-apiv2 +++ b/test/apiv2/test-apiv2 @@ -23,6 +23,8 @@ REGISTRY_IMAGE="${PODMAN_TEST_IMAGE_REGISTRY}/${PODMAN_TEST_IMAGE_USER}/registry ############################################################################### # BEGIN setup +USER=$PODMAN_ROOTLESS_USER +UID=$PODMAN_ROOTLESS_UID TMPDIR=${TMPDIR:-/tmp} WORKDIR=$(mktemp --tmpdir -d $ME.tmp.XXXXXX) diff --git a/test/compose/disable_healthcheck/docker-compose.yml b/test/compose/disable_healthcheck/docker-compose.yml new file mode 100644 index 000000000..1f608c895 --- /dev/null +++ b/test/compose/disable_healthcheck/docker-compose.yml @@ -0,0 +1,10 @@ +version: "3.7" +services: + noHc: + image: alpine + container_name: noHc + ports: + - "4000:80" + restart: unless-stopped + healthcheck: + disable: true diff --git a/test/compose/disable_healthcheck/tests.sh b/test/compose/disable_healthcheck/tests.sh new file mode 100644 index 000000000..2460a687e --- /dev/null +++ b/test/compose/disable_healthcheck/tests.sh @@ -0,0 +1,2 @@ +podman inspect --format='{{.Config.Healthcheck.Test}}' noHc +like $output "[NONE]" "$testname: healthcheck properly disabled" diff --git a/test/compose/update_network_mtu/docker-compose.yml b/test/compose/update_network_mtu/docker-compose.yml new file mode 100644 index 000000000..fabd7b4f2 --- /dev/null +++ b/test/compose/update_network_mtu/docker-compose.yml @@ -0,0 +1,26 @@ +version: '3.7' + +services: + nginx: + image: alpine + ports: + - 8000:5000 + networks: + - default + - macvlan_net + +networks: + default: + driver: bridge + driver_opts: + com.docker.network.bridge.name: docker0 + com.docker.network.driver.mtu: 9000 + macvlan_net: + driver: macvlan + driver_opts: + mode: bridge + ipam: + config: + - + subnet: 192.168.20.0/24 + gateway: 192.168.20.1 diff --git a/test/compose/update_network_mtu/tests.sh b/test/compose/update_network_mtu/tests.sh new file mode 100644 index 000000000..57411eb34 --- /dev/null +++ b/test/compose/update_network_mtu/tests.sh @@ -0,0 +1,10 @@ +# -*- bash -*- + +podman network inspect --format='{{ range . }} {{ .Options.mtu }} {{ end }}' update_network_mtu_default +like "$output" "9000" "$testname : network mtu is set" + +podman network inspect --format='{{ range . }} {{ .NetworkInterface }} {{ end }}' update_network_mtu_default +like "$output" "docker0" "$testname: network interface is set" + +podman network inspect --format='{{ range . }} {{ .Options.mode }} {{ end }}' update_network_mtu_macvlan_net +like "$output" "bridge" "$testname : network mode is set" diff --git a/test/e2e/benchmarks_test.go b/test/e2e/benchmarks_test.go index ef4d51893..fe045b97a 100644 --- a/test/e2e/benchmarks_test.go +++ b/test/e2e/benchmarks_test.go @@ -132,7 +132,7 @@ var _ = Describe("Podman Benchmark Suite", func() { Measure("Podman Benchmark Suite", func(b Benchmarker) { registryOptions := &podmanRegistry.Options{ - Image: "docker-archive:" + imageTarPath(registry), + Image: "docker-archive:" + imageTarPath(REGISTRY_IMAGE), } for i := range allBenchmarks { diff --git a/test/e2e/build/Containerfile.with-platform b/test/e2e/build/Containerfile.with-platform new file mode 100644 index 000000000..3bb585a0a --- /dev/null +++ b/test/e2e/build/Containerfile.with-platform @@ -0,0 +1 @@ +FROM --platform=$TARGETPLATFORM alpine diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index 1da199714..5ccafeb37 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -23,10 +23,31 @@ import ( func getRunString(input []string) []string { // CRIU does not work with seccomp correctly on RHEL7 : seccomp=unconfined - runString := []string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", "--ip", GetRandomIPAddress()} + runString := []string{"run", "--security-opt", "seccomp=unconfined", "-d", "--ip", GetRandomIPAddress()} return append(runString, input...) } +// FIXME FIXME FIXME: workaround for #14653, please remove this function +// and all calls to it once that bug is fixed. +func fixmeFixme14653(podmanTest *PodmanTestIntegration, cid string) { + if !IsRemote() { + // Race condition only affects podman-remote + return + } + + // Wait for container to truly go away + for i := 0; i < 5; i++ { + ps := podmanTest.Podman([]string{"container", "exists", cid}) + ps.WaitWithDefaultTimeout() + if ps.ExitCode() == 1 { + // yay, it's gone + return + } + time.Sleep(time.Second) + } + // Fall through. Container still exists, but return anyway. +} + var _ = Describe("Podman checkpoint", func() { var ( tempdir string @@ -318,7 +339,7 @@ var _ = Describe("Podman checkpoint", func() { It("podman checkpoint container with established tcp connections", func() { // Broken on Ubuntu. SkipIfNotFedora() - localRunString := getRunString([]string{redis}) + localRunString := getRunString([]string{REDIS_IMAGE}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -478,6 +499,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -530,6 +552,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -548,6 +571,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -566,6 +590,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -584,6 +609,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -645,6 +671,7 @@ var _ = Describe("Podman checkpoint", func() { result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -694,6 +721,7 @@ var _ = Describe("Podman checkpoint", func() { result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -735,6 +763,7 @@ var _ = Describe("Podman checkpoint", func() { result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -772,6 +801,7 @@ var _ = Describe("Podman checkpoint", func() { result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -821,6 +851,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -890,6 +921,7 @@ var _ = Describe("Podman checkpoint", func() { result = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", checkpointFileName}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -1020,7 +1052,7 @@ var _ = Describe("Podman checkpoint", func() { It("podman checkpoint and restore container with different port mappings", func() { randomPort, err := utils.GetRandomPort() Expect(err).ShouldNot(HaveOccurred()) - localRunString := getRunString([]string{"-p", fmt.Sprintf("%d:6379", randomPort), "--rm", redis}) + localRunString := getRunString([]string{"-p", fmt.Sprintf("%d:6379", randomPort), "--rm", REDIS_IMAGE}) session := podmanTest.Podman(localRunString) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -1044,6 +1076,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -1140,6 +1173,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).To(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) Expect(podmanTest.NumberOfContainers()).To(Equal(1)) @@ -1252,6 +1286,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -1296,6 +1331,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -1324,11 +1360,11 @@ var _ = Describe("Podman checkpoint", func() { }) It("podman checkpoint and restore containers with --print-stats", func() { - session1 := podmanTest.Podman(getRunString([]string{redis})) + session1 := podmanTest.Podman(getRunString([]string{REDIS_IMAGE})) session1.WaitWithDefaultTimeout() Expect(session1).Should(Exit(0)) - session2 := podmanTest.Podman(getRunString([]string{redis, "top"})) + session2 := podmanTest.Podman(getRunString([]string{REDIS_IMAGE, "top"})) session2.WaitWithDefaultTimeout() Expect(session2).Should(Exit(0)) @@ -1489,6 +1525,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -1518,6 +1555,93 @@ var _ = Describe("Podman checkpoint", func() { os.Remove(fileName) }) + It("podman checkpoint container with export and verify non-default runtime", func() { + SkipIfRemote("podman-remote does not support --runtime flag") + // This test triggers the edge case where: + // 1. Default runtime is crun + // 2. Container is created with runc + // 3. Checkpoint without setting --runtime into archive + // 4. Restore without setting --runtime from archive + // It should be expected that podman identifies runtime + // from the checkpoint archive. + + // Prevent --runtime arg from being set to force using default + // runtime unless explicitly set through passed args. + preservedMakeOptions := podmanTest.PodmanMakeOptions + podmanTest.PodmanMakeOptions = func(args []string, noEvents, noCache bool) []string { + defaultArgs := preservedMakeOptions(args, noEvents, noCache) + for i := range args { + // Runtime is set explicitly, so we should keep --runtime arg. + if args[i] == "--runtime" { + return defaultArgs + } + } + updatedArgs := make([]string, 0) + for i := 0; i < len(defaultArgs); i++ { + // Remove --runtime arg, letting podman fall back to its default + if defaultArgs[i] == "--runtime" { + i++ + } else { + updatedArgs = append(updatedArgs, defaultArgs[i]) + } + } + return updatedArgs + } + + for _, runtime := range []string{"runc", "crun"} { + if err := exec.Command(runtime, "--help").Run(); err != nil { + Skip(fmt.Sprintf("%s not found in PATH; this test requires both runc and crun", runtime)) + } + } + + // Detect default runtime + session := podmanTest.Podman([]string{"info", "--format", "{{.Host.OCIRuntime.Name}}"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + if defaultRuntime := session.OutputToString(); defaultRuntime != "crun" { + Skip(fmt.Sprintf("Default runtime is %q; this test requires crun to be default", defaultRuntime)) + } + + // Force non-default runtime "runc" + localRunString := getRunString([]string{"--runtime", "runc", "--rm", ALPINE, "top"}) + session = podmanTest.Podman(localRunString) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + cid := session.OutputToString() + + session = podmanTest.Podman([]string{"inspect", "--format", "{{.OCIRuntime}}", cid}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).To(Equal("runc")) + + checkpointExportPath := "/tmp/checkpoint-" + cid + ".tar.gz" + + session = podmanTest.Podman([]string{"container", "checkpoint", cid, "-e", checkpointExportPath}) + session.WaitWithDefaultTimeout() + // As the container has been started with '--rm' it will be completely + // cleaned up after checkpointing. + Expect(session).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + Expect(podmanTest.NumberOfContainers()).To(Equal(0)) + + session = podmanTest.Podman([]string{"container", "restore", "-i", checkpointExportPath}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up")) + + // The restored container should have the same runtime as the original container + session = podmanTest.Podman([]string{"inspect", "--format", "{{.OCIRuntime}}", cid}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).To(Equal("runc")) + + // Remove exported checkpoint + os.Remove(checkpointExportPath) + }) + It("podman checkpoint container with export and try to change the runtime", func() { SkipIfRemote("podman-remote does not support --runtime flag") // This test will only run if runc and crun both exist @@ -1573,6 +1697,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) @@ -1651,6 +1776,7 @@ var _ = Describe("Podman checkpoint", func() { // As the container has been started with '--rm' it will be completely // cleaned up after checkpointing. Expect(result).Should(Exit(0)) + fixmeFixme14653(podmanTest, cid) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.NumberOfContainers()).To(Equal(0)) diff --git a/test/e2e/commit_test.go b/test/e2e/commit_test.go index c82e5e471..452a378c2 100644 --- a/test/e2e/commit_test.go +++ b/test/e2e/commit_test.go @@ -362,7 +362,7 @@ var _ = Describe("Podman commit", func() { Expect(images[0].Config.ExposedPorts).To(HaveKey("80/tcp")) name = "testcon2" - s = podmanTest.Podman([]string{"run", "--name", name, "-d", nginx}) + s = podmanTest.Podman([]string{"run", "--name", name, "-d", NGINX_IMAGE}) s.WaitWithDefaultTimeout() Expect(s).Should(Exit(0)) diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index 194d592f4..43367cf63 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -2,6 +2,7 @@ package integration import ( "bytes" + "errors" "fmt" "io/ioutil" "math/rand" @@ -30,16 +31,15 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gexec" - "github.com/pkg/errors" "github.com/sirupsen/logrus" ) var ( //lint:ignore ST1003 - PODMAN_BINARY string //nolint:revive,stylecheck - INTEGRATION_ROOT string //nolint:revive,stylecheck - CGROUP_MANAGER = "systemd" //nolint:revive,stylecheck - RESTORE_IMAGES = []string{ALPINE, BB, nginx} //nolint:revive,stylecheck + PODMAN_BINARY string //nolint:revive,stylecheck + INTEGRATION_ROOT string //nolint:revive,stylecheck + CGROUP_MANAGER = "systemd" //nolint:revive,stylecheck + RESTORE_IMAGES = []string{ALPINE, BB, NGINX_IMAGE} //nolint:revive,stylecheck defaultWaitTimeout = 90 CGROUPSV2, _ = cgroups.IsCgroup2UnifiedMode() ) @@ -115,7 +115,7 @@ var _ = SynchronizedBeforeSuite(func() []byte { podman := PodmanTestSetup("/tmp") // Pull cirros but don't put it into the cache - pullImages := []string{cirros, fedoraToolbox, volumeTest} + pullImages := []string{CIRROS_IMAGE, fedoraToolbox, volumeTest} pullImages = append(pullImages, CACHE_IMAGES...) for _, image := range pullImages { podman.createArtifact(image) @@ -322,7 +322,7 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration { } } - // Setup registries.conf ENV variable + // Set up registries.conf ENV variable p.setDefaultRegistriesConfigEnv() // Rewrite the PodmanAsUser function p.PodmanMakeOptions = p.makeOptions @@ -464,7 +464,7 @@ func (p *PodmanTestIntegration) RunNginxWithHealthCheck(name string) (*PodmanSes podmanArgs = append(podmanArgs, "--name", name) } // curl without -f exits 0 even if http code >= 400! - podmanArgs = append(podmanArgs, "-dt", "-P", "--health-cmd", "curl -f http://localhost/", nginx) + podmanArgs = append(podmanArgs, "-dt", "-P", "--health-cmd", "curl -f http://localhost/", NGINX_IMAGE) session := p.Podman(podmanArgs) session.WaitWithDefaultTimeout() return session, session.OutputToString() @@ -618,14 +618,14 @@ func (p *PodmanTestIntegration) RunHealthCheck(cid string) error { restart := p.Podman([]string{"restart", cid}) restart.WaitWithDefaultTimeout() if restart.ExitCode() != 0 { - return errors.Errorf("unable to restart %s", cid) + return fmt.Errorf("unable to restart %s", cid) } } } fmt.Printf("Waiting for %s to pass healthcheck\n", cid) time.Sleep(1 * time.Second) } - return errors.Errorf("unable to detect %s as running", cid) + return fmt.Errorf("unable to detect %s as running", cid) } func (p *PodmanTestIntegration) CreateSeccompJSON(in []byte) (string, error) { @@ -1042,18 +1042,15 @@ var IPRegex = `(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01 // digShort execs into the given container and does a dig lookup with a timeout // backoff. If it gets a response, it ensures that the output is in the correct // format and iterates a string array for match -func digShort(container, lookupName string, matchNames []string, p *PodmanTestIntegration) { +func digShort(container, lookupName, expectedIP string, p *PodmanTestIntegration) { digInterval := time.Millisecond * 250 for i := 0; i < 6; i++ { time.Sleep(digInterval * time.Duration(i)) dig := p.Podman([]string{"exec", container, "dig", "+short", lookupName}) dig.WaitWithDefaultTimeout() - if dig.ExitCode() == 0 { - output := dig.OutputToString() - Expect(output).To(MatchRegexp(IPRegex)) - for _, name := range matchNames { - Expect(output).To(Equal(name)) - } + output := dig.OutputToString() + if dig.ExitCode() == 0 && output != "" { + Expect(output).To(Equal(expectedIP)) // success return } @@ -1064,13 +1061,13 @@ func digShort(container, lookupName string, matchNames []string, p *PodmanTestIn // WaitForFile to be created in defaultWaitTimeout seconds, returns false if file not created func WaitForFile(path string) (err error) { until := time.Now().Add(time.Duration(defaultWaitTimeout) * time.Second) - for i := 1; time.Now().Before(until); i++ { + for time.Now().Before(until) { _, err = os.Stat(path) switch { case err == nil: return nil case errors.Is(err, os.ErrNotExist): - time.Sleep(time.Duration(i) * time.Second) + time.Sleep(10 * time.Millisecond) default: return err } @@ -1078,18 +1075,21 @@ func WaitForFile(path string) (err error) { return err } -// WaitForService blocks, waiting for some service listening on given host:port +// WaitForService blocks for defaultWaitTimeout seconds, waiting for some service listening on given host:port func WaitForService(address url.URL) { // Wait for podman to be ready - var conn net.Conn var err error - for i := 1; i <= 5; i++ { + until := time.Now().Add(time.Duration(defaultWaitTimeout) * time.Second) + for time.Now().Before(until) { + var conn net.Conn conn, err = net.Dial("tcp", address.Host) - if err != nil { - // Podman not available yet... - time.Sleep(time.Duration(i) * time.Second) + if err == nil { + conn.Close() + break } + + // Podman not available yet... + time.Sleep(10 * time.Millisecond) } Expect(err).ShouldNot(HaveOccurred()) - conn.Close() } diff --git a/test/e2e/config.go b/test/e2e/config.go index 2ca8e2a15..a8dd6301f 100644 --- a/test/e2e/config.go +++ b/test/e2e/config.go @@ -1,7 +1,7 @@ package integration var ( - redis = "quay.io/libpod/redis:alpine" + REDIS_IMAGE = "quay.io/libpod/redis:alpine" //nolint:revive,stylecheck fedoraMinimal = "registry.fedoraproject.org/fedora-minimal:34" ALPINE = "quay.io/libpod/alpine:latest" ALPINELISTTAG = "quay.io/libpod/alpine:3.10.2" @@ -10,12 +10,12 @@ var ( ALPINEAMD64ID = "961769676411f082461f9ef46626dd7a2d1e2b2a38e6a44364bcbecf51e66dd4" ALPINEARM64DIGEST = "quay.io/libpod/alpine@sha256:f270dcd11e64b85919c3bab66886e59d677cf657528ac0e4805d3c71e458e525" ALPINEARM64ID = "915beeae46751fc564998c79e73a1026542e945ca4f73dc841d09ccc6c2c0672" - infra = "k8s.gcr.io/pause:3.2" + INFRA_IMAGE = "k8s.gcr.io/pause:3.2" //nolint:revive,stylecheck BB = "quay.io/libpod/busybox:latest" - healthcheck = "quay.io/libpod/alpine_healthcheck:latest" + HEALTHCHECK_IMAGE = "quay.io/libpod/alpine_healthcheck:latest" //nolint:revive,stylecheck ImageCacheDir = "/tmp/podman/imagecachedir" fedoraToolbox = "registry.fedoraproject.org/fedora-toolbox:36" - volumeTest = "quay.io/libpod/volume-plugin-test-img:latest" + volumeTest = "quay.io/libpod/volume-plugin-test-img:20220623" // This image has seccomp profiles that blocks all syscalls. // The intention behind blocking all syscalls is to prevent diff --git a/test/e2e/config_amd64.go b/test/e2e/config_amd64.go index c4cb97b2e..f32542df8 100644 --- a/test/e2e/config_amd64.go +++ b/test/e2e/config_amd64.go @@ -1,16 +1,16 @@ package integration var ( - STORAGE_FS = "vfs" //nolint:revive,stylecheck - STORAGE_OPTIONS = "--storage-driver vfs" //nolint:revive,stylecheck - ROOTLESS_STORAGE_FS = "vfs" //nolint:revive,stylecheck - ROOTLESS_STORAGE_OPTIONS = "--storage-driver vfs" //nolint:revive,stylecheck - CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, nginx, redis, registry, infra, labels, healthcheck, UBI_INIT, UBI_MINIMAL, fedoraToolbox} //nolint:revive,stylecheck - nginx = "quay.io/libpod/alpine_nginx:latest" - BB_GLIBC = "docker.io/library/busybox:glibc" //nolint:revive,stylecheck - registry = "quay.io/libpod/registry:2.6" - labels = "quay.io/libpod/alpine_labels:latest" - UBI_MINIMAL = "registry.access.redhat.com/ubi8-minimal" //nolint:revive,stylecheck - UBI_INIT = "registry.access.redhat.com/ubi8-init" //nolint:revive,stylecheck - cirros = "quay.io/libpod/cirros:latest" + STORAGE_FS = "vfs" //nolint:revive,stylecheck + STORAGE_OPTIONS = "--storage-driver vfs" //nolint:revive,stylecheck + ROOTLESS_STORAGE_FS = "vfs" //nolint:revive,stylecheck + ROOTLESS_STORAGE_OPTIONS = "--storage-driver vfs" //nolint:revive,stylecheck + CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, NGINX_IMAGE, REDIS_IMAGE, REGISTRY_IMAGE, INFRA_IMAGE, LABELS_IMAGE, HEALTHCHECK_IMAGE, UBI_INIT, UBI_MINIMAL, fedoraToolbox} //nolint:revive,stylecheck + NGINX_IMAGE = "quay.io/libpod/alpine_nginx:latest" //nolint:revive,stylecheck + BB_GLIBC = "docker.io/library/busybox:glibc" //nolint:revive,stylecheck + REGISTRY_IMAGE = "quay.io/libpod/registry:2.6" //nolint:revive,stylecheck + LABELS_IMAGE = "quay.io/libpod/alpine_labels:latest" //nolint:revive,stylecheck + UBI_MINIMAL = "registry.access.redhat.com/ubi8-minimal" //nolint:revive,stylecheck + UBI_INIT = "registry.access.redhat.com/ubi8-init" //nolint:revive,stylecheck + CIRROS_IMAGE = "quay.io/libpod/cirros:latest" //nolint:revive,stylecheck ) diff --git a/test/e2e/config_ppc64le.go b/test/e2e/config_ppc64le.go index 569a34efb..a4bec748a 100644 --- a/test/e2e/config_ppc64le.go +++ b/test/e2e/config_ppc64le.go @@ -5,9 +5,9 @@ var ( STORAGE_OPTIONS = "--storage-driver overlay" ROOTLESS_STORAGE_FS = "vfs" ROOTLESS_STORAGE_OPTIONS = "--storage-driver vfs" - CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, nginx, redis, infra, labels} - nginx = "quay.io/libpod/alpine_nginx-ppc64le:latest" + CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, NGINX_IMAGE, REDIS_IMAGE, INFRA_IMAGE, LABELS_IMAGE} + NGINX_IMAGE = "quay.io/libpod/alpine_nginx-ppc64le:latest" BB_GLIBC = "docker.io/ppc64le/busybox:glibc" - labels = "quay.io/libpod/alpine_labels-ppc64le:latest" - registry string + LABELS_IMAGE = "quay.io/libpod/alpine_labels-ppc64le:latest" + REGISTRY_IMAGE string ) diff --git a/test/e2e/container_inspect_test.go b/test/e2e/container_inspect_test.go index 5aed943da..436c60c05 100644 --- a/test/e2e/container_inspect_test.go +++ b/test/e2e/container_inspect_test.go @@ -58,7 +58,7 @@ var _ = Describe("Podman container inspect", func() { It("podman inspect shows exposed ports on image", func() { name := "testcon" - session := podmanTest.Podman([]string{"run", "-d", "--expose", "8989", "--name", name, nginx}) + session := podmanTest.Podman([]string{"run", "-d", "--expose", "8989", "--name", name, NGINX_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) diff --git a/test/e2e/create_staticip_test.go b/test/e2e/create_staticip_test.go index 6fd88753b..85cc5023c 100644 --- a/test/e2e/create_staticip_test.go +++ b/test/e2e/create_staticip_test.go @@ -25,7 +25,7 @@ var _ = Describe("Podman create with --ip flag", func() { } podmanTest = PodmanTestCreate(tempdir) podmanTest.Setup() - // Cleanup the CNI networks used by the tests + // Clean up the CNI networks used by the tests os.RemoveAll("/var/lib/cni/networks/podman") }) diff --git a/test/e2e/create_staticmac_test.go b/test/e2e/create_staticmac_test.go index f02d9c88b..32deb04a8 100644 --- a/test/e2e/create_staticmac_test.go +++ b/test/e2e/create_staticmac_test.go @@ -25,7 +25,7 @@ var _ = Describe("Podman run with --mac-address flag", func() { } podmanTest = PodmanTestCreate(tempdir) podmanTest.Setup() - // Cleanup the CNI networks used by the tests + // Clean up the CNI networks used by the tests os.RemoveAll("/var/lib/cni/networks/podman") }) diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index 63544d579..9679aad24 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -63,7 +63,7 @@ var _ = Describe("Podman create", func() { lock := GetPortLock("5000") defer lock.Unlock() - session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) + session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", REGISTRY_IMAGE, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -273,7 +273,7 @@ var _ = Describe("Podman create", func() { It("podman run entrypoint and cmd test", func() { name := "test101" - create := podmanTest.Podman([]string{"create", "--name", name, redis}) + create := podmanTest.Podman([]string{"create", "--name", name, REDIS_IMAGE}) create.WaitWithDefaultTimeout() Expect(create).Should(Exit(0)) @@ -560,7 +560,7 @@ var _ = Describe("Podman create", func() { session = podmanTest.Podman([]string{"create", "--umask", "9999", "--name", "bad", ALPINE}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) - Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask")) + Expect(session.ErrorToString()).To(ContainSubstring("invalid umask")) }) It("create container in pod with IP should fail", func() { diff --git a/test/e2e/events_test.go b/test/e2e/events_test.go index 725118ab0..528fa143d 100644 --- a/test/e2e/events_test.go +++ b/test/e2e/events_test.go @@ -216,4 +216,25 @@ var _ = Describe("Podman events", func() { Expect(result.OutputToString()).To(ContainSubstring("create")) }) + It("podman events health_status generated", func() { + session := podmanTest.Podman([]string{"run", "--name", "test-hc", "-dt", "--health-cmd", "echo working", "busybox"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + for i := 0; i < 5; i++ { + hc := podmanTest.Podman([]string{"healthcheck", "run", "test-hc"}) + hc.WaitWithDefaultTimeout() + exitCode := hc.ExitCode() + if exitCode == 0 || i == 4 { + break + } + time.Sleep(1 * time.Second) + } + + result := podmanTest.Podman([]string{"events", "--stream=false", "--filter", "event=health_status"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(len(result.OutputToStringArray())).To(BeNumerically(">=", 1), "Number of health_status events") + }) + }) diff --git a/test/e2e/generate_systemd_test.go b/test/e2e/generate_systemd_test.go index 08e8fbc8c..45a2f1f86 100644 --- a/test/e2e/generate_systemd_test.go +++ b/test/e2e/generate_systemd_test.go @@ -111,7 +111,7 @@ var _ = Describe("Podman generate systemd", func() { }) It("podman generate systemd", func() { - n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", nginx}) + n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", NGINX_IMAGE}) n.WaitWithDefaultTimeout() Expect(n).Should(Exit(0)) @@ -124,7 +124,7 @@ var _ = Describe("Podman generate systemd", func() { }) It("podman generate systemd --files --name", func() { - n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", nginx}) + n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", NGINX_IMAGE}) n.WaitWithDefaultTimeout() Expect(n).Should(Exit(0)) @@ -139,7 +139,7 @@ var _ = Describe("Podman generate systemd", func() { }) It("podman generate systemd with timeout", func() { - n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", nginx}) + n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", NGINX_IMAGE}) n.WaitWithDefaultTimeout() Expect(n).Should(Exit(0)) @@ -159,7 +159,7 @@ var _ = Describe("Podman generate systemd", func() { }) It("podman generate systemd with user-defined dependencies", func() { - n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", nginx}) + n := podmanTest.Podman([]string{"run", "--name", "nginx", "-dt", NGINX_IMAGE}) n.WaitWithDefaultTimeout() Expect(n).Should(Exit(0)) diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index add739988..fd4e763f9 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -45,7 +45,7 @@ var _ = Describe("Podman healthcheck run", func() { }) It("podman disable healthcheck with --no-healthcheck on valid container", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--no-healthcheck", "--name", "hc", healthcheck}) + session := podmanTest.Podman([]string{"run", "-dt", "--no-healthcheck", "--name", "hc", HEALTHCHECK_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) @@ -54,7 +54,7 @@ var _ = Describe("Podman healthcheck run", func() { }) It("podman disable healthcheck with --no-healthcheck must not show starting on status", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--no-healthcheck", "--name", "hc", healthcheck}) + session := podmanTest.Podman([]string{"run", "-dt", "--no-healthcheck", "--name", "hc", HEALTHCHECK_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.State.Health.Status}}", "hc"}) @@ -98,7 +98,7 @@ var _ = Describe("Podman healthcheck run", func() { }) It("podman disable healthcheck with --health-cmd=none on valid container", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "none", "--name", "hc", healthcheck}) + session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "none", "--name", "hc", HEALTHCHECK_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) hc := podmanTest.Podman([]string{"healthcheck", "run", "hc"}) @@ -108,7 +108,7 @@ var _ = Describe("Podman healthcheck run", func() { It("podman healthcheck on valid container", func() { Skip("Extremely consistent flake - re-enable on debugging") - session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", healthcheck}) + session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", HEALTHCHECK_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -143,7 +143,7 @@ var _ = Describe("Podman healthcheck run", func() { }) It("podman healthcheck on stopped container", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", healthcheck, "ls"}) + session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", HEALTHCHECK_IMAGE, "ls"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) diff --git a/test/e2e/image_scp_test.go b/test/e2e/image_scp_test.go index 2ad3cc75e..77fe810bd 100644 --- a/test/e2e/image_scp_test.go +++ b/test/e2e/image_scp_test.go @@ -22,12 +22,10 @@ var _ = Describe("podman image scp", func() { ) BeforeEach(func() { - ConfPath.Value, ConfPath.IsSet = os.LookupEnv("CONTAINERS_CONF") conf, err := ioutil.TempFile("", "containersconf") - if err != nil { - panic(err) - } + Expect(err).ToNot(HaveOccurred()) + os.Setenv("CONTAINERS_CONF", conf.Name()) tempdir, err = CreateTempDirInTempDir() if err != nil { @@ -52,42 +50,40 @@ var _ = Describe("podman image scp", func() { }) It("podman image scp bogus image", func() { - if IsRemote() { - Skip("this test is only for non-remote") - } scp := podmanTest.Podman([]string{"image", "scp", "FOOBAR"}) scp.WaitWithDefaultTimeout() - Expect(scp).To(ExitWithError()) + Expect(scp).Should(ExitWithError()) }) It("podman image scp with proper connection", func() { - if IsRemote() { - Skip("this test is only for non-remote") - } cmd := []string{"system", "connection", "add", "--default", "QA", - "ssh://root@server.fubar.com:2222/run/podman/podman.sock", + "ssh://root@podman.test:2222/run/podman/podman.sock", } session := podmanTest.Podman(cmd) session.WaitWithDefaultTimeout() - Expect(session).To(Exit(0)) + Expect(session).Should(Exit(0)) cfg, err := config.ReadCustomConfig() Expect(err).ShouldNot(HaveOccurred()) - Expect(cfg.Engine).To(HaveField("ActiveService", "QA")) + Expect(cfg.Engine).Should(HaveField("ActiveService", "QA")) Expect(cfg.Engine.ServiceDestinations).To(HaveKeyWithValue("QA", config.Destination{ - URI: "ssh://root@server.fubar.com:2222/run/podman/podman.sock", + URI: "ssh://root@podman.test:2222/run/podman/podman.sock", }, )) scp := podmanTest.Podman([]string{"image", "scp", ALPINE, "QA::"}) - scp.Wait(45) + scp.WaitWithDefaultTimeout() // exit with error because we cannot make an actual ssh connection // This tests that the input we are given is validated and prepared correctly - // The error given should either be a missing image (due to testing suite complications) or a i/o timeout on ssh - Expect(scp).To(ExitWithError()) + // The error given should either be a missing image (due to testing suite complications) or a no such host timeout on ssh + Expect(scp).Should(ExitWithError()) + // podman-remote exits with a different error + if !IsRemote() { + Expect(scp.ErrorToString()).Should(ContainSubstring("no such host")) + } }) diff --git a/test/e2e/inspect_test.go b/test/e2e/inspect_test.go index 6fe850f0b..1ce2fa93d 100644 --- a/test/e2e/inspect_test.go +++ b/test/e2e/inspect_test.go @@ -182,8 +182,8 @@ var _ = Describe("Podman inspect", func() { }) It("podman inspect shows healthcheck on docker image", func() { - podmanTest.AddImageToRWStore(healthcheck) - session := podmanTest.Podman([]string{"inspect", "--format=json", healthcheck}) + podmanTest.AddImageToRWStore(HEALTHCHECK_IMAGE) + session := podmanTest.Podman([]string{"inspect", "--format=json", HEALTHCHECK_IMAGE}) session.WaitWithDefaultTimeout() imageData := session.InspectImageJSON() Expect(imageData[0].HealthCheck.Timeout).To(BeNumerically("==", 3000000000)) diff --git a/test/e2e/manifest_test.go b/test/e2e/manifest_test.go index 88ccdc87d..2f8b47e25 100644 --- a/test/e2e/manifest_test.go +++ b/test/e2e/manifest_test.go @@ -91,6 +91,27 @@ var _ = Describe("Podman manifest", func() { Expect(session.OutputToString()).To(ContainSubstring(imageListARM64InstanceDigest)) }) + It("add with new version", func() { + // Following test must pass for both podman and podman-remote + session := podmanTest.Podman([]string{"manifest", "create", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + id := strings.TrimSpace(string(session.Out.Contents())) + + session = podmanTest.Podman([]string{"manifest", "inspect", id}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"manifest", "add", "--os-version", "7.7.7", "foo", imageListInstance}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"manifest", "inspect", "foo"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).To(ContainSubstring("7.7.7")) + }) + It("tag", func() { session := podmanTest.Podman([]string{"manifest", "create", "foobar"}) session.WaitWithDefaultTimeout() @@ -274,7 +295,7 @@ var _ = Describe("Podman manifest", func() { It("authenticated push", func() { registryOptions := &podmanRegistry.Options{ - Image: "docker-archive:" + imageTarPath(registry), + Image: "docker-archive:" + imageTarPath(REGISTRY_IMAGE), } registry, err := podmanRegistry.StartWithOptions(registryOptions) Expect(err).To(BeNil()) @@ -384,4 +405,32 @@ var _ = Describe("Podman manifest", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) }) + + It("manifest rm should not remove image and should be able to remove tagged manifest list", func() { + // manifest rm should fail with `image is not a manifest list` + session := podmanTest.Podman([]string{"manifest", "rm", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(125)) + Expect(session.ErrorToString()).To(ContainSubstring("image is not a manifest list")) + + manifestName := "testmanifest:sometag" + session = podmanTest.Podman([]string{"manifest", "create", manifestName}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + // verify if manifest exists + session = podmanTest.Podman([]string{"manifest", "exists", manifestName}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + // manifest rm should be able to remove tagged manifest list + session = podmanTest.Podman([]string{"manifest", "rm", manifestName}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + // verify that manifest should not exist + session = podmanTest.Podman([]string{"manifest", "exists", manifestName}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(1)) + }) }) diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go index 715455521..d4f60d3e4 100644 --- a/test/e2e/network_test.go +++ b/test/e2e/network_test.go @@ -163,6 +163,26 @@ var _ = Describe("Podman network", func() { Expect(session.OutputToString()).To(Not(ContainSubstring(name))) }) + It("podman network list --filter dangling", func() { + name, path := generateNetworkConfig(podmanTest) + defer removeConf(path) + + session := podmanTest.Podman([]string{"network", "ls", "--filter", "dangling=true"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).To(ContainSubstring(name)) + + session = podmanTest.Podman([]string{"network", "ls", "--filter", "dangling=false"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).NotTo(ContainSubstring(name)) + + session = podmanTest.Podman([]string{"network", "ls", "--filter", "dangling=foo"}) + session.WaitWithDefaultTimeout() + Expect(session).To(ExitWithError()) + Expect(session.ErrorToString()).To(ContainSubstring(`invalid dangling filter value "foo"`)) + }) + It("podman network ID test", func() { net := "networkIDTest" // the network id should be the sha256 hash of the network name @@ -487,14 +507,14 @@ var _ = Describe("Podman network", func() { interval *= 2 } - top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", nginx}) + top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", NGINX_IMAGE}) top.WaitWithDefaultTimeout() Expect(top).Should(Exit(0)) interval = 250 * time.Millisecond // Wait for the nginx service to be running for i := 0; i < 6; i++ { // Test curl against the container's name - c1 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web"}) + c1 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, NGINX_IMAGE, "curl", "web"}) c1.WaitWithDefaultTimeout() worked = c1.ExitCode() == 0 if worked { @@ -507,12 +527,12 @@ var _ = Describe("Podman network", func() { // Nginx is now running so no need to do a loop // Test against the first alias - c2 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web1"}) + c2 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, NGINX_IMAGE, "curl", "web1"}) c2.WaitWithDefaultTimeout() Expect(c2).Should(Exit(0)) // Test against the second alias - c3 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web2"}) + c3 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, NGINX_IMAGE, "curl", "web2"}) c3.WaitWithDefaultTimeout() Expect(c3).Should(Exit(0)) }) @@ -538,14 +558,14 @@ var _ = Describe("Podman network", func() { interval *= 2 } - top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", nginx}) + top := podmanTest.Podman([]string{"run", "-dt", "--name=web", "--network=" + netName, "--network-alias=web1", "--network-alias=web2", NGINX_IMAGE}) top.WaitWithDefaultTimeout() Expect(top).Should(Exit(0)) interval = 250 * time.Millisecond // Wait for the nginx service to be running for i := 0; i < 6; i++ { // Test curl against the container's name - c1 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web"}) + c1 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, NGINX_IMAGE, "curl", "web"}) c1.WaitWithDefaultTimeout() worked = c1.ExitCode() == 0 if worked { @@ -558,12 +578,12 @@ var _ = Describe("Podman network", func() { // Nginx is now running so no need to do a loop // Test against the first alias - c2 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web1"}) + c2 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, NGINX_IMAGE, "curl", "web1"}) c2.WaitWithDefaultTimeout() Expect(c2).Should(Exit(0)) // Test against the second alias - c3 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, nginx, "curl", "web2"}) + c3 := podmanTest.Podman([]string{"run", "--dns-search", "dns.podman", "--network=" + netName, NGINX_IMAGE, "curl", "web2"}) c3.WaitWithDefaultTimeout() Expect(c3).Should(Exit(0)) }) diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go index 566aca07e..d677eddb0 100644 --- a/test/e2e/pause_test.go +++ b/test/e2e/pause_test.go @@ -273,7 +273,7 @@ var _ = Describe("Podman pause", func() { It("Pause a bunch of running containers", func() { for i := 0; i < 3; i++ { name := fmt.Sprintf("test%d", i) - run := podmanTest.Podman([]string{"run", "-dt", "--name", name, nginx}) + run := podmanTest.Podman([]string{"run", "-dt", "--name", name, NGINX_IMAGE}) run.WaitWithDefaultTimeout() Expect(run).Should(Exit(0)) @@ -300,7 +300,7 @@ var _ = Describe("Podman pause", func() { It("Unpause a bunch of running containers", func() { for i := 0; i < 3; i++ { name := fmt.Sprintf("test%d", i) - run := podmanTest.Podman([]string{"run", "-dt", "--name", name, nginx}) + run := podmanTest.Podman([]string{"run", "-dt", "--name", name, NGINX_IMAGE}) run.WaitWithDefaultTimeout() Expect(run).Should(Exit(0)) diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go index 61f2b3a1c..457aaebb2 100644 --- a/test/e2e/play_kube_test.go +++ b/test/e2e/play_kube_test.go @@ -1512,7 +1512,7 @@ var _ = Describe("Podman play kube", func() { // If you do not supply command or args for a Container, the defaults defined in the Docker image are used. It("podman play kube test correct args and cmd when not specified", func() { - pod := getPod(withCtr(getCtr(withImage(registry), withCmd(nil), withArg(nil)))) + pod := getPod(withCtr(getCtr(withImage(REGISTRY_IMAGE), withCmd(nil), withArg(nil)))) err := generateKubeYaml("pod", pod, kubeYaml) Expect(err).To(BeNil()) @@ -1536,7 +1536,7 @@ var _ = Describe("Podman play kube", func() { // If you supply a command but no args for a Container, only the supplied command is used. // The default EntryPoint and the default Cmd defined in the Docker image are ignored. It("podman play kube test correct command with only set command in yaml file", func() { - pod := getPod(withCtr(getCtr(withImage(registry), withCmd([]string{"echo", "hello"}), withArg(nil)))) + pod := getPod(withCtr(getCtr(withImage(REGISTRY_IMAGE), withCmd([]string{"echo", "hello"}), withArg(nil)))) err := generateKubeYaml("pod", pod, kubeYaml) Expect(err).To(BeNil()) @@ -1587,7 +1587,7 @@ var _ = Describe("Podman play kube", func() { // If you supply only args for a Container, the default Entrypoint defined in the Docker image is run with the args that you supplied. It("podman play kube test correct command with only set args in yaml file", func() { - pod := getPod(withCtr(getCtr(withImage(registry), withCmd(nil), withArg([]string{"echo", "hello"})))) + pod := getPod(withCtr(getCtr(withImage(REGISTRY_IMAGE), withCmd(nil), withArg([]string{"echo", "hello"})))) err := generateKubeYaml("pod", pod, kubeYaml) Expect(err).To(BeNil()) @@ -1611,7 +1611,7 @@ var _ = Describe("Podman play kube", func() { // the default Entrypoint and the default Cmd defined in the Docker image are ignored. // Your command is run with your args. It("podman play kube test correct command with both set args and cmd in yaml file", func() { - pod := getPod(withCtr(getCtr(withImage(registry), withCmd([]string{"echo"}), withArg([]string{"hello"})))) + pod := getPod(withCtr(getCtr(withImage(REGISTRY_IMAGE), withCmd([]string{"echo"}), withArg([]string{"hello"})))) err := generateKubeYaml("pod", pod, kubeYaml) Expect(err).To(BeNil()) @@ -2507,7 +2507,7 @@ spec: Expect(kube).To(ExitWithError()) }) - It("podman play kube test with read only HostPath volume", func() { + It("podman play kube test with read-only HostPath volume", func() { hostPathLocation := filepath.Join(tempdir, "file") f, err := os.Create(hostPathLocation) Expect(err).To(BeNil()) @@ -3705,7 +3705,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q blockVolume := getHostPathVolume("BlockDevice", devicePath) - pod := getPod(withVolume(blockVolume), withCtr(getCtr(withImage(registry), withCmd(nil), withArg(nil), withVolumeMount(devicePath, false)))) + pod := getPod(withVolume(blockVolume), withCtr(getCtr(withImage(REGISTRY_IMAGE), withCmd(nil), withArg(nil), withVolumeMount(devicePath, false)))) err = generateKubeYaml("pod", pod, kubeYaml) Expect(err).To(BeNil()) @@ -3744,7 +3744,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q charVolume := getHostPathVolume("CharDevice", devicePath) - pod := getPod(withVolume(charVolume), withCtr(getCtr(withImage(registry), withCmd(nil), withArg(nil), withVolumeMount(devicePath, false)))) + pod := getPod(withVolume(charVolume), withCtr(getCtr(withImage(REGISTRY_IMAGE), withCmd(nil), withArg(nil), withVolumeMount(devicePath, false)))) err = generateKubeYaml("pod", pod, kubeYaml) Expect(err).To(BeNil()) @@ -3772,7 +3772,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q blockVolume := getHostPathVolume("BlockDevice", devicePath) - pod := getPod(withVolume(blockVolume), withCtr(getCtr(withImage(registry), withCmd(nil), withArg(nil), withVolumeMount(devicePath, false)))) + pod := getPod(withVolume(blockVolume), withCtr(getCtr(withImage(REGISTRY_IMAGE), withCmd(nil), withArg(nil), withVolumeMount(devicePath, false)))) err = generateKubeYaml("pod", pod, kubeYaml) Expect(err).To(BeNil()) @@ -3798,7 +3798,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q charVolume := getHostPathVolume("BlockDevice", devicePath) - pod := getPod(withVolume(charVolume), withCtr(getCtr(withImage(registry), withCmd(nil), withArg(nil), withVolumeMount(devicePath, false)))) + pod := getPod(withVolume(charVolume), withCtr(getCtr(withImage(REGISTRY_IMAGE), withCmd(nil), withArg(nil), withVolumeMount(devicePath, false)))) err = generateKubeYaml("pod", pod, kubeYaml) Expect(err).To(BeNil()) @@ -3823,7 +3823,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q charVolume := getHostPathVolume("CharDevice", devicePath) - pod := getPod(withVolume(charVolume), withCtr(getCtr(withImage(registry), withCmd(nil), withArg(nil), withVolumeMount(devicePath, false)))) + pod := getPod(withVolume(charVolume), withCtr(getCtr(withImage(REGISTRY_IMAGE), withCmd(nil), withArg(nil), withVolumeMount(devicePath, false)))) err = generateKubeYaml("pod", pod, kubeYaml) Expect(err).To(BeNil()) diff --git a/test/e2e/pod_clone_test.go b/test/e2e/pod_clone_test.go index b62e1205c..0a1d2358c 100644 --- a/test/e2e/pod_clone_test.go +++ b/test/e2e/pod_clone_test.go @@ -11,9 +11,10 @@ import ( var _ = Describe("Podman pod clone", func() { var ( - tempdir string - err error - podmanTest *PodmanTestIntegration + tempdir string + err error + podmanTest *PodmanTestIntegration + hostname, _ = os.Hostname() ) BeforeEach(func() { @@ -138,4 +139,56 @@ var _ = Describe("Podman pod clone", func() { Expect(data.Mounts[0]).To(HaveField("Name", volName)) }) + It("podman pod clone --shm-size", func() { + podCreate := podmanTest.Podman([]string{"pod", "create"}) + podCreate.WaitWithDefaultTimeout() + Expect(podCreate).Should(Exit(0)) + + podClone := podmanTest.Podman([]string{"pod", "clone", "--shm-size", "10mb", podCreate.OutputToString()}) + podClone.WaitWithDefaultTimeout() + Expect(podClone).Should(Exit(0)) + + run := podmanTest.Podman([]string{"run", "-it", "--pod", podClone.OutputToString(), ALPINE, "mount"}) + run.WaitWithDefaultTimeout() + Expect(run).Should(Exit(0)) + t, strings := run.GrepString("shm on /dev/shm type tmpfs") + Expect(t).To(BeTrue()) + Expect(strings[0]).Should(ContainSubstring("size=10240k")) + }) + + It("podman pod create --uts test", func() { + SkipIfRemote("hostname for the custom NS test is not as expected on the remote client") + + session := podmanTest.Podman([]string{"pod", "create"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"pod", "clone", "--uts", "host", session.OutputToString()}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"run", "-it", "--pod", session.OutputToString(), ALPINE, "printenv", "HOSTNAME"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToString()).To(ContainSubstring(hostname)) + + podName := "utsPod" + ns := "ns:/proc/self/ns/" + + session = podmanTest.Podman([]string{"pod", "create"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + // just share uts with a custom path + podCreate := podmanTest.Podman([]string{"pod", "clone", "--uts", ns, "--name", podName, session.OutputToString()}) + podCreate.WaitWithDefaultTimeout() + Expect(podCreate).Should(Exit(0)) + + podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) + podInspect.WaitWithDefaultTimeout() + Expect(podInspect).Should(Exit(0)) + podJSON := podInspect.InspectPodToJSON() + Expect(podJSON.InfraConfig).To(HaveField("UtsNS", ns)) + }) + }) diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index 4919cc670..10a8d52b5 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -23,9 +23,10 @@ import ( var _ = Describe("Podman pod create", func() { var ( - tempdir string - err error - podmanTest *PodmanTestIntegration + tempdir string + err error + podmanTest *PodmanTestIntegration + hostname, _ = os.Hostname() ) BeforeEach(func() { @@ -98,7 +99,7 @@ var _ = Describe("Podman pod create", func() { Expect(session).Should(Exit(0)) pod := session.OutputToString() - webserver := podmanTest.Podman([]string{"run", "--pod", pod, "-dt", nginx}) + webserver := podmanTest.Podman([]string{"run", "--pod", pod, "-dt", NGINX_IMAGE}) webserver.WaitWithDefaultTimeout() Expect(webserver).Should(Exit(0)) @@ -114,7 +115,7 @@ var _ = Describe("Podman pod create", func() { Expect(session).Should(Exit(0)) pod := session.OutputToString() - webserver := podmanTest.Podman([]string{"run", "--pod", pod, "-dt", nginx}) + webserver := podmanTest.Podman([]string{"run", "--pod", pod, "-dt", NGINX_IMAGE}) webserver.WaitWithDefaultTimeout() Expect(webserver).Should(Exit(0)) Expect(ncz(port)).To(BeTrue()) @@ -128,7 +129,7 @@ var _ = Describe("Podman pod create", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - webserver := podmanTest.Podman([]string{"run", "--pod-id-file", file, "-dt", nginx}) + webserver := podmanTest.Podman([]string{"run", "--pod-id-file", file, "-dt", NGINX_IMAGE}) webserver.WaitWithDefaultTimeout() Expect(webserver).Should(Exit(0)) Expect(ncz(port)).To(BeTrue()) @@ -899,27 +900,6 @@ ENTRYPOINT ["sleep","99999"] }) - It("podman pod create --device-read-bps", func() { - SkipIfRootless("Cannot create devices in /dev in rootless mode") - SkipIfRootlessCgroupsV1("Setting device-read-bps not supported on cgroupv1 for rootless users") - - podName := "testPod" - session := podmanTest.Podman([]string{"pod", "create", "--device-read-bps", "/dev/zero:1mb", "--name", podName}) - session.WaitWithDefaultTimeout() - Expect(session).Should(Exit(0)) - - if CGROUPSV2 { - session = podmanTest.Podman([]string{"run", "--rm", "--pod", podName, ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"}) - } else { - session = podmanTest.Podman([]string{"run", "--rm", "--pod", podName, ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"}) - } - session.WaitWithDefaultTimeout() - Expect(session).Should(Exit(0)) - if !CGROUPSV2 { - Expect(session.OutputToString()).To(ContainSubstring("1048576")) - } - }) - It("podman pod create --volumes-from", func() { volName := "testVol" volCreate := podmanTest.Podman([]string{"volume", "create", volName}) @@ -1134,4 +1114,53 @@ ENTRYPOINT ["sleep","99999"] 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(Exit(0)) + + run := podmanTest.Podman([]string{"run", "-it", "--pod", podCreate.OutputToString(), ALPINE, "mount"}) + run.WaitWithDefaultTimeout() + Expect(run).Should(Exit(0)) + t, strings := run.GrepString("shm on /dev/shm type tmpfs") + Expect(t).To(BeTrue()) + 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(Exit(0)) + + run := podmanTest.Podman([]string{"run", "-dt", "--pod", podCreate.OutputToString(), "--ipc", "host", ALPINE}) + run.WaitWithDefaultTimeout() + Expect(run).ShouldNot(Exit(0)) + }) + + It("podman pod create --uts test", func() { + session := podmanTest.Podman([]string{"pod", "create", "--uts", "host"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"run", "-it", "--pod", session.OutputToString(), ALPINE, "printenv", "HOSTNAME"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + if !IsRemote() { // remote hostname will not match os.Hostname() + 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(Exit(0)) + + podInspect := podmanTest.Podman([]string{"pod", "inspect", podName}) + podInspect.WaitWithDefaultTimeout() + Expect(podInspect).Should(Exit(0)) + podJSON := podInspect.InspectPodToJSON() + Expect(podJSON.InfraConfig).To(HaveField("UtsNS", ns)) + }) }) diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go index 20794a29c..a2e090524 100644 --- a/test/e2e/pod_infra_container_test.go +++ b/test/e2e/pod_infra_container_test.go @@ -114,7 +114,7 @@ var _ = Describe("Podman pod create", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"run", "-d", "--pod", podID, nginx}) + session = podmanTest.Podman([]string{"run", "-d", "--pod", podID, NGINX_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -237,11 +237,11 @@ var _ = Describe("Podman pod create", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"run", "-d", "--pod", podID, nginx}) + session = podmanTest.Podman([]string{"run", "-d", "--pod", podID, NGINX_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"run", "--pod", podID, "--network", "bridge", nginx, "curl", "-f", "localhost"}) + session = podmanTest.Podman([]string{"run", "--pod", podID, "--network", "bridge", NGINX_IMAGE, "curl", "-f", "localhost"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) }) diff --git a/test/e2e/pod_pause_test.go b/test/e2e/pod_pause_test.go index d78890347..39e5696fa 100644 --- a/test/e2e/pod_pause_test.go +++ b/test/e2e/pod_pause_test.go @@ -56,7 +56,7 @@ var _ = Describe("Podman pod pause", func() { Expect(result).Should(Exit(0)) }) - It("podman pod pause a running pod by id", func() { + It("pause a running pod by id", func() { _, ec, podid := podmanTest.CreatePod(nil) Expect(ec).To(Equal(0)) @@ -73,11 +73,10 @@ var _ = Describe("Podman pod pause", func() { result = podmanTest.Podman([]string{"pod", "unpause", podid}) result.WaitWithDefaultTimeout() - Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) - It("podman unpause a running pod by id", func() { + It("unpause a paused pod by id", func() { _, ec, podid := podmanTest.CreatePod(nil) Expect(ec).To(Equal(0)) @@ -85,14 +84,21 @@ var _ = Describe("Podman pod pause", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - result := podmanTest.Podman([]string{"pod", "unpause", podid}) + result := podmanTest.Podman([]string{"pod", "pause", podid}) result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(result.OutputToStringArray()).Should(HaveLen(1)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) + Expect(podmanTest.GetContainerStatus()).To(Equal(pausedState)) + result = podmanTest.Podman([]string{"pod", "unpause", podid}) + result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) + Expect(result.OutputToStringArray()).Should(HaveLen(1)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) }) - It("podman pod pause a running pod by name", func() { + It("unpause a paused pod by name", func() { _, ec, _ := podmanTest.CreatePod(map[string][]string{"--name": {"test1"}}) Expect(ec).To(Equal(0)) @@ -102,13 +108,42 @@ var _ = Describe("Podman pod pause", func() { result := podmanTest.Podman([]string{"pod", "pause", "test1"}) result.WaitWithDefaultTimeout() - Expect(result).Should(Exit(0)) + Expect(result.OutputToStringArray()).Should(HaveLen(1)) Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0)) Expect(podmanTest.GetContainerStatus()).To(Equal(pausedState)) result = podmanTest.Podman([]string{"pod", "unpause", "test1"}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) + Expect(result.OutputToStringArray()).Should(HaveLen(1)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + }) + + It("unpause --all", func() { + _, ec, podid1 := podmanTest.CreatePod(nil) + Expect(ec).To(Equal(0)) + _, ec, podid2 := podmanTest.CreatePod(nil) + Expect(ec).To(Equal(0)) + + session := podmanTest.RunTopContainerInPod("", podid1) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + session = podmanTest.RunTopContainerInPod("", podid2) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + result := podmanTest.Podman([]string{"pod", "pause", podid1}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(result.OutputToStringArray()).Should(HaveLen(1)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1)) + Expect(podmanTest.GetContainerStatus()).To(ContainSubstring(pausedState)) + + result = podmanTest.Podman([]string{"pod", "unpause", "--all"}) + result.WaitWithDefaultTimeout() + Expect(result).Should(Exit(0)) + Expect(result.OutputToStringArray()).Should(HaveLen(1)) + Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2)) }) }) diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go index 55e8d637b..04b7a280d 100644 --- a/test/e2e/pull_test.go +++ b/test/e2e/pull_test.go @@ -256,7 +256,7 @@ var _ = Describe("Podman pull", func() { It("podman pull from docker-archive", func() { SkipIfRemote("podman-remote does not support pulling from docker-archive") - podmanTest.AddImageToRWStore(cirros) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) tarfn := filepath.Join(podmanTest.TempDir, "cirros.tar") session := podmanTest.Podman([]string{"save", "-o", tarfn, "cirros"}) session.WaitWithDefaultTimeout() @@ -319,7 +319,7 @@ var _ = Describe("Podman pull", func() { It("podman pull from oci-archive", func() { SkipIfRemote("podman-remote does not support pulling from oci-archive") - podmanTest.AddImageToRWStore(cirros) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) tarfn := filepath.Join(podmanTest.TempDir, "oci-cirrus.tar") session := podmanTest.Podman([]string{"save", "--format", "oci-archive", "-o", tarfn, "cirros"}) session.WaitWithDefaultTimeout() @@ -339,7 +339,7 @@ var _ = Describe("Podman pull", func() { It("podman pull from local directory", func() { SkipIfRemote("podman-remote does not support pulling from local directory") - podmanTest.AddImageToRWStore(cirros) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) dirpath := filepath.Join(podmanTest.TempDir, "cirros") err = os.MkdirAll(dirpath, os.ModePerm) Expect(err).ToNot(HaveOccurred()) @@ -363,7 +363,7 @@ var _ = Describe("Podman pull", func() { It("podman pull from local OCI directory", func() { SkipIfRemote("podman-remote does not support pulling from OCI directory") - podmanTest.AddImageToRWStore(cirros) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) dirpath := filepath.Join(podmanTest.TempDir, "cirros") err = os.MkdirAll(dirpath, os.ModePerm) Expect(err).ToNot(HaveOccurred()) diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go index 864278777..97567e40d 100644 --- a/test/e2e/push_test.go +++ b/test/e2e/push_test.go @@ -100,12 +100,12 @@ var _ = Describe("Podman push", func() { Skip("No registry image for ppc64le") } if rootless.IsRootless() { - err := podmanTest.RestoreArtifact(registry) + err := podmanTest.RestoreArtifact(REGISTRY_IMAGE) Expect(err).ToNot(HaveOccurred()) } lock := GetPortLock("5000") defer lock.Unlock() - session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) + session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", REGISTRY_IMAGE, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -156,7 +156,7 @@ var _ = Describe("Podman push", func() { } lock := GetPortLock("5000") defer lock.Unlock() - session := podmanTest.Podman([]string{"run", "--entrypoint", "htpasswd", registry, "-Bbn", "podmantest", "test"}) + session := podmanTest.Podman([]string{"run", "--entrypoint", "htpasswd", REGISTRY_IMAGE, "-Bbn", "podmantest", "test"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -173,7 +173,7 @@ var _ = Describe("Podman push", func() { strings.Join([]string{authPath, "/auth"}, ":"), "-e", "REGISTRY_AUTH=htpasswd", "-e", "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "-e", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd", "-v", strings.Join([]string{certPath, "/certs"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", - "-e", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key", registry}) + "-e", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key", REGISTRY_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) diff --git a/test/e2e/rmi_test.go b/test/e2e/rmi_test.go index cc3cceda5..d1a0cd6f5 100644 --- a/test/e2e/rmi_test.go +++ b/test/e2e/rmi_test.go @@ -50,7 +50,7 @@ var _ = Describe("Podman rmi", func() { }) It("podman rmi with short name", func() { - podmanTest.AddImageToRWStore(cirros) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) session := podmanTest.Podman([]string{"rmi", "cirros"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -58,7 +58,7 @@ var _ = Describe("Podman rmi", func() { }) It("podman rmi all images", func() { - podmanTest.AddImageToRWStore(nginx) + podmanTest.AddImageToRWStore(NGINX_IMAGE) session := podmanTest.Podman([]string{"rmi", "-a"}) session.WaitWithDefaultTimeout() images := podmanTest.Podman([]string{"images"}) @@ -68,7 +68,7 @@ var _ = Describe("Podman rmi", func() { }) It("podman rmi all images forcibly with short options", func() { - podmanTest.AddImageToRWStore(nginx) + podmanTest.AddImageToRWStore(NGINX_IMAGE) session := podmanTest.Podman([]string{"rmi", "-fa"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -76,12 +76,12 @@ var _ = Describe("Podman rmi", func() { }) It("podman rmi tagged image", func() { - podmanTest.AddImageToRWStore(cirros) - setup := podmanTest.Podman([]string{"images", "-q", cirros}) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) + setup := podmanTest.Podman([]string{"images", "-q", CIRROS_IMAGE}) setup.WaitWithDefaultTimeout() Expect(setup).Should(Exit(0)) - session := podmanTest.Podman([]string{"tag", cirros, "foo:bar", "foo"}) + session := podmanTest.Podman([]string{"tag", CIRROS_IMAGE, "foo:bar", "foo"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -93,8 +93,8 @@ var _ = Describe("Podman rmi", func() { }) It("podman rmi image with tags by ID cannot be done without force", func() { - podmanTest.AddImageToRWStore(cirros) - setup := podmanTest.Podman([]string{"images", "-q", cirros}) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) + setup := podmanTest.Podman([]string{"images", "-q", CIRROS_IMAGE}) setup.WaitWithDefaultTimeout() Expect(setup).Should(Exit(0)) cirrosID := setup.OutputToString() @@ -116,8 +116,8 @@ var _ = Describe("Podman rmi", func() { It("podman rmi image that is a parent of another image", func() { Skip("I need help with this one. i don't understand what is going on") - podmanTest.AddImageToRWStore(cirros) - session := podmanTest.Podman([]string{"run", "--name", "c_test", cirros, "true"}) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) + session := podmanTest.Podman([]string{"run", "--name", "c_test", CIRROS_IMAGE, "true"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -129,7 +129,7 @@ var _ = Describe("Podman rmi", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"rmi", cirros}) + session = podmanTest.Podman([]string{"rmi", CIRROS_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -183,12 +183,12 @@ var _ = Describe("Podman rmi", func() { }) It("podman rmi with cached images", func() { - podmanTest.AddImageToRWStore(cirros) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) dockerfile := fmt.Sprintf(`FROM %s RUN mkdir hello RUN touch test.txt ENV foo=bar - `, cirros) + `, CIRROS_IMAGE) podmanTest.BuildImage(dockerfile, "test", "true") dockerfile = fmt.Sprintf(`FROM %s @@ -196,7 +196,7 @@ var _ = Describe("Podman rmi", func() { RUN touch test.txt RUN mkdir blah ENV foo=bar - `, cirros) + `, CIRROS_IMAGE) podmanTest.BuildImage(dockerfile, "test2", "true") @@ -225,7 +225,7 @@ var _ = Describe("Podman rmi", func() { podmanTest.BuildImage(dockerfile, "test3", "true") - session = podmanTest.Podman([]string{"rmi", cirros}) + session = podmanTest.Podman([]string{"rmi", CIRROS_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -250,7 +250,7 @@ var _ = Describe("Podman rmi", func() { }) It("podman rmi -a with parent|child images", func() { - podmanTest.AddImageToRWStore(cirros) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) dockerfile := fmt.Sprintf(`FROM %s AS base RUN touch /1 ENV LOCAL=/1 @@ -258,7 +258,7 @@ RUN find $LOCAL FROM base RUN find $LOCAL -`, cirros) +`, CIRROS_IMAGE) podmanTest.BuildImage(dockerfile, "test", "true") session := podmanTest.Podman([]string{"rmi", "-a"}) session.WaitWithDefaultTimeout() @@ -285,7 +285,7 @@ RUN find $LOCAL // a race, we may not hit the condition a 100 percent of times // but ocal reproducers hit it all the time. - podmanTest.AddImageToRWStore(cirros) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) var wg sync.WaitGroup buildAndRemove := func(i int) { @@ -293,7 +293,7 @@ RUN find $LOCAL defer wg.Done() imageName := fmt.Sprintf("rmtest:%d", i) containerfile := fmt.Sprintf(`FROM %s -RUN touch %s`, cirros, imageName) +RUN touch %s`, CIRROS_IMAGE, imageName) podmanTest.BuildImage(containerfile, imageName, "false") session := podmanTest.Podman([]string{"rmi", "-f", imageName}) diff --git a/test/e2e/run_aardvark_test.go b/test/e2e/run_aardvark_test.go index 25eb8b538..2c7dea9f4 100644 --- a/test/e2e/run_aardvark_test.go +++ b/test/e2e/run_aardvark_test.go @@ -42,7 +42,7 @@ var _ = Describe("Podman run networking", func() { defer podmanTest.removeNetwork(netName) Expect(session).Should(Exit(0)) - ctrID := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netName, nginx}) + ctrID := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netName, NGINX_IMAGE}) ctrID.WaitWithDefaultTimeout() Expect(ctrID).Should(Exit(0)) cid := ctrID.OutputToString() @@ -53,7 +53,7 @@ var _ = Describe("Podman run networking", func() { cip := ctrIP.OutputToString() Expect(cip).To(MatchRegexp(IPRegex)) - digShort(cid, "aone", []string{cip}, podmanTest) + digShort(cid, "aone", cip, podmanTest) reverseLookup := podmanTest.Podman([]string{"exec", cid, "dig", "+short", "-x", cip}) reverseLookup.WaitWithDefaultTimeout() @@ -72,7 +72,7 @@ var _ = Describe("Podman run networking", func() { defer podmanTest.removeNetwork(netName) Expect(session).Should(Exit(0)) - ctr1 := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netName, nginx}) + ctr1 := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netName, NGINX_IMAGE}) ctr1.WaitWithDefaultTimeout() Expect(ctr1).Should(Exit(0)) cid1 := ctr1.OutputToString() @@ -83,7 +83,7 @@ var _ = Describe("Podman run networking", func() { cip1 := ctrIP1.OutputToString() Expect(cip1).To(MatchRegexp(IPRegex)) - ctr2 := podmanTest.Podman([]string{"run", "-dt", "--name", "atwo", "--network", netName, nginx}) + ctr2 := podmanTest.Podman([]string{"run", "-dt", "--name", "atwo", "--network", netName, NGINX_IMAGE}) ctr2.WaitWithDefaultTimeout() Expect(ctr2).Should(Exit(0)) cid2 := ctr2.OutputToString() @@ -94,9 +94,9 @@ var _ = Describe("Podman run networking", func() { cip2 := ctrIP2.OutputToString() Expect(cip2).To(MatchRegexp(IPRegex)) - digShort("aone", "atwo", []string{cip2}, podmanTest) + digShort("aone", "atwo", cip2, podmanTest) - digShort("atwo", "aone", []string{cip1}, podmanTest) + digShort("atwo", "aone", cip1, podmanTest) reverseLookup12 := podmanTest.Podman([]string{"exec", cid1, "dig", "+short", "-x", cip2}) reverseLookup12.WaitWithDefaultTimeout() @@ -123,7 +123,7 @@ var _ = Describe("Podman run networking", func() { defer podmanTest.removeNetwork(netName) Expect(session).Should(Exit(0)) - ctr1 := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netName, "--network-alias", "alias_a1,alias_1a", nginx}) + ctr1 := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netName, "--network-alias", "alias_a1,alias_1a", NGINX_IMAGE}) ctr1.WaitWithDefaultTimeout() Expect(ctr1).Should(Exit(0)) @@ -133,7 +133,7 @@ var _ = Describe("Podman run networking", func() { cip1 := ctrIP1.OutputToString() Expect(cip1).To(MatchRegexp(IPRegex)) - ctr2 := podmanTest.Podman([]string{"run", "-dt", "--name", "atwo", "--network", netName, "--network-alias", "alias_a2,alias_2a", nginx}) + ctr2 := podmanTest.Podman([]string{"run", "-dt", "--name", "atwo", "--network", netName, "--network-alias", "alias_a2,alias_2a", NGINX_IMAGE}) ctr2.WaitWithDefaultTimeout() Expect(ctr2).Should(Exit(0)) @@ -143,17 +143,17 @@ var _ = Describe("Podman run networking", func() { cip2 := ctrIP2.OutputToString() Expect(cip2).To(MatchRegexp(IPRegex)) - digShort("aone", "atwo", []string{cip2}, podmanTest) + digShort("aone", "atwo", cip2, podmanTest) - digShort("aone", "alias_a2", []string{cip2}, podmanTest) + digShort("aone", "alias_a2", cip2, podmanTest) - digShort("aone", "alias_2a", []string{cip2}, podmanTest) + digShort("aone", "alias_2a", cip2, podmanTest) - digShort("atwo", "aone", []string{cip1}, podmanTest) + digShort("atwo", "aone", cip1, podmanTest) - digShort("atwo", "alias_a1", []string{cip1}, podmanTest) + digShort("atwo", "alias_a1", cip1, podmanTest) - digShort("atwo", "alias_1a", []string{cip1}, podmanTest) + digShort("atwo", "alias_1a", cip1, podmanTest) }) @@ -170,11 +170,11 @@ var _ = Describe("Podman run networking", func() { defer podmanTest.removeNetwork(netNameB) Expect(sessionB).Should(Exit(0)) - ctrA1 := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netNameA, nginx}) + ctrA1 := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netNameA, NGINX_IMAGE}) ctrA1.WaitWithDefaultTimeout() cidA1 := ctrA1.OutputToString() - ctrB1 := podmanTest.Podman([]string{"run", "-dt", "--name", "bone", "--network", netNameB, nginx}) + ctrB1 := podmanTest.Podman([]string{"run", "-dt", "--name", "bone", "--network", netNameB, NGINX_IMAGE}) ctrB1.WaitWithDefaultTimeout() cidB1 := ctrB1.OutputToString() @@ -214,7 +214,7 @@ var _ = Describe("Podman run networking", func() { defer podmanTest.removeNetwork(netNameB) Expect(sessionB).Should(Exit(0)) - ctrA1 := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netNameA, nginx}) + ctrA1 := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netNameA, NGINX_IMAGE}) ctrA1.WaitWithDefaultTimeout() cidA1 := ctrA1.OutputToString() @@ -224,7 +224,7 @@ var _ = Describe("Podman run networking", func() { cipA1 := ctrIPA1.OutputToString() Expect(cipA1).To(MatchRegexp(IPRegex)) - ctrB1 := podmanTest.Podman([]string{"run", "-dt", "--name", "bone", "--network", netNameB, nginx}) + ctrB1 := podmanTest.Podman([]string{"run", "-dt", "--name", "bone", "--network", netNameB, NGINX_IMAGE}) ctrB1.WaitWithDefaultTimeout() cidB1 := ctrB1.OutputToString() @@ -234,7 +234,7 @@ var _ = Describe("Podman run networking", func() { cipB1 := ctrIPB1.OutputToString() Expect(cipB1).To(MatchRegexp(IPRegex)) - ctrA2B2 := podmanTest.Podman([]string{"run", "-dt", "--name", "atwobtwo", "--network", netNameA, "--network", netNameB, nginx}) + ctrA2B2 := podmanTest.Podman([]string{"run", "-dt", "--name", "atwobtwo", "--network", netNameA, "--network", netNameB, NGINX_IMAGE}) ctrA2B2.WaitWithDefaultTimeout() cidA2B2 := ctrA2B2.OutputToString() @@ -250,13 +250,13 @@ var _ = Describe("Podman run networking", func() { cipA2B22 := ctrIPA2B22.OutputToString() Expect(cipA2B22).To(MatchRegexp(IPRegex)) - digShort("aone", "atwobtwo", []string{cipA2B21}, podmanTest) + digShort("aone", "atwobtwo", cipA2B21, podmanTest) - digShort("bone", "atwobtwo", []string{cipA2B22}, podmanTest) + digShort("bone", "atwobtwo", cipA2B22, podmanTest) - digShort("atwobtwo", "aone", []string{cipA1}, podmanTest) + digShort("atwobtwo", "aone", cipA1, podmanTest) - digShort("atwobtwo", "bone", []string{cipB1}, podmanTest) + digShort("atwobtwo", "bone", cipB1, podmanTest) }) It("Aardvark Test 6: Three subnets, first container on 1/2 and second on 2/3, w/ network aliases", func() { @@ -278,11 +278,11 @@ var _ = Describe("Podman run networking", func() { defer podmanTest.removeNetwork(netNameC) Expect(sessionC).Should(Exit(0)) - ctrA := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netNameA, nginx}) + ctrA := podmanTest.Podman([]string{"run", "-dt", "--name", "aone", "--network", netNameA, NGINX_IMAGE}) ctrA.WaitWithDefaultTimeout() Expect(ctrA).Should(Exit(0)) - ctrC := podmanTest.Podman([]string{"run", "-dt", "--name", "cone", "--network", netNameC, nginx}) + ctrC := podmanTest.Podman([]string{"run", "-dt", "--name", "cone", "--network", netNameC, NGINX_IMAGE}) ctrC.WaitWithDefaultTimeout() Expect(ctrC).Should(Exit(0)) @@ -304,10 +304,9 @@ var _ = Describe("Podman run networking", func() { Expect(ctrIPCB2).Should(Exit(0)) cipCB2 := ctrIPCB2.OutputToString() - digShort("aone", "testB2_nw", []string{cipCB2}, podmanTest) - - digShort("cone", "testB1_nw", []string{cipAB1}, podmanTest) + digShort("aone", "testB2_nw", cipCB2, podmanTest) + digShort("cone", "testB1_nw", cipAB1, podmanTest) }) }) diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 4081ec45b..1ad78c950 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -513,7 +513,7 @@ EXPOSE 2004-2005/tcp`, ALPINE) }) It("podman run network expose ports in image metadata", func() { - session := podmanTest.Podman([]string{"create", "--name", "test", "-t", "-P", nginx}) + session := podmanTest.Podman([]string{"create", "--name", "test", "-t", "-P", NGINX_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) results := podmanTest.Podman([]string{"inspect", "test"}) diff --git a/test/e2e/run_staticip_test.go b/test/e2e/run_staticip_test.go index af3f98d4b..8207f6d0b 100644 --- a/test/e2e/run_staticip_test.go +++ b/test/e2e/run_staticip_test.go @@ -28,7 +28,7 @@ var _ = Describe("Podman run with --ip flag", func() { } podmanTest = PodmanTestCreate(tempdir) podmanTest.Setup() - // Cleanup the CNI networks used by the tests + // Clean up the CNI networks used by the tests os.RemoveAll("/var/lib/cni/networks/podman") }) @@ -101,7 +101,7 @@ var _ = Describe("Podman run with --ip flag", func() { It("Podman run two containers with the same IP", func() { ip := GetRandomIPAddress() - result := podmanTest.Podman([]string{"run", "-d", "--name", "nginx", "--ip", ip, nginx}) + result := podmanTest.Podman([]string{"run", "-d", "--name", "nginx", "--ip", ip, NGINX_IMAGE}) result.WaitWithDefaultTimeout() Expect(result).Should(Exit(0)) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 828e92170..6edb705a1 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -73,8 +73,30 @@ var _ = Describe("Podman run", func() { Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1")) }) + It("podman run from manifest list", func() { + session := podmanTest.Podman([]string{"manifest", "create", "localhost/test:latest"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"build", "-f", "build/Containerfile.with-platform", "--platform", "linux/amd64,linux/arm64", "--manifest", "localhost/test:latest"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"run", "--platform", "linux/arm64", "localhost/test", "uname", "-a"}) + session.WaitWithDefaultTimeout() + exitCode := session.ExitCode() + // CI could either support requested platform or not, if it supports then output should contain `aarch64` + // if not run should fail with a very specific error i.e `Exec format error` anything other than this should + // be marked as failure of test. + if exitCode == 0 { + Expect(session.OutputToString()).To(ContainSubstring("aarch64")) + } else { + Expect(session.ErrorToString()).To(ContainSubstring("Exec format error")) + } + }) + It("podman run a container based on a complex local image name", func() { - imageName := strings.TrimPrefix(nginx, "quay.io/") + imageName := strings.TrimPrefix(NGINX_IMAGE, "quay.io/") session := podmanTest.Podman([]string{"run", imageName, "ls"}) session.WaitWithDefaultTimeout() Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull")) @@ -119,10 +141,10 @@ var _ = Describe("Podman run", func() { }) It("podman run a container based on on a short name with localhost", func() { - tag := podmanTest.Podman([]string{"tag", nginx, "localhost/libpod/alpine_nginx:latest"}) + tag := podmanTest.Podman([]string{"tag", NGINX_IMAGE, "localhost/libpod/alpine_nginx:latest"}) tag.WaitWithDefaultTimeout() - rmi := podmanTest.Podman([]string{"rmi", nginx}) + rmi := podmanTest.Podman([]string{"rmi", NGINX_IMAGE}) rmi.WaitWithDefaultTimeout() session := podmanTest.Podman([]string{"run", "libpod/alpine_nginx:latest", "ls"}) @@ -132,10 +154,10 @@ var _ = Describe("Podman run", func() { }) It("podman container run a container based on on a short name with localhost", func() { - tag := podmanTest.Podman([]string{"image", "tag", nginx, "localhost/libpod/alpine_nginx:latest"}) + tag := podmanTest.Podman([]string{"image", "tag", NGINX_IMAGE, "localhost/libpod/alpine_nginx:latest"}) tag.WaitWithDefaultTimeout() - rmi := podmanTest.Podman([]string{"image", "rm", nginx}) + rmi := podmanTest.Podman([]string{"image", "rm", NGINX_IMAGE}) rmi.WaitWithDefaultTimeout() session := podmanTest.Podman([]string{"container", "run", "libpod/alpine_nginx:latest", "ls"}) @@ -176,7 +198,7 @@ var _ = Describe("Podman run", func() { lock := GetPortLock("5000") defer lock.Unlock() - session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) + session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", REGISTRY_IMAGE, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -1019,7 +1041,7 @@ echo -n %s >%s }) It("podman run with built-in volume image", func() { - session := podmanTest.Podman([]string{"run", "--rm", redis, "ls"}) + session := podmanTest.Podman([]string{"run", "--rm", REDIS_IMAGE, "ls"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -1084,7 +1106,7 @@ USER mail`, BB) Expect(session).Should(Exit(0)) ctrID := session.OutputToString() - // check that the read only option works + // check that the read-only option works session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro", ALPINE, "touch", mountpoint + "abc.txt"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(1)) @@ -1108,13 +1130,13 @@ USER mail`, BB) Expect(session).Should(Exit(125)) Expect(session.ErrorToString()).To(ContainSubstring("cannot set :z more than once in mount options")) - // create new read only volume + // create new read-only volume session = podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint + ":ro", ALPINE, "cat", mountpoint + filename}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) ctrID = session.OutputToString() - // check if the original volume was mounted as read only that --volumes-from also mount it as read only + // check if the original volume was mounted as read-only that --volumes-from also mount it as read-only session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "touch", mountpoint + "abc.txt"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(1)) @@ -1122,7 +1144,7 @@ USER mail`, BB) }) It("podman run --volumes-from flag with built-in volumes", func() { - session := podmanTest.Podman([]string{"create", redis, "sh"}) + session := podmanTest.Podman([]string{"create", REDIS_IMAGE, "sh"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) ctrID := session.OutputToString() @@ -1637,7 +1659,7 @@ USER mail`, BB) session = podmanTest.Podman([]string{"run", "--umask", "9999", "--rm", ALPINE, "sh", "-c", "umask"}) session.WaitWithDefaultTimeout() Expect(session).To(ExitWithError()) - Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask")) + Expect(session.ErrorToString()).To(ContainSubstring("invalid umask")) }) It("podman run makes workdir from image", func() { @@ -1679,24 +1701,24 @@ WORKDIR /madethis`, BB) }) It("podman run container with --pull missing and only pull once", func() { - session := podmanTest.Podman([]string{"run", "--pull", "missing", cirros, "ls"}) + session := podmanTest.Podman([]string{"run", "--pull", "missing", CIRROS_IMAGE, "ls"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull")) - session = podmanTest.Podman([]string{"run", "--pull", "missing", cirros, "ls"}) + session = podmanTest.Podman([]string{"run", "--pull", "missing", CIRROS_IMAGE, "ls"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull")) }) It("podman run container with --pull missing should pull image multiple times", func() { - session := podmanTest.Podman([]string{"run", "--pull", "always", cirros, "ls"}) + session := podmanTest.Podman([]string{"run", "--pull", "always", CIRROS_IMAGE, "ls"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull")) - session = podmanTest.Podman([]string{"run", "--pull", "always", cirros, "ls"}) + session = podmanTest.Podman([]string{"run", "--pull", "always", CIRROS_IMAGE, "ls"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull")) diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go index f31e62e42..aa8f49176 100644 --- a/test/e2e/run_volume_test.go +++ b/test/e2e/run_volume_test.go @@ -150,7 +150,7 @@ var _ = Describe("Podman run with volumes", func() { }) It("podman run with conflict between image volume and user mount succeeds", func() { - err = podmanTest.RestoreArtifact(redis) + err = podmanTest.RestoreArtifact(REDIS_IMAGE) Expect(err).ToNot(HaveOccurred()) mountPath := filepath.Join(podmanTest.TempDir, "secrets") err := os.Mkdir(mountPath, 0755) @@ -160,7 +160,7 @@ var _ = Describe("Podman run with volumes", func() { Expect(err).To(BeNil(), "os.Create(testfile)") f.Close() Expect(err).To(BeNil()) - session := podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:/data", mountPath), redis, "ls", "/data/test1"}) + session := podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:/data", mountPath), REDIS_IMAGE, "ls", "/data/test1"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) }) @@ -452,6 +452,14 @@ var _ = Describe("Podman run with volumes", func() { separateVolumeSession.WaitWithDefaultTimeout() Expect(separateVolumeSession).Should(Exit(0)) Expect(separateVolumeSession.OutputToString()).To(Equal(baselineOutput)) + + copySession := podmanTest.Podman([]string{"run", "--rm", "-v", "testvol3:/etc/apk:copy", ALPINE, "stat", "-c", "%h", "/etc/apk/arch"}) + copySession.WaitWithDefaultTimeout() + Expect(copySession).Should(Exit(0)) + + noCopySession := podmanTest.Podman([]string{"run", "--rm", "-v", "testvol4:/etc/apk:nocopy", ALPINE, "stat", "-c", "%h", "/etc/apk/arch"}) + noCopySession.WaitWithDefaultTimeout() + Expect(noCopySession).Should(Exit(1)) }) It("podman named volume copyup symlink", func() { @@ -584,7 +592,7 @@ RUN sh -c "cd /etc/apk && ln -s ../../testfile"`, ALPINE) }) It("podman run image volume is not noexec", func() { - session := podmanTest.Podman([]string{"run", "--rm", redis, "grep", "/data", "/proc/self/mountinfo"}) + session := podmanTest.Podman([]string{"run", "--rm", REDIS_IMAGE, "grep", "/data", "/proc/self/mountinfo"}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) Expect(session.OutputToString()).To(Not(ContainSubstring("noexec"))) @@ -670,6 +678,15 @@ VOLUME /test/`, ALPINE) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) + // Test overlay mount when lowerdir is relative path. + f, err = os.Create("hello") + Expect(err).To(BeNil(), "os.Create") + f.Close() + session = podmanTest.Podman([]string{"run", "--rm", "-v", ".:/app:O", ALPINE, "ls", "/app"}) + session.WaitWithDefaultTimeout() + Expect(session.OutputToString()).To(ContainSubstring("hello")) + Expect(session).Should(Exit(0)) + // Make sure modifications in container do not show up on host session = podmanTest.Podman([]string{"run", "--rm", "-v", volumeFlag, ALPINE, "touch", "/run/test/container"}) session.WaitWithDefaultTimeout() @@ -953,4 +970,32 @@ USER testuser`, fedoraMinimal) Expect(volMount).Should(Exit(0)) Expect(volMount.OutputToString()).To(Equal("1000:1000")) }) + + It("podman run -v with a relative dir", func() { + mountPath := filepath.Join(podmanTest.TempDir, "vol") + err = os.Mkdir(mountPath, 0755) + Expect(err).ToNot(HaveOccurred()) + defer func() { + err := os.RemoveAll(mountPath) + Expect(err).ToNot(HaveOccurred()) + }() + + f, err := os.CreateTemp(mountPath, "podman") + Expect(err).ToNot(HaveOccurred()) + + cwd, err := os.Getwd() + Expect(err).ToNot(HaveOccurred()) + + err = os.Chdir(mountPath) + Expect(err).ToNot(HaveOccurred()) + defer func() { + err := os.Chdir(cwd) + Expect(err).ToNot(HaveOccurred()) + }() + + run := podmanTest.Podman([]string{"run", "-it", "--security-opt", "label=disable", "-v", "./:" + dest, ALPINE, "ls", dest}) + run.WaitWithDefaultTimeout() + Expect(run).Should(Exit(0)) + Expect(run.OutputToString()).Should(ContainSubstring(strings.TrimLeft("/vol/", f.Name()))) + }) }) diff --git a/test/e2e/save_test.go b/test/e2e/save_test.go index 7a1fb0fc2..94c363dd4 100644 --- a/test/e2e/save_test.go +++ b/test/e2e/save_test.go @@ -153,7 +153,7 @@ var _ = Describe("Podman save", func() { defer os.Setenv("GNUPGHOME", origGNUPGHOME) port := 5000 - session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", strings.Join([]string{strconv.Itoa(port), strconv.Itoa(port)}, ":"), "quay.io/libpod/registry:2.6"}) + session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", strings.Join([]string{strconv.Itoa(port), strconv.Itoa(port)}, ":"), REGISTRY_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) { diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index d37d8fd1a..f8b1bc836 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -206,7 +206,7 @@ registries = ['{{.Host}}:{{.Port}}']` port := GetPort() fakereg := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", fmt.Sprintf("%d:5000", port), - registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) + REGISTRY_IMAGE, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) fakereg.WaitWithDefaultTimeout() Expect(fakereg).Should(Exit(0)) @@ -231,7 +231,7 @@ registries = ['{{.Host}}:{{.Port}}']` } port := GetPort() registry := podmanTest.Podman([]string{"run", "-d", "--name", "registry3", - "-p", fmt.Sprintf("%d:5000", port), registry, + "-p", fmt.Sprintf("%d:5000", port), REGISTRY_IMAGE, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) registry.WaitWithDefaultTimeout() Expect(registry).Should(Exit(0)) @@ -268,7 +268,7 @@ registries = ['{{.Host}}:{{.Port}}']` port := GetPort() ep := endpoint{Port: fmt.Sprintf("%d", port), Host: "localhost"} registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%d:5000", port), - "--name", "registry4", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) + "--name", "registry4", REGISTRY_IMAGE, "/entrypoint.sh", "/etc/docker/registry/config.yml"}) registry.WaitWithDefaultTimeout() Expect(registry).Should(Exit(0)) @@ -313,7 +313,7 @@ registries = ['{{.Host}}:{{.Port}}']` port := GetPort() ep := endpoint{Port: fmt.Sprintf("%d", port), Host: "localhost"} registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%d:5000", port), - "--name", "registry5", registry}) + "--name", "registry5", REGISTRY_IMAGE}) registry.WaitWithDefaultTimeout() Expect(registry).Should(Exit(0)) @@ -353,7 +353,7 @@ registries = ['{{.Host}}:{{.Port}}']` port := GetPort() ep := endpoint{Port: fmt.Sprintf("%d", port), Host: "localhost"} registry := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%d:5000", port), - "--name", "registry6", registry}) + "--name", "registry6", REGISTRY_IMAGE}) registry.WaitWithDefaultTimeout() Expect(registry).Should(Exit(0)) @@ -401,7 +401,7 @@ registries = ['{{.Host}}:{{.Port}}']` ep3 := endpoint{Port: fmt.Sprintf("%d", port3), Host: "localhost"} registryLocal := podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%d", port1), - "--name", "registry7", registry}) + "--name", "registry7", REGISTRY_IMAGE}) registryLocal.WaitWithDefaultTimeout() Expect(registryLocal).Should(Exit(0)) @@ -409,7 +409,7 @@ registries = ['{{.Host}}:{{.Port}}']` Fail("Cannot start docker registry on port %s", port1) } - registryLocal = podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%d:5000", port2), "--name", "registry8", registry}) + registryLocal = podmanTest.Podman([]string{"run", "-d", "-p", fmt.Sprintf("%d:5000", port2), "--name", "registry8", REGISTRY_IMAGE}) registryLocal.WaitWithDefaultTimeout() Expect(registryLocal).Should(Exit(0)) diff --git a/test/e2e/system_connection_test.go b/test/e2e/system_connection_test.go index 2228c23b2..baa31424b 100644 --- a/test/e2e/system_connection_test.go +++ b/test/e2e/system_connection_test.go @@ -47,9 +47,7 @@ var _ = Describe("podman system connection", func() { } f := CurrentGinkgoTestDescription() - _, _ = GinkgoWriter.Write( - []byte( - fmt.Sprintf("Test: %s completed in %f seconds", f.TestText, f.Duration.Seconds()))) + processTestResult(f) }) Context("without running API service", func() { @@ -58,7 +56,7 @@ var _ = Describe("podman system connection", func() { "--default", "--identity", "~/.ssh/id_rsa", "QA", - "ssh://root@server.fubar.com:2222/run/podman/podman.sock", + "ssh://root@podman.test:2222/run/podman/podman.sock", } session := podmanTest.Podman(cmd) session.WaitWithDefaultTimeout() @@ -67,10 +65,10 @@ var _ = Describe("podman system connection", func() { cfg, err := config.ReadCustomConfig() Expect(err).ShouldNot(HaveOccurred()) - Expect(cfg).To(HaveActiveService("QA")) + Expect(cfg).Should(HaveActiveService("QA")) Expect(cfg).Should(VerifyService( "QA", - "ssh://root@server.fubar.com:2222/run/podman/podman.sock", + "ssh://root@podman.test:2222/run/podman/podman.sock", "~/.ssh/id_rsa", )) @@ -82,7 +80,7 @@ var _ = Describe("podman system connection", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - Expect(config.ReadCustomConfig()).To(HaveActiveService("QE")) + Expect(config.ReadCustomConfig()).Should(HaveActiveService("QE")) }) It("add UDS", func() { @@ -141,7 +139,7 @@ var _ = Describe("podman system connection", func() { "--default", "--identity", "~/.ssh/id_rsa", "QA", - "ssh://root@server.fubar.com:2222/run/podman/podman.sock", + "ssh://root@podman.test:2222/run/podman/podman.sock", }) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -155,8 +153,8 @@ var _ = Describe("podman system connection", func() { cfg, err := config.ReadCustomConfig() Expect(err).ShouldNot(HaveOccurred()) - Expect(cfg.Engine.ActiveService).To(BeEmpty()) - Expect(cfg.Engine.ServiceDestinations).To(BeEmpty()) + Expect(cfg.Engine.ActiveService).Should(BeEmpty()) + Expect(cfg.Engine.ServiceDestinations).Should(BeEmpty()) } }) @@ -165,7 +163,7 @@ var _ = Describe("podman system connection", func() { "--default", "--identity", "~/.ssh/id_rsa", "QA", - "ssh://root@server.fubar.com:2222/run/podman/podman.sock", + "ssh://root@podman.test:2222/run/podman/podman.sock", }) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -187,7 +185,7 @@ var _ = Describe("podman system connection", func() { "--default", "--identity", "~/.ssh/id_rsa", name, - "ssh://root@server.fubar.com:2222/run/podman/podman.sock", + "ssh://root@podman.test:2222/run/podman/podman.sock", } session := podmanTest.Podman(cmd) session.WaitWithDefaultTimeout() @@ -247,7 +245,7 @@ var _ = Describe("podman system connection", func() { // podman-remote commands will be executed by ginkgo directly. SkipIfContainerized("sshd is not available when running in a container") SkipIfRemote("connection heuristic requires both podman and podman-remote binaries") - SkipIfNotRootless(fmt.Sprintf("FIXME: setup ssh keys when root. uid(%d) euid(%d)", os.Getuid(), os.Geteuid())) + SkipIfNotRootless(fmt.Sprintf("FIXME: set up ssh keys when root. uid(%d) euid(%d)", os.Getuid(), os.Geteuid())) SkipIfSystemdNotRunning("cannot test connection heuristic if systemd is not running") SkipIfNotActive("sshd", "cannot test connection heuristic if sshd is not running") }) diff --git a/test/e2e/system_df_test.go b/test/e2e/system_df_test.go index 5a23fc0bb..998fa8b59 100644 --- a/test/e2e/system_df_test.go +++ b/test/e2e/system_df_test.go @@ -70,6 +70,17 @@ var _ = Describe("podman system df", func() { Expect(containers[1]).To(Equal("2"), "total containers expected") Expect(volumes[2]).To(Equal("2"), "total volumes expected") Expect(volumes[6]).To(Equal("(50%)"), "percentage usage expected") + + session = podmanTest.Podman([]string{"rm", "container1"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + session = podmanTest.Podman([]string{"system", "df"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + volumes = strings.Fields(session.OutputToStringArray()[3]) + // percentages on volumes were being calculated incorrectly. Make sure we only report 100% and not above + Expect(volumes[6]).To(Equal("(100%)"), "percentage usage expected") + }) It("podman system df image with no tag", func() { @@ -86,4 +97,17 @@ var _ = Describe("podman system df", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) }) + + It("podman system df --format \"{{ json . }}\"", func() { + session := podmanTest.Podman([]string{"create", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"system", "df", "--format", "{{ json . }}"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.LineInOutputContains("Size")) + Expect(session.LineInOutputContains("Reclaimable")) + Expect(session.IsJSONOutputValid()) + }) }) diff --git a/test/e2e/system_reset_test.go b/test/e2e/system_reset_test.go index 28f2e25ca..075ea435c 100644 --- a/test/e2e/system_reset_test.go +++ b/test/e2e/system_reset_test.go @@ -4,6 +4,7 @@ import ( "fmt" "os" + "github.com/containers/podman/v4/pkg/rootless" . "github.com/containers/podman/v4/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -92,9 +93,12 @@ var _ = Describe("podman system reset", func() { // TODO: machine tests currently don't run outside of the machine test pkg // no machines are created here to cleanup - session = podmanTest.Podman([]string{"machine", "list", "-q"}) - session.WaitWithDefaultTimeout() - Expect(session).Should(Exit(0)) - Expect(session.OutputToStringArray()).To(BeEmpty()) + // machine commands are rootless only + if rootless.IsRootless() { + session = podmanTest.Podman([]string{"machine", "list", "-q"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToStringArray()).To(BeEmpty()) + } }) }) diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go index a1a080904..7b3552cc2 100644 --- a/test/e2e/systemd_test.go +++ b/test/e2e/systemd_test.go @@ -60,7 +60,7 @@ WantedBy=default.target Expect(stop).Should(Exit(0)) }() - create := podmanTest.Podman([]string{"create", "--name", "redis", redis}) + create := podmanTest.Podman([]string{"create", "--name", "redis", REDIS_IMAGE}) create.WaitWithDefaultTimeout() Expect(create).Should(Exit(0)) diff --git a/test/e2e/tree_test.go b/test/e2e/tree_test.go index e1282d2b4..5b552e987 100644 --- a/test/e2e/tree_test.go +++ b/test/e2e/tree_test.go @@ -36,7 +36,7 @@ var _ = Describe("Podman image tree", func() { It("podman image tree", func() { SkipIfRemote("podman-image-tree is not supported for remote clients") - podmanTest.AddImageToRWStore(cirros) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) dockerfile := `FROM quay.io/libpod/cirros:latest RUN mkdir hello RUN touch test.txt diff --git a/test/e2e/untag_test.go b/test/e2e/untag_test.go index 90b0cc95f..b53d654f8 100644 --- a/test/e2e/untag_test.go +++ b/test/e2e/untag_test.go @@ -33,8 +33,8 @@ var _ = Describe("Podman untag", func() { }) It("podman untag all", func() { - podmanTest.AddImageToRWStore(cirros) - tags := []string{cirros, "registry.com/foo:bar", "localhost/foo:bar"} + podmanTest.AddImageToRWStore(CIRROS_IMAGE) + tags := []string{CIRROS_IMAGE, "registry.com/foo:bar", "localhost/foo:bar"} cmd := []string{"tag"} cmd = append(cmd, tags...) @@ -50,7 +50,7 @@ var _ = Describe("Podman untag", func() { } // No arguments -> remove all tags. - session = podmanTest.Podman([]string{"untag", cirros}) + session = podmanTest.Podman([]string{"untag", CIRROS_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -63,7 +63,7 @@ var _ = Describe("Podman untag", func() { }) It("podman tag/untag - tag normalization", func() { - podmanTest.AddImageToRWStore(cirros) + podmanTest.AddImageToRWStore(CIRROS_IMAGE) tests := []struct { tag, normalized string @@ -77,7 +77,7 @@ var _ = Describe("Podman untag", func() { // Make sure that the user input is normalized correctly for // `podman tag` and `podman untag`. for _, tt := range tests { - session := podmanTest.Podman([]string{"tag", cirros, tt.tag}) + session := podmanTest.Podman([]string{"tag", CIRROS_IMAGE, tt.tag}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) @@ -85,7 +85,7 @@ var _ = Describe("Podman untag", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) - session = podmanTest.Podman([]string{"untag", cirros, tt.tag}) + session = podmanTest.Podman([]string{"untag", CIRROS_IMAGE, tt.tag}) session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) diff --git a/test/e2e/volume_create_test.go b/test/e2e/volume_create_test.go index 499283cab..7a975f6a5 100644 --- a/test/e2e/volume_create_test.go +++ b/test/e2e/volume_create_test.go @@ -162,4 +162,19 @@ var _ = Describe("Podman volume create", func() { Expect(inspectOpts).Should(Exit(0)) Expect(inspectOpts.OutputToString()).To(Equal(optionStrFormatExpect)) }) + + It("podman create volume with o=timeout", func() { + volName := "testVol" + timeout := 10 + timeoutStr := "10" + session := podmanTest.Podman([]string{"volume", "create", "--opt", fmt.Sprintf("o=timeout=%d", timeout), volName}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + inspectTimeout := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .Timeout }}", volName}) + inspectTimeout.WaitWithDefaultTimeout() + Expect(inspectTimeout).Should(Exit(0)) + Expect(inspectTimeout.OutputToString()).To(Equal(timeoutStr)) + + }) }) diff --git a/test/e2e/volume_ls_test.go b/test/e2e/volume_ls_test.go index 19f87fb8a..dcfb13f4e 100644 --- a/test/e2e/volume_ls_test.go +++ b/test/e2e/volume_ls_test.go @@ -152,6 +152,37 @@ var _ = Describe("Podman volume ls", func() { Expect(lsDangling).Should(Exit(0)) Expect(lsDangling.OutputToString()).To(ContainSubstring(volName1)) }) + + It("podman ls volume with --filter name", func() { + volName1 := "volume1" + session := podmanTest.Podman([]string{"volume", "create", volName1}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + volName2 := "volume2" + session2 := podmanTest.Podman([]string{"volume", "create", volName2}) + session2.WaitWithDefaultTimeout() + Expect(session2).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "ls", "--filter", "name=volume1*"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToStringArray()).To(HaveLen(3)) + Expect(session.OutputToStringArray()[1]).To(ContainSubstring(volName1)) + Expect(session.OutputToStringArray()[2]).To(ContainSubstring(volName2)) + + session = podmanTest.Podman([]string{"volume", "ls", "--filter", "name=volumex"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToStringArray()).To(BeEmpty()) + + session = podmanTest.Podman([]string{"volume", "ls", "--filter", "name=volume1"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToStringArray()).To(HaveLen(2)) + Expect(session.OutputToStringArray()[1]).To(ContainSubstring(volName1)) + }) + It("podman ls volume with multiple --filter flag", func() { session := podmanTest.Podman([]string{"volume", "create", "--label", "foo=bar", "myvol"}) volName := session.OutputToString() diff --git a/test/e2e/volume_plugin_test.go b/test/e2e/volume_plugin_test.go index 4700afdb5..b585f8dd8 100644 --- a/test/e2e/volume_plugin_test.go +++ b/test/e2e/volume_plugin_test.go @@ -6,6 +6,7 @@ import ( "path/filepath" . "github.com/containers/podman/v4/test/utils" + "github.com/containers/storage/pkg/stringid" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" . "github.com/onsi/gomega/gexec" @@ -188,4 +189,71 @@ var _ = Describe("Podman volume plugins", func() { rmAll.WaitWithDefaultTimeout() Expect(rmAll).Should(Exit(0)) }) + + It("podman volume reload", func() { + podmanTest.AddImageToRWStore(volumeTest) + + confFile := filepath.Join(podmanTest.TempDir, "containers.conf") + err := os.WriteFile(confFile, []byte(`[engine] +[engine.volume_plugins] +testvol5 = "/run/docker/plugins/testvol5.sock"`), 0o644) + Expect(err).ToNot(HaveOccurred()) + os.Setenv("CONTAINERS_CONF", confFile) + + pluginStatePath := filepath.Join(podmanTest.TempDir, "volumes") + err = os.Mkdir(pluginStatePath, 0755) + Expect(err).ToNot(HaveOccurred()) + + // Keep this distinct within tests to avoid multiple tests using the same plugin. + pluginName := "testvol5" + ctrName := "pluginCtr" + plugin := podmanTest.Podman([]string{"run", "--name", ctrName, "--security-opt", "label=disable", "-v", "/run/docker/plugins:/run/docker/plugins", + "-v", fmt.Sprintf("%v:%v", pluginStatePath, pluginStatePath), "-d", volumeTest, "--sock-name", pluginName, "--path", pluginStatePath}) + plugin.WaitWithDefaultTimeout() + Expect(plugin).Should(Exit(0)) + + localvol := "local-" + stringid.GenerateNonCryptoID() + // create local volume + session := podmanTest.Podman([]string{"volume", "create", localvol}) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + + vol1 := "vol1-" + stringid.GenerateNonCryptoID() + session = podmanTest.Podman([]string{"volume", "create", "--driver", pluginName, vol1}) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + + // now create volume in plugin without podman + vol2 := "vol2-" + stringid.GenerateNonCryptoID() + plugin = podmanTest.Podman([]string{"exec", ctrName, "/usr/local/bin/testvol", "--sock-name", pluginName, "create", vol2}) + plugin.WaitWithDefaultTimeout() + Expect(plugin).Should(Exit(0)) + + session = podmanTest.Podman([]string{"volume", "ls", "-q"}) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + Expect(session.OutputToStringArray()).To(ContainElements(localvol, vol1)) + Expect(session.ErrorToString()).To(Equal("")) // make sure no errors are shown + + plugin = podmanTest.Podman([]string{"exec", ctrName, "/usr/local/bin/testvol", "--sock-name", pluginName, "remove", vol1}) + plugin.WaitWithDefaultTimeout() + Expect(plugin).Should(Exit(0)) + + // now reload volumes from plugins + session = podmanTest.Podman([]string{"volume", "reload"}) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + Expect(string(session.Out.Contents())).To(Equal(fmt.Sprintf(`Added: +%s +Removed: +%s +`, vol2, vol1))) + Expect(session.ErrorToString()).To(Equal("")) // make sure no errors are shown + + session = podmanTest.Podman([]string{"volume", "ls", "-q"}) + session.WaitWithDefaultTimeout() + Expect(session).To(Exit(0)) + Expect(session.OutputToStringArray()).To(ContainElements(localvol, vol2)) + Expect(session.ErrorToString()).To(Equal("")) // make no errors are shown + }) }) diff --git a/test/framework/framework.go b/test/framework/framework.go index 57c6bda2a..26e8bf21c 100644 --- a/test/framework/framework.go +++ b/test/framework/framework.go @@ -37,7 +37,7 @@ func NilFunc(f *TestFramework) error { func (t *TestFramework) Setup() { // Global initialization for the whole framework goes in here - // Setup the actual test suite + // Set up the actual test suite gomega.Expect(t.setup(t)).To(gomega.Succeed()) } diff --git a/test/system/030-run.bats b/test/system/030-run.bats index 117d791d6..b3e3cef00 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -376,17 +376,7 @@ json-file | f while read driver do_check; do msg=$(random_string 15) run_podman run --name myctr --log-driver $driver $IMAGE echo $msg - - # Simple output check - # Special case: 'json-file' emits a warning, the rest do not - # ...but with podman-remote the warning is on the server only - if [[ $do_check == 'f' ]] && ! is_remote; then # 'f' for 'fallback' - is "${lines[0]}" ".* level=error msg=\"json-file logging specified but not supported. Choosing k8s-file logging instead\"" \ - "Fallback warning emitted" - is "${lines[1]}" "$msg" "basic output sanity check (driver=$driver)" - else - is "$output" "$msg" "basic output sanity check (driver=$driver)" - fi + is "$output" "$msg" "basic output sanity check (driver=$driver)" # Simply confirm that podman preserved our argument as-is run_podman inspect --format '{{.HostConfig.LogConfig.Type}}' myctr @@ -740,7 +730,7 @@ EOF run_podman 125 run --device-cgroup-rule="x 7:* rmw" --rm $IMAGE is "$output" "Error: invalid device type in device-access-add: x" run_podman 125 run --device-cgroup-rule="a a:* rmw" --rm $IMAGE - is "$output" "Error: strconv.ParseInt: parsing \"a\": invalid syntax" + is "$output" "Error: strconv.ParseUint: parsing \"a\": invalid syntax" } @test "podman run closes stdin" { diff --git a/test/system/050-stop.bats b/test/system/050-stop.bats index c2dfba84d..39002512b 100644 --- a/test/system/050-stop.bats +++ b/test/system/050-stop.bats @@ -171,4 +171,19 @@ load helpers run_podman --noout stop -t 0 stopme is "$output" "" "output should be empty" } + +@test "podman stop, with --rm container" { + OCIDir=/run/$(podman_runtime) + + if is_rootless; then + OCIDir=/run/user/$(id -u)/$(podman_runtime) + fi + + run_podman run --rm -d --name rmstop $IMAGE sleep infinity + local cid="$output" + run_podman stop rmstop + + # Check the OCI runtime directory has removed. + is "$(ls $OCIDir | grep $cid)" "" "The OCI runtime directory should have been removed" +} # vim: filetype=sh diff --git a/test/system/055-rm.bats b/test/system/055-rm.bats index 69663fafa..0ef2216b8 100644 --- a/test/system/055-rm.bats +++ b/test/system/055-rm.bats @@ -52,10 +52,20 @@ load helpers } @test "podman rm <-> run --rm race" { + OCIDir=/run/$(podman_runtime) + + if is_rootless; then + OCIDir=/run/user/$(id -u)/$(podman_runtime) + fi + # 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 + local cid="$output" run_podman rm -af + + # Check the OCI runtime directory has removed. + is "$(ls $OCIDir | grep $cid)" "" "The OCI runtime directory should have been removed" } @test "podman rm --depend" { diff --git a/test/system/060-mount.bats b/test/system/060-mount.bats index 2735d2afd..4498e675f 100644 --- a/test/system/060-mount.bats +++ b/test/system/060-mount.bats @@ -87,7 +87,7 @@ load helpers # Run a container with an image mount run_podman run --rm --mount type=image,src=$IMAGE,dst=/image-mount $IMAGE diff /etc/os-release /image-mount/etc/os-release - # Make sure the mount is read only + # Make sure the mount is read-only run_podman 1 run --rm --mount type=image,src=$IMAGE,dst=/image-mount $IMAGE touch /image-mount/read-only is "$output" "touch: /image-mount/read-only: Read-only file system" diff --git a/test/system/120-load.bats b/test/system/120-load.bats index 5a7f63b43..7f0bcfd95 100644 --- a/test/system/120-load.bats +++ b/test/system/120-load.bats @@ -128,8 +128,24 @@ verify_iid_and_name() { run_podman image inspect --format '{{.Digest}}' $newname is "$output" "$src_digest" "Digest of re-fetched image matches original" - # Clean up + # test tagging capability + run_podman untag $IMAGE $newname + run_podman image scp ${notme}@localhost::$newname foobar:123 + + run_podman image inspect --format '{{.Digest}}' foobar:123 + is "$output" "$src_digest" "Digest of re-fetched image matches original" + + # remove root img for transfer back with another name _sudo $PODMAN image rm $newname + + # get foobar's ID, for an ID transfer test + run_podman image inspect --format '{{.ID}}' foobar:123 + run_podman image scp $output ${notme}@localhost::foobartwo + + _sudo $PODMAN image exists foobartwo + + # Clean up + _sudo $PODMAN image rm foobartwo run_podman untag $IMAGE $newname # Negative test for nonexistent image. @@ -142,12 +158,6 @@ verify_iid_and_name() { run_podman 125 image scp $nope ${notme}@localhost:: is "$output" "Error: $nope: image not known.*" "Pushing nonexistent image" - # Negative test for copying to a different name - run_podman 125 image scp $IMAGE ${notme}@localhost::newname:newtag - is "$output" "Error: cannot specify an image rename: invalid argument" \ - "Pushing with a different name: not allowed" - - # FIXME: any point in copying by image ID? What else should we test? } diff --git a/test/system/130-kill.bats b/test/system/130-kill.bats index a9456e03c..96b633a42 100644 --- a/test/system/130-kill.bats +++ b/test/system/130-kill.bats @@ -130,4 +130,14 @@ load helpers is "$output" $cname } +@test "podman kill - concurrent stop" { + # 14761 - concurrent kill/stop must record the exit code + random_name=$(random_string 10) + run_podman run -d --replace --name=$random_name alpine sh -c "trap 'echo Received SIGTERM, ignoring' SIGTERM; echo READY; while :; do sleep 0.2; done" + $PODMAN stop -t 1 $random_name & + run_podman kill $random_name + run_podman wait $random_name + run_podman rm -f $random_name +} + # vim: filetype=sh diff --git a/test/system/150-login.bats b/test/system/150-login.bats index 33b8438bf..dc902d5fe 100644 --- a/test/system/150-login.bats +++ b/test/system/150-login.bats @@ -314,7 +314,7 @@ function _test_skopeo_credential_sharing() { fi # Make sure socket is closed - if { exec 3<> /dev/tcp/127.0.0.1/${PODMAN_LOGIN_REGISTRY_PORT}; } &>/dev/null; then + if ! port_is_free $PODMAN_LOGIN_REGISTRY_PORT; then die "Socket still seems open" fi } diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats index 797883ec6..da60112a0 100644 --- a/test/system/160-volumes.bats +++ b/test/system/160-volumes.bats @@ -64,6 +64,29 @@ function teardown() { } +# Filter volumes by name +@test "podman volume filter --name" { + suffix=$(random_string) + prefix="volume" + + for i in 1 2; do + myvolume=${prefix}_${i}_${suffix} + run_podman volume create $myvolume + is "$output" "$myvolume" "output from volume create $i" + done + + run_podman volume ls --filter name=${prefix}_1.+ --format "{{.Name}}" + is "$output" "${prefix}_1_${suffix}" "--filter name=${prefix}_1.+ shows only one volume" + + # The _1* is intentional as asterisk has different meaning in glob and regexp. Make sure this is regexp + run_podman volume ls --filter name=${prefix}_1* --format "{{.Name}}" + is "$output" "${prefix}_1_${suffix}.*${prefix}_2_${suffix}.*" "--filter name=${prefix}_1* shows ${prefix}_1_${suffix} and ${prefix}_2_${suffix}" + + for i in 1 2; do + run_podman volume rm ${prefix}_${i}_${suffix} + done +} + # Named volumes @test "podman volume create / run" { myvolume=myvol$(random_string) diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats index 404ad67ec..0e522b34d 100644 --- a/test/system/200-pod.bats +++ b/test/system/200-pod.bats @@ -472,4 +472,49 @@ spec: run_podman pod rm $name-pod } +@test "pod resource limits" { + skip_if_remote "resource limits only implemented on non-remote" + if is_rootless; then + skip "only meaningful for rootful" + fi + + local name1="resources1" + run_podman --cgroup-manager=systemd pod create --name=$name1 --cpus=5 --memory=10m + run_podman --cgroup-manager=systemd pod start $name1 + run_podman pod inspect --format '{{.CgroupPath}}' $name1 + local path1="$output" + local actual1=$(< /sys/fs/cgroup/$path1/cpu.max) + is "$actual1" "500000 100000" "resource limits set properly" + local actual2=$(< /sys/fs/cgroup/$path1/memory.max) + is "$actual2" "10485760" "resource limits set properly" + run_podman pod --cgroup-manager=systemd rm -f $name1 + + local name2="resources2" + run_podman --cgroup-manager=cgroupfs pod create --cpus=5 --memory=10m --name=$name2 + run_podman --cgroup-manager=cgroupfs pod start $name2 + run_podman pod inspect --format '{{.CgroupPath}}' $name2 + local path2="$output" + local actual2=$(< /sys/fs/cgroup/$path2/cpu.max) + is "$actual2" "500000 100000" "resource limits set properly" + local actual2=$(< /sys/fs/cgroup/$path2/memory.max) + is "$actual2" "10485760" "resource limits set properly" + run_podman --cgroup-manager=cgroupfs pod rm $name2 +} + +@test "podman pod ps doesn't race with pod rm" { + # create a few pods + for i in {0..10}; do + run_podman pod create + done + + # and delete them + $PODMAN pod rm -a & + + # pod ps should not fail while pods are deleted + run_podman pod ps -q + + # wait for pod rm -a + wait +} + # vim: filetype=sh diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats index e251e8a6d..fc3c33975 100644 --- a/test/system/250-systemd.bats +++ b/test/system/250-systemd.bats @@ -295,12 +295,12 @@ LISTEN_FDNAMES=listen_fdnames" | sort) run_podman network rm -f $netname } -@test "podman-play-kube@.service template" { +@test "podman-kube@.service template" { skip_if_remote "systemd units do not work with remote clients" # If running from a podman source directory, build and use the source # version of the play-kube-@ unit file - unit_name="podman-play-kube@.service" + unit_name="podman-kube@.service" unit_file="contrib/systemd/system/${unit_name}" if [[ -e ${unit_file}.in ]]; then echo "# [Building & using $unit_name from source]" >&3 @@ -329,7 +329,7 @@ spec: EOF # Dispatch the YAML file - service_name="podman-play-kube@$(systemd-escape $yaml_source).service" + service_name="podman-kube@$(systemd-escape $yaml_source).service" systemctl start $service_name systemctl is-active $service_name diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index 2ad53620d..0d724985e 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -359,7 +359,7 @@ load helpers run curl -s $SERVER/index.txt is "$output" "$random_1" "curl 127.0.0.1:/index.txt" - # cleanup the container + # clean up the container run_podman rm -t 0 -f $cid # test that we cannot remove the default network @@ -549,7 +549,7 @@ load helpers run curl --max-time 3 -s $SERVER/index.txt is "$output" "$random_1" "curl 127.0.0.1:/index.txt should still work" - # cleanup + # clean up run_podman rm -t 0 -f $cid $background_cid run_podman network rm -t 0 -f $netname $netname2 } @@ -622,7 +622,7 @@ load helpers run_podman rm -t 0 -f $cid done - # Cleanup network + # Clean up network run_podman network rm -t 0 -f $netname } @@ -676,12 +676,12 @@ EOF @test "podman run port forward range" { for netmode in bridge slirp4netns:port_handler=slirp4netns slirp4netns:port_handler=rootlesskit; do - local port=$(random_free_port) - local end_port=$(( $port + 2 )) - local range="$port-$end_port:$port-$end_port" + local range=$(random_free_port_range 3) + local port="${test%-*}" + local end_port="${test#-*}" local random=$(random_string) - run_podman run --network $netmode -p "$range" -d $IMAGE sleep inf + run_podman run --network $netmode -p "$range:$range" -d $IMAGE sleep inf cid="$output" for port in $(seq $port $end_port); do run_podman exec -d $cid nc -l -p $port -e /bin/cat diff --git a/test/system/helpers.bash b/test/system/helpers.bash index 74b5ddc4b..273e8d2f5 100644 --- a/test/system/helpers.bash +++ b/test/system/helpers.bash @@ -284,7 +284,7 @@ function random_free_port() { local port for port in $(shuf -i ${range}); do - if ! { exec {unused_fd}<> /dev/tcp/127.0.0.1/$port; } &>/dev/null; then + if port_is_free $port; then echo $port return fi @@ -293,6 +293,35 @@ function random_free_port() { die "Could not find open port in range $range" } +function random_free_port_range() { + local size=${1?Usage: random_free_port_range SIZE (as in, number of ports)} + + local maxtries=10 + while [[ $maxtries -gt 0 ]]; do + local firstport=$(random_free_port) + local all_ports_free=1 + for i in $(seq 2 $size); do + if ! port_is_free $((firstport + $i)); then + all_ports_free= + break + fi + done + if [[ -n "$all_ports_free" ]]; then + echo "$firstport-$((firstport + $size - 1))" + return + fi + + maxtries=$((maxtries - 1)) + done + + die "Could not find free port range with size $size" +} + +function port_is_free() { + local port=${1?Usage: port_is_free PORT} + ! { exec {unused_fd}<> /dev/tcp/127.0.0.1/$port; } &>/dev/null +} + ################### # wait_for_port # Returns once port is available on host ################### diff --git a/test/testvol/Containerfile b/test/testvol/Containerfile new file mode 100644 index 000000000..32448f5a9 --- /dev/null +++ b/test/testvol/Containerfile @@ -0,0 +1,9 @@ +FROM docker.io/library/golang:1.18-alpine AS build-img +COPY ./ /go/src/github.com/containers/podman/ +WORKDIR /go/src/github.com/containers/podman +RUN GO111MODULE=off go build -o /testvol ./test/testvol + +FROM alpine +COPY --from=build-img /testvol /usr/local/bin +WORKDIR / +ENTRYPOINT ["/usr/local/bin/testvol", "serve"] diff --git a/test/testvol/create.go b/test/testvol/create.go new file mode 100644 index 000000000..d29300f0b --- /dev/null +++ b/test/testvol/create.go @@ -0,0 +1,26 @@ +package main + +import ( + pluginapi "github.com/docker/go-plugins-helpers/volume" + "github.com/spf13/cobra" +) + +var createCmd = &cobra.Command{ + Use: "create NAME", + Short: "create a volume", + Long: `Create a volume in the volume plugin listening on --sock-name`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + return createVol(config.sockName, args[0]) + }, +} + +func createVol(sockName, volName string) error { + plugin, err := getPlugin(sockName) + if err != nil { + return err + } + createReq := new(pluginapi.CreateRequest) + createReq.Name = volName + return plugin.CreateVolume(createReq) +} diff --git a/test/testvol/list.go b/test/testvol/list.go new file mode 100644 index 000000000..fea615a70 --- /dev/null +++ b/test/testvol/list.go @@ -0,0 +1,32 @@ +package main + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +var listCmd = &cobra.Command{ + Use: "list", + Short: "list all volumes", + Long: `List all volumes from the volume plugin listening on --sock-name`, + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + return listVol(config.sockName) + }, +} + +func listVol(sockName string) error { + plugin, err := getPlugin(sockName) + if err != nil { + return err + } + vols, err := plugin.ListVolumes() + if err != nil { + return err + } + for _, vol := range vols { + fmt.Println(vol.Name) + } + return nil +} diff --git a/test/testvol/main.go b/test/testvol/main.go index 30ab365b3..dd4ba642d 100644 --- a/test/testvol/main.go +++ b/test/testvol/main.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "io/ioutil" "os" "path/filepath" @@ -8,19 +9,25 @@ import ( "time" "github.com/docker/go-plugins-helpers/volume" - "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) var rootCmd = &cobra.Command{ - Use: "testvol", - Short: "testvol - volume plugin for Podman", + Use: "testvol", + Short: "testvol - volume plugin for Podman testing", + PersistentPreRunE: before, + SilenceUsage: true, +} + +var serveCmd = &cobra.Command{ + Use: "serve", + Short: "serve the volume plugin on the unix socket", Long: `Creates simple directory volumes using the Volume Plugin API for testing volume plugin functionality`, + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { return startServer(config.sockName) }, - PersistentPreRunE: before, } // Configuration for the volume plugin @@ -37,9 +44,12 @@ var config = cliConfig{ } func init() { - rootCmd.Flags().StringVar(&config.sockName, "sock-name", config.sockName, "Name of unix socket for plugin") - rootCmd.Flags().StringVar(&config.path, "path", "", "Path to initialize state and mount points") + rootCmd.PersistentFlags().StringVar(&config.sockName, "sock-name", config.sockName, "Name of unix socket for plugin") rootCmd.PersistentFlags().StringVar(&config.logLevel, "log-level", config.logLevel, "Log messages including and over the specified level: debug, info, warn, error, fatal, panic") + + serveCmd.Flags().StringVar(&config.path, "path", "", "Path to initialize state and mount points") + + rootCmd.AddCommand(serveCmd, createCmd, removeCmd, listCmd) } func before(cmd *cobra.Command, args []string) error { @@ -59,11 +69,8 @@ func before(cmd *cobra.Command, args []string) error { func main() { if err := rootCmd.Execute(); err != nil { - logrus.Errorf("Running volume plugin: %v", err) os.Exit(1) } - - os.Exit(0) } // startServer runs the HTTP server and responds to requests @@ -73,16 +80,16 @@ func startServer(socketPath string) error { if config.path == "" { path, err := ioutil.TempDir("", "test_volume_plugin") if err != nil { - return errors.Wrapf(err, "error getting directory for plugin") + return fmt.Errorf("error getting directory for plugin: %w", err) } config.path = path } else { pathStat, err := os.Stat(config.path) if err != nil { - return errors.Wrapf(err, "unable to access requested plugin state directory") + return fmt.Errorf("unable to access requested plugin state directory: %w", err) } if !pathStat.IsDir() { - return errors.Errorf("cannot use %v as plugin state dir as it is not a directory", config.path) + return fmt.Errorf("cannot use %v as plugin state dir as it is not a directory", config.path) } } @@ -91,7 +98,7 @@ func startServer(socketPath string) error { server := volume.NewHandler(handle) if err := server.ServeUnix(socketPath, 0); err != nil { - return errors.Wrapf(err, "error starting server") + return fmt.Errorf("error starting server: %w", err) } return nil } @@ -140,7 +147,7 @@ func (d *DirDriver) Create(opts *volume.CreateRequest) error { logrus.Infof("Hit Create() endpoint") if _, exists := d.volumes[opts.Name]; exists { - return errors.Errorf("volume with name %s already exists", opts.Name) + return fmt.Errorf("volume with name %s already exists", opts.Name) } newVol := new(dirVol) @@ -154,7 +161,7 @@ func (d *DirDriver) Create(opts *volume.CreateRequest) error { volPath := filepath.Join(d.volumesPath, opts.Name) if err := os.Mkdir(volPath, 0755); err != nil { - return errors.Wrapf(err, "error making volume directory") + return fmt.Errorf("error making volume directory: %w", err) } newVol.path = volPath @@ -197,7 +204,7 @@ func (d *DirDriver) Get(req *volume.GetRequest) (*volume.GetResponse, error) { vol, exists := d.volumes[req.Name] if !exists { logrus.Debugf("Did not find volume %s", req.Name) - return nil, errors.Errorf("no volume with name %s found", req.Name) + return nil, fmt.Errorf("no volume with name %s found", req.Name) } logrus.Debugf("Found volume %s", req.Name) @@ -221,19 +228,19 @@ func (d *DirDriver) Remove(req *volume.RemoveRequest) error { vol, exists := d.volumes[req.Name] if !exists { logrus.Debugf("Did not find volume %s", req.Name) - return errors.Errorf("no volume with name %s found", req.Name) + return fmt.Errorf("no volume with name %s found", req.Name) } logrus.Debugf("Found volume %s", req.Name) if len(vol.mounts) > 0 { logrus.Debugf("Cannot remove %s, is mounted", req.Name) - return errors.Errorf("volume %s is mounted and cannot be removed", req.Name) + return fmt.Errorf("volume %s is mounted and cannot be removed", req.Name) } delete(d.volumes, req.Name) if err := os.RemoveAll(vol.path); err != nil { - return errors.Wrapf(err, "error removing mountpoint of volume %s", req.Name) + return fmt.Errorf("error removing mountpoint of volume %s: %w", req.Name, err) } logrus.Debugf("Removed volume %s", req.Name) @@ -253,7 +260,7 @@ func (d *DirDriver) Path(req *volume.PathRequest) (*volume.PathResponse, error) vol, exists := d.volumes[req.Name] if !exists { logrus.Debugf("Cannot locate volume %s", req.Name) - return nil, errors.Errorf("no volume with name %s found", req.Name) + return nil, fmt.Errorf("no volume with name %s found", req.Name) } return &volume.PathResponse{ @@ -271,7 +278,7 @@ func (d *DirDriver) Mount(req *volume.MountRequest) (*volume.MountResponse, erro vol, exists := d.volumes[req.Name] if !exists { logrus.Debugf("Cannot locate volume %s", req.Name) - return nil, errors.Errorf("no volume with name %s found", req.Name) + return nil, fmt.Errorf("no volume with name %s found", req.Name) } vol.mounts[req.ID] = true @@ -291,13 +298,13 @@ func (d *DirDriver) Unmount(req *volume.UnmountRequest) error { vol, exists := d.volumes[req.Name] if !exists { logrus.Debugf("Cannot locate volume %s", req.Name) - return errors.Errorf("no volume with name %s found", req.Name) + return fmt.Errorf("no volume with name %s found", req.Name) } mount := vol.mounts[req.ID] if !mount { logrus.Debugf("Volume %s is not mounted by %s", req.Name, req.ID) - return errors.Errorf("volume %s is not mounted by %s", req.Name, req.ID) + return fmt.Errorf("volume %s is not mounted by %s", req.Name, req.ID) } delete(vol.mounts, req.ID) diff --git a/test/testvol/remove.go b/test/testvol/remove.go new file mode 100644 index 000000000..2839b0b50 --- /dev/null +++ b/test/testvol/remove.go @@ -0,0 +1,26 @@ +package main + +import ( + pluginapi "github.com/docker/go-plugins-helpers/volume" + "github.com/spf13/cobra" +) + +var removeCmd = &cobra.Command{ + Use: "remove NAME", + Short: "remove a volume", + Long: `Remove a volume in the volume plugin listening on --sock-name`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + return removeVol(config.sockName, args[0]) + }, +} + +func removeVol(sockName, volName string) error { + plugin, err := getPlugin(sockName) + if err != nil { + return err + } + removeReq := new(pluginapi.RemoveRequest) + removeReq.Name = volName + return plugin.RemoveVolume(removeReq) +} diff --git a/test/testvol/util.go b/test/testvol/util.go new file mode 100644 index 000000000..b50bb3afb --- /dev/null +++ b/test/testvol/util.go @@ -0,0 +1,29 @@ +package main + +import ( + "path/filepath" + "strings" + + "github.com/containers/podman/v4/libpod/plugin" +) + +const pluginSockDir = "/run/docker/plugins" + +func getSocketPath(pathOrName string) string { + if filepath.IsAbs(pathOrName) { + return pathOrName + } + + // only a name join it with the default path + return filepath.Join(pluginSockDir, pathOrName+".sock") +} + +func getPluginName(pathOrName string) string { + return strings.TrimSuffix(filepath.Base(pathOrName), ".sock") +} + +func getPlugin(sockNameOrPath string) (*plugin.VolumePlugin, error) { + path := getSocketPath(sockNameOrPath) + name := getPluginName(sockNameOrPath) + return plugin.GetVolumePlugin(name, path, 0) +} |