diff --git a/deploy.sh b/deploy.sh index 7bd191e..4e4116c 100644 --- a/deploy.sh +++ b/deploy.sh @@ -7,10 +7,10 @@ export GUM_SPIN_SPINNER_BOLD=true export GUM_SPIN_SHOW_ERROR=true export GUM_SPIN_TITLE_BOLD=true -NECESSARY_VARIABLES_LIST=("TARGET_HOST" "REMOTE_PASS" "SSH_PUBLIC_KEY" "DOMAIN_NAME" \ +NECESSARY_VARIABLES_LIST=( "TARGET_HOST" "REMOTE_PASS" "SSH_PUBLIC_KEY" "DOMAIN_NAME" \ "EMAIL_ADDRESS" "CF_DNS_API_TOKEN" "SENDER_EMAIL_ADDRESS" "SENDER_EMAIL_ADDRESS_PASSWORD" \ "SENDER_EMAIL_DOMAIN" "SENDER_EMAIL_PORT" "HOME_ROUTER_SUBNET" "HOME_ROUTER_IP" \ -"HOME_SERVER_IP" "SELECTED_SERVICES" "SERVER_OWNER_NAME") +"HOME_SERVER_IP" "SELECTED_SERVICES" "SERVER_OWNER_NAME" ) ### Default settings <-- user_input() { @@ -141,7 +141,7 @@ hardware_detection() { ssh_to_host 'bash -s' << SSHEND for brand in Intel AMD NVIDIA; do - if lspci -nn 2>/dev/null | grep -i "vga" | grep -iq "\${brand}"; then + if lspci -nn > /dev/null 2>&1 | grep -i "vga" | grep -iq "\${brand}"; then TARGET_GRAPHICS="true" TARGET_GRAPHICS_BRAND+=("\${brand}") else @@ -149,14 +149,14 @@ for brand in Intel AMD NVIDIA; do fi done -ls /dev/dri/ 2>/dev/null | grep -iq "renderD128" && TARGET_GRAPHICS_RENDERER="true" || TARGET_GRAPHICS_RENDERER="false" -lsusb 2>/dev/null | grep -iq "google" && TARGET_USB_CORAL="true" || TARGET_USB_CORAL="false" -lspci -nn 2>/dev/null | grep -iq "089a" && TARGET_PCIE_CORAL="true" || TARGET_PCIE_CORAL="false" -ls /dev/serial/by-id/ 2>/dev/null | grep -i "zigbee" && TARGET_ZIGBEE_DEVICE=\$(ls /dev/serial/by-id/ 2>/dev/null | grep -i "zigbee" | head -n 1) || TARGET_ZIGBEE_DEVICE="" +ls /dev/dri/ > /dev/null 2>&1 | grep -iq "renderD128" && TARGET_GRAPHICS_RENDERER="true" || TARGET_GRAPHICS_RENDERER="false" +lsusb > /dev/null 2>&1 | grep -iq "google" && TARGET_USB_CORAL="true" || TARGET_USB_CORAL="false" +lspci -nn > /dev/null 2>&1 | grep -iq "089a" && TARGET_PCIE_CORAL="true" || TARGET_PCIE_CORAL="false" +ls /dev/serial/by-id/ > /dev/null 2>&1 | grep -i "zigbee" && TARGET_ZIGBEE_DEVICE=\$(ls /dev/serial/by-id/ > /dev/null 2>&1 | grep -i "zigbee" | head -n 1) || TARGET_ZIGBEE_DEVICE="" TARGET_INTERFACE=\$(ip -4 route show default | awk '{print \$5}' | head -n1) -if ls -l /sys/class/tpm/tpm0/ >/dev/null 2>&1; then +if ls -l /sys/class/tpm/tpm0/ > /dev/null 2>&1; then TARGET_TPM="true" TARGET_TPM_VERSION=\$(cat /sys/class/tpm/tpm0/tpm_version_major) else @@ -186,7 +186,7 @@ for DISK in \$(lsblk -x SIZE -d -n -e 7,11 -o NAME); do else DISK_TYPE+=("Other") fi # Disk health - if [[ \$(echo "$REMOTE_PASS" | sudo -S smartctl -H /dev/\$DISK 2>/dev/null | grep 'self-assessment' | awk '{print \$6}') == "PASSED" ]]; then + if [[ \$(echo "$REMOTE_PASS" | sudo -S smartctl -H /dev/\$DISK > /dev/null 2>&1 | grep 'self-assessment' | awk '{print \$6}') == "PASSED" ]]; then DISK_HEALTH+=("PASSED") else DISK_HEALTH+=("N/A") @@ -239,7 +239,7 @@ SSHEND } services_selection() { - echo -e "\n\n➡️ You will now select the services you want installed on your server:" + echo -e "\n\n ➡️ You will now select the services you want installed on your server:" local AVAILABLE_SERVICES=( "frigate" "gitea" "home-assistant" "immich" "it-tools" \ "nextcloud" "passbolt" "pi-hole" "virtualization" ) @@ -258,12 +258,20 @@ services_selection() { local SELECTED_SERVICES_DESCRIPTION=$(gum choose --no-limit --header "Homelab services:" "${SERVICES_DESCRIPTION[@]}") for i in ${!AVAILABLE_SERVICES[@]}; do - if printf '%s' "$SELECTED_SERVICES_DESCRIPTION" | grep -iq "${AVAILABLE_SERVICES[$i]}"; then - SELECTED_SERVICES+=(${AVAILABLE_SERVICES[$i]}) + if printf '%s' "${SELECTED_SERVICES_DESCRIPTION}" | grep -iq "${AVAILABLE_SERVICES[${i}]}"; then + SELECTED_SERVICES+=("${AVAILABLE_SERVICES[${i}]}") + if [[ "${AVAILABLE_SERVICES[${i}]}" == "nextcloud" ]]; then + SELECTED_SERVICES_DNS+=("nextcloud.${DOMAIN_NAME}" "nextcloud-aio.${DOMAIN_NAME}") + elif [[ "${AVAILABLE_SERVICES[${i}]}" == "virtualization" ]]; then + : + else + SELECTED_SERVICES_DNS+=("${AVAILABLE_SERVICES[${i}]}.${DOMAIN_NAME}") + fi fi done export SELECTED_SERVICES + export SELECTED_SERVICES_DNS } disks_selection() { @@ -274,14 +282,14 @@ disks_selection() { !! ALL DATA WILL BE WIPED ON THE DISKS YOU CHOOSE !! Please press CTRL+C to abort. " - gum confirm "Do you understand and wish to proceed?" || { echo -e "\n\n❌ Aborting as requested."; exit 1; } + gum confirm "Do you understand and wish to proceed?" || { echo -e "\n\n ❌ Aborting as requested."; exit 1; } - 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)" ### Disk wiping warning <-- ### --> Disk selection if [[ "${#DISK_NAME[@]}" -eq 0 ]]; then - echo -e "\n❌ No disks found on the target host. Aborting." + echo -e "\n ❌ No disks found on the target host. Aborting." exit 1 fi @@ -291,13 +299,13 @@ disks_selection() { local GUM_PRINTED_ELEMENT=$(printf "%-12s %-12s %-12s %-12s %s" \ "${DISK_NAME[${i}]}" "${DISK_TYPE[${i}]}" "${DISK_SIZE[${i}]}" \ "${DISK_HEALTH[${i}]}" "${DISK_DEVPATH[${i}]}") - local GUM_PRINTED_ELEMENTS+=("$GUM_PRINTED_ELEMENT") + local GUM_PRINTED_ELEMENTS+=("${GUM_PRINTED_ELEMENT}") done echo "" gum style --foreground 212 "➡️ Please choose one (stripe) or two (mirror) disks for your NixOS boot installation :" - local SELECTED_BOOT_DISK=$(gum choose --limit 2 --header "$HEADER" "${GUM_PRINTED_ELEMENTS[@]}") + local SELECTED_BOOT_DISK=$(gum choose --limit 2 --header "${HEADER}" "${GUM_PRINTED_ELEMENTS[@]}") for i in ${!DISK_NAME[@]}; do if printf '%s' "$SELECTED_BOOT_DISK" | grep -iqw "${DISK_NAME[${i}]}"; then @@ -308,23 +316,23 @@ disks_selection() { done if [[ "${#BOOT_DISKS_ID[@]}" -eq 0 ]]; then - echo -e "\n\n❌ No boot disk selected. Aborting." + echo -e "\n\n ❌ No boot disk selected. Aborting." exit 1 elif [[ "${#BOOT_DISKS_ID[@]}" -eq 1 ]]; then - echo -e "\n\n⚠️ One boot disk selected, continuing with striped boot disk configuration." + echo -e "\n\n ⚠️ One boot disk selected, continuing with striped boot disk configuration." echo -e "Consider using 2 boot disks instead to get data protection features on the boot disks." export BOOT_DISK_1_ID="${BOOT_DISKS_ID[0]}" export BOOT_DISK_1_NAME="${DISK_NAME[0]}" elif [[ "${#BOOT_DISKS_ID[@]}" -eq 2 ]]; then - echo -e "\n\n✅ Two boot disks selected, continuing with mirrored boot disks configuration." - echo -e "\n\n⚠️ If the two disks are different sizes, the resulting usable space size will be \ + echo -e "\n\n ✅ Two boot disks selected, continuing with mirrored boot disks configuration." + echo -e "\n\n ⚠️ If the two disks are different sizes, the resulting usable space size will be \ the one of the smallest disk." export BOOT_DISK_1_ID="${BOOT_DISKS_ID[0]}" export BOOT_DISK_2_ID="${BOOT_DISKS_ID[1]}" export BOOT_DISK_1_NAME="${BOOT_DISKS_NAME[0]}" export BOOT_DISK_2_NAME="${BOOT_DISKS_NAME[1]}" else - echo -e "\n\n❌ Unexpected bug. Please contact the developer. Aborting." + echo -e "\n\n ❌ Unexpected bug. Please contact the developer. Aborting." exit 1 fi @@ -384,7 +392,7 @@ services_generation() { export "${SERVICE_UPPER}_DB_PASSWORD"="$(xkcdpass -d "-")" } - echo -e "\n✅ Writing configuration files for the selected homelab services..." + echo -e "\n ✅ Writing configuration files for the selected homelab services..." cp templates/nix-config/podman/traefik.nix final-nix-config/etc/nixos/podman/traefik.nix cp -avu templates/nix-config/configuration.nix final-nix-config/etc/nixos/configuration.nix envsubst < templates/podman-config/traefik/traefik.yaml > final-nix-config/mnt/config/traefik/traefik.yaml @@ -473,7 +481,7 @@ services_generation() { disks_generation() { # Boot disk(s) - echo -e "\n\n✅ Generating disko configuration from templates..." + echo -e "\n\n ✅ Generating disko configuration from templates..." local TEMPLATE_FILE="templates/nix-config/disks/boot-${#BOOT_DISKS_ID[@]}.nix" (envsubst < "$TEMPLATE_FILE") > final-nix-config/etc/nixos/disks/disko.nix @@ -527,7 +535,7 @@ disks_generation() { MOUNT_DEPENDENCIES_STOP+=" \${pkgs.util-linux}/bin/umount /mnt/content-${j}"$'\n' MOUNT_DEPENDENCIES_STOP+=" \${pkgs.cryptsetup}/bin/cryptsetup close crypted-content-${j}"$'\n' done - echo -e "\n✅ Generated $CONTENT_DISK_NUMBER data disk configuration(s)." + echo -e "\n ✅ Generated $CONTENT_DISK_NUMBER data disk configuration(s)." j=0 for i in $(seq $CONTENT_DISK_NUMBER $((${#DATA_DISKS_ID[@]} - 1))); do export j=$((j + 1)) @@ -541,7 +549,7 @@ disks_generation() { MOUNT_DEPENDENCIES_STOP+=" \${pkgs.util-linux}/bin/umount /mnt/parity-${j}"$'\n' MOUNT_DEPENDENCIES_STOP+=" \${pkgs.cryptsetup}/bin/cryptsetup close crypted-parity-${j}"$'\n' done - echo -e "\n✅ Generated $PARITY_DISK_NUMBER parity disk configuration(s)." + echo -e "\n ✅ Generated $PARITY_DISK_NUMBER parity disk configuration(s)." export SNAPRAID_CONTENT_FILES export SNAPRAID_DATA_DISKS export SNAPRAID_PARITY_FILES @@ -557,7 +565,7 @@ disks_generation() { } EOF - echo -e "\n✅ Final disko configuration created." + echo -e "\n ✅ Final disko configuration created." if [[ -n "${DATA_DISKS_ID[@]}" ]]; then for i in ${!DATA_DISKS_ID[@]}; do @@ -572,7 +580,7 @@ EOF FORMATTED_DISKS+=" \"$disk\"\n" done sed -i "s|DISK_LIST|${FORMATTED_DISKS}|" final-nix-config/etc/nixos/disks/spindown.nix - echo -e "\n✅ Disk spindown configuration created." + echo -e "\n ✅ Disk spindown configuration created." fi fi ### Config generation <-- @@ -601,20 +609,20 @@ EOF PASS="$(xkcdpass)" echo -n "$PASS" > "final-nix-config/etc/secrets/disks/parity-${i}" chmod 600 "final-nix-config/etc/secrets/disks/parity-${i}" - ssh_to_host 'bash -s' << EOF + ssh_to_host 'bash -s' << EOF echo "$REMOTE_PASS" | sudo -S bash -c "printf '%s' '$PASS' > /etc/secrets/disks/parity-${i}" EOF done ### Generate disk keys <-- - echo -e "\n✅ Generating sops-nix keys..." + echo -e "\n ✅ Generating sops-nix keys..." ssh-to-age -private-key -i final-nix-config/home/numbus-admin/.ssh/id_ed25519 > final-nix-config/var/lib/sops-nix/key.txt export SOPS_PUBLIC_KEY=$(age-keygen -y final-nix-config/var/lib/sops-nix/key.txt) - echo -e "\n✅ Generating sops-nix configuration files..." + echo -e "\n ✅ Generating sops-nix configuration files..." envsubst < templates/nix-config/sops-nix/.sops.yaml > final-nix-config/etc/nixos/.sops.yaml - echo -e "\n✅ Encrypting secrets in the correct file..." + echo -e "\n ✅ Encrypting secrets in the correct file..." envsubst < "templates/nix-config/sops-nix/secrets.yaml" \ | sops encrypt --filename-override secrets.yaml \ --input-type yaml --output-type yaml \ @@ -623,12 +631,12 @@ EOF } nix_generation() { - echo -e "\n✅ Copying the configuration to the new machine..." + echo -e "\n ✅ Copying the configuration to the new machine..." cp -avu templates/nix-config/flake.nix final-nix-config/etc/nixos/ cp -avu templates/nix-config/misc/* final-nix-config/etc/nixos/misc/ echo "${SERVER_OWNER_NAME:-User}" > final-nix-config/etc/numbus-server/owner - echo -e "\n✅ Writing correct ips to configuration.nix..." + echo -e "\n ✅ Writing correct ips to configuration.nix..." sed -i "s|HOME_SERVER_IP|${HOME_SERVER_IP}|g" final-nix-config/etc/nixos/misc/networking.nix sed -i "s|HOME_ROUTER_IP|${HOME_ROUTER_IP}|g" final-nix-config/etc/nixos/misc/networking.nix sed -i "s|TARGET_INTERFACE|${TARGET_INTERFACE}|g" final-nix-config/etc/nixos/misc/networking.nix @@ -668,7 +676,7 @@ EOF ) gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "$(gum format <<< "${DISK_RECAP_CONTENT}")" - gum confirm "Proceed with this disk configuration?" || { echo -e "\n\n❌ Aborting as requested."; exit 1; } + gum confirm "Proceed with this disk configuration?" || { echo -e "\n\n ❌ Aborting as requested."; exit 1; } ### Disk selection recap <-- ### Keys recap <-- @@ -701,7 +709,7 @@ EOF ) gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "$(gum format <<< "${KEYS_RECAP_CONTENT}")" - gum confirm "Do you want to deploy NixOS on the target host?" || { echo -e "\n\n❌ Aborting as requested"; exit 1; } + gum confirm "Do you want to deploy NixOS on the target host?" || { echo -e "\n\n ❌ Aborting as requested"; exit 1; } ### Keys recap <-- } @@ -729,59 +737,86 @@ export_configuration() { echo -e "\n# Podman SETTINGS" >> $CONFIG_EXPORT_FILE echo "export PODMAN_NETWORKS=\"${PODMAN_NETWORKS}\"" >> $CONFIG_EXPORT_FILE echo "export TRAEFIK_NETWORKS=\"${TRAEFIK_NETWORKS}\"" >> $CONFIG_EXPORT_FILE - echo "export TRAEFIK_REF_NETWORKS=\"${TRAEFIK_REF_NETWORKS}\"" >> $CONFIG_EXPORT_FILE + echo "export TRAEFIK_REF_NETWORKS=\"${TRAEFIK_REF_NETWORKS}\"" >> $CONFIG_EXPORT_FILE } cloudflare_dns_setup() { - echo -e "\n\n☁️ Configuring Cloudflare DNS records..." + local ZONE_ID && local RECORD_COUNT && local IS_MATCHING + local DNS_RECORDS && local CREATION_STATUS - # 1. Get Zone ID - local ZONE_ID + create_records() { + local SUBDOMAIN="${1}" + local CREATION_STATUS + + CREATION_STATUS=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \ + -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ + -H "Content-Type: application/json" \ + --data "{\"type\":\"A\",\"name\":\"${SUBDOMAIN}\",\"content\":\"${HOME_SERVER_IP}\",\"ttl\":1,\"proxied\":false}" | jq -r '.success') + + if [[ "${CREATION_STATUS}" == "true" ]]; then + echo " ✅ Successfully create a DNS record for ${SUBDOMAIN}" + else + echo -e " ❌ Failed to create a DNS record for ${SUBDOMAIN}. Check documentation to \n + learn how you can create them manually." + fi + } + + erase_records() { + local SUBDOMAIN="${1}" + local DELETION_STATUS + + gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 " + ⚠️ $(gum style --foreground 212 'WARNING:') One or more existing type A DNS records found for \`${SUBDOMAIN}\`. + This script can clear those DNS records for you and create the correct ones needed for the server. + If you are unsure that these records are actually in use, please select \"no\"." + gum confirm "Select \"yes\" to clear ALL EXISTING type A DNS records for this subdomain and automatically create the correct ones." \ + || { echo -e "\n ⚠️ DNS records for ${SUBDOMAIN} will not be updated"; return 0; } + + RECORD_IDS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${SUBDOMAIN}&type=A" \ + -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ + -H "Content-Type: application/json" | jq -r '.result[].id') + + for id in ${RECORD_IDS}; do + curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${id}" \ + -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ + -H "Content-Type: application/json" > /dev/null 2>&1 + done + + create_records "${SUBDOMAIN}" + } + + echo -e "\n\n ☁️ Configuring Cloudflare DNS records..." + + # Get Zone ID ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=${DOMAIN_NAME}" \ -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ -H "Content-Type: application/json" | jq -r '.result[0].id') if [[ "${ZONE_ID}" == "null" || -z "${ZONE_ID}" ]]; then - echo -e "\n\n⚠️ Could not fetch Zone ID for ${DOMAIN_NAME}. Please check your Cloudflare \"DNS ZONE\" API token" - echo "Check out the Numbus-Server documentation to see out to get one." + echo -e "\n\n ⚠️ Could not fetch Zone ID for ${DOMAIN_NAME}. Please check your Cloudflare \"DNS ZONE\" API token" + echo "Check the Numbus-Server documentation to learn how to get one." fi - # 2. Iterate services - for service in "${SELECTED_SERVICES[@]}"; do - if [[ "${service}" == "virtualization" ]]; then continue; fi - - local SUBDOMAIN="${service}.${DOMAIN_NAME}" - echo -n " - Checking for existing record : ${SUBDOMAIN}..." - - # Check existence - local RECORD_ID - RECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${SUBDOMAIN}&type=A" \ + # Check for existing records and create them if non-existent + for service_domain in "${SELECTED_SERVICES_DNS[@]}"; do + DNS_RECORDS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${service_domain}&type=A" \ -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ - -H "Content-Type: application/json" | jq -r '.result[0].id') + -H "Content-Type: application/json") - if [[ "${RECORD_ID}" != "null" && -n "${RECORD_ID}" ]]; then - RECORD_ID_CONTENT=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=${SUBDOMAIN}&type=A" \ - -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ - -H "Content-Type: application/json" | jq -r '.result[0].content') - if [[ "${RECORD_ID_CONTENT}" == "${HOME_SERVER_IP}" ]]; then - echo " ✅ Already configured" - else - echo " ⚠️ A DNS record is configured but does not point to the correct IP" - echo "Do you want to update it? It could break past DNS record you defined" - fi - else - echo -n " ⏳ Creating..." - local CREATE_RES - CREATE_RES=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \ - -H "Authorization: Bearer ${CF_DNS_API_TOKEN}" \ - -H "Content-Type: application/json" \ - --data "{\"type\":\"A\",\"name\":\"${SUBDOMAIN}\",\"content\":\"${HOME_SERVER_IP}\",\"ttl\":1,\"proxied\":false}" | jq -r '.success') + RECORD_COUNT=$(echo "${DNS_RECORDS}" | jq '.result | length') - if [[ "${CREATE_RES}" == "true" ]]; then - echo " ✅ Created." + if [[ "${RECORD_COUNT}" -eq 0 ]]; then + echo -e "\n ⚠️ No DNS record found for ${service_domain}" + create_records "${service_domain}" + elif [[ "${RECORD_COUNT}" -eq 1 ]]; then + if [[ $(echo "${DNS_RECORDS}" | jq ".result[0].content == \"${HOME_SERVER_IP}\"") == "true" ]]; then + echo -e "\n ✅ DNS record already configured for ${service_domain}" else - echo " ❌ Failed." + echo -e "\n ⚠️ No DNS record found for ${service_domain}" + erase_records "${service_domain}" fi + elif [[ "${RECORD_COUNT}" -gt 1 ]]; then + erase_records "${service_domain}" fi done } diff --git a/templates/nix-config/configuration.nix b/templates/nix-config/configuration.nix index 053e3a8..fbeda87 100644 --- a/templates/nix-config/configuration.nix +++ b/templates/nix-config/configuration.nix @@ -44,7 +44,7 @@ boot.initrd.systemd.enable = true; boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; - boot.swraid.mdadmConf = "MAILADDR ${config.email.toAddress}"; + boot.swraid.mdadmConf = "MAILADDR ${config.email.userAddress},${config.email.adminAddress}"; # boot.initrd.systemd.tpm2.enable = true; # TPM2 PCR check diff --git a/templates/nix-config/misc/mail.nix b/templates/nix-config/misc/mail.nix index 36792cb..4fcfa67 100644 --- a/templates/nix-config/misc/mail.nix +++ b/templates/nix-config/misc/mail.nix @@ -13,7 +13,7 @@ in type = lib.types.str; default = "no-reply@DOMAIN_NAME"; }; - toAddress = lib.mkOption { + userAddress = lib.mkOption { description = "The 'to' address"; type = lib.types.str; default = "EMAIL_ADDRESS"; @@ -47,8 +47,8 @@ in config = lib.mkIf cfg.enable { environment.etc."aliases".text = '' - root: ${config.email.toAddress}, ${config.email.adminAddress} - default: ${config.email.toAddress}, ${config.email.adminAddress} + root: ${config.email.userAddress}, ${config.email.adminAddress} + default: ${config.email.userAddress}, ${config.email.adminAddress} ''; programs.msmtp = { diff --git a/templates/nix-config/misc/smart.nix b/templates/nix-config/misc/smart.nix index 019f7e6..e352a7c 100644 --- a/templates/nix-config/misc/smart.nix +++ b/templates/nix-config/misc/smart.nix @@ -10,6 +10,7 @@ let TECH_BODY=" SMARTD Alert Details: + Server owner: $OWNER_NAME Device: $SMARTD_DEVICE Type: $SMARTD_DEVICETYPE Failure Type: $SMARTD_FAILTYPE @@ -22,17 +23,23 @@ let # 2. Send Friendly Email to Owner OWNER_NAME=$(cat /etc/numbus-server/owner 2>/dev/null || echo "User") - USER_EMAIL="${config.email.toAddress}" + USER_EMAIL="${config.email.userAddress}" - FRIENDLY_BODY="Hello $OWNER_NAME, + FRIENDLY_BODY="Cher/Chère $OWNER_NAME, - We detected a potential hardware issue on your server ($SMARTD_DEVICE). - Don't panic! The administrator has been notified and received the technical details. - They will contact you if any action is required on your part. + Votre serveur a automatiquement détecté une panne matérielle de disque dur. + Ce genre de panne est tout à fait normal selon l'âge de votre matériel et n'entraîne + dans la grande majorité des cas aucune perte de données grâce au système de + stockage redondant préventif. - Your Numbus Server" + Votre administrateur a été notifié de cette panne. Il vous recontactera dans de très + brefs délais afin de procéder au remplacement, si nécessaire, du disque dur défaillant. + + Merci de votre confiance, + L'équipe de support, + Numbus-Server." - printf "Subject: [Alert] Hardware check on your server\n\n$FRIENDLY_BODY" | /run/wrappers/bin/sendmail -t "$USER_EMAIL" + printf "Subject: [Alerte] Défaillance matérielle sur votre serveur Numbus\n\n$FRIENDLY_BODY" | /run/wrappers/bin/sendmail -t "$USER_EMAIL" ''; in { @@ -47,7 +54,7 @@ in mail = { enable = true; sender = config.email.fromAddress; - recipient = "${config.email.toAddress},${config.email.adminAddress}"; + recipient = "${config.email.userAddress},${config.email.adminAddress}"; }; }; };