From 4ca5ae5c8f39fb0d012be39ae294f12a30babbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Numbus?= Date: Fri, 15 May 2026 22:23:49 +0200 Subject: [PATCH] Removed a lot of unnecessary code. Now all configuration is done through the browser. Need to work more on the deployment process. --- script/deploy.sh | 339 +++-------------------------------------------- 1 file changed, 21 insertions(+), 318 deletions(-) diff --git a/script/deploy.sh b/script/deploy.sh index 6c9cc6d..3f84101 100755 --- a/script/deploy.sh +++ b/script/deploy.sh @@ -238,118 +238,12 @@ launch_gui() { sleep 5 echo -e "\n ➡️ If it doesn't automatically, open your browser at: $(gum style --foreground 212 "http://localhost:${WEBSERVER_PORT}")" - } # --- MAIN WEB FUNCTIONS ---< # --- MAIN TUI FUNCTIONS ---> -preparation() { - echo -e "\n ➡️ This script will now guide you through the configuration and gather the necessary information." - - echo "" - RAW_DEVICE_TYPE=$(gum choose --header "Choose the device you want to deploy :" \ - "Numbus Server : Professional-grade hosting, strictly kept under your roof." \ - "Numbus Backup Server : Automated, high-efficiency protection for your entire ecosystem." \ - "Numbus Computer : A modern, privacy-respecting machine built for work, creation, and play — without the corporate bloat." \ - "Numbus TV : A premium cinematic experience free from trackers and forced subscriptions." \ - "Numbus Game Console : An unbreakable Steam bigscreen experience.") - - case "${RAW_DEVICE_TYPE}" in - "Numbus Server : "* ) DEVICE_TYPE="server" ;; - "Numbus Backup Server : "* ) DEVICE_TYPE="backup" ;; - "Numbus Computer : "* ) DEVICE_TYPE="computer" ;; - "Numbus TV : "* ) DEVICE_TYPE="tv" ;; - "Numbus Game Console : "* ) DEVICE_TYPE="console" ;; - esac - - RAW_DEPLOYMENT_MODE=$(gum choose --header "Choose your preferred deployment mode :" \ - "Interactive : You don't already have a configuration." \ - "Non-interactive : You have a valid configuration hosted on a Git platform.") - - case "${RAW_DEPLOYMENT_MODE}" in - "Interactive : "* ) DEPLOYMENT_MODE="interactive" ;; - "Non-interactive : "* ) DEPLOYMENT_MODE="non-interactive" ;; - esac - - if [[ "${DEPLOYMENT_MODE}" == "non-interactive" ]]; then - git_url() { - IMPORTED_CONFIG_URL=$(gum input --placeholder "https://yourgitplatform.tld/your-user/repo-containing-the-configuration" --header "Please provide the URL to the git repository containing your configuration :") - } - - git_url - - until git clone "${IMPORTED_CONFIG_URL}" imported_configuration; do - echo -e "\n ⚠️ This did not work correctly." - - echo -e "\n Is this URL correct [y/n] ? ${IMPORTED_CONFIG_URL}" - read URL - - if [[ "${URL^^}" == "N" ]]; then - git_url - fi - - echo -e "\n You will be prompted for your credentials again. Make sure that they are correct." - done - fi - - echo "" - gum format -- \ - "➡️ To continue, you need to start the target device in a NixOS live environment : - 1. Download the NixOS iso from the **[official website](https://nixos.org/download/)**. - 2. Flash it to a USB stick. (use a flashing tool like **[Rufus](https://rufus.ie/en/#download)**, **[BalenaEtcher](https://etcher.balena.io/#download-etcher)**, **[Impression](https://flathub.org/en/apps/io.gitlab.adhami3310.Impression)**, ...) - 3. Make sure your computer allows booting from USB drives and is in UEFI mode. - 4. Boot into the NixOS live environment. - 5. Launch a terminal. Set a password using \`passwd\` and find the IP address using \`ip a\`" - - echo "" - gum confirm "Is the device ready ?" || { echo "❌ You need to prepare the device. The script cannot continue."; exit 1; } - - # LIVE TARGET SETTINGS - user_input "LIVE_TARGET_IP" " Please provide the IP address of the target host :" "For example : 192.168.1.100" "${IP_REGEX}" - user_input "LIVE_TARGET_PASSWORD" " Please enter the password for '${TARGET_USER}@${LIVE_TARGET_IP}' :" "${LIVE_TARGET_IP}'s password" "" "" "true" - - # INTERNATIONALIZATION SETTINGS - user_input "INTERNATIONALIZATION_TIMEZONE" " Please provide the wanted timezone :" "For example : Europe/Paris, Europe/Berlin, Europe/London, etc" - user_input "INTERNATIONALIZATION_LANGUAGE" " Please provide the wanted language :" "For example : French, Deutsch, English, etc" - user_input "INTERNATIONALIZATION_COUNTRY" " Please provide your country :" "For example : France, Germany, Great-Britain, etc" -} - -configuration() { - if [[ "${DEVICE_TYPE}" == "server" ]]; then - - # Users & Groups - user_input "SERVER_OWNER_NAME" " Please provide the name of the owner of this server :" "For example : Steve" - user_input "SERVER_ADMIN_EMAIL" " Please provide a valid ADMIN email address (ACME, system failures notifications, etc) :" "For example : myemail@mydomain.mytld" "${EMAIL_REGEX}" - user_input "AUTHORIZED_SSH_PUBLIC_KEY" " Please provide the SSH public key of an authorized device (or a comma-separated list) :" "For example : ssh-ed25519 AAAAC3Nzam0uYewNAbxL8Fci8 user@your-pc or ssh-* * *, ssh-* * *, etc" "${SSH_KEY_REGEX}" "Invalid SSH key format (must start with ssh-...)." - - echo -e "\n\n ➡️ You will access your services via a domain name (e.g. cloud.mydomain.com) and containers need credentials to create those subdomains" - # TRAEFIK SETTINGS - user_input "DOMAIN_NAME" " Please provide the domain name (FQDN) your home server will use :" "For example : yourdomain.com" "${DOMAIN_REGEX}" - user_input "CLOUDFLARE_DNS_API_TOKEN" " Please provide a cloudflare API token with DNS zone permission :" "For example : bA7hdvCOuXGytlNKohi3ZGtlVpf5CHpLuCMiJrE" "" "" "true" - - echo -e "\n\n ➡️ Some services will be able to send you emails. For that you need an email that supports sending emails (like Gmail for example)" - # SMTP SETTINGS - user_input "SMTP_SERVER_USERNAME" " Please provide a valid sender email address :" "For example : myemail@gmail.com" "${EMAIL_REGEX}" - user_input "SMTP_SERVER_PASSWORD" " Please provide the password of this email address :" "abcd efgh ijkl mnop" "" "" "true" - user_input "SMTP_SERVER_HOST" " Please provide the SMTP server endpoint :" "For Gmail : smtp.gmail.com" "${DOMAIN_REGEX}" "Invalid domain name format." - user_input "SMTP_SERVER_PORT" " Please provide the smtp TLS port :" "For Gmail : 587" "${PORT_REGEX}" "Invalid port number." - - echo -e "\n\n ➡️ This server will connect to your local network and you will configure its IP address\n" - # NETWORK SETTINGS - user_input "NETWORK_SUBNET" " Please provide your network subnet :" "For example 192.168.1.0/24" "${SUBNET_REGEX}" "Invalid subnet format (e.g. 192.168.1.1/24)." - user_input "NETWORK_ROUTER_IP" " Please provide the ip address of your router :" "Most likely 192.168.1.1 or 192.168.1.254" "${IP_REGEX}" "Invalid IP address format." - user_input "HOME_SERVER_IP" " Please choose the ip address that your server will use (i.e. any address in the 192.168.1.1/24 range that is not in use.) :" "For example 192.168.1.5" "${IP_REGEX}" "Invalid IP address format." - elif [[ "${DEVICE_TYPE}" == "backup" ]]; then - : - elif [[ "${DEVICE_TYPE}" == "computer" ]]; then - : - elif [[ "${DEVICE_TYPE}" == "tv" ]]; then - : - fi -} - setup_ssh() { echod "\n ✅ Generating new SSH key for numbus-admin..." @@ -370,125 +264,6 @@ setup_ssh() { fi } -services_selection() { - services_choice() { - local SERVICES_LIST=( "${1[@]}" ) - local SERVICES_DESCRIPTION=( "${2[@]}" ) - local FINAL_VARIABLE="${3}" - local HEADER="${4}" - local LIMIT="${5:---no-limit}" - - local SELECTED_SERVICES=() - local SELECTED_SERVICES_DESCRIPTION=() - - local SELECTED_SERVICES_DESCRIPTION=$(gum choose ${LIMIT} --header "${HEADER}" "${SERVICES_DESCRIPTION[@]}") - - for i in ${!SERVICES_LIST[@]}; do - if printf '%s' "${SELECTED_SERVICES_DESCRIPTION}" | grep -iq "${SERVICES_LIST[${i}]}"; then - SELECTED_SERVICES+=("${SERVICES_LIST[${i}]}") - fi - done - - export "${FINAL_VARIABLE}=(${SELECTED_SERVICES[@]})" - } - - echo -e "\n\n ➡️ You will now select the services you want installed on your server:" - - services_choice "${DNS_SERVICES_LIST[@]}" "${DNS_SERVICES_DESCRIPTION[@]}" "SELECTED_DNS_SERVICE" "Choose your preferred DNS service :" "--limit=1" - services_choice "${WEB_APPLICATIONS_LIST[@]}" "${WEB_APPLICATIONS_DESCRIPTION[@]}" "SELECTED_WEB_APPLICATIONS" "Choose the web applications you want to install :" - services_choice "${SYSTEM_SERVICES_LIST[@]}" "${SYSTEM_SERVICES_DESCRIPTION[@]}" "SELECTED_SYSTEM_SERVICES" "Choose the system services you want to install :" - - gum confirm "Do you want to edit the default subdomain of your services ?" || { echo -e "\n\n✅ Continuing..."; return 0; } - - for service in ${SELECTED_WEB_APPLICATIONS[@]} ${SELECTED_DNS_SERVICE[@]}; do - if gum confirm "Change the subdomain of ${service} ?"; then - SELECTED_WEB_APPLICATIONS_SUBDOMAIN+=( "$(gum input --placeholder "${service}" --header "Please provide the desired subdomain for ${service}:")" ) - fi - done - - return 0 -} - -disks_selection() { - gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 " - ⚠️ $(gum style --foreground 212 'WARNING:') You will choose the disks to install NixOS on. - !! PLEASE MAKE SURE YOU BACKED UP ANY IMPORTANT DATA !! - !! 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; } - - echo -e "\n\n 🔎 Fetching and analyzing disks from target host... (This may take a moment)" - - if [[ "${#DISK_NAME[@]}" -eq 0 ]]; then - echo -e "\n❌ No disks found on the target host. Aborting." - exit 1 - fi - - local HEADER=$(printf " %-12s %-12s %-12s %-12s %s" "Device" "Type" "Size" "SMART" "Path") - - for i in ${!DISK_NAME[@]}; do - 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}") - 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[@]}") - - for i in ${!DISK_NAME[@]}; do - if printf '%s' "$SELECTED_BOOT_DISK" | grep -iqw "${DISK_NAME[${i}]}"; then - BOOT_DISKS_ID_LIST+=("\"${DISK_ID[${i}]:-${DISK_DEVPATH[${i}]}}\"") - BOOT_DISKS_NAME+=("${DISK_NAME[${i}]}") - unset "GUM_PRINTED_ELEMENTS[${i}]" - fi - done - - echo "" - gum style --foreground 212 "➡️ Please choose data and parity disks (up to 9 total) :" - - local SELECTED_DATA_DISK=$(gum choose --limit 9 --header "$HEADER" "${GUM_PRINTED_ELEMENTS[@]}") - - for i in ${!DISK_NAME[@]}; do - if printf '%s' "$SELECTED_DATA_DISK" | grep -iq "${DISK_NAME[${i}]}"; then - DATA_DISKS_ID+=("${DISK_ID[${i}]:-${DISK_DEVPATH[${i}]}}") - DATA_DISKS_TYPE+=("${DISK_TYPE[${i}]}") - fi - done - - if [[ "${#DATA_DISKS_ID[@]}" -eq 1 ]]; then - export PARITY_DISK_NUMBER=0 - export CONTENT_DISK_NUMBER=1 - export PARITY_DISK_LIST=() - export CONTENT_DISK_LIST=("\"${DATA_DISKS_ID[0]}\"") - else - export PARITY_DISK_NUMBER=$(((${#DATA_DISKS_ID[@]} + 2) / 3)) - export CONTENT_DISK_NUMBER=$((${#DATA_DISKS_ID[@]} - PARITY_DISK_NUMBER)) - for i in $(seq 0 $(($CONTENT_DISK_NUMBER - 1))); do - CONTENT_DISK_LIST+=("\"${DATA_DISKS_ID[${i}]}\"") - done - for i in $(seq $CONTENT_DISK_NUMBER $((${#DATA_DISKS_ID[@]} - 1))); do - PARITY_DISK_LIST+=("\"${DATA_DISKS_ID[${i}]}\"") - done - fi - - if [[ "${#DATA_DISKS_ID[@]}" -gt 0 ]]; then - for i in ${!DATA_DISKS_ID[@]}; do - if [[ "${DATA_DISKS_TYPE[${i}]}" == "HDD" ]]; then - SPINDOWN_DISKS_LIST+=("\"${DATA_DISKS_ID[${i}]}\"") - fi - done - fi - - export SPINDOWN_DISKS_LIST - export BOOT_DISKS_ID_LIST - export PARITY_DISK_LIST - export CONTENT_DISK_LIST -} - server_config_generation() { echod "\n 📝 Generating structured settings.json..." @@ -616,87 +391,6 @@ EOF --output ${EXTRA_FILES_PATH}/etc/nixos/secrets/secrets.yaml } -sum_up() { - DISK_RECAP_CONTENT=$(cat << EOF -### Disk Configuration Summary - -Please review the selected disk layout before proceeding. - -**Boot Disks (${#BOOT_DISKS_ID_LIST[@]}) :** - -* **Boot 1:** \`${BOOT_DISKS_ID_LIST[0]}\` -$( [[ -n "${BOOT_DISKS_ID_LIST[1]:-}" ]] && echo "* **Boot 2:** \`${BOOT_DISKS_ID_LIST[1]}\`" ) - -**Data Disks ($CONTENT_DISK_NUMBER) :** - -$( [[ $CONTENT_DISK_NUMBER -gt 0 ]] && j=1 && for i in $(seq 0 $(($CONTENT_DISK_NUMBER - 1))); do echo "* **Data ${j}:** \`${DATA_DISKS_ID[${i}]}\`" && j=$((j + 1)); done ) -$( [[ $CONTENT_DISK_NUMBER -eq 0 ]] && echo "* *Not configured*" ) - -**Parity Disks ($PARITY_DISK_NUMBER) :** - -$( [[ $PARITY_DISK_NUMBER -gt 0 ]] && j=1 && for i in $(seq $CONTENT_DISK_NUMBER $((${#DATA_DISKS_ID[@]} - 1))); do echo "* **Parity ${j}:** \`${DATA_DISKS_ID[${i}]}\`" && j=$((j + 1)); done ) -$( [[ $PARITY_DISK_NUMBER -eq 0 ]] && echo "* *Not configured*" ) - -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; } - - SERVICES_RECAP_CONTENT=$(cat << EOF -### Services Configuration Summary - -Please review the selected services before proceeding. - -**DNS Service (${#SELECTED_DNS_SERVICE[@]}) :** - -$(echo "* \`${SELECTED_DNS_SERVICE[0]^}\`") - -**Web Applications (${#SELECTED_WEB_APPLICATIONS[@]}) :** - -$(for app in "${SELECTED_WEB_APPLICATIONS[@]}"; do echo "* \`${app^}\`"; done) - -**System Services (${#SELECTED_SYSTEM_SERVICES[@]}) :** - -$(for service in "${SELECTED_SYSTEM_SERVICES[@]}"; do echo "* \`${service^}\`"; done) - -EOF -) - - gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "$(gum format <<< "${SERVICES_RECAP_CONTENT}")" - gum confirm "➡️ Proceed with this services configuration?" || { echo -e "\n\n❌ Aborting as requested."; exit 1; } - - DISK_RECAP_CONTENT=$(cat << EOF -### Secrets Summary - -Please save the following secrets to a secure place (i.e. your local password manager, or a hidden sheet of paper). - -**Boot Disks (${#BOOT_DISKS_ID_LIST[@]}) :** - -* **Disk 1 Secret Key :** \`$( cat ${EXTRA_FILES_PATH}/etc/secrets/disks/boot-1 )\` -$( [[ -n "${BOOT_DISKS_ID_LIST[1]:-}" ]] && echo "* **Disk 2 secret key :** \`$( cat ${EXTRA_FILES_PATH}/etc/secrets/disks/boot-2 )\`" ) - -**Data Disks ($CONTENT_DISK_NUMBER):** - -$( [[ $CONTENT_DISK_NUMBER -eq 0 ]] && echo "* *Not configured*" ) -$( [[ $CONTENT_DISK_NUMBER -gt 0 ]] && j=1 && for i in $(seq 0 $(($CONTENT_DISK_NUMBER - 1))); do echo "* **Disk ${j} Secret Key :** \`$( cat ${EXTRA_FILES_PATH}/etc/secrets/disks/content-${j} )\`" && j=$((j + 1)); done ) - -**Parity Disks ($PARITY_DISK_NUMBER):** - -$( [[ $PARITY_DISK_NUMBER -eq 0 ]] && echo "* *Not configured*" ) -$( [[ $PARITY_DISK_NUMBER -gt 0 ]] && j=1 && for i in $(seq $CONTENT_DISK_NUMBER $((${#DATA_DISKS_ID[@]} - 1))); do echo "* **Disk ${j} Secret Key :** \`$( cat ${EXTRA_FILES_PATH}/etc/secrets/disks/parity-${j} )\`" && j=$((j + 1)); done ) - -EOF -) - - gum style --border normal --margin "1" --padding "1 2" --border-foreground 212 "$(gum format <<< "${DISK_RECAP_CONTENT}")" - gum confirm "✅ I have stored these credentials in a safe place" || { echo -e "\n\n❌ Please store these credentials in a safe place as you will need them later."; exit 1; } - - gum confirm "➡️ Would you like to manually edit the configuration (⚠️ advanced users only)" || { echo -e "\n\n✅ continuing with the installation..."; return 0; } - - nano ${EXTRA_FILES_PATH}/etc/nixos/configuration.nix -} - cloudflare_dns_setup() { gum confirm "➡️ This script can automatically create DNS records for your services. Proceed? (recommended)" || { echo -e "\n\n ⚠️ skipping the DNS records creation step..."; return 0; } @@ -914,9 +608,8 @@ securely on a hidden sheet of paper or add it to your password manager (locally # --- DEFAULT VARIABLES ---> WEBSERVER_PORT=${WEBSERVER_PORT:-8088} -LIVE_DATA_PATH="/run/user/$(id -u)/numbus/web/live_settings.json" -HARDWARE_DATA_PATH="/run/user/$(id -u)/numbus/web/hardware.json" - +LIVE_DATA_FILE="../config/live.yaml" +HW_DATA_FILE="../config/hardware.yaml" CONFIG_FILE="../config/numbus.yaml" TARGET_USER="nixos" @@ -978,15 +671,25 @@ DEPLOYMENT_STRATEGY=$(gum choose --header "Choose your preferred deployment stra if [[ "${DEPLOYMENT_STRATEGY}" == "I don't have a configuration" ]]; then BRIDGE_SCRIPT="../web/logic/interactive.py" launch_gui + hierarchy_preparation + until [[ -e ../web/signals/hw_detection_ready ]]; do + sleep 5 + done + LIVE_TARGET_IP="$(yq -r '.live_target_ip' ${LIVE_DATA_FILE})" + LIVE_TARGET_PASSWORD="$(yq -r '.live_target_password' ${LIVE_DATA_FILE})" + until [[ -e ../web/signals/configuration_ready ]]; do + done + until [[ -e ../web/signals/deployment_ready ]]; do + done else - DEPLOYMENT_MODE=$(gum choose --header "Choose your preferred deployment mode :" \ - "Through my web browser (Recommended for beginners)" \ - "Through my terminal (TUI)") - if [[ "${DEPLOYMENT_MODE}" == "Through my web browser (Recommended for beginners)" ]]; then - BRIDGE_SCRIPT="../web/logic/non-interactive.py" - launch_gui - else - launch_tui - fi + BRIDGE_SCRIPT="../web/logic/non-interactive.py" + launch_gui + hierarchy_preparation + until [[ -e ../web/signals/hw_detection_ready ]]; do + done + until [[ -e ../web/signals/hw_detection_ready ]]; do + done + until [[ -e ../web/signals/hw_detection_ready ]]; do + done fi # --- MAIN LOGIC ---< \ No newline at end of file