From 94e50ca5aa19b5a2a8590b317c57412d8862ca9d Mon Sep 17 00:00:00 2001 From: William Manley Date: Wed, 27 Jul 2016 16:40:05 +0100 Subject: [PATCH] tests: Add basic tests for ostree-prepare-root These tests use unshare and mount to prepare a fake initrd/early boot directory structure so we can then test ostree-prepare-root. Things that are tested: * Running in an initrd environment * Running without initrd * /var and /sysroot being mounted correctly * /usr being mounted read-only Things not tested (yet): * Running as init - this could be accomplished by unsharing the pid namespace too. * mounting/unmounting `/proc` if `/proc/cmdline` isn't available * Persistent overlayfs for `/usr` * Probably other things The tests are basic but can be extended in the future as we do more work on `ostree-prepare-root`. These tests must be run as root as they require the ability to `mount` and to `unshare` the mount namespace. Perhaps in the future we can use user namespaces for this test once they are more widely available. Closes: #403 Approved by: cgwalters --- Makefile-tests.am | 1 + tests/libtest.sh | 33 ++++++--------- tests/test-switchroot.sh | 87 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 21 deletions(-) create mode 100755 tests/test-switchroot.sh diff --git a/Makefile-tests.am b/Makefile-tests.am index 63d11ec8..4316f2ee 100644 --- a/Makefile-tests.am +++ b/Makefile-tests.am @@ -87,6 +87,7 @@ dist_test_scripts = \ tests/test-prune.sh \ tests/test-refs.sh \ tests/test-demo-buildsystem.sh \ + tests/test-switchroot.sh \ $(NULL) if BUILDOPT_FUSE diff --git a/tests/libtest.sh b/tests/libtest.sh index 2d064299..958f6769 100755 --- a/tests/libtest.sh +++ b/tests/libtest.sh @@ -399,34 +399,25 @@ os_repository_new_commit () cd ${test_tmpdir} } +skip() { + echo "1..0 # SKIP" "$@" + exit 0 +} + skip_without_user_xattrs () { touch test-xattrs - if ! setfattr -n user.testvalue -v somevalue test-xattrs; then - echo "1..0 # SKIP this test requires xattr support" - exit 0 - fi + setfattr -n user.testvalue -v somevalue test-xattrs || \ + skip "this test requires xattr support" } skip_without_fuse () { - if ! fusermount --version >/dev/null 2>&1; then - echo "1..0 # SKIP no fusermount" - exit 0 - fi + fusermount --version >/dev/null 2>&1 || skip "no fusermount" - if ! capsh --print | grep -q 'Bounding set.*[^a-z]cap_sys_admin'; then - echo "1..0 # SKIP No cap_sys_admin in bounding set, can't use FUSE" - exit 0 - fi + capsh --print | grep -q 'Bounding set.*[^a-z]cap_sys_admin' || \ + skip "No cap_sys_admin in bounding set, can't use FUSE" - if ! [ -w /dev/fuse ]; then - echo "1..0 # SKIP no write access to /dev/fuse" - exit 0 - fi - - if ! [ -e /etc/mtab ]; then - echo "1..0 # SKIP no /etc/mtab" - exit 0 - fi + [ -w /dev/fuse ] || skip "no write access to /dev/fuse" + [ -e /etc/mtab ] || skip "no /etc/mtab" } libtest_cleanup_gpg () { diff --git a/tests/test-switchroot.sh b/tests/test-switchroot.sh new file mode 100755 index 00000000..e039f5b7 --- /dev/null +++ b/tests/test-switchroot.sh @@ -0,0 +1,87 @@ +#!/bin/bash -ex + +this_script="${BASH_SOURCE:-$(readlink -f "$0")}" + +setup_bootfs() { + mkdir -p "$1/proc" "$1/bin" + echo "quiet ostree=/ostree/boot.0 ro" >"$1/proc/cmdline" + touch "$1/this_is_bootfs" + cp "$(dirname "$this_script")/../src/switchroot/ostree-prepare-root" "$1/bin" +} + +setup_rootfs() { + mkdir -p "$1/ostree/deploy/linux/deploy/1334/sysroot" \ + "$1/ostree/deploy/linux/deploy/1334/var" \ + "$1/ostree/deploy/linux/deploy/1334/usr" \ + "$1/ostree/deploy/linux/var" \ + "$1/bin" + ln -s "deploy/linux/deploy/1334" "$1/ostree/boot.0" + ln -s . "$1/sysroot" + touch "$1/ostree/deploy/linux/deploy/1334/this_is_ostree_root" \ + "$1/ostree/deploy/linux/var/this_is_ostree_var" \ + "$1/ostree/deploy/linux/deploy/1334/usr/this_is_ostree_usr" \ + "$1/this_is_real_root" + cp /bin/busybox "$1/bin" + busybox --list | xargs -n1 -I '{}' ln -s busybox "$1/bin/{}" + cp -r "$1/bin" "$1/ostree/deploy/linux/deploy/1334/" +} + +enter_fs() { + cd "$1" + mkdir testroot + pivot_root . testroot + export PATH=$PATH:/sysroot/bin + cd / + umount -l testroot + rmdir testroot +} + +find_in_env() { + tmpdir="$(mktemp -dt ostree-test-switchroot.XXXXXX)" + unshare -m <<-EOF + set -e + . "$this_script" + "$1" "$tmpdir" + enter_fs "$tmpdir" + ostree-prepare-root /sysroot + find / + touch /usr/usr_writable 2>/null \ + && echo "/usr is writable" \ + || echo "/usr is not writable" + touch /sysroot/usr/sysroot_usr_writable 2>/null \ + && echo "/sysroot/usr is writable" \ + || echo "/sysroot/usr is not writable" + EOF + rm -rf "$tmpdir" +} + +setup_initrd_env() { + mount -t tmpfs tmpfs "$1" + setup_bootfs "$1" + mkdir "$1/sysroot" + mount -t tmpfs tmpfs "$1/sysroot" + setup_rootfs "$1/sysroot" +} + +test_that_prepare_root_sets_sysroot_up_correctly_with_initrd() { + find_in_env setup_initrd_env >files + + grep -qx "/this_is_bootfs" files + grep -qx "/sysroot/this_is_ostree_root" files + grep -qx "/sysroot/sysroot/this_is_real_root" files + grep -qx "/sysroot/var/this_is_ostree_var" files + grep -qx "/sysroot/usr/this_is_ostree_usr" files + + grep -qx "/sysroot/usr is not writable" files + echo "ok ostree-prepare-root sets sysroot up correctly with initrd" +} + +# This script sources itself so we only want to run tests if we're the parent: +if [ "${BASH_SOURCE[0]}" = "${0}" ]; then + . $(dirname $0)/libtest.sh + unshare -m true || \ + skip "this test needs to set up mount namespaces, rerun as root" + + echo "1..1" + test_that_prepare_root_sets_sysroot_up_correctly_with_initrd +fi