diff --git a/autopart-stratis-encrypted.ks.in b/autopart-stratis-encrypted.ks.in new file mode 100644 index 00000000..4790ed98 --- /dev/null +++ b/autopart-stratis-encrypted.ks.in @@ -0,0 +1,68 @@ +%ksappend repos/default.ks +%ksappend common/common_no_storage_and_payload.ks +%ksappend payload/default_packages.ks + +zerombr +clearpart --all --initlabel +autopart --type=stratis --encrypted --passphrase="passphrase" + +%post +# check that root is on stratis +root_source=$(findmnt -n -o SOURCE /) +if [[ "$root_source" != /dev/mapper/stratis* ]]; then + echo "*** root device is not a Stratis filesystem: $root_source" >> /root/RESULT + exit 1 +fi + +# check that a stratis pool exists +if [ ! -d /dev/stratis ] || [ -z "$(ls -A /dev/stratis/)" ]; then + echo "*** no Stratis pool found in /dev/stratis/" >> /root/RESULT + exit 1 +fi + +# get pool name from /dev/stratis +pool_name=$(ls /dev/stratis/) +if [[ -z "$pool_name" ]]; then + echo "*** failed to get Stratis pool name" >> /root/RESULT + exit 1 +fi + +# check pool properties +pool_info=$(stratis pool list --name "$pool_name") + +pool_encryption=$(echo "$pool_info" | awk -F: '/Encryption Enabled/ { gsub(/ /,"",$2); print $2 }') +if [[ "$pool_encryption" != "Yes" ]]; then + echo "*** unexpected pool encryption: $pool_encryption (expected Yes)" >> /root/RESULT +fi + +pool_overprov=$(echo "$pool_info" | awk -F: '/Allows Overprovisioning/ { gsub(/ /,"",$2); print $2 }') +if [[ "$pool_overprov" != "No" ]]; then + echo "*** unexpected pool overprovisioning: $pool_overprov (expected No)" >> /root/RESULT +fi + +# check filesystem properties +fs_info=$(stratis filesystem list "$pool_name" --name root) + +fs_name=$(echo "$fs_info" | awk -F: '/^Name/ { gsub(/ /,"",$2); print $2 }') +if [[ "$fs_name" != "root" ]]; then + echo "*** unexpected filesystem name: $fs_name (expected root)" >> /root/RESULT +fi + +fs_pool=$(echo "$fs_info" | awk -F: '/^Pool/ { gsub(/ /,"",$2); print $2 }') +if [[ "$fs_pool" != "$pool_name" ]]; then + echo "*** filesystem pool mismatch: $fs_pool (expected $pool_name)" >> /root/RESULT +fi + +if [ ! -e /root/RESULT ]; then + echo SUCCESS > /root/RESULT +fi +%end + +%post --nochroot + +@KSINCLUDE@ post-nochroot-lib-storage.sh + +# libguestfs does not support stratis, copy results and logs to /boot +copy_results_to_boot + +%end diff --git a/autopart-stratis-encrypted.sh b/autopart-stratis-encrypted.sh new file mode 100755 index 00000000..b488a3aa --- /dev/null +++ b/autopart-stratis-encrypted.sh @@ -0,0 +1,29 @@ +# +# Copyright (C) 2026 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Vojtech Trefny + +# Ignore unused variable parsed out by tooling scripts as test tags metadata +# shellcheck disable=SC2034 +TESTTYPE="autopart storage stratis skip-on-rhel skip-on-centos" + +. ${KSTESTDIR}/functions.sh + +validate() { + validate_stratis $1 + return $? +} diff --git a/autopart-stratis.ks.in b/autopart-stratis.ks.in new file mode 100644 index 00000000..230ad424 --- /dev/null +++ b/autopart-stratis.ks.in @@ -0,0 +1,69 @@ +%ksappend repos/default.ks +%ksappend common/common_no_storage_and_payload.ks +%ksappend payload/default_packages.ks + +zerombr +clearpart --all --initlabel +autopart --type=stratis + +%post + +# check that root is on stratis +root_source=$(findmnt -n -o SOURCE /) +if [[ "$root_source" != /dev/mapper/stratis* ]]; then + echo "*** root device is not a Stratis filesystem: $root_source" >> /root/RESULT + exit 1 +fi + +# check that a stratis pool exists +if [ ! -d /dev/stratis ] || [ -z "$(ls -A /dev/stratis/)" ]; then + echo "*** no Stratis pool found in /dev/stratis/" >> /root/RESULT + exit 1 +fi + +# get pool name from /dev/stratis +pool_name=$(ls /dev/stratis/) +if [[ -z "$pool_name" ]]; then + echo "*** failed to get Stratis pool name" >> /root/RESULT + exit 1 +fi + +# check pool properties +pool_info=$(stratis pool list --name "$pool_name") + +pool_encryption=$(echo "$pool_info" | awk -F: '/Encryption Enabled/ { gsub(/ /,"",$2); print $2 }') +if [[ "$pool_encryption" != "No" ]]; then + echo "*** unexpected pool encryption: $pool_encryption (expected No)" >> /root/RESULT +fi + +pool_overprov=$(echo "$pool_info" | awk -F: '/Allows Overprovisioning/ { gsub(/ /,"",$2); print $2 }') +if [[ "$pool_overprov" != "No" ]]; then + echo "*** unexpected pool overprovisioning: $pool_overprov (expected No)" >> /root/RESULT +fi + +# check filesystem properties +fs_info=$(stratis filesystem list "$pool_name" --name root) + +fs_name=$(echo "$fs_info" | awk -F: '/^Name/ { gsub(/ /,"",$2); print $2 }') +if [[ "$fs_name" != "root" ]]; then + echo "*** unexpected filesystem name: $fs_name (expected root)" >> /root/RESULT +fi + +fs_pool=$(echo "$fs_info" | awk -F: '/^Pool/ { gsub(/ /,"",$2); print $2 }') +if [[ "$fs_pool" != "$pool_name" ]]; then + echo "*** filesystem pool mismatch: $fs_pool (expected $pool_name)" >> /root/RESULT +fi + +if [ ! -e /root/RESULT ]; then + echo SUCCESS > /root/RESULT +fi +%end + +%post --nochroot + +@KSINCLUDE@ post-nochroot-lib-storage.sh + +# libguestfs does not support stratis, copy results and logs to /boot +copy_results_to_boot + +%end diff --git a/autopart-stratis.sh b/autopart-stratis.sh new file mode 100755 index 00000000..b488a3aa --- /dev/null +++ b/autopart-stratis.sh @@ -0,0 +1,29 @@ +# +# Copyright (C) 2026 Red Hat, Inc. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions of +# the GNU General Public License v.2, or (at your option) any later version. +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY expressed or implied, including the implied warranties of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. You should have received a copy of the +# GNU General Public License along with this program; if not, write to the +# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the +# source code or documentation are not subject to the GNU General Public +# License and may only be used or replicated with the express permission of +# Red Hat, Inc. +# +# Red Hat Author(s): Vojtech Trefny + +# Ignore unused variable parsed out by tooling scripts as test tags metadata +# shellcheck disable=SC2034 +TESTTYPE="autopart storage stratis skip-on-rhel skip-on-centos" + +. ${KSTESTDIR}/functions.sh + +validate() { + validate_stratis $1 + return $? +} diff --git a/functions.sh b/functions.sh index 68f15e87..ade715d3 100644 --- a/functions.sh +++ b/functions.sh @@ -235,6 +235,32 @@ validate() { return $? } +validate_stratis() { + disksdir=$1 + args=$(for d in ${disksdir}/disk-*img; do echo -a ${d}; done) + + local boot_dev + boot_dev=$(run_with_timeout ${COPY_FROM_IMAGE_TIMEOUT} \ + "guestfish --ro ${args} run : list-filesystems" \ + | grep "ext\|xfs" | awk -F: '{ print $1 }') + + if [[ -z "$boot_dev" ]]; then + echo '*** could not find boot partition in VM image.' + return 1 + fi + + run_with_timeout ${COPY_FROM_IMAGE_TIMEOUT} \ + "guestfish --ro ${args} run : mount-ro ${boot_dev} / : copy-out /kstest-results ${disksdir}/" 2>/dev/null + + if [[ -d ${disksdir}/kstest-results ]]; then + mv ${disksdir}/kstest-results/* ${disksdir}/ 2>/dev/null + rm -rf ${disksdir}/kstest-results + fi + + check_result_file "${disksdir}" + return $? +} + validate_journal_contains() { # Check if journal from the installation contains a regexp, # write error message and return with 1 if the message has diff --git a/post-nochroot-lib-storage.sh b/post-nochroot-lib-storage.sh new file mode 100644 index 00000000..1a124428 --- /dev/null +++ b/post-nochroot-lib-storage.sh @@ -0,0 +1,16 @@ +SYSROOT=/mnt/sysroot + +# Copy results and logs to /boot so they can be extracted from a partition +# that guestfish can read (e.g. when root is on Stratis or another filesystem +# not supported by libguestfs). +function copy_results_to_boot() { + RESULTS_DIR=$SYSROOT/boot/kstest-results + + mkdir -p $RESULTS_DIR + cp $SYSROOT/root/RESULT $RESULTS_DIR/RESULT 2>/dev/null + cp $SYSROOT/root/original-ks.cfg $RESULTS_DIR/ 2>/dev/null + cp $SYSROOT/root/anaconda-ks.cfg $RESULTS_DIR/ 2>/dev/null + mkdir -p $RESULTS_DIR/anaconda + cp /tmp/*.log $RESULTS_DIR/anaconda/ 2>/dev/null + cp /tmp/syslog $RESULTS_DIR/anaconda/ 2>/dev/null +}