From c8124b88aecf8b01f6376950b7caf1ba9f619988 Mon Sep 17 00:00:00 2001 From: Ed Santiago Date: Mon, 10 Jan 2022 11:54:12 -0700 Subject: [WIP] Tests for podman image scp (the sudo form) Start inching our way back to having tests for the sudo form of podman image scp. Basically, copy an image to another user and then back, using a pseudorandom name. Confirm that the image makes it to the remote end, and that when we copy it back, the original image digest is preserved. When scp'ing as root, we identify the destination rootless user account via the $PODMAN_ROOTLESS_USER envariable. Setting this and creating the account is left as an exercise for the CI framework (be it github, or Fedora/CentOS/RHEL gating, or other). Also: amend hack/bats to set and relay $PODMAN_ROOTLESS_USER, so developers can test locally. Also: remove what I'm 99% sure is a debugging printf. Signed-off-by: Ed Santiago --- hack/bats | 4 ++ test/system/120-load.bats | 98 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 87 insertions(+), 15 deletions(-) diff --git a/hack/bats b/hack/bats index cd81a9c73..0776521f4 100755 --- a/hack/bats +++ b/hack/bats @@ -98,6 +98,9 @@ if [[ -z "$CONTAINERS_HELPER_BINARY_DIR" ]]; then export CONTAINERS_HELPER_BINARY_DIR=$(pwd)/bin fi +# Used in 120-load test to identify rootless destination for podman image scp +export PODMAN_ROOTLESS_USER=$(id -un) + # Root if [ -z "$ROOTLESS_ONLY" ]; then echo "# bats ${bats_filter[@]} $TESTS" @@ -105,6 +108,7 @@ if [ -z "$ROOTLESS_ONLY" ]; then --preserve-env=PODMAN_TEST_DEBUG \ --preserve-env=OCI_RUNTIME \ --preserve-env=CONTAINERS_HELPER_BINARY_DIR \ + --preserve-env=PODMAN_ROOTLESS_USER \ bats "${bats_opts[@]}" "${bats_filter[@]}" $TESTS rc=$? fi diff --git a/test/system/120-load.bats b/test/system/120-load.bats index b1d181d50..f5ba93d8a 100644 --- a/test/system/120-load.bats +++ b/test/system/120-load.bats @@ -80,26 +80,94 @@ verify_iid_and_name() { @test "podman image scp transfer" { skip_if_remote "only applicable under local podman" + if is_ubuntu; then + skip "I don't have time to deal with this" + fi - skip "FIXME FIXME FIXME: this needs a big rewrite" - - get_iid_and_name + # The testing is the same whether we're root or rootless; all that + # differs is the destination (not-me) username. if is_rootless; then + # Simple: push to root. whoami=$(id -un) - # FIXME: first, test that we can sudo. If we can't, skip. - # FIXME: test 'scp $IMAGE root@localhost::' - # FIXME: then test the rest - # FIXME: check output - run_podman image scp $whoami@localhost::$iid root@localhost:: - is "$output" "Loaded image.*: $iid" "...." - - # FIXME: "-q" is a NOP - run_podman image scp -q $whoami@localhost::$iid root@localhost:: + notme=root + _sudo() { command sudo -n "$@"; } else - # root - # FIXME: identify a rootless user. DO NOT CREATE ONE. - run_podman image scp root@localhost::$iid 1000:1000@localhost:: + # Harder: our CI infrastructure needs to define this & set up the acct + whoami=root + notme=${PODMAN_ROOTLESS_USER} + if [[ -z "$notme" ]]; then + skip "To run this test, set PODMAN_ROOTLESS_USER to a safe username" + fi + _sudo() { command sudo -n -u "$notme" "$@"; } fi + + # If we can't sudo, we can't test. + _sudo true || skip "cannot sudo to $notme" + + # FIXME FIXME FIXME: it'd be reeeeeeally nice if we could pass --root + # to the non-self user, hence avoid vandalizing + # their storage. + + # Preserve digest of original image; we will compare against it later + run_podman image inspect --format '{{.Digest}}' $IMAGE + src_digest=$output + + # image name that is not likely to exist in the destination + newname=foo.bar/nonesuch/c_$(random_string 10 | tr A-Z a-z):mytag + run_podman tag $IMAGE $newname + + # Copy it there. + # FIXME: the first '.*' in the expect string below is unfortunate; it's + # a workaround for Ubuntu which gripes: + # "warning.*defaulting to su since machinectl is not available" + # Reexamine this once #12829 is fixed + run_podman image scp $newname ${notme}@localhost:: + is "$output" ".*Copying blob .*Copying config.*Writing manifest.*Storing signatures" + + # confirm that image was copied. FIXME: also try $PODMAN image inspect? + _sudo $PODMAN image exists $newname + + # Copy it back, this time using -q + run_podman untag $IMAGE $newname + run_podman image scp -q ${notme}@localhost::$newname + + expect="Loaded image(s): $newname" + # FIXME FIXME FIXME: ubuntu has no machinectl, emits useless warning message instead + if ! is_rootless; then + # FIXME: root on fedora uses machinectl, which emits useless \n and \r (#12829) + NL=$'\n' + CR=$'\r' + expect="$NL$expect$CR" + fi + is "$output" "$expect" "-q silences output" + + # Confirm that we have it, and that its digest matches our original + run_podman image inspect --format '{{.Digest}}' $newname + is "$output" "$src_digest" "Digest of re-fetched image matches original" + + # Clean up + _sudo $PODMAN image rm $newname + run_podman untag $IMAGE $newname + + # Negative test for nonexistent image. + # FIXME FIXME: cannot test on root, because it uses machinectl (#12829) + if is_rootless; then + # FIXME: error message is 2 lines, the 2nd being "exit status 125". + # FIXME: is that fixable, or do we have to live with it? + nope="nope.nope/nonesuch:notag" + run_podman 125 image scp ${notme}@localhost::$nope + is "$output" "Error: $nope: image not known.*" "Pulling nonexistent image" + + run_podman 125 image scp $nope ${notme}@localhost:: + is "$output" "Error: $nope: image not known.*" "Pushing nonexistent image" + fi + + # 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? } -- cgit v1.2.3-54-g00ecf From 471a4356bfc57e37218afa6e2db4e9a58e53032b Mon Sep 17 00:00:00 2001 From: Ed Santiago Date: Tue, 11 Jan 2022 10:33:55 -0700 Subject: CI: rootless user: also create in some root tests viz, rootful system tests. The rootless account will be used by image-scp tests. Unfortunately, having ssh available means the system-connection tests will start running, which is very bad because they will fail, because system connection doesn't actually work (long story). Add a few more checks to prevent this test from running. Signed-off-by: Ed Santiago --- contrib/cirrus/lib.sh | 18 +++++++++++++----- contrib/cirrus/setup_environment.sh | 15 +++++++++++---- test/system/272-system-connection.bats | 8 ++++++-- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index c7352106a..ae538d23f 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -138,7 +138,9 @@ passthrough_envars(){ } setup_rootless() { - req_env_vars ROOTLESS_USER GOPATH GOSRC SECRET_ENV_RE + req_env_vars GOPATH GOSRC SECRET_ENV_RE + + ROOTLESS_USER="${ROOTLESS_USER:-some${RANDOM}dude}" local rootless_uid local rootless_gid @@ -150,9 +152,11 @@ setup_rootless() { # shellcheck disable=SC2154 if passwd --status $ROOTLESS_USER then - msg "Updating $ROOTLESS_USER user permissions on possibly changed libpod code" - chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC" - return 0 + if [[ $PRIV_NAME = "rootless" ]]; then + msg "Updating $ROOTLESS_USER user permissions on possibly changed libpod code" + chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC" + return 0 + fi fi msg "************************************************************" msg "Setting up rootless user '$ROOTLESS_USER'" @@ -164,7 +168,11 @@ setup_rootless() { msg "creating $rootless_uid:$rootless_gid $ROOTLESS_USER user" groupadd -g $rootless_gid $ROOTLESS_USER useradd -g $rootless_gid -u $rootless_uid --no-user-group --create-home $ROOTLESS_USER - chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC" + + # We also set up rootless user for image-scp tests (running as root) + if [[ $PRIV_NAME = "rootless" ]]; then + chown -R $ROOTLESS_USER:$ROOTLESS_USER "$GOPATH" "$GOSRC" + fi echo "$ROOTLESS_USER ALL=(root) NOPASSWD: ALL" > /etc/sudoers.d/ci-rootless mkdir -p "$HOME/.ssh" "/home/$ROOTLESS_USER/.ssh" diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index 8f535c7e7..03b954a5b 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -177,19 +177,26 @@ esac # Required to be defined by caller: Are we testing as root or a regular user case "$PRIV_NAME" in - root) ;; + root) + if [[ "$TEST_FLAVOR" = "sys" ]]; then + # Used in local image-scp testing + setup_rootless + echo "PODMAN_ROOTLESS_USER=$ROOTLESS_USER" >> /etc/ci_environment + fi + ;; rootless) # load kernel modules since the rootless user has no permission to do so modprobe ip6_tables || : modprobe ip6table_nat || : - # Needs to exist for setup_rootless() - ROOTLESS_USER="${ROOTLESS_USER:-some${RANDOM}dude}" - echo "ROOTLESS_USER=$ROOTLESS_USER" >> /etc/ci_environment setup_rootless ;; *) die_unknown PRIV_NAME esac +if [[ -n "$ROOTLESS_USER" ]]; then + echo "ROOTLESS_USER=$ROOTLESS_USER" >> /etc/ci_environment +fi + # Required to be defined by caller: Are we testing podman or podman-remote client # shellcheck disable=SC2154 case "$PODBIN_NAME" in diff --git a/test/system/272-system-connection.bats b/test/system/272-system-connection.bats index 4e9ac4dd6..7b70f60f4 100644 --- a/test/system/272-system-connection.bats +++ b/test/system/272-system-connection.bats @@ -124,10 +124,14 @@ $c2[ ]\+tcp://localhost:54321[ ]\+true" \ # If we have ssh access to localhost (unlikely in CI), test that. @test "podman system connection - ssh" { - rand=$(random_string 20) - echo $rand >$PODMAN_TMPDIR/testfile + # system connection only really works if we have an agent + run ssh-add -l + test "$status" -eq 0 || skip "Not running under ssh-agent" + test "${#lines[@]}" -ge 1 || skip "ssh agent has no identities" # Can we actually ssh to localhost? + rand=$(random_string 20) + echo $rand >$PODMAN_TMPDIR/testfile run ssh -q -o BatchMode=yes \ -o UserKnownHostsFile=/dev/null \ -o StrictHostKeyChecking=no \ -- cgit v1.2.3-54-g00ecf