From b2d39de984f23eb728b9411221ff898503b2d8d5 Mon Sep 17 00:00:00 2001 From: Raphael Numbus Date: Sun, 7 Dec 2025 11:30:37 +0100 Subject: [PATCH] Added mirror configuration --- config-files/disks/mirror.nix | 44 ++++++++++++++++ deploy.sh | 99 ++++++++++++++++++++++------------- 2 files changed, 107 insertions(+), 36 deletions(-) create mode 100644 config-files/disks/mirror.nix diff --git a/config-files/disks/mirror.nix b/config-files/disks/mirror.nix new file mode 100644 index 0000000..5fc4f53 --- /dev/null +++ b/config-files/disks/mirror.nix @@ -0,0 +1,44 @@ + + # Data mirror configuration generated by deploy.sh + disk = { + "content-1" = { + type = "disk"; + device = "${CONTENT_DISK_1}"; + content = { + type = "gpt"; + partitions = { + "data-1" = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-content-1"; + settings.keyFile = "/etc/secrets/disks/content-disk-1"; + }; + }; + }; + }; + }; + "parity-1" = { + type = "disk"; + device = "${PARITY_DISK_1}"; + content = { + type = "gpt"; + partitions = { + "parity-1" = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-parity-1"; + settings.keyFile = "/etc/secrets/disks/parity-disk-1"; + }; + }; + }; + }; + }; + }; + mdadm.raid-devices = [ "/dev/mapper/crypted-content-1" "/dev/mapper/crypted-parity-1" ]; + fs."/dev/md/data-storage" = { + type = "xfs"; + label = "data-storage"; + mountpoint = "/mnt/data-storage"; + }; \ No newline at end of file diff --git a/deploy.sh b/deploy.sh index 4369b5c..f9807b9 100755 --- a/deploy.sh +++ b/deploy.sh @@ -377,38 +377,63 @@ disk_config_generation() { num_parity=0 num_content=0 - if (( num_selected == 1 )); then # If only one data disk is selected, it is a content disk + if (( num_selected == 2 )); then + # Special case for 2 data disks: create a mirror. + echo -e "\n ✅ Two data disks detected, creating a mirror configuration." + + disk1_name=${selected_data_names[0]} + disk2_name=${selected_data_names[1]} + disk1_size=${DISK_SIZE_MAP[$disk1_name]} + disk2_size=${DISK_SIZE_MAP[$disk2_name]} + + if [[ "$disk1_size" -ne "$disk2_size" ]]; then + gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "⚠️ The two selected disks for the mirror have different sizes. The mirror will be created using the size of the smaller disk, and the extra space on the larger disk will be unused." + gum confirm "Do you want to proceed anyway?" || { echo " ❌ Aborting as requested."; exit 1; } + fi + + export CONTENT_DISK_1=${DISK_BY_ID_MAP[${selected_data_names[0]}]} + export PARITY_DISK_1=${DISK_BY_ID_MAP[${selected_data_names[1]}]} + export CONTENT_DISK_1_KEY_VAR="CONTENT_DISK_1_KEY" + export PARITY_DISK_1_KEY_VAR="PARITY_DISK_1_KEY" + export CONTENT_DISK_1_KEY=${!CONTENT_DISK_1_KEY_VAR} + export PARITY_DISK_1_KEY=${!PARITY_DISK_1_KEY_VAR} + (envsubst < "config-files/disks/mirror.nix") >> ./nix-config/disks/disko.nix + NUMBER_OF_CONTENT_DISKS=1 # For summary and key generation + NUMBER_OF_PARITY_DISKS=1 + + elif (( num_selected == 1 )); then # If only one data disk is selected, it is a content disk num_content=1 num_parity=0 - elif (( num_selected > 1 )); then # If more than one data disk is selected + elif (( num_selected > 2 )); then # If more than two data disks are selected # 1 parity for up to 2 content disks. num_parity=$(( (num_selected + 2) / 3 )) num_content=$(( num_selected - num_parity )) fi - # Sort selected disks by size (largest first) - sorted_disks=($( - # shellcheck disable=SC2145 - for name in "${selected_data_names[@]}"; do - echo "${DISK_SIZE_MAP[$name]} $name" - done | sort -rn | awk '{print $2}' - )) + if (( num_selected != 2 )); then + # Sort selected disks by size (largest first) for snapraid + sorted_disks=($( + for name in "${selected_data_names[@]}"; do + echo "${DISK_SIZE_MAP[$name]} $name" + done | sort -rn | awk '{print $2}' + )) - # Assign parity disks (the largest ones) - parity_disks_final=() - for i in $(seq 0 $((num_parity > 0 ? num_parity - 1 : -1))); do - [[ -n "${sorted_disks[$i]}" ]] && parity_disks_final+=("${DISK_BY_ID_MAP[${sorted_disks[$i]}]}") - done + # Assign parity disks (the largest ones) + parity_disks_final=() + for i in $(seq 0 $((num_parity > 0 ? num_parity - 1 : -1))); do + [[ -n "${sorted_disks[$i]}" ]] && parity_disks_final+=("${DISK_BY_ID_MAP[${sorted_disks[$i]}]}") + done - # Assign content disks (the remaining ones) - content_disks_final=() - for i in $(seq $num_parity $((num_selected - 1))); do - [[ -n "${sorted_disks[$i]}" ]] && content_disks_final+=("${DISK_BY_ID_MAP[${sorted_disks[$i]}]}") - done + # Assign content disks (the remaining ones) + content_disks_final=() + for i in $(seq $num_parity $((num_selected - 1))); do + [[ -n "${sorted_disks[$i]}" ]] && content_disks_final+=("${DISK_BY_ID_MAP[${sorted_disks[$i]}]}") + done - # Set exported variables (up to 6 content disks and 3 parity disks) - for i in {0..5}; do export "CONTENT_DISK_$((i+1))"="${content_disks_final[$i]:-}"; done - for i in {0..2}; do export "PARITY_DISK_$((i+1))"="${parity_disks_final[$i]:-}"; done + # Set exported variables (up to 6 content disks and 3 parity disks) + for i in {0..5}; do export "CONTENT_DISK_$((i+1))"="${content_disks_final[$i]:-}"; done + for i in {0..2}; do export "PARITY_DISK_$((i+1))"="${parity_disks_final[$i]:-}"; done + fi fi else echo -e "\n\n ⚠️ No remaining disks to select for data." @@ -459,21 +484,23 @@ EOF (envsubst < "$template_file") > ./nix-config/disks/disko.nix echo -e "\n ✅ Generated boot disk configuration." - for i in $(seq 1 $NUMBER_OF_CONTENT_DISKS); do - disk_var="CONTENT_DISK_$i" - export DISK_NUMBER=$i - export DISK_PATH=${!disk_var} - (envsubst < "config-files/disks/content.nix") >> ./nix-config/disks/disko.nix - done - [[ "$NUMBER_OF_CONTENT_DISKS" -gt 0 ]] && echo -e "\n ✅ Generated $NUMBER_OF_CONTENT_DISKS data disk configuration(s)." + if (( NUMBER_OF_CONTENT_DISKS != 2 )); then + for i in $(seq 1 $NUMBER_OF_CONTENT_DISKS); do + disk_var="CONTENT_DISK_$i" + export DISK_NUMBER=$i + export DISK_PATH=${!disk_var} + (envsubst < "config-files/disks/content.nix") >> ./nix-config/disks/disko.nix + done + [[ "$NUMBER_OF_CONTENT_DISKS" -gt 0 ]] && echo -e "\n ✅ Generated $NUMBER_OF_CONTENT_DISKS data disk configuration(s)." - for i in $(seq 1 $NUMBER_OF_PARITY_DISKS); do - disk_var="PARITY_DISK_$i" - export DISK_NUMBER=$i - export DISK_PATH=${!disk_var} - (envsubst < "config-files/disks/parity.nix") >> ./nix-config/disks/disko.nix - done - [[ "$NUMBER_OF_PARITY_DISKS" -gt 0 ]] && echo -e "\n ✅ Generated $NUMBER_OF_PARITY_DISKS parity disk configuration(s)." + for i in $(seq 1 $NUMBER_OF_PARITY_DISKS); do + disk_var="PARITY_DISK_$i" + export DISK_NUMBER=$i + export DISK_PATH=${!disk_var} + (envsubst < "config-files/disks/parity.nix") >> ./nix-config/disks/disko.nix + done + [[ "$NUMBER_OF_PARITY_DISKS" -gt 0 ]] && echo -e "\n ✅ Generated $NUMBER_OF_PARITY_DISKS parity disk configuration(s)." + fi # Close the disko.nix block cat <<'EOF' >> ./nix-config/disks/disko.nix