From edb5016809f3bc657283d8c2402970dbbab3c5cf Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Tue, 23 Jun 2026 20:55:07 -0400 Subject: fix(installer): RAID validation, set -e fix, drop dead shadow branch Two installer cleanups from the todo backlog. validate_config now rejects a RAID_LEVEL the selected disk count can't support, guarding the unattended path (the interactive path already constrains the choice). While adding it I found a latent bug: the error loop's ((errors++)) returned 0 on the first error and tripped set -e in the monolith's `[[ UNATTENDED == true ]] && validate_config` call, aborting after one warning instead of listing every problem. Switched to pre-increment so the count accumulates as designed. Added four bats cases, including one that runs validate_config under set -e outside bats' run shield. build.sh dropped the dead shadow-file rebuild else-branch. The profile is always copied fresh from releng (which ships /etc/shadow), so the branch never ran, and its hardcoded account list had drifted from what releng provides. Replaced with an assertion that fails the build loudly if the file is ever missing. --- tests/unit/test_config.bats | 58 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'tests') diff --git a/tests/unit/test_config.bats b/tests/unit/test_config.bats index af23e4a..4169c5e 100644 --- a/tests/unit/test_config.bats +++ b/tests/unit/test_config.bats @@ -5,6 +5,8 @@ setup() { # shellcheck disable=SC1091 source "${BATS_TEST_DIRNAME}/../../installer/lib/common.sh" # shellcheck disable=SC1091 + source "${BATS_TEST_DIRNAME}/../../installer/lib/raid.sh" + # shellcheck disable=SC1091 source "${BATS_TEST_DIRNAME}/../../installer/lib/config.sh" } @@ -93,6 +95,62 @@ EOF [[ "$output" == *"4 error"* ]] } +@test "validate_config under set -e reports every error, not just the first" { + # Reproduces the monolith's call structure: `set -e` is active and + # validate_config is invoked as the final command of an && list. A + # post-increment that returns the pre-increment value (0 on the first + # error) trips set -e and aborts the function after one warning. This + # test runs outside bats' `run` shield (which sets +e) so the real + # accumulate-and-report behavior is exercised. + run bash -c ' + set -e + source "'"${BATS_TEST_DIRNAME}"'/../../installer/lib/common.sh" + source "'"${BATS_TEST_DIRNAME}"'/../../installer/lib/raid.sh" + source "'"${BATS_TEST_DIRNAME}"'/../../installer/lib/config.sh" + HOSTNAME=""; TIMEZONE=""; SELECTED_DISKS=(); ROOT_PASSWORD="" + UNATTENDED=true + [[ "$UNATTENDED" == true ]] && validate_config + ' + [ "$status" -eq 1 ] + [[ "$output" == *"HOSTNAME not set"* ]] + [[ "$output" == *"TIMEZONE not set"* ]] + [[ "$output" == *"No disks selected"* ]] + [[ "$output" == *"ROOT_PASSWORD not set"* ]] + [[ "$output" == *"4 error"* ]] +} + +@test "validate_config rejects a RAID_LEVEL invalid for the disk count" { + HOSTNAME=h + TIMEZONE=UTC + ROOT_PASSWORD=x + SELECTED_DISKS=(/dev/sda /dev/sdb) + RAID_LEVEL=raidz1 + run validate_config + [ "$status" -eq 1 ] + [[ "$output" == *"Invalid RAID_LEVEL"* ]] + [[ "$output" == *"raidz1"* ]] +} + +@test "validate_config accepts a RAID_LEVEL valid for the disk count" { + HOSTNAME=h + TIMEZONE=UTC + ROOT_PASSWORD=x + SELECTED_DISKS=(/dev/sda /dev/sdb /dev/sdc) + RAID_LEVEL=raidz1 + run validate_config + [[ "$output" != *"Invalid RAID_LEVEL"* ]] +} + +@test "validate_config accepts an empty RAID_LEVEL for a single disk" { + HOSTNAME=h + TIMEZONE=UTC + ROOT_PASSWORD=x + SELECTED_DISKS=(/dev/sda) + RAID_LEVEL="" + run validate_config + [[ "$output" != *"Invalid RAID_LEVEL"* ]] +} + @test "validate_config rejects an invalid timezone" { HOSTNAME="h" TIMEZONE="Not/A_Real_Zone_xyz" -- cgit v1.2.3