Big work on the disk selection. Improved efficiency and clarity. Have to continue working on it.
This commit is contained in:
@@ -41,4 +41,3 @@
|
|||||||
type = "xfs";
|
type = "xfs";
|
||||||
label = "data-storage";
|
label = "data-storage";
|
||||||
mountpoint = "/mnt/data-storage";
|
mountpoint = "/mnt/data-storage";
|
||||||
|
|
||||||
|
|||||||
@@ -282,46 +282,93 @@ disk_config_generation() {
|
|||||||
|
|
||||||
echo -e "\n\n 🔎 Fetching and analyzing disks from target host... (This may take a moment)"
|
echo -e "\n\n 🔎 Fetching and analyzing disks from target host... (This may take a moment)"
|
||||||
|
|
||||||
declare -A DISK_INFO_MAP
|
|
||||||
declare -A DISK_SIZE_MAP
|
|
||||||
declare -A DISK_BY_ID_MAP
|
|
||||||
declare -A DISK_LABEL_MAP
|
|
||||||
DISK_OPTIONS=()
|
|
||||||
|
|
||||||
DISK_NAMES=$(ssh_to_host "lsblk -d -n -o NAME,TYPE | awk '\$2==\"disk\" {print \$1}'")
|
|
||||||
|
|
||||||
# --> Get disks info
|
### --> Get disk information
|
||||||
for name in $DISK_NAMES; do
|
DISK_DETAILS=$(ssh_to_host "
|
||||||
details=$(echo "$REMOTE_PASS" | ssh_to_host "
|
# Declare arrays and variables
|
||||||
set -e
|
DISK_DEVPATH=()
|
||||||
devpath=/dev/$name
|
DISK_NAME=()
|
||||||
rota=1 # Default to rotational (HDD)
|
DISK_TYPE=()
|
||||||
[ -f /sys/block/$name/queue/rotational ] && rota=\$(cat /sys/block/$name/queue/rotational)
|
DISK_HEALTH=()
|
||||||
tran=\$(lsblk -d -n -o TRAN \"\$devpath\" || echo 'unknown')
|
DISK_ID=()
|
||||||
health=\$(sudo -S smartctl -H \"\$devpath\" 2>/dev/null | grep 'self-assessment' | awk '{print \$6}')
|
DISK_SIZE=()
|
||||||
by_id=\$(ls -l /dev/disk/by-id | grep -m 1 \"../../$name\$\" | awk '{print \"/dev/disk/by-id/\"\$9}')
|
HDD=1
|
||||||
|
|
||||||
# Determine type
|
|
||||||
if [[ \"\$name\" == nvme* ]]; then type=\"NVMe\"; # Check for NVMe first
|
|
||||||
elif [[ \"\$rota\" == \"0\" ]]; then type=\"SSD\";
|
|
||||||
elif [[ \"\$tran\" == \"usb\" ]]; then type=\"USB\";
|
|
||||||
else type=\"HDD\"; fi
|
|
||||||
|
|
||||||
# Fallback for health and by-id
|
for DISK in \$(lsblk -d -n -o NAME); do
|
||||||
[[ -z \"\$health\" || \"\$health\" == \"\" ]] && health=\"N/A\"
|
# Disk name and simple path
|
||||||
[ -z \"\$by_id\" ] && by_id=\"\$devpath\"
|
DISK_DEVPATH+=(\"/dev/\$DISK\")
|
||||||
|
DISK_NAME+=(\"\$DISK\")
|
||||||
|
|
||||||
# Get size last, after other commands that might fail
|
# Disk type
|
||||||
size=\$(lsblk -b -d -n -o SIZE \"\$devpath\")
|
HDD=\$(cat /sys/block/\$DISK/queue/rotational)
|
||||||
echo \"\$size:::\$type:::\$health:::\$by_id\"
|
TRANSPORT_PROTOCOL=\$(lsblk -d -n -o TRAN /dev/\$DISK)
|
||||||
")
|
if [[ \"\$DISK\" == \"nvme*\" ]]; then DISK_TYPE+=(\"NVMe\");
|
||||||
# Get disks info <--
|
elif [[ \"\$TRANSPORT_PROTOCOL\" == \"usb\" ]]; then DISK_TYPE+=(\"USB\");
|
||||||
|
elif [[ \"\$HDD\" == \"1\" ]]; then DISK_TYPE+=(\"HDD\");
|
||||||
|
elif [[ \"\$HDD\" == \"0\" ]]; then DISK_TYPE+=(\"SSD\");
|
||||||
|
else DISK_TYPE+=(\"Other\")
|
||||||
|
fi
|
||||||
|
|
||||||
mapfile -t parts < <(echo "$details" | tr ':' '\n')
|
# Disk health
|
||||||
size="${parts[0]}"
|
if [[ \$(echo "$REMOTE_PASS" | sudo -S smartctl -H /dev/\$DISK 2>/dev/null | grep 'self-assessment' | awk '{print \$6}') == \"PASSED\" ]]; then
|
||||||
disk_type="${parts[3]}"
|
DISK_HEALTH+=(\"PASSED\")
|
||||||
health="${parts[6]}"
|
else
|
||||||
by_id="${parts[9]}"
|
DISK_HEALTH+=(\"N/A\")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Disk ID
|
||||||
|
DISK_ID+=(\$(ls -l /dev/disk/by-id | grep -m1 \"../../\$DISK\" | awk '{print \"/dev/disk/by-id/\" \$9}'))
|
||||||
|
|
||||||
|
# Disk size
|
||||||
|
DISK_SIZE+=(\"\$(lsblk -d -n -o SIZE /dev/\$DISK)\")
|
||||||
|
done
|
||||||
|
|
||||||
|
# Print elements
|
||||||
|
echo \"\${DISK_DEVPATH[@]}\"
|
||||||
|
echo \"\${DISK_NAME[@]}\"
|
||||||
|
echo \"\${DISK_TYPE[@]}\"
|
||||||
|
echo \"\${DISK_HEALTH[@]}\"
|
||||||
|
echo \"\${DISK_ID[@]}\"
|
||||||
|
echo \"\${DISK_SIZE[@]}\"
|
||||||
|
"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get arrays back
|
||||||
|
readarray -t LINES <<<"$DISK_DETAILS"
|
||||||
|
read -r -a DISK_DEVPATH <<<"${LINES[0]}"
|
||||||
|
read -r -a DISK_NAME <<<"${LINES[1]}"
|
||||||
|
read -r -a DISK_TYPE <<<"${LINES[2]}"
|
||||||
|
read -r -a DISK_HEALTH <<<"${LINES[3]}"
|
||||||
|
read -r -a DISK_ID <<<"${LINES[4]}"
|
||||||
|
read -r -a DISK_SIZE <<<"${LINES[5]}"
|
||||||
|
### Get disk information <--
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### --> Disk selection
|
||||||
|
NUMBER_OF_DISKS=${#DISK_NAME[@]}
|
||||||
|
|
||||||
|
if [ "$NUMBER_OF_DISKS" -eq 0 ]; then
|
||||||
|
echo " ❌ No disks found on the target host. Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
HEADER=$(printf " %-12s %-12s %-12s %-12s %s" "Device" "Type" "Size" "SMART" "Path")
|
||||||
|
|
||||||
|
i=0
|
||||||
|
for DISK in $(seq 1 $NUMBER_OF_DISKS); do
|
||||||
|
PRINTED_ELEMENT=$(printf "%-12s %-12s %-12s %-12s %s" "${DISK_NAME[$i]}" "${DISK_TYPE[$i]}" "${DISK_SIZE[$i]}" "${DISK_HEALTH[$i]}" "${DISK_DEVPATH[$i]}")
|
||||||
|
PRINTED_ELEMENTS+=("$PRINTED_ELEMENT")
|
||||||
|
i=$i+1
|
||||||
|
done
|
||||||
|
|
||||||
|
gum style --foreground 212 " ➡️ Please choose one (stripe) or two (mirror) disks for your NixOS boot installation:"
|
||||||
|
echo -e ""
|
||||||
|
mapfile -t SELECTED_BOOT_LABELS < <(gum choose --limit 2 --header "$HEADER" "${PRINTED_ELEMENTS[@]}")
|
||||||
|
### Disk selection <--
|
||||||
|
|
||||||
|
## Now you have to look at associative arrays to define clear variable for the following logic (i.e. BOOT_DISK_1, BOOT_DISK_2, etc)
|
||||||
|
|
||||||
human_size=$(numfmt --to=iec-i --suffix=B "$size")
|
human_size=$(numfmt --to=iec-i --suffix=B "$size")
|
||||||
label=$(printf "%-12s %-12s %-12s %-12s %s" "$name" "$disk_type" "$human_size" "$health" "$by_id")
|
label=$(printf "%-12s %-12s %-12s %-12s %s" "$name" "$disk_type" "$human_size" "$health" "$by_id")
|
||||||
@@ -333,10 +380,6 @@ disk_config_generation() {
|
|||||||
DISK_LABEL_MAP["$name"]="$label"
|
DISK_LABEL_MAP["$name"]="$label"
|
||||||
done
|
done
|
||||||
|
|
||||||
if [ ${#DISK_OPTIONS[@]} -eq 0 ]; then
|
|
||||||
echo " ❌ No disks found on the target host. Aborting."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
HEADER=$(printf " %-12s %-12s %-12s %-12s %s" "Device" "Type" "Size" "SMART" "ID")
|
HEADER=$(printf " %-12s %-12s %-12s %-12s %s" "Device" "Type" "Size" "SMART" "ID")
|
||||||
gum style --foreground 212 " ➡️ Please choose one (stripe) or two (mirror) disks for your NixOS boot installation:"
|
gum style --foreground 212 " ➡️ Please choose one (stripe) or two (mirror) disks for your NixOS boot installation:"
|
||||||
@@ -442,7 +485,7 @@ The mirror will be created using the size of the smaller disk, and any extra spa
|
|||||||
echo -e "\n\n ⚠️ No remaining disks to select for data."
|
echo -e "\n\n ⚠️ No remaining disks to select for data."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --> Final recap
|
### --> Final recap
|
||||||
NUMBER_OF_BOOT_DISKS=0
|
NUMBER_OF_BOOT_DISKS=0
|
||||||
[[ -n "$BOOT_DISK_1" ]] && NUMBER_OF_BOOT_DISKS=$((NUMBER_OF_BOOT_DISKS + 1)) && export BOOT_DISK_1
|
[[ -n "$BOOT_DISK_1" ]] && NUMBER_OF_BOOT_DISKS=$((NUMBER_OF_BOOT_DISKS + 1)) && export BOOT_DISK_1
|
||||||
[[ -n "$BOOT_DISK_2" ]] && NUMBER_OF_BOOT_DISKS=$((NUMBER_OF_BOOT_DISKS + 1)) && export BOOT_DISK_2
|
[[ -n "$BOOT_DISK_2" ]] && NUMBER_OF_BOOT_DISKS=$((NUMBER_OF_BOOT_DISKS + 1)) && export BOOT_DISK_2
|
||||||
@@ -468,35 +511,36 @@ EOF
|
|||||||
|
|
||||||
gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "$(gum format <<< "$RECAP_CONTENT")"
|
gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "$(gum format <<< "$RECAP_CONTENT")"
|
||||||
gum confirm "Proceed with this disk configuration?" || { echo " ❌ Aborting as requested."; exit 1; }
|
gum confirm "Proceed with this disk configuration?" || { echo " ❌ Aborting as requested."; exit 1; }
|
||||||
# Final recap <--
|
### Final recap <--
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### --> Disko file generation
|
||||||
echo -e "\n\n ✅ Generating disko configuration from templates..."
|
echo -e "\n\n ✅ Generating disko configuration from templates..."
|
||||||
template_file="config-files/disks/boot-${NUMBER_OF_BOOT_DISKS}.nix"
|
template_file="config-files/disks/boot-${NUMBER_OF_BOOT_DISKS}.nix"
|
||||||
(envsubst < "$template_file") > ./nix-config/disks/disko.nix
|
(envsubst < "$template_file") > ./nix-config/disks/disko.nix
|
||||||
echo -e "\n ✅ Generated boot disk configuration."
|
echo -e "\n ✅ Generated boot disk configuration."
|
||||||
|
|
||||||
if (( NUMBER_OF_CONTENT_DISKS == 1 && NUMBER_OF_PARITY_DISKS == 1 )); then
|
# Mirror configuration
|
||||||
|
if [[ "$NUMBER_OF_CONTENT_DISKS" == 1 && "$NUMBER_OF_PARITY_DISKS" == 1 ]]; then
|
||||||
(envsubst < "config-files/disks/mirror.nix") >> ./nix-config/disks/disko.nix
|
(envsubst < "config-files/disks/mirror.nix") >> ./nix-config/disks/disko.nix
|
||||||
fi
|
# SnapRAID configuration
|
||||||
|
elif [[ "$NUMBER_OF_CONTENT_DISKS" -gt 0 ]]; then
|
||||||
if (( NUMBER_OF_CONTENT_DISKS != 2 )); then
|
|
||||||
for i in $(seq 1 $NUMBER_OF_CONTENT_DISKS); do
|
for i in $(seq 1 $NUMBER_OF_CONTENT_DISKS); do
|
||||||
disk_var="CONTENT_DISK_$i"
|
LOOP_DISK="CONTENT_DISK_$i"
|
||||||
export DISK_NUMBER=$i
|
export DISK_NUMBER=$i
|
||||||
export DISK_PATH=${!disk_var}
|
export DISK_PATH=${!LOOP_DISK}
|
||||||
(envsubst < "config-files/disks/content.nix") >> ./nix-config/disks/disko.nix
|
(envsubst < "config-files/disks/content.nix") >> ./nix-config/disks/disko.nix
|
||||||
done
|
done
|
||||||
[[ "$NUMBER_OF_CONTENT_DISKS" -gt 0 ]] && echo -e "\n ✅ Generated $NUMBER_OF_CONTENT_DISKS data disk configuration(s)."
|
echo -e "\n ✅ Generated $NUMBER_OF_CONTENT_DISKS data disk configuration(s)."
|
||||||
|
|
||||||
for i in $(seq 1 $NUMBER_OF_PARITY_DISKS); do
|
for i in $(seq 1 $NUMBER_OF_PARITY_DISKS); do
|
||||||
disk_var="PARITY_DISK_$i"
|
LOOP_DISK="PARITY_DISK_$i"
|
||||||
export DISK_NUMBER=$i
|
export DISK_NUMBER=$i
|
||||||
export DISK_PATH=${!disk_var}
|
export DISK_PATH=${!LOOP_DISK}
|
||||||
(envsubst < "config-files/disks/parity.nix") >> ./nix-config/disks/disko.nix
|
(envsubst < "config-files/disks/parity.nix") >> ./nix-config/disks/disko.nix
|
||||||
done
|
done
|
||||||
[[ "$NUMBER_OF_PARITY_DISKS" -gt 0 ]] && echo -e "\n ✅ Generated $NUMBER_OF_PARITY_DISKS parity disk configuration(s)."
|
echo -e "\n ✅ Generated $NUMBER_OF_PARITY_DISKS parity disk configuration(s)."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Close the disko.nix block
|
# Close the disko.nix block
|
||||||
cat <<'EOF' >> ./nix-config/disks/disko.nix
|
cat <<'EOF' >> ./nix-config/disks/disko.nix
|
||||||
};
|
};
|
||||||
@@ -504,6 +548,9 @@ EOF
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
echo -e "\n ✅ Final disko configuration created."
|
echo -e "\n ✅ Final disko configuration created."
|
||||||
|
### Disko file generation <--
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# --> Generate automatic unlock configuration in ./nix-config/disks/snapraid.nix
|
# --> Generate automatic unlock configuration in ./nix-config/disks/snapraid.nix
|
||||||
if [[ "$NUMBER_OF_CONTENT_DISKS" -gt 1 && "$NUMBER_OF_PARITY_DISKS" -gt 0 ]]; then
|
if [[ "$NUMBER_OF_CONTENT_DISKS" -gt 1 && "$NUMBER_OF_PARITY_DISKS" -gt 0 ]]; then
|
||||||
|
|||||||
Reference in New Issue
Block a user