From 460e2de8db01d72f1182d4c7e704bb3ebb0e8e0b Mon Sep 17 00:00:00 2001 From: Ramkumar Chinchani Date: Mon, 18 Nov 2024 22:49:02 +0000 Subject: [PATCH] test: add a erofs test Signed-off-by: Ramkumar Chinchani --- install-build-deps.sh | 1 + test/atomfs-erofs.bats | 164 +++++++++++++++++++++++++++++++++++++++++ test/helpers.bash | 22 +++--- 3 files changed, 176 insertions(+), 11 deletions(-) create mode 100644 test/atomfs-erofs.bats diff --git a/install-build-deps.sh b/install-build-deps.sh index bae0a887..883ff161 100755 --- a/install-build-deps.sh +++ b/install-build-deps.sh @@ -43,6 +43,7 @@ installdeps_ubuntu() { squashfs-tools squashfuse libarchive-tools + erofs-utils ) case "$VERSION_ID" in diff --git a/test/atomfs-erofs.bats b/test/atomfs-erofs.bats new file mode 100644 index 00000000..6df71b14 --- /dev/null +++ b/test/atomfs-erofs.bats @@ -0,0 +1,164 @@ +load helpers + +function setup() { + stacker_setup +} + +function teardown() { + cleanup +} + +function verity_checkusedloops() { + # search for loopdevices which have backing files with the current + # BATS_TEST_DIRNAME value and complain if they're present. + local usedloops="" found="" x="" + for ((x=0; x<5; x++)); do + usedloops=$(losetup -a | grep $BATS_TEST_DIRNAME || echo) + if [ -n "$usedloops" ]; then + found=1 + udevadm settle + else + return 0 + fi + done + echo "found used loops in testdir=$BATS_TEST_DIRNAME :$usedloops" >&3 + [ $found = 1 ] +} + +function basic_test() { + require_privilege priv + local verity_arg=$1 + + cat > stacker.yaml <<"EOF" +test: + from: + type: oci + url: ${{BUSYBOX_OCI}} + run: | + touch /hello +EOF + stacker build --layer-type=erofs $verity_arg --substitute BUSYBOX_OCI=${BUSYBOX_OCI} + mkdir mountpoint + stacker internal-go atomfs mount test-erofs mountpoint + + [ -f mountpoint/hello ] + stacker internal-go atomfs umount mountpoint +} + +@test "--no-verity works" { + basic_test --no-verity + verity_checkusedloops +} + +@test "mount + umount works" { + basic_test + + # last layer shouldn't exist any more, since it is unique + manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:) + last_layer_num=$(($(cat oci/blobs/sha256/$manifest | jq -r '.layers | length')-1)) + last_layer_hash=$(cat oci/blobs/sha256/$manifest | jq -r .layers[$last_layer].digest | cut -f2 -d:) + [ ! -b "/dev/mapper/$last_layer_hash-verity" ] + verity_checkusedloops +} + +@test "mount + umount + mount a tree of images works" { + require_privilege priv + cat > stacker.yaml <<"EOF" +base: + from: + type: oci + url: ${{BUSYBOX_OCI}} + run: touch /base +a: + from: + type: built + tag: base + run: touch /a +b: + from: + type: built + tag: base + run: touch /b +c: + from: + type: built + tag: base + run: touch /c +EOF + stacker build --layer-type=erofs --substitute BUSYBOX_OCI=${BUSYBOX_OCI} + + mkdir a + stacker internal-go atomfs mount a-erofs a + [ -f a/a ] + + mkdir b + stacker internal-go atomfs mount b-erofs b + [ -f b/b ] + + cat /proc/self/mountinfo + echo "mountinfo after b^" + + stacker internal-go atomfs umount b + + # first layer should still exist since a is still mounted + manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:) + first_layer_hash=$(cat oci/blobs/sha256/$manifest | jq -r .layers[0].digest | cut -f2 -d:) + [ ! -b "/dev/mapper/$last_layer_hash-verity" ] + + mkdir c + stacker internal-go atomfs mount c-erofs c + [ -f c/c ] + + cat /proc/self/mountinfo + echo "mountinfo after c^" + + stacker internal-go atomfs umount a + + cat /proc/self/mountinfo + echo "mountinfo after umount a^" + + # first layer should still exist since c is still mounted + manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:) + first_layer_hash=$(cat oci/blobs/sha256/$manifest | jq -r .layers[0].digest | cut -f2 -d:) + [ ! -b "/dev/mapper/$last_layer_hash-verity" ] + + # c should still be ok + [ -f c/c ] + [ -f c/bin/sh ] + stacker internal-go atomfs umount c + + # c's last layer shouldn't exist any more, since it is unique + manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:) + last_layer_num=$(($(cat oci/blobs/sha256/$manifest | jq -r '.layers | length')-1)) + last_layer_hash=$(cat oci/blobs/sha256/$manifest | jq -r .layers[$last_layer].digest | cut -f2 -d:) + [ ! -b "/dev/mapper/$last_layer_hash-verity" ] + verity_checkusedloops +} + +@test "bad existing verity device is rejected" { + require_privilege priv + cat > stacker.yaml <<"EOF" +test: + from: + type: oci + url: ${{BUSYBOX_OCI}} + run: | + touch /hello +EOF + stacker build --layer-type=erofs --substitute BUSYBOX_OCI=${BUSYBOX_OCI} + + manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:) + first_layer_hash=$(cat oci/blobs/sha256/$manifest | jq -r .layers[0].digest | cut -f2 -d:) + devname="$first_layer_hash-verity" + + # make an evil device and fake it as an existing verity device + dd if=/dev/random of=mydev bs=50K count=1 + root_hash=$(veritysetup format mydev mydev.hash | grep "Root hash:" | awk '{print $NF}') + echo "root hash $root_hash" + veritysetup open mydev "$devname" mydev.hash "$root_hash" + + mkdir mountpoint + bad_stacker internal-go atomfs mount test-erofs mountpoint | grep "invalid root hash" + veritysetup close "$devname" + verity_checkusedloops +} diff --git a/test/helpers.bash b/test/helpers.bash index f61000eb..ac82cae4 100644 --- a/test/helpers.bash +++ b/test/helpers.bash @@ -8,6 +8,17 @@ if [ "$(id -u)" != "0" ]; then exit 1 fi +function give_user_ownership() { + if [ "$PRIVILEGE_LEVEL" = "priv" ]; then + return + fi + if [ -z "$SUDO_UID" ]; then + echo "PRIVILEGE_LEVEL=$PRIVILEGE_LEVEL but empty SUDO_USER" + exit 1 + fi + chown -R "$SUDO_USER:$SUDO_USER" "$@" +} + function skip_if_no_unpriv_overlay { local wdir="" # use a workdir to ensure no side effects to the caller @@ -80,17 +91,6 @@ function stacker_setup() { chown -R $SUDO_USER:$SUDO_USER . } -function give_user_ownership() { - if [ "$PRIVILEGE_LEVEL" = "priv" ]; then - return - fi - if [ -z "$SUDO_UID" ]; then - echo "PRIVILEGE_LEVEL=$PRIVILEGE_LEVEL but empty SUDO_USER" - exit 1 - fi - chown -R "$SUDO_USER:$SUDO_USER" "$@" - } - function cleanup() { cd "$ROOT_DIR/test" umount_under "$TEST_TMPDIR"