Removed a lot of unnecessary code. Now all configuration is done through the browser. Need to work more on the deployment process.

This commit is contained in:
Raphaël Numbus
2026-05-15 22:23:49 +02:00
parent 522ee16611
commit 4ca5ae5c8f
+21 -318
View File
@@ -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 ---<