From 6827785db7debaa503781146b91cbe0264c8e231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Billet?= Date: Tue, 18 Nov 2025 22:35:09 +0100 Subject: [PATCH] Standardize system disk on LVM-on-LUKS for snapshot support. Add dedicated parity disk and correct data disk mountpoints. Resolve various Nix syntax errors in disk templates. Set data disk filesystem to XFS for better large-file performance. --- config-examples/secrets.example.yaml | 35 --- config-files/disks/boot-1-data-0.nix | 62 ++++++ config-files/disks/boot-1-data-1.nix | 86 ++++++++ config-files/disks/boot-1-data-2.nix | 110 ++++++++++ config-files/disks/boot-1-data-3.nix | 134 ++++++++++++ config-files/disks/boot-1-data-4.nix | 158 ++++++++++++++ .../example}/deploy.example.conf | 0 config-files/sops-nix/.sops.yaml | 9 + config-files/sops-nix/secrets.yaml | 35 +++ deploy.sh | 203 ++++++++++++------ disk-config.nix | 70 ------ test.sh | 5 - 12 files changed, 733 insertions(+), 174 deletions(-) delete mode 100644 config-examples/secrets.example.yaml create mode 100644 config-files/disks/boot-1-data-0.nix create mode 100644 config-files/disks/boot-1-data-1.nix create mode 100644 config-files/disks/boot-1-data-2.nix create mode 100644 config-files/disks/boot-1-data-3.nix create mode 100644 config-files/disks/boot-1-data-4.nix rename {config-examples => config-files/example}/deploy.example.conf (100%) create mode 100644 config-files/sops-nix/.sops.yaml create mode 100644 config-files/sops-nix/secrets.yaml delete mode 100644 test.sh diff --git a/config-examples/secrets.example.yaml b/config-examples/secrets.example.yaml deleted file mode 100644 index d280b6f..0000000 --- a/config-examples/secrets.example.yaml +++ /dev/null @@ -1,35 +0,0 @@ -ssh-public-keys: $SSH_PUBLIC_KEY - -docker: - nextcloud: | - DOMAIN_NAME=$DOMAIN_NAME - NEXTCLOUD_ENABLE_DRI_DEVICE=$TARGET_GRAPHICS - frigate: | - DOMAIN_NAME=$DOMAIN_NAME - FRIGATE_MQTT_USER=$HOME_ASSISTANT_MQTT_USER - FRIGATE_MQTT_PASSWORD=$HOME_ASSISTANT_MQTT_PASSWORD - traefik: | - DOMAIN_NAME=$DOMAIN_NAME - CF_DNS_API_TOKEN: $CF_DNS_API_TOKEN - hass: | - DOMAIN_NAME=$DOMAIN_NAME - HOME_ASSISTANT_MQTT_USER: $HOME_ASSISTANT_MQTT_USER - HOME_ASSISTANT_MQTT_PASSWORD: $HOME_ASSISTANT_MQTT_PASSWORD - passbolt: | - DOMAIN_NAME=$DOMAIN_NAME - TZ="Europe/Paris" - PASSBOLT_MYSQL_DATABASE: $PASSBOLT_MYSQL_DATABASE - PASSBOLT_MYSQL_USER: $PASSBOLT_MYSQL_USER - PASSBOLT_MYSQL_PASSWORD: $PASSBOLT_MYSQL_PASSWORD - SENDER_EMAIL_ADDRESS: $SENDER_EMAIL_ADDRESS - SENDER_EMAIL_ADDRESS_PASSWORD: $SENDER_EMAIL_ADDRESS_PASSWORD - SENDER_EMAIL_DOMAIN: $SENDER_EMAIL_DOMAIN - SENDER_EMAIL_PORT: $SENDER_EMAIL_PORT - EMAIL_ADDRESS: $EMAIL_ADDRESS - pihole: | - DOMAIN_NAME=$DOMAIN_NAME - TZ="Europe/Paris" - HOME_ROUTER_SUBNET=$HOME_ROUTER_SUBNET - HOME_ROUTER_IP=$HOME_ROUTER_IP - HOME_SERVER_IP=$HOME_SERVER_IP - FTLCONF_webserver_api_password: $FTLCONF_webserver_api_password \ No newline at end of file diff --git a/config-files/disks/boot-1-data-0.nix b/config-files/disks/boot-1-data-0.nix new file mode 100644 index 0000000..f1c44d0 --- /dev/null +++ b/config-files/disks/boot-1-data-0.nix @@ -0,0 +1,62 @@ +{ lib, ... }: +{ + disko.devices = { + disk = { + # Boot disk + system = { + type = "disk"; + device = "${BOOT_DISK_1}"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted"; + settings = { + allowDiscards = true; + }; + content = { + type = "lvm_pv"; + vg = "pool"; + }; + }; + }; + }; + }; + }; + }; + + # Boot disk LVM configuration + lvm_vg = { + pool = { + type = "lvm_vg"; + lvs = { + root = { + size = "100%FREE"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + swap = { + size = "8G"; + content.type = "swap"; + }; + }; + }; + }; + }; +} \ No newline at end of file diff --git a/config-files/disks/boot-1-data-1.nix b/config-files/disks/boot-1-data-1.nix new file mode 100644 index 0000000..d58ef13 --- /dev/null +++ b/config-files/disks/boot-1-data-1.nix @@ -0,0 +1,86 @@ +{ lib, ... }: +{ + disko.devices = { + disk = { + # Boot disk + system = { + type = "disk"; + device = "${BOOT_DISK_1}"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted"; + settings = { + allowDiscards = true; + }; + content = { + type = "lvm_pv"; + vg = "pool"; + }; + }; + }; + }; + }; + }; + + # First data disk + data1 = { + type = "disk"; + device = "${DATA_DISK_1}"; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-data-1"; + keyFile = "/run/secrets/disks/data-disk-1"; + content = { + type = "filesystem"; + format = "xfs"; + mountpoint = "/mnt/data-1"; + }; + }; + }; + }; + }; + }; + }; + + # Boot disk LVM configuration + lvm_vg = { + pool = { + type = "lvm_vg"; + lvs = { + root = { + size = "100%FREE"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + swap = { + size = "8G"; + content.type = "swap"; + }; + }; + }; + }; + }; +} diff --git a/config-files/disks/boot-1-data-2.nix b/config-files/disks/boot-1-data-2.nix new file mode 100644 index 0000000..766ee78 --- /dev/null +++ b/config-files/disks/boot-1-data-2.nix @@ -0,0 +1,110 @@ +{ lib, ... }: +{ + disko.devices = { + disk = { + # Boot disk + system = { + type = "disk"; + device = "${BOOT_DISK_1}"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted"; + settings = { + allowDiscards = true; + }; + content = { + type = "lvm_pv"; + vg = "pool"; + }; + }; + }; + }; + }; + }; + + # First data disk + data1 = { + type = "disk"; + device = "${DATA_DISK_1}"; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-data-1"; + keyFile = "/run/secrets/disks/data-disk-1"; + content = { + type = "filesystem"; + format = "xfs"; + mountpoint = "/mnt/data-1"; + }; + }; + }; + }; + }; + }; + + # Parity disk + parity1 = { + type = "disk"; + device = "${PARITY_DISK_1}"; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-parity-1"; + keyFile = "/run/secrets/disks/parity-disk-1"; + content = { + type = "filesystem"; + format = "xfs"; + mountpoint = "/mnt/parity-1"; + }; + }; + }; + }; + }; + }; + }; + + # Boot disk LVM configuration + lvm_vg = { + pool = { + type = "lvm_vg"; + lvs = { + root = { + size = "100%FREE"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + swap = { + size = "8G"; + content.type = "swap"; + }; + }; + }; + }; + }; +} diff --git a/config-files/disks/boot-1-data-3.nix b/config-files/disks/boot-1-data-3.nix new file mode 100644 index 0000000..d364027 --- /dev/null +++ b/config-files/disks/boot-1-data-3.nix @@ -0,0 +1,134 @@ +{ lib, ... }: +{ + disko.devices = { + disk = { + # Boot disk + system = { + type = "disk"; + device = "${BOOT_DISK_1}"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted"; + settings = { + allowDiscards = true; + }; + content = { + type = "lvm_pv"; + vg = "pool"; + }; + }; + }; + }; + }; + }; + + # First data disk + data1 = { + type = "disk"; + device = "${DATA_DISK_1}"; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-data-1"; + keyFile = "/run/secrets/disks/data-disk-1"; + content = { + type = "filesystem"; + format = "xfs"; + mountpoint = "/mnt/data-1"; + }; + }; + }; + }; + }; + }; + + # Second data disk + data2 = { + type = "disk"; + device = "${DATA_DISK_2}"; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-data-2"; + keyFile = "/run/secrets/disks/data-disk-2"; + content = { + type = "filesystem"; + format = "xfs"; + mountpoint = "/mnt/data-2"; + }; + }; + }; + }; + }; + }; + + # Parity disk + parity1 = { + type = "disk"; + device = "${PARITY_DISK_1}"; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-parity-1"; + keyFile = "/run/secrets/disks/parity-disk-1"; + content = { + type = "filesystem"; + format = "xfs"; + mountpoint = "/mnt/parity-1"; + }; + }; + }; + }; + }; + }; + }; + + # Boot disk LVM configuration + lvm_vg = { + pool = { + type = "lvm_vg"; + lvs = { + root = { + size = "100%FREE"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + swap = { + size = "8G"; + content.type = "swap"; + }; + }; + }; + }; + }; +} \ No newline at end of file diff --git a/config-files/disks/boot-1-data-4.nix b/config-files/disks/boot-1-data-4.nix new file mode 100644 index 0000000..1dcea29 --- /dev/null +++ b/config-files/disks/boot-1-data-4.nix @@ -0,0 +1,158 @@ +{ lib, ... }: +{ + disko.devices = { + disk = { + # Boot disk + system = { + type = "disk"; + device = "${BOOT_DISK_1}"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted"; + settings = { + allowDiscards = true; + }; + content = { + type = "lvm_pv"; + vg = "pool"; + }; + }; + }; + }; + }; + }; + + # First data disk + data1 = { + type = "disk"; + device = "${DATA_DISK_1}"; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-data-1"; + keyFile = "/run/secrets/disks/data-disk-1"; + content = { + type = "filesystem"; + format = "xfs"; + mountpoint = "/mnt/data-1"; + }; + }; + }; + }; + }; + }; + + # Second data disk + data2 = { + type = "disk"; + device = "${DATA_DISK_2}"; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-data-2"; + keyFile = "/run/secrets/disks/data-disk-2"; + content = { + type = "filesystem"; + format = "xfs"; + mountpoint = "/mnt/data-2"; + }; + }; + }; + }; + }; + }; + + # Third data disk + data3 = { + type = "disk"; + device = "${DATA_DISK_3}"; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-data-3"; + keyFile = "/run/secrets/disks/data-disk-3"; + content = { + type = "filesystem"; + format = "xfs"; + mountpoint = "/mnt/data-3"; + }; + }; + }; + }; + }; + }; + + # Parity disk + parity1 = { + type = "disk"; + device = "${PARITY_DISK_1}"; + content = { + type = "gpt"; + partitions = { + luks = { + size = "100%"; + content = { + type = "luks"; + name = "crypted-parity-1"; + keyFile = "/run/secrets/disks/parity-disk-1"; + content = { + type = "filesystem"; + format = "xfs"; + mountpoint = "/mnt/parity-1"; + }; + }; + }; + }; + }; + }; + }; + + # Boot disk LVM configuration + lvm_vg = { + pool = { + type = "lvm_vg"; + lvs = { + root = { + size = "100%FREE"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + swap = { + size = "8G"; + content.type = "swap"; + }; + }; + }; + }; + }; +} \ No newline at end of file diff --git a/config-examples/deploy.example.conf b/config-files/example/deploy.example.conf similarity index 100% rename from config-examples/deploy.example.conf rename to config-files/example/deploy.example.conf diff --git a/config-files/sops-nix/.sops.yaml b/config-files/sops-nix/.sops.yaml new file mode 100644 index 0000000..de69314 --- /dev/null +++ b/config-files/sops-nix/.sops.yaml @@ -0,0 +1,9 @@ +# .sops.yaml + +keys: + - &primary $SOPS_PUBLIC_KEY +creation_rules: + - path_regex: secrets/secrets.yaml$ + key_groups: + - age: + - *primary \ No newline at end of file diff --git a/config-files/sops-nix/secrets.yaml b/config-files/sops-nix/secrets.yaml new file mode 100644 index 0000000..3f07db2 --- /dev/null +++ b/config-files/sops-nix/secrets.yaml @@ -0,0 +1,35 @@ +ssh-public-keys: $SSH_PUBLIC_KEY + +docker: + nextcloud: | + DOMAIN_NAME=$DOMAIN_NAME + NEXTCLOUD_ENABLE_DRI_DEVICE=$TARGET_GRAPHICS + frigate: | + DOMAIN_NAME=$DOMAIN_NAME + FRIGATE_MQTT_USER=$HOME_ASSISTANT_MQTT_USER + FRIGATE_MQTT_PASSWORD=$HOME_ASSISTANT_MQTT_PASSWORD + traefik: | + DOMAIN_NAME=$DOMAIN_NAME + CF_DNS_API_TOKEN=$CF_DNS_API_TOKEN + hass: | + DOMAIN_NAME=$DOMAIN_NAME + HOME_ASSISTANT_MQTT_USER=$HOME_ASSISTANT_MQTT_USER + HOME_ASSISTANT_MQTT_PASSWORD=$HOME_ASSISTANT_MQTT_PASSWORD + passbolt: | + DOMAIN_NAME=$DOMAIN_NAME + TZ="Europe/Paris" + PASSBOLT_MYSQL_DATABASE=$PASSBOLT_MYSQL_DATABASE + PASSBOLT_MYSQL_USER=$PASSBOLT_MYSQL_USER + PASSBOLT_MYSQL_PASSWORD=$PASSBOLT_MYSQL_PASSWORD + SENDER_EMAIL_ADDRESS=$SENDER_EMAIL_ADDRESS + SENDER_EMAIL_ADDRESS_PASSWORD=$SENDER_EMAIL_ADDRESS_PASSWORD + SENDER_EMAIL_DOMAIN=$SENDER_EMAIL_DOMAIN + SENDER_EMAIL_PORT=$SENDER_EMAIL_PORT + EMAIL_ADDRESS=$EMAIL_ADDRESS + pihole: | + DOMAIN_NAME=$DOMAIN_NAME + TZ="Europe/Paris" + HOME_ROUTER_SUBNET=$HOME_ROUTER_SUBNET + HOME_ROUTER_IP=$HOME_ROUTER_IP + HOME_SERVER_IP=$HOME_SERVER_IP + FTLCONF_webserver_api_password=$FTLCONF_WEBSERVER_PASSWORD \ No newline at end of file diff --git a/deploy.sh b/deploy.sh index a8dc7ad..9902618 100644 --- a/deploy.sh +++ b/deploy.sh @@ -1,17 +1,6 @@ #!/bin/bash -install_prerun_action() { - echo -e "\n\n ➡️ On the target host : start the computer and boot into the NixOS iso.\n Launch a console and set up a new user password." - SETUP_ANSWER="$(gum input --placeholder "Type 'done' when you have finished.")" - if [[ "$SETUP_ANSWER" == "done" ]]; then - : - else - echo " Aborting - you did not type 'done'." - exit 1 - fi -} - -update_prerun_action() { - echo -e "\n\n ➡️ On the target host : make sure the NixOS installation you want to update is up-and-running, accessible with SSH." +prerun_action() { + echo -e "$1" SETUP_ANSWER="$(gum input --placeholder "Type 'done' when you have finished.")" if [[ "$SETUP_ANSWER" == "done" ]]; then : @@ -76,6 +65,56 @@ necessary_credentials_with_config() { fi } +hardware_detection() { + echo -e "\n\n ➡️ Please provide the password of the target host :" + ssh-copy-id -i extra-files/home/numbus-admin/.ssh/id_ed25519.pub nixos@$TARGET_HOST + + ssh_to_host() { + ssh -i extra-files/home/numbus-admin/.ssh/id_ed25519 nixos@$TARGET_HOST "$1" + } + + echo -e "\n\n 🔎 Detecting graphics card on target host..." + VGA_INFO=$(ssh_to_host "lspci -nn | grep -i 'vga'") + if echo "$VGA_INFO" | grep -iq "intel"; then + echo -e " ✅ Intel graphics card detected." + TARGET_GRAPHICS="true" + elif echo "$VGA_INFO" | grep -iq "amd"; then + echo -e " ✅ AMD graphics card detected." + TARGET_GRAPHICS="true" + elif echo "$VGA_INFO" | grep -iq "nvidia"; then + echo -e " ✅ NVIDIA graphics card detected." + TARGET_GRAPHICS="true" + else + echo -e " ℹ️ No dedicated graphics card detected." + TARGET_GRAPHICS="false" + fi + echo -e "\n\n 🔎 Detecting transconding acceleration on target host..." + if ssh_to_host "ls /dev/dri/renderD128"; then + echo -e " ✅ Transcoding capable card detected." + TARGET_GRAPHICS_RENDERER="true" + else + echo -e " ℹ️ No transcoding capable card detected." + TARGET_GRAPHICS_RENDERER="false" + fi + echo -e "\n\n 🔎 Detecting USB Google Coral TPU on target host..." + if ssh_to_host "lsusb | grep -iq 'google'"; then + echo -e " ✅ USB Google Coral TPU detected." + TARGET_USB_CORAL="true" + else + echo -e " ℹ️ No USB Google Coral TPU detected." + TARGET_USB_CORAL="false" + fi + echo -e "\n\n 🔎 Detecting Zigbee coordinator on target host..." + if ssh_to_host "ls /dev/serial/by-id/ | grep -i 'zigbee'"; then + echo -e " ✅ Zigbee device found in /dev/serial/by-id/." + TARGET_ZIGBEE_DEVICE=$(ssh_to_host "ls /dev/serial/by-id/ | grep -i 'zigbee'") + TARGET_ZIGBEE="true" + else + echo -e " ℹ️ No Zigbee device found." + TARGET_ZIGBEE="false" + fi +} + files_generation() { echo -e "\n\n ✅ Generating necessary folder tree..." mkdir -p extra-files/home/numbus-admin/.ssh/ @@ -190,57 +229,11 @@ files_generation() { nix shell nixpkgs#mosquitto -c mosquitto_passwd -b extra-files/mnt/config-storage/hass/mqtt/config/password.txt $HOME_ASSISTANT_MQTT_USER $HOME_ASSISTANT_MQTT_PASSWORD } -hardware_detection() { - echo -e "\n\n ➡️ Please provide the password of the target host :" - ssh-copy-id -i extra-files/home/numbus-admin/.ssh/id_ed25519.pub nixos@$TARGET_HOST - +disk_config_generation() { ssh_to_host() { ssh -i extra-files/home/numbus-admin/.ssh/id_ed25519 nixos@$TARGET_HOST "$1" } - echo -e "\n\n 🔎 Detecting graphics card on target host..." - VGA_INFO=$(ssh_to_host "lspci -nn | grep -i 'vga'") - if echo "$VGA_INFO" | grep -iq "intel"; then - echo -e " ✅ Intel graphics card detected." - TARGET_GRAPHICS="true" - elif echo "$VGA_INFO" | grep -iq "amd"; then - echo -e " ✅ AMD graphics card detected." - TARGET_GRAPHICS="true" - elif echo "$VGA_INFO" | grep -iq "nvidia"; then - echo -e " ✅ NVIDIA graphics card detected." - TARGET_GRAPHICS="true" - else - echo -e " ℹ️ No dedicated graphics card detected." - TARGET_GRAPHICS="false" - fi - echo -e "\n\n 🔎 Detecting transconding acceleration on target host..." - if ssh_to_host "ls /dev/dri/renderD128"; then - echo -e " ✅ Transcoding capable card detected." - TARGET_GRAPHICS_RENDERER="true" - else - echo -e " ℹ️ No transcoding capable card detected." - TARGET_GRAPHICS_RENDERER="false" - fi - echo -e "\n\n 🔎 Detecting USB Google Coral TPU on target host..." - if ssh_to_host "lsusb | grep -iq 'google'"; then - echo -e " ✅ USB Google Coral TPU detected." - TARGET_USB_CORAL="true" - else - echo -e " ℹ️ No USB Google Coral TPU detected." - TARGET_USB_CORAL="false" - fi - echo -e "\n\n 🔎 Detecting Zigbee coordinator on target host..." - if ssh_to_host "ls /dev/serial/by-id/ | grep -i 'zigbee'"; then - echo -e " ✅ Zigbee device found in /dev/serial/by-id/." - TARGET_ZIGBEE_DEVICE=$(ssh_to_host "ls /dev/serial/by-id/ | grep -i 'zigbee'") - TARGET_ZIGBEE="true" - else - echo -e " ℹ️ No Zigbee device found." - TARGET_ZIGBEE="false" - fi -} - -disk_config_generation() { echo -e "\n\n ⚠️ WARNING: you will choose the disks you want to install NixOS on." echo -e " !! PLEASE MAKE SURE YOU BACKED UP ANY IMPORTANT DATA !!" echo -e " !! ALL DATA WILL BE WIPED ON THE DISKS YOU CHOOSE !!" @@ -254,8 +247,86 @@ disk_config_generation() { exit 1 fi - sleep 10 + echo -e "\n\n 🔎 Fetching disks from target host..." + DISK_JSON=$(ssh_to_host "lsblk -d --json -o NAME,ROTA,SIZE,PATH") + BY_ID_RAW=$(ssh_to_host "ls -l /dev/disk/by-id/") + if [ -z "$DISK_JSON" ]; then + echo " ❌ Could not find any disks on the target host. Aborting." + exit 1 + fi + + declare -A BY_ID_MAP + + while read -r line; do + if [[ "$line" =~ "-> ../../"(.*)$ ]]; then + dev_name="${BASH_REMATCH[1]}" + by_id_path="/dev/disk/by-id/$(echo "$line" | awk '{print $9}')" + if [[ ! -v "BY_ID_MAP[$dev_name]" && ! "$by_id_path" =~ -part ]]; then + BY_ID_MAP["$dev_name"]="$by_id_path" + fi + fi + done <<< "$BY_ID_RAW" + + declare -A DISK_MAP + declare -a DISK_OPTIONS + + while read -r name type size; do + by_id=${BY_ID_MAP[$name]} + if [ -z "$by_id" ]; then continue; fi + option=$(printf "%-8s %-5s %-8s (%s)" "$name" "$type" "$size" "$by_id") + DISK_OPTIONS+=("$option") + DISK_MAP["$option"]="$by_id" + done < <(echo "$DISK_JSON" | jq -r '.blockdevices[] | "\(.name) \(if .name | test("^nvme") then "NVMe" else (if .rota == "0" then "SSD" else "HDD" end) end) \(.size)"') + echo -e "\n\n ➡️ Please choose one (stripe) or two (mirror) disks for your NixOS boot installation:" + mapfile -t SELECTED_BOOT_OPTIONS < <(gum choose --limit 2 "${DISK_OPTIONS[@]}") + if [ ${#SELECTED_BOOT_OPTIONS[@]} -eq 0 ]; then + echo " ❌ No boot disk selected. Aborting." + exit 1 + fi + + NUMBER_OF_BOOT_DISKS=${#SELECTED_BOOT_OPTIONS[@]} + BOOT_DISK_1=${DISK_MAP["${SELECTED_BOOT_OPTIONS[0]}"]} + + if [ "$NUMBER_OF_BOOT_DISKS" -eq 2 ]; then + BOOT_DISK_2=${DISK_MAP["${SELECTED_BOOT_OPTIONS[1]}"]} + fi + + REMAINING_DISKS=() + for option in "${DISK_OPTIONS[@]}"; do + is_boot_disk=false + for selected in "${SELECTED_BOOT_OPTIONS[@]}"; do + if [[ "$option" == "$selected" ]]; then + is_boot_disk=true + break + fi + done + if ! $is_boot_disk; then + REMAINING_DISKS+=("$option") + fi + done + + if [ ${#REMAINING_DISKS[@]} -gt 0 ]; then + echo -e "\n\n ➡️ Please choose your data disks (up to 4):" + mapfile -t SELECTED_DATA_OPTIONS < <(gum choose --limit 4 "${REMAINING_DISKS[@]}") + NUMBER_OF_DATA_DISKS=${#SELECTED_DATA_OPTIONS[@]} + for i in $(seq 0 $(($NUMBER_OF_DATA_DISKS - 1))); do + declare "DATA_DISK_$(($i + 1))"="${DISK_MAP["${SELECTED_DATA_OPTIONS[$i]}"]}" + done + else + echo -e "\n\n ℹ️ No remaining disks available for data storage." + NUMBER_OF_DATA_DISKS=0 + fi + + DISK_CONFIG_TEMPLATE="config-files/disks/boot-${NUMBER_OF_BOOT_DISKS}-data-${NUMBER_OF_DATA_DISKS}.nix" + + if [[ -f "$DISK_CONFIG_TEMPLATE" ]]; then + echo -e "\n\n ✅ Generating disk configuration from template: $DISK_CONFIG_TEMPLATE" + envsubst < "$DISK_CONFIG_TEMPLATE" > disk-config.nix + else + echo -e "\n\n ❌ Error: No disk configuration template found for $NUMBER_OF_BOOT_DISKS boot disk(s) and $NUMBER_OF_DATA_DISKS data disk(s)." + echo " Looked for: $DISK_CONFIG_TEMPLATE" + exit 1 } deploy() { @@ -322,17 +393,21 @@ echo $ACTION_ANSWER if [[ "$ACTION_ANSWER" == "[1] 🌐 Deploy NixOS on a remote machine" ]]; then echo -e "\n ➡️ Proceeding with deployment…" - install_prerun_action + prerun_action "\n\n ➡️ On the target host : start the computer and boot into the NixOS iso.\n Launch a console and set up a new user password." necessary_credentials + hardware_detection files_generation + disk_config_generation elif [[ "$ACTION_ANSWER" == "[2] 💽 Deploy NixOS on a remote machine with a file configuration" ]]; then echo -e "\n ➡️ Proceeding with deployment using a config file…" - install_prerun_action + prerun_action "\n\n ➡️ On the target host : start the computer and boot into the NixOS iso.\n Launch a console and set up a new user password." necessary_credentials_with_config + hardware_detection files_generation + disk_config_generation elif [[ "$ACTION_ANSWER" == "[3] 🛠️ Update a NixOS remote machine" ]]; then echo -e "\n ➡️ Proceeding with update…" - update_prerun_action + prerun_action "\n\n ➡️ On the target host : make sure the NixOS installation you want to update is up-and-running, accessible with SSH." nixos_update else echo "Aborting - you did not type '1, 2 or 3'." diff --git a/disk-config.nix b/disk-config.nix index 6fd3a35..e69de29 100644 --- a/disk-config.nix +++ b/disk-config.nix @@ -1,70 +0,0 @@ -{ lib, ... }: -{ - disko.devices = { - disk = { - main = { - type = "disk"; - device = "TARGET_DISK"; - content = { - type = "gpt"; - partitions = { - ESP = { - size = "1G"; - type = "EF00"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - mountOptions = [ "umask=0077" ]; - }; - }; - luks = { - size = "100%"; - content = { - type = "luks"; - name = "crypted"; - extraOpenArgs = [ ]; - settings = { - allowDiscards = true; - }; - content = { - type = "lvm_pv"; - vg = "pool"; - }; - }; - }; - }; - }; - }; - }; - lvm_vg = { - pool = { - type = "lvm_vg"; - lvs = { - root = { - size = "100%"; - content = { - type = "filesystem"; - format = "ext4"; - mountpoint = "/"; - mountOptions = [ - "defaults" - ]; - }; - }; - home = { - size = "10M"; - content = { - type = "filesystem"; - format = "ext4"; - mountpoint = "/home"; - }; - }; - raw = { - size = "10M"; - }; - }; - }; - }; - }; -} \ No newline at end of file diff --git a/test.sh b/test.sh deleted file mode 100644 index 2268f60..0000000 --- a/test.sh +++ /dev/null @@ -1,5 +0,0 @@ -ssh_to_host() { - ssh raphael@192.168.11.1 "$1" -} -VGA_INFO=$(ssh_to_host "lspci -nn | grep -i 'vga'") -echo $VGA_INFO \ No newline at end of file