]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
test: Extend systemd-sysext tests to cover the mutability feature
authorKrzesimir Nowak <knowak@microsoft.com>
Thu, 15 Feb 2024 14:40:55 +0000 (15:40 +0100)
committerKrzesimir Nowak <knowak@microsoft.com>
Thu, 22 Feb 2024 18:06:22 +0000 (19:06 +0100)
test/units/testsuite-50.sh

index 54a43338db6cc8055afb43b94da9dca2b6b43b58..370e8f01ed3b9a267aaec3753a8acbd7c7824480 100755 (executable)
@@ -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
 #