diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/compose/mount_and_label/tests.sh | 3 | ||||
-rwxr-xr-x | test/compose/test-compose | 52 | ||||
-rw-r--r-- | test/compose/two_networks/Readme.md | 8 | ||||
-rw-r--r-- | test/compose/two_networks/docker-compose.yml | 11 | ||||
-rw-r--r-- | test/compose/two_networks/tests.sh | 7 | ||||
-rw-r--r-- | test/e2e/network_connect_disconnect_test.go | 25 | ||||
-rw-r--r-- | test/e2e/run_networking_test.go | 22 | ||||
-rw-r--r-- | test/system/001-basic.bats | 7 | ||||
-rw-r--r-- | test/system/005-info.bats | 9 | ||||
-rw-r--r-- | test/system/070-build.bats | 45 | ||||
-rw-r--r-- | test/system/270-socket-activation.bats | 103 | ||||
-rw-r--r-- | test/system/410-selinux.bats | 28 | ||||
-rw-r--r-- | test/system/500-networking.bats | 7 |
13 files changed, 285 insertions, 42 deletions
diff --git a/test/compose/mount_and_label/tests.sh b/test/compose/mount_and_label/tests.sh index 07ff089b5..fa929bed6 100644 --- a/test/compose/mount_and_label/tests.sh +++ b/test/compose/mount_and_label/tests.sh @@ -1,4 +1,5 @@ # -*- bash -*- test_port 5000 = "Podman rulez!" -podman container inspect -l --format '{{.Config.Labels}}' | grep "the_best" +podman container inspect -l --format '{{.Config.Labels}}' +like "$output" "io.podman:the_best" "$testname : Container label is set" diff --git a/test/compose/test-compose b/test/compose/test-compose index 9558fbf58..704c71a9f 100755 --- a/test/compose/test-compose +++ b/test/compose/test-compose @@ -13,7 +13,8 @@ TEST_ROOTDIR=$(realpath $(dirname $0)) # Podman executable PODMAN_BIN=$(realpath $TEST_ROOTDIR/../../bin)/podman -# Local path to docker socket (we will add the unix:/ prefix when we need it) +# Local path to docker socket with unix prefix +# The path will be changed for rootless users DOCKER_SOCK=/var/run/docker.sock # END stuff you can but probably shouldn't customize @@ -40,6 +41,13 @@ echo 0 >$failures_file ############################################################################### # BEGIN infrastructure code - the helper functions used in tests themselves +################# +# is_rootless # Check if we run as normal user +################# +function is_rootless() { + [ "$(id -u)" -ne 0 ] +} + ######### # die # Exit error with a message to stderr ######### @@ -155,7 +163,7 @@ function test_port() { local op="$2" # '=' or '~' local expect="$3" # what to expect from curl output - local actual=$(curl --retry 5 --retry-connrefused -s http://127.0.0.1:$port/) + local actual=$(curl --retry 10 --retry-all-errors -s http://127.0.0.1:$port/) local curl_rc=$? if [ $curl_rc -ne 0 ]; then _show_ok 0 "$testname - curl failed with status $curl_rc" @@ -179,7 +187,12 @@ function start_service() { test -x $PODMAN_BIN || die "Not found: $PODMAN_BIN" # FIXME: use ${testname} subdir but we can't: 50-char limit in runroot - rm -rf $WORKDIR/{root,runroot,cni} + if ! is_rootless; then + rm -rf $WORKDIR/{root,runroot,cni} + else + $PODMAN_BIN unshare rm -rf $WORKDIR/{root,runroot,cni} + fi + rm -f $DOCKER_SOCK mkdir --mode 0755 $WORKDIR/{root,runroot,cni} chcon --reference=/var/lib/containers $WORKDIR/root cp /etc/cni/net.d/*podman*conflist $WORKDIR/cni/ @@ -190,7 +203,7 @@ function start_service() { --cgroup-manager=systemd \ --cni-config-dir $WORKDIR/cni \ system service \ - --time 0 unix:/$DOCKER_SOCK \ + --time 0 unix://$DOCKER_SOCK \ &> $WORKDIR/server.log & service_pid=$! @@ -211,10 +224,11 @@ function start_service() { ############ function podman() { echo "\$ podman $*" >>$WORKDIR/output.log - $PODMAN_BIN \ + output=$($PODMAN_BIN \ --root $WORKDIR/root \ --runroot $WORKDIR/runroot \ - "$@" >>$WORKDIR/output.log 2>&1 + "$@") + echo -n "$output" >>$WORKDIR/output.log } ################### @@ -239,6 +253,14 @@ done ############################################################################### # BEGIN entry handler (subtest invoker) +# When rootless use a socket path accessible by the rootless user +if is_rootless; then + DOCKER_SOCK="$WORKDIR/docker.sock" + DOCKER_HOST="unix://$DOCKER_SOCK" + # export DOCKER_HOST docker-compose will use it + export DOCKER_HOST +fi + # Identify the tests to run. If called with args, use those as globs. tests_to_run=() if [ -n "$*" ]; then @@ -308,7 +330,7 @@ for t in ${tests_to_run[@]}; do fi # Done. Clean up. - docker-compose down &> $logfile + docker-compose down &>> $logfile rc=$? if [[ $rc -eq 0 ]]; then _show_ok 1 "$testname - down" @@ -322,7 +344,11 @@ for t in ${tests_to_run[@]}; do wait $service_pid # FIXME: otherwise we get EBUSY - umount $WORKDIR/root/overlay &>/dev/null + if ! is_rootless; then + umount $WORKDIR/root/overlay &>/dev/null + else + $PODMAN_BIN unshare umount $WORKDIR/root/overlay &>/dev/null + fi # FIXME: run 'podman ps'? # rm -rf $WORKDIR/${testname} @@ -336,9 +362,13 @@ done test_count=$(<$testcounter_file) failure_count=$(<$failures_file) -#if [ -z "$PODMAN_TESTS_KEEP_WORKDIR" ]; then -# rm -rf $WORKDIR -#fi +if [ -z "$PODMAN_TESTS_KEEP_WORKDIR" ]; then + if ! is_rootless; then + rm -rf $WORKDIR + else + $PODMAN_BIN unshare rm -rf $WORKDIR + fi +fi echo "1..${test_count}" diff --git a/test/compose/two_networks/Readme.md b/test/compose/two_networks/Readme.md new file mode 100644 index 000000000..471004f7d --- /dev/null +++ b/test/compose/two_networks/Readme.md @@ -0,0 +1,8 @@ +two networks +=============== + +This test checks that we can create containers with more than one network. + +Validation +------------ +* podman container inspect two_networks_con1_1 --format '{{len .NetworkSettings.Networks}}' shows 2 diff --git a/test/compose/two_networks/docker-compose.yml b/test/compose/two_networks/docker-compose.yml new file mode 100644 index 000000000..686396ccc --- /dev/null +++ b/test/compose/two_networks/docker-compose.yml @@ -0,0 +1,11 @@ +version: '3' +services: + con1: + image: alpine + command: top + networks: + - net1 + - net2 +networks: + net1: + net2: diff --git a/test/compose/two_networks/tests.sh b/test/compose/two_networks/tests.sh new file mode 100644 index 000000000..1cc88aa5f --- /dev/null +++ b/test/compose/two_networks/tests.sh @@ -0,0 +1,7 @@ +# -*- bash -*- + +podman container inspect two_networks_con1_1 --format '{{len .NetworkSettings.Networks}}' +is "$output" "2" "$testname : Container is connected to both networks" +podman container inspect two_networks_con1_1 --format '{{.NetworkSettings.Networks}}' +like "$output" "two_networks_net1" "$testname : First network name exists" +like "$output" "two_networks_net2" "$testname : Second network name exists" diff --git a/test/e2e/network_connect_disconnect_test.go b/test/e2e/network_connect_disconnect_test.go index e9a7b421f..6974c7614 100644 --- a/test/e2e/network_connect_disconnect_test.go +++ b/test/e2e/network_connect_disconnect_test.go @@ -33,14 +33,12 @@ var _ = Describe("Podman network connect and disconnect", func() { }) It("bad network name in disconnect should result in error", func() { - SkipIfRootless("network connect and disconnect are only rootful") dis := podmanTest.Podman([]string{"network", "disconnect", "foobar", "test"}) dis.WaitWithDefaultTimeout() Expect(dis.ExitCode()).ToNot(BeZero()) }) It("bad container name in network disconnect should result in error", func() { - SkipIfRootless("network connect and disconnect are only rootful") netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() @@ -72,7 +70,6 @@ var _ = Describe("Podman network connect and disconnect", func() { }) It("podman network disconnect", func() { - SkipIfRootless("network connect and disconnect are only rootful") netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() @@ -102,14 +99,12 @@ var _ = Describe("Podman network connect and disconnect", func() { }) It("bad network name in connect should result in error", func() { - SkipIfRootless("network connect and disconnect are only rootful") dis := podmanTest.Podman([]string{"network", "connect", "foobar", "test"}) dis.WaitWithDefaultTimeout() Expect(dis.ExitCode()).ToNot(BeZero()) }) It("bad container name in network connect should result in error", func() { - SkipIfRootless("network connect and disconnect are only rootful") netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() @@ -141,7 +136,6 @@ var _ = Describe("Podman network connect and disconnect", func() { }) It("podman connect on a container that already is connected to the network should error", func() { - SkipIfRootless("network connect and disconnect are only rootful") netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() @@ -159,7 +153,6 @@ var _ = Describe("Podman network connect and disconnect", func() { It("podman network connect", func() { SkipIfRemote("This requires a pending PR to be merged before it will work") - SkipIfRootless("network connect and disconnect are only rootful") netName := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName}) session.WaitWithDefaultTimeout() @@ -203,18 +196,23 @@ var _ = Describe("Podman network connect and disconnect", func() { }) It("podman network connect when not running", func() { - SkipIfRootless("network connect and disconnect are only rootful") - netName := "aliasTest" + stringid.GenerateNonCryptoID() - session := podmanTest.Podman([]string{"network", "create", netName}) + netName1 := "connect1" + stringid.GenerateNonCryptoID() + session := podmanTest.Podman([]string{"network", "create", netName1}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) - defer podmanTest.removeCNINetwork(netName) + defer podmanTest.removeCNINetwork(netName1) - ctr := podmanTest.Podman([]string{"create", "--name", "test", ALPINE, "top"}) + netName2 := "connect2" + stringid.GenerateNonCryptoID() + session = podmanTest.Podman([]string{"network", "create", netName2}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(BeZero()) + defer podmanTest.removeCNINetwork(netName2) + + ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName1, ALPINE, "top"}) ctr.WaitWithDefaultTimeout() Expect(ctr.ExitCode()).To(BeZero()) - dis := podmanTest.Podman([]string{"network", "connect", netName, "test"}) + dis := podmanTest.Podman([]string{"network", "connect", netName2, "test"}) dis.WaitWithDefaultTimeout() Expect(dis.ExitCode()).To(BeZero()) @@ -286,7 +284,6 @@ var _ = Describe("Podman network connect and disconnect", func() { }) It("podman network disconnect when not running", func() { - SkipIfRootless("network connect and disconnect are only rootful") netName1 := "aliasTest" + stringid.GenerateNonCryptoID() session := podmanTest.Podman([]string{"network", "create", netName1}) session.WaitWithDefaultTimeout() diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index 0e6e636bc..4c66e2823 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -641,22 +641,26 @@ var _ = Describe("Podman run networking", func() { Expect(run.OutputToString()).To(ContainSubstring(ipAddr)) }) - It("podman rootless fails custom CNI network with --uidmap", func() { - SkipIfNotRootless("The configuration works with rootless") - + It("podman cni network works across user ns", func() { netName := stringid.GenerateNonCryptoID() create := podmanTest.Podman([]string{"network", "create", netName}) create.WaitWithDefaultTimeout() Expect(create.ExitCode()).To(BeZero()) defer podmanTest.removeCNINetwork(netName) - run := podmanTest.Podman([]string{"run", "--rm", "--net", netName, "--uidmap", "0:1:4096", ALPINE, "true"}) + name := "nc-server" + run := podmanTest.Podman([]string{"run", "-d", "--name", name, "--net", netName, ALPINE, "nc", "-l", "-p", "8080"}) + run.WaitWithDefaultTimeout() + Expect(run.ExitCode()).To(Equal(0)) + + run = podmanTest.Podman([]string{"run", "--rm", "--net", netName, "--uidmap", "0:1:4096", ALPINE, "sh", "-c", fmt.Sprintf("echo podman | nc -w 1 %s.dns.podman 8080", name)}) run.WaitWithDefaultTimeout() - Expect(run.ExitCode()).To(Equal(125)) + Expect(run.ExitCode()).To(Equal(0)) - remove := podmanTest.Podman([]string{"network", "rm", netName}) - remove.WaitWithDefaultTimeout() - Expect(remove.ExitCode()).To(BeZero()) + log := podmanTest.Podman([]string{"logs", name}) + log.WaitWithDefaultTimeout() + Expect(log.ExitCode()).To(Equal(0)) + Expect(log.OutputToString()).To(Equal("podman")) }) It("podman run with new:pod and static-ip", func() { @@ -762,7 +766,7 @@ var _ = Describe("Podman run networking", func() { Expect(session.ExitCode()).To(Equal(1)) Expect(session.ErrorToString()).To(ContainSubstring("can't resolve 'con1'")) - session = podmanTest.Podman([]string{"run", "--name", "con4", "--network", net, ALPINE, "nslookup", pod2}) + session = podmanTest.Podman([]string{"run", "--name", "con4", "--network", net, ALPINE, "nslookup", pod2 + ".dns.podman"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(BeZero()) }) diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats index d276cfda1..081bb1171 100644 --- a/test/system/001-basic.bats +++ b/test/system/001-basic.bats @@ -10,6 +10,13 @@ function setup() { : } +@test "podman --context emits reasonable output" { + run_podman 125 --context=swarm version + is "$output" "Error: Podman does not support swarm, the only --context value allowed is \"default\"" "--context=default or fail" + + run_podman --context=default version +} + @test "podman version emits reasonable output" { run_podman version diff --git a/test/system/005-info.bats b/test/system/005-info.bats index 7452c1901..c0af2e937 100644 --- a/test/system/005-info.bats +++ b/test/system/005-info.bats @@ -53,4 +53,13 @@ store.imageStore.number | 1 } +@test "podman info --storage-opt='' " { + skip_if_remote "--storage-opt flag is not supported for remote" + skip_if_rootless "storage opts are required for rootless running" + run_podman --storage-opt='' info + # Note this will not work in rootless mode, unless you specify + # storage-driver=vfs, until we have kernels that support rootless overlay + # mounts. + is "$output" ".*graphOptions: {}" "output includes graphOptions: {}" +} # vim: filetype=sh diff --git a/test/system/070-build.bats b/test/system/070-build.bats index e5b68a0d8..5a887c71e 100644 --- a/test/system/070-build.bats +++ b/test/system/070-build.bats @@ -712,6 +712,51 @@ EOF run_podman rmi -f build_test } +@test "podman build check_label" { + skip_if_no_selinux + tmpdir=$PODMAN_TMPDIR/build-test + mkdir -p $tmpdir + tmpbuilddir=$tmpdir/build + mkdir -p $tmpbuilddir + dockerfile=$tmpbuilddir/Dockerfile + cat >$dockerfile <<EOF +FROM $IMAGE +RUN cat /proc/self/attr/current +EOF + + run_podman build -t build_test --security-opt label=level:s0:c3,c4 --format=docker $tmpbuilddir + is "$output" ".*s0:c3,c4STEP 3: COMMIT" "label setting level" + + run_podman rmi -f build_test +} + +@test "podman build check_seccomp_ulimits" { + tmpdir=$PODMAN_TMPDIR/build-test + mkdir -p $tmpdir + tmpbuilddir=$tmpdir/build + mkdir -p $tmpbuilddir + dockerfile=$tmpbuilddir/Dockerfile + cat >$dockerfile <<EOF +FROM $IMAGE +RUN grep Seccomp: /proc/self/status |awk '{ print \$1\$2 }' +RUN grep "Max open files" /proc/self/limits |awk '{ print \$4":"\$5 }' +EOF + + run_podman build --ulimit nofile=101:102 -t build_test $tmpbuilddir + is "$output" ".*Seccomp:2" "setting seccomp" + is "$output" ".*101:102" "setting ulimits" + run_podman rmi -f build_test + + run_podman build -t build_test --security-opt seccomp=unconfined $tmpbuilddir + is "$output" ".*Seccomp:0" "setting seccomp" + run_podman rmi -f build_test +} + +@test "podman build --authfile bogus test" { + run_podman 125 build --authfile=/tmp/bogus - <<< "from scratch" + is "$output" ".*/tmp/bogus: no such file or directory" +} + function teardown() { # A timeout or other error in 'build' can leave behind stale images # that podman can't even see and which will cascade into subsequent diff --git a/test/system/270-socket-activation.bats b/test/system/270-socket-activation.bats new file mode 100644 index 000000000..25206c6a7 --- /dev/null +++ b/test/system/270-socket-activation.bats @@ -0,0 +1,103 @@ +#!/usr/bin/env bats -*- bats -*- +# +# Tests podman system service under systemd socket activation +# + +load helpers + +SERVICE_NAME="podman_test_$(random_string)" + +SYSTEMCTL="systemctl" +UNIT_DIR="/usr/lib/systemd/system" +SERVICE_SOCK_ADDR="/run/podman/podman.sock" + +if is_rootless; then + UNIT_DIR="$HOME/.config/systemd/user" + mkdir -p $UNIT_DIR + + SYSTEMCTL="$SYSTEMCTL --user" + if [ -z "$XDG_RUNTIME_DIR" ]; then + export XDG_RUNTIME_DIR=/run/user/$(id -u) + fi + SERVICE_SOCK_ADDR="$XDG_RUNTIME_DIR/podman/podman.sock" +fi + +SERVICE_FILE="$UNIT_DIR/$SERVICE_NAME.service" +SOCKET_FILE="$UNIT_DIR/$SERVICE_NAME.socket" + + +function setup() { + skip_if_remote "systemd tests are meaningless over remote" + + basic_setup + + cat > $SERVICE_FILE <<EOF +[Unit] +Description=Podman API Service +Requires=podman.socket +After=podman.socket +Documentation=man:podman-system-service(1) +StartLimitIntervalSec=0 + +[Service] +Type=exec +KillMode=process +Environment=LOGGING="--log-level=info" +ExecStart=$PODMAN $LOGGING system service -t 2 +EOF + cat > $SOCKET_FILE <<EOF +[Unit] +Description=Podman API Socket +Documentation=man:podman-system-service(1) + +[Socket] +ListenStream=%t/podman/podman.sock +SocketMode=0660 + +[Install] +WantedBy=sockets.target +EOF + + # ensure pause die before each test runs + if is_rootless; then + local pause_pid="$XDG_RUNTIME_DIR/libpod/tmp/pause.pid" + if [ -f $pause_pid ]; then + kill -9 $(cat $pause_pid) 2> /dev/null + rm -f $pause_pid + fi + fi + $SYSTEMCTL start "$SERVICE_NAME.socket" +} + +function teardown() { + $SYSTEMCTL stop "$SERVICE_NAME.socket" + rm -f "$SERVICE_FILE" "$SOCKET_FILE" + $SYSTEMCTL daemon-reload + basic_teardown +} + +@test "podman system service - socket activation - no container" { + run curl -s --max-time 3 --unix-socket $SERVICE_SOCK_ADDR http://podman/libpod/_ping + is "$output" "OK" "podman service responses normally" +} + +@test "podman system service - socket activation - exist container " { + run_podman run $IMAGE sleep 90 + run curl -s --max-time 3 --unix-socket $SERVICE_SOCK_ADDR http://podman/libpod/_ping + is "$output" "OK" "podman service responses normally" +} + +@test "podman system service - socket activation - kill rootless pause " { + if ! is_rootless; then + skip "root podman no need pause process" + fi + run_podman run $IMAGE sleep 90 + local pause_pid="$XDG_RUNTIME_DIR/libpod/tmp/pause.pid" + if [ -f $pause_pid ]; then + kill -9 $(cat $pause_pid) 2> /dev/null + fi + run curl -s --max-time 3 --unix-socket $SERVICE_SOCK_ADDR http://podman/libpod/_ping + is "$output" "OK" "podman service responses normally" +} + +# vim: filetype=sh diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats index 4a2c7b7a4..8a690fb48 100644 --- a/test/system/410-selinux.bats +++ b/test/system/410-selinux.bats @@ -191,5 +191,33 @@ function check_label() { is "$output" "Error.*: \`/proc/thread-self/attr/exec\`: OCI runtime error: unable to assign security attribute" "useful diagnostic" } +@test "podman selinux: check relabel" { + skip_if_no_selinux + + LABEL="system_u:object_r:tmp_t:s0" + tmpdir=$PODMAN_TMPDIR/vol + touch $tmpdir + chcon -vR ${LABEL} $tmpdir + ls -Z $tmpdir + + run_podman run -v $tmpdir:/test $IMAGE cat /proc/self/attr/current + level=$(secon -l $output) + run ls -dZ ${tmpdir} + is "$output" ${LABEL} "No Relabel Correctly" + + run_podman run -v $tmpdir:/test:Z --security-opt label=disable $IMAGE cat /proc/self/attr/current + level=$(secon -l $output) + run ls -dZ $tmpdir + is "$output" ${LABEL} "No Privileged Relabel Correctly" + + run_podman run -v $tmpdir:/test:Z $IMAGE cat /proc/self/attr/current + level=$(secon -l $output) + run ls -dZ $tmpdir + is "$output" "system_u:object_r:container_file_t:$level" "Confined Relabel Correctly" + + run_podman run -v $tmpdir:/test:z $IMAGE cat /proc/self/attr/current + run ls -dZ $tmpdir + is "$output" "system_u:object_r:container_file_t:s0" "Shared Relabel Correctly" +} # vim: filetype=sh diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats index 4868ad6a0..804dd46b1 100644 --- a/test/system/500-networking.bats +++ b/test/system/500-networking.bats @@ -143,13 +143,6 @@ load helpers run_podman network rm $mynetname run_podman 1 network rm $mynetname - - # rootless CNI leaves behind an image pulled by SHA, hence with no tag. - # Remove it if present; we can only remove it by ID. - run_podman images --format '{{.Id}}' rootless-cni-infra - if [ -n "$output" ]; then - run_podman rmi $output - fi } @test "podman network reload" { |