test: Extend systemd-sysext tests to cover the mutability feature

This commit is contained in:
Krzesimir Nowak
2024-02-15 15:40:55 +01:00
parent 58a28be5ac
commit bfa2dd7558

View File

@@ -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
#