aboutsummaryrefslogtreecommitdiff
path: root/installer
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-04-26 01:08:50 -0500
committerCraig Jennings <c@cjennings.net>2026-04-26 01:08:50 -0500
commit6b65665eca8a4b36b0b6eae4d761fccd7b4c1fc4 (patch)
tree69cbf8bf23d4d97c89979909d2f96f799ced92e2 /installer
parentbdda6b17c83e0e298c76bbaf146f082218389cd8 (diff)
downloadarchangel-6b65665eca8a4b36b0b6eae4d761fccd7b4c1fc4.tar.gz
archangel-6b65665eca8a4b36b0b6eae4d761fccd7b4c1fc4.zip
refactor: extract get_raid_level fzf preview into raid.sh helper
`get_raid_level()` carried a 98-line inline fzf `--preview` shell snippet that contained five nearly-parallel `case` branches emitting per-level preview text, plus three exported variables (`RAID_DISK_COUNT`, `RAID_TOTAL_GB`, `RAID_SMALLEST_GB`) just to pass values into the fzf preview subshell. The inline shell-in-shell had no syntax highlighting, no shellcheck on the inner snippet, and any edit to preview copy meant editing inside a single-quoted argument. I extracted the per-level text into a new `raid_preview(level, disk_count, total_gb, smallest_gb)` helper in `lib/raid.sh`. It reuses the existing `raid_fault_tolerance` and `raid_usable_bytes` primitives for the data lines instead of redoing the arithmetic inline. That keeps the math in one place. The fzf `--preview` argument is now a one-liner that calls `raid_preview` with the sizing values, and the env-var exports are gone. `export -f raid_preview raid_fault_tolerance raid_usable_bytes` makes the functions visible in fzf's preview subshell. I verified this against a fresh `bash -c` subshell, which is what fzf spawns internally. `get_raid_level()` shrinks from 144 to 49 lines. Preview text is now bats-tested. Added 8 unit tests across the 5 RAID levels (headline, fault-tolerance line, computed usable space), mixed-size handling for mirror (smallest disk, not average), unknown level returning 1 with empty output, and a sanity loop confirming every valid level produces non-empty output. No behavior change. The preview pane shows the same text, the same level options, the same selected output. The pure logic in `lib/raid.sh` is unchanged.
Diffstat (limited to 'installer')
-rwxr-xr-xinstaller/archangel108
-rw-r--r--installer/lib/raid.sh119
2 files changed, 125 insertions, 102 deletions
diff --git a/installer/archangel b/installer/archangel
index b3c232f..a40710b 100755
--- a/installer/archangel
+++ b/installer/archangel
@@ -373,114 +373,18 @@ get_raid_level() {
local options
options=$(raid_valid_levels_for_count "$disk_count")
- # Export variables for preview subshell
- export RAID_DISK_COUNT=$disk_count
- export RAID_TOTAL_GB=$total_gb
- export RAID_SMALLEST_GB=$smallest_gb
+ # Make raid_preview and its dependencies available to fzf's preview
+ # subshell. The text and math live in lib/raid.sh so they're
+ # bats-tested and editor-friendly instead of buried in a
+ # single-quoted fzf argument.
+ export -f raid_preview raid_fault_tolerance raid_usable_bytes
RAID_LEVEL=$(echo "$options" \
| fzf --height=20 --layout=reverse --border \
--header="Select RAID Level ($disk_count disks, ${total_gb}GB total)" \
- --preview='
- n=$RAID_DISK_COUNT
- total=$RAID_TOTAL_GB
- small=$RAID_SMALLEST_GB
-
- case {} in
- mirror)
- echo "MIRROR"
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- echo ""
- echo "All disks contain identical copies of data."
- echo "Maximum redundancy - can survive loss of"
- echo "all disks except one."
- echo ""
- echo "Redundancy: Can lose $((n-1)) of $n disks"
- echo "Usable space: ~${small}GB (smallest disk)"
- echo "Read speed: Fast (parallel reads)"
- echo "Write speed: Normal"
- echo ""
- echo "Best for:"
- echo " - Boot drives"
- echo " - Critical data"
- echo " - Maximum safety"
- ;;
- stripe)
- echo "STRIPE (RAID0)"
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- echo ""
- echo "WARNING: NO REDUNDANCY!"
- echo "Data is striped across all disks."
- echo "ANY disk failure = ALL data lost!"
- echo ""
- echo "Redundancy: NONE"
- echo "Usable space: ~${total}GB (all disks)"
- echo "Read speed: Very fast"
- echo "Write speed: Very fast"
- echo ""
- echo "Best for:"
- echo " - Scratch/temp space"
- echo " - Replaceable data"
- echo " - Maximum performance"
- ;;
- raidz1)
- usable=$(( (n-1) * small ))
- echo "RAIDZ1 (Single Parity)"
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- echo ""
- echo "One disk worth of parity distributed"
- echo "across all disks."
- echo ""
- echo "Redundancy: Can lose 1 disk"
- echo "Usable space: ~${usable}GB ($((n-1)) of $n disks)"
- echo "Read speed: Fast"
- echo "Write speed: Good"
- echo ""
- echo "Best for:"
- echo " - General storage"
- echo " - Good balance of space/safety"
- ;;
- raidz2)
- usable=$(( (n-2) * small ))
- echo "RAIDZ2 (Double Parity)"
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- echo ""
- echo "Two disks worth of parity distributed"
- echo "across all disks."
- echo ""
- echo "Redundancy: Can lose 2 disks"
- echo "Usable space: ~${usable}GB ($((n-2)) of $n disks)"
- echo "Read speed: Fast"
- echo "Write speed: Good"
- echo ""
- echo "Best for:"
- echo " - Large arrays (5+ disks)"
- echo " - Important data"
- ;;
- raidz3)
- usable=$(( (n-3) * small ))
- echo "RAIDZ3 (Triple Parity)"
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- echo ""
- echo "Three disks worth of parity distributed"
- echo "across all disks."
- echo ""
- echo "Redundancy: Can lose 3 disks"
- echo "Usable space: ~${usable}GB ($((n-3)) of $n disks)"
- echo "Read speed: Fast"
- echo "Write speed: Moderate"
- echo ""
- echo "Best for:"
- echo " - Very large arrays (8+ disks)"
- echo " - Archival storage"
- ;;
- esac
- ' \
+ --preview="raid_preview {} $disk_count $total_gb $smallest_gb" \
--preview-window=right:50%)
- # Clean up exported variables
- unset RAID_DISK_COUNT RAID_TOTAL_GB RAID_SMALLEST_GB
-
if [[ -z "$RAID_LEVEL" ]]; then
error "No RAID level selected!"
fi
diff --git a/installer/lib/raid.sh b/installer/lib/raid.sh
index 3e28177..6eccfa7 100644
--- a/installer/lib/raid.sh
+++ b/installer/lib/raid.sh
@@ -68,3 +68,122 @@ raid_fault_tolerance() {
*) return 1 ;;
esac
}
+
+#############################
+# Preview text
+#############################
+
+# Print preview text for a single RAID level. Used by get_raid_level()
+# in the fzf preview pane. Calls raid_fault_tolerance and
+# raid_usable_bytes for the data lines so the math stays in one place.
+# Numeric arguments are unit-agnostic — pass GB if you want GB out.
+#
+# Usage: raid_preview LEVEL DISK_COUNT TOTAL_GB SMALLEST_GB
+# Returns 1 for unknown level (no output).
+raid_preview() {
+ local level=$1 count=$2 total=$3 small=$4
+ local tol usable
+
+ tol=$(raid_fault_tolerance "$level" "$count") || return 1
+ usable=$(raid_usable_bytes "$level" "$count" "$small" "$total") || return 1
+
+ case "$level" in
+ mirror)
+ cat <<EOF
+MIRROR
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+All disks contain identical copies of data.
+Maximum redundancy. Can survive loss of all
+disks except one.
+
+Redundancy: Can lose $tol of $count disks
+Usable space: ~${usable}GB (smallest disk)
+Read speed: Fast (parallel reads)
+Write speed: Normal
+
+Best for:
+ - Boot drives
+ - Critical data
+ - Maximum safety
+EOF
+ ;;
+ stripe)
+ cat <<EOF
+STRIPE (RAID0)
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+WARNING: NO REDUNDANCY!
+Data is striped across all disks.
+ANY disk failure = ALL data lost!
+
+Redundancy: NONE
+Usable space: ~${usable}GB (all disks)
+Read speed: Very fast
+Write speed: Very fast
+
+Best for:
+ - Scratch/temp space
+ - Replaceable data
+ - Maximum performance
+EOF
+ ;;
+ raidz1)
+ cat <<EOF
+RAIDZ1 (Single Parity)
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+One disk worth of parity distributed
+across all disks.
+
+Redundancy: Can lose $tol of $count disks
+Usable space: ~${usable}GB ($((count - 1)) of $count disks)
+Read speed: Fast
+Write speed: Good
+
+Best for:
+ - General storage
+ - Good balance of space/safety
+EOF
+ ;;
+ raidz2)
+ cat <<EOF
+RAIDZ2 (Double Parity)
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+Two disks worth of parity distributed
+across all disks.
+
+Redundancy: Can lose $tol of $count disks
+Usable space: ~${usable}GB ($((count - 2)) of $count disks)
+Read speed: Fast
+Write speed: Good
+
+Best for:
+ - Large arrays (5+ disks)
+ - Important data
+EOF
+ ;;
+ raidz3)
+ cat <<EOF
+RAIDZ3 (Triple Parity)
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+Three disks worth of parity distributed
+across all disks.
+
+Redundancy: Can lose $tol of $count disks
+Usable space: ~${usable}GB ($((count - 3)) of $count disks)
+Read speed: Fast
+Write speed: Moderate
+
+Best for:
+ - Very large arrays (8+ disks)
+ - Archival storage
+EOF
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+}