From bfa2dd7558374e7fa01b10adeda251915a2bba98 Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Thu, 15 Feb 2024 15:40:55 +0100 Subject: [PATCH] test: Extend systemd-sysext tests to cover the mutability feature --- test/units/testsuite-50.sh | 458 ++++++++++++++++++++++++++++++++++++- 1 file changed, 450 insertions(+), 8 deletions(-) diff --git a/test/units/testsuite-50.sh b/test/units/testsuite-50.sh index 54a43338db6..370e8f01ed3 100755 --- a/test/units/testsuite-50.sh +++ b/test/units/testsuite-50.sh @@ -808,7 +808,7 @@ prep_root() { local r=${1}; shift local h=${1}; shift - mkdir -p "${r}${h}" "${r}/usr/lib" "${r}/var/lib/extensions" + mkdir -p "${r}${h}" "${r}/usr/lib" "${r}/var/lib/extensions" "${r}/var/lib/extensions.mutable" } gen_os_release() { @@ -835,6 +835,26 @@ gen_test_ext_image() { touch "${d}${h}/preexisting-file-in-extension-image" } +hierarchy_ext_mut_path() { + local r=${1}; shift + local h=${1}; shift + + # /a/b/c -> a.b.c + local n=${h} + n="${n##+(/)}" + n="${n%%+(/)}" + n="${n//\//.}" + + printf '%s' "${r}/var/lib/extensions.mutable/${n}" +} + +prep_ext_mut() { + local p=${1}; shift + + mkdir -p "${p}" + touch "${p}/preexisting-file-in-extensions-mutable" +} + make_ro() { local r=${1}; shift local h=${1}; shift @@ -861,6 +881,7 @@ prep_ro_hierarchy() { # extra args: # "e" for checking for the preexisting file in extension # "h" for checking for the preexisting file in hierarchy +# "u" for checking for the preexisting file in upperdir check_usual_suspects() { local root=${1}; shift local hierarchy=${1}; shift @@ -868,11 +889,11 @@ check_usual_suspects() { local arg # shellcheck disable=SC2034 # the variables below are used indirectly - local e='' h='' + local e='' h='' u='' for arg; do case ${arg} in - e|h) + e|h|u) local -n v=${arg} v=x unset -n v @@ -887,6 +908,7 @@ check_usual_suspects() { local pairs=( e:preexisting-file-in-extension-image h:preexisting-file-in-hierarchy + u:preexisting-file-in-extensions-mutable ) local pair name file desc full_path for pair in "${pairs[@]}"; do @@ -925,9 +947,11 @@ check_usual_suspects_after_unmerge() { } - # -# simple case, read-only hierarchy +# no extension data in /var/lib/extensions.mutable/…, read-only hierarchy, +# mutability disabled by default +# +# read-only merged # @@ -955,7 +979,10 @@ check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" h touch "${fake_root}${hierarchy}/should-still-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only after unmerge" # -# simple case, mutable hierarchy +# no extension data in /var/lib/extensions.mutable/…, mutable hierarchy, +# mutability disabled by default +# +# read-only merged # @@ -984,7 +1011,10 @@ touch "${fake_root}${hierarchy}/should-succeed-on-mutable-fs-again" || die "${fa # -# simple case, no hierarchy either +# no extension data in /var/lib/extensions.mutable/…, no hierarchy either, +# mutability disabled by default +# +# read-only merged # @@ -1008,7 +1038,10 @@ check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" # -# simple case, an empty hierarchy +# no extension data in /var/lib/extensions.mutable/…, an empty hierarchy, +# mutability disabled by default +# +# read-only merged # @@ -1034,6 +1067,415 @@ SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" u check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" +# +# extension data in /var/lib/extensions.mutable/…, read-only hierarchy, mutability disabled-by-default +# +# read-only merged +# + + +fake_root=${fake_roots_dir}/simple-mutable-with-read-only-hierarchy-disabled +hierarchy=/usr + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") +prep_ext_mut "${ext_data_path}" + +prep_ro_hierarchy "${fake_root}" "${hierarchy}" + +touch "${fake_root}${hierarchy}/should-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" merge + +touch "${fake_root}${hierarchy}/should-be-read-only" && die "${fake_root}${hierarchy} is not read-only" +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e h + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" h + + +# +# extension data in /var/lib/extensions.mutable/…, read-only hierarchy, auto-mutability +# +# mutable merged +# + + +fake_root=${fake_roots_dir}/simple-mutable-with-read-only-hierarchy +hierarchy=/usr + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") +prep_ext_mut "${ext_data_path}" + +prep_ro_hierarchy "${fake_root}" "${hierarchy}" + +touch "${fake_root}${hierarchy}/should-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=auto merge + +touch "${fake_root}${hierarchy}/now-is-mutable" || die "${fake_root}${hierarchy} is not mutable" +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e h u +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable is not stored in expected location" + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" h +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable disappeared from writable storage after unmerge" +test ! -f "${fake_root}${hierarchy}/now-is-mutable" || die "now-is-mutable did not disappear from hierarchy after unmerge" + + +# +# extension data in /var/lib/extensions.mutable/…, missing hierarchy, +# auto-mutability +# +# mutable merged +# + + +fake_root=${fake_roots_dir}/simple-mutable-with-missing-hierarchy +hierarchy=/opt + +prep_root "${fake_root}" "${hierarchy}" +rmdir "${fake_root}/${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") +prep_ext_mut "${ext_data_path}" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=auto merge + +touch "${fake_root}${hierarchy}/now-is-mutable" || die "${fake_root}${hierarchy} is not mutable" +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e u +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable is not stored in expected location" + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable disappeared from writable storage after unmerge" +test ! -f "${fake_root}${hierarchy}/now-is-mutable" || die "now-is-mutable did not disappear from hierarchy after unmerge" + + +# +# extension data in /var/lib/extensions.mutable/…, empty hierarchy, auto-mutability +# +# mutable merged +# + + +fake_root=${fake_roots_dir}/simple-mutable-with-empty-hierarchy +hierarchy=/opt + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") +prep_ext_mut "${ext_data_path}" + +make_ro "${fake_root}" "${hierarchy}" + +touch "${fake_root}${hierarchy}/should-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=auto merge + +touch "${fake_root}${hierarchy}/now-is-mutable" || die "${fake_root}${hierarchy} is not mutable" +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e u +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable is not stored in expected location" + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable disappeared from writable storage after unmerge" +test ! -f "${fake_root}${hierarchy}/now-is-mutable" || die "now-is-mutable did not disappear from hierarchy after unmerge" + + +# +# /var/lib/extensions.mutable/… is a symlink to /some/other/dir, read-only +# hierarchy, auto-mutability +# +# mutable merged +# + + +fake_root=${fake_roots_dir}/mutable-symlink-with-read-only-hierarchy +hierarchy=/usr + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +# generate extension writable data +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") +real_ext_dir="${fake_root}/upperdir" +prep_ext_mut "${real_ext_dir}" +ln -sfTr "${real_ext_dir}" "${ext_data_path}" + +prep_ro_hierarchy "${fake_root}" "${hierarchy}" + +touch "${fake_root}${hierarchy}/should-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=auto merge + +touch "${fake_root}${hierarchy}/now-is-mutable" || die "${fake_root}${hierarchy} is not mutable" +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e h u +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable is not stored in expected location" +test -f "${real_ext_dir}/now-is-mutable" || die "now-is-mutable is not stored in expected location" + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" h +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable disappeared from writable storage after unmerge" +test -f "${real_ext_dir}/now-is-mutable" || die "now-is-mutable disappeared from writable storage after unmerge" +test ! -f "${fake_root}${hierarchy}/now-is-mutable" || die "now-is-mutable did not disappear from hierarchy after unmerge" + + +# +# /var/lib/extensions.mutable/… is a symlink to the hierarchy itself, auto-mutability +# +# for this to work, hierarchy must be mutable +# +# mutable merged +# + + +fake_root=${fake_roots_dir}/mutable-self-upper +hierarchy=/usr + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +# generate extension writable data +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") +real_ext_dir="${fake_root}${hierarchy}" +prep_ext_mut "${real_ext_dir}" +ln -sfTr "${real_ext_dir}" "${ext_data_path}" + +# prepare writable hierarchy +touch "${fake_root}${hierarchy}/preexisting-file-in-hierarchy" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=auto merge + +touch "${fake_root}${hierarchy}/now-is-mutable" || die "${fake_root}${hierarchy} is not mutable" +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e h u +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable is not stored in expected location" +test -f "${real_ext_dir}/now-is-mutable" || die "now-is-mutable is not stored in expected location" + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" h u +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable disappeared from writable storage after unmerge" +test -f "${real_ext_dir}/now-is-mutable" || die "now-is-mutable disappeared from writable storage after unmerge" + + +# +# /var/lib/extensions.mutable/… is a symlink to the hierarchy itself, which is +# read-only, auto-mutability +# +# expecting a failure here +# + + +fake_root=${fake_roots_dir}/failure-self-upper-ro +hierarchy=/usr + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +# generate extension writable data +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") +real_ext_dir="${fake_root}${hierarchy}" +prep_ext_mut "${real_ext_dir}" +ln -sfTr "${real_ext_dir}" "${ext_data_path}" + +prep_ro_hierarchy "${fake_root}" "${hierarchy}" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=auto merge || die "expected merge to fail" + + +# +# /var/lib/extensions.mutable/… is a dangling symlink, auto-mutability +# +# read-only merged +# + + +fake_root=${fake_roots_dir}/read-only-mutable-dangling-symlink +hierarchy=/usr + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") +ln -sfTr "/should/not/exist/" "${ext_data_path}" + +prep_ro_hierarchy "${fake_root}" "${hierarchy}" + +touch "${fake_root}${hierarchy}/should-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=auto merge + +touch "${fake_root}${hierarchy}/should-still-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e h + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" h + + +# +# /var/lib/extensions.mutable/… exists, but it's ignored, mutability disabled explicitly +# +# read-only merged +# + + +fake_root=${fake_roots_dir}/disabled +hierarchy=/usr + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") +prep_ext_mut "${ext_data_path}" + +prep_ro_hierarchy "${fake_root}" "${hierarchy}" + +touch "${fake_root}${hierarchy}/should-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=no merge + +touch "${fake_root}${hierarchy}/should-still-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e h + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" h + + +# +# /var/lib/extensions.mutable/… exists, but it's imported instead +# +# read-only merged +# + + +fake_root=${fake_roots_dir}/imported +hierarchy=/usr + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") +prep_ext_mut "${ext_data_path}" + +prep_ro_hierarchy "${fake_root}" "${hierarchy}" + +touch "${fake_root}${hierarchy}/should-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=import merge + +touch "${fake_root}${hierarchy}/should-still-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e h u + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" h + + +# +# /var/lib/extensions.mutable/… does not exist, but mutability is enabled +# explicitly +# +# mutable merged +# + + +fake_root=${fake_roots_dir}/enabled +hierarchy=/usr + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +ext_data_path=$(hierarchy_ext_mut_path "${fake_root}" "${hierarchy}") + +prep_ro_hierarchy "${fake_root}" "${hierarchy}" + +touch "${fake_root}${hierarchy}/should-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +test ! -d "${ext_data_path}" || die "extensions.mutable should not exist" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=yes merge + +test -d "${ext_data_path}" || die "extensions.mutable should exist now" +touch "${fake_root}${hierarchy}/now-is-mutable" || die "${fake_root}${hierarchy} is not mutable" +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e h +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable is not stored in expected location" + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" h +test -f "${ext_data_path}/now-is-mutable" || die "now-is-mutable disappeared from writable storage after unmerge" +test ! -f "${fake_root}${hierarchy}/now-is-mutable" || die "now-is-mutable did not disappear from hierarchy after unmerge" + + +# +# /var/lib/extensions.mutable/… does not exist, auto-mutability +# +# read-only merged +# + + +fake_root=${fake_roots_dir}/simple-read-only-explicit +hierarchy=/usr + +prep_root "${fake_root}" "${hierarchy}" +gen_os_release "${fake_root}" +gen_test_ext_image "${fake_root}" "${hierarchy}" + +prep_ro_hierarchy "${fake_root}" "${hierarchy}" + +touch "${fake_root}${hierarchy}/should-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" + +# run systemd-sysext +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" --mutable=auto merge + +touch "${fake_root}${hierarchy}/should-still-fail-on-read-only-fs" && die "${fake_root}${hierarchy} is not read-only" +check_usual_suspects_after_merge "${fake_root}" "${hierarchy}" e h + +SYSTEMD_SYSEXT_HIERARCHIES="${hierarchy}" systemd-sysext --root="${fake_root}" unmerge + +check_usual_suspects_after_unmerge "${fake_root}" "${hierarchy}" h + + # # done # -- 2.47.3