# Injecté comme corps de script par pkgs.writeShellScriptBin # (installer-base.nix) : pas de mode strict par défaut, d'où le `set` # explicite ci-dessous. set -euo pipefail # Installeur unique pour les deux repos : # - branche "flotte" -> nixos_fleet (public, jamais chiffré) # - branche "utilisateur nommé" -> nixos_users (privé, chiffrement au choix) # Le token du repo privé est saisi en direct, jamais stocké dans ce # fichier ni dans un repo git. FLEET_REPO="git+https://gitea.miniclic.net/Damien/Nixos_Fleet.git" USERS_REPO_HOST="gitea.miniclic.net" USERS_REPO_PATH="Damien/Nixos_Users.git" # Le script se lance dès le login (autologin), potentiellement avant que # NetworkManager ait fini de négocier le DHCP. echo "Attente du réseau..." for _ in $(seq 1 30); do ip route | grep -q '^default' && break sleep 1 done # 4 étapes séparées (clone -> partition -> swap sur le disque cible -> # build) plutôt qu'un seul `disko-install` : ce dernier construit tout # dans le tmpfs RAM de l'environnement live, qui sature sur les PC à # 4 Go avant même de toucher le disque cible. Le swapfile posé sur /mnt # donne accès au disque comme mémoire virtuelle pendant le build. # # Le clone local est nécessaire : `disko` seul (contrairement à # `disko-install`) n'a aucun mécanisme de substitution de disque nommé. # On substitue donc le vrai disque dans une copie locale du fichier # disko (sed), puis `disko` et `nixos-install` pointent tous les deux # sur ce même clone. do_install() { local remote_url="$1" # URL flake (git+https://...), pour cloner local attr="$2" local disko_rel_path="$3" # diskos/plain.nix ou diskos/luks.nix local repo_dir="/tmp/install-repo" local clone_url="${remote_url#git+}" # git clone ne comprend pas le préfixe git+ echo "Récupération de la config ($attr)..." rm -rf "$repo_dir" git clone --depth 1 "$clone_url" "$repo_dir" echo "Substitution du disque cible dans la config disko..." sed -i "s#/dev/placeholder#$DEVICE#" "$repo_dir/$disko_rel_path" echo "Partitionnement de $DEVICE..." # --yes-wipe-all-disks : évite la confirmation interactive, un install # de flotte ne doit dépendre de personne au clavier. nix run --no-write-lock-file --refresh 'github:nix-community/disko' -- \ --mode destroy,format,mount \ --yes-wipe-all-disks \ "$repo_dir/$disko_rel_path" echo "Swap temporaire sur le disque cible (RAM limitée sur certains PC du parc)..." # btrfs : chattr +C (NOCOW) doit précéder toute écriture dans le # fichier, sinon swapon échoue avec "Invalid argument". truncate -s 0 /mnt/.install-swapfile chattr +C /mnt/.install-swapfile fallocate -l 4G /mnt/.install-swapfile chmod 600 /mnt/.install-swapfile mkswap /mnt/.install-swapfile swapon /mnt/.install-swapfile echo "Construction et installation du système (peut prendre plusieurs minutes)..." # --no-root-passwd : le mot de passe root est déjà déclaré # (initialPassword) côté cible, on évite juste un prompt interactif. # --flake pointe sur le clone local (disque déjà substitué). nixos-install --root /mnt --flake "${repo_dir}#${attr}" --no-channel-copy --no-root-passwd swapoff /mnt/.install-swapfile rm -f /mnt/.install-swapfile # Persiste la config sur le disque cible : sans ça, le clone ne vit # que dans /tmp du live (RAM), effacé au reboot -- plus rien à éditer # ni à `git pull` ensuite. system.autoUpgrade continue de fonctionner # sans ça (il pointe sur l'URL distante), mais un technicien n'a alors # aucun accès local. echo "Installation de la configuration dans /mnt/etc/nixos..." rm -rf /mnt/etc/nixos mkdir -p /mnt/etc cp -a "$repo_dir" /mnt/etc/nixos # installer/ (script d'install, obsolète une fois fait) et # pxe-server/ (config d'un autre host) ne servent à rien sur un poste # client -- ne concerne que nixos_fleet, ces rm sont des no-op côté # nixos_users. rm -rf /mnt/etc/nixos/installer /mnt/etc/nixos/pxe-server # Committé en local (jamais poussé) pour que `git status` reste propre # sur la machine installée. git -C /mnt/etc/nixos \ -c user.name="Installeur Nixos_Fleet" \ -c user.email="installeur@nixos-fleet.local" \ commit -aqm "Config locale : disque substitué ($DEVICE), installer/pxe-server retirés (inutiles sur ce poste)" INSTALLED_ATTR="$attr" } echo "=== Installeur Nixos_Fleet ===" echo "1) PC de la flotte (générique)" echo "2) Poste utilisateur nommé" read -rp "Choix [1/2] : " CHOICE # --- Détection automatique du disque cible ------------------------------- # Exclut les disques amovibles (la clé USB de boot) et les loop/rom. # S'il en reste plusieurs, on prend le plus gros et on le signale. echo echo "Détection du disque cible..." mapfile -t CANDIDATES < <( lsblk -dn -b -o NAME,TYPE,RM,SIZE | awk '$2 == "disk" && $3 == 0 { print $4, $1 }' | sort -rn ) if [ "${#CANDIDATES[@]}" -eq 0 ]; then echo "Aucun disque fixe détecté. Abandon." >&2 exec bash fi DEVICE="/dev/$(echo "${CANDIDATES[0]}" | awk '{print $2}')" if [ "${#CANDIDATES[@]}" -gt 1 ]; then echo "ATTENTION : plusieurs disques fixes détectés, le plus gros a été retenu : $DEVICE" printf ' %s\n' "${CANDIDATES[@]}" else echo "Disque retenu : $DEVICE" fi case "$CHOICE" in 1) echo echo "Installation du profil générique 'usagers' sur $DEVICE..." do_install "$FLEET_REPO" "usagers" "diskos/plain.nix" ;; 2) read -rp "Utilisateur (thomas/clara/jade/oreo) : " USER_PROFILE USER_PROFILE=$(echo "$USER_PROFILE" | tr '[:upper:]' '[:lower:]' | xargs) case "$USER_PROFILE" in thomas|clara|jade|oreo) ;; *) echo "Utilisateur inconnu : $USER_PROFILE" >&2 exec bash ;; esac read -rp "Chiffrer le disque ? [o/N] : " ENCRYPT ATTR="$USER_PROFILE" if [[ "$ENCRYPT" =~ ^[oOyY] ]]; then ATTR="${USER_PROFILE}-luks" fi read -rsp "Token Gitea (repo privé Nixos_Users) : " TOKEN echo # Utilisé seulement en mémoire/ligne de commande pour ce fetch # ponctuel, jamais écrit dans un fichier suivi par git. AUTHED_URL="git+https://${TOKEN}@${USERS_REPO_HOST}/${USERS_REPO_PATH}" echo echo "Installation du profil '$ATTR' sur $DEVICE..." DISKO_REL_PATH="diskos/plain.nix" if [[ "$ATTR" == *-luks ]]; then echo "Disque chiffré : disko va demander une passphrase LUKS pendant le partitionnement." DISKO_REL_PATH="diskos/luks.nix" fi do_install "$AUTHED_URL" "$ATTR" "$DISKO_REL_PATH" # Netrc laissé pour que le système installé continue de tirer ses # mises à jour du repo privé tout seul (nix.settings.netrc-file # pointe vers ce même chemin côté nixos_users). Jamais commité, # jamais dans le Nix store. # # ATTENTION : le format exact attendu par Gitea (login=token vs # login+password séparés) dépend de la version/config du serveur -- # à vérifier sur l'instance réelle avant le déploiement pilote. mkdir -p /mnt/etc/nix { echo "machine ${USERS_REPO_HOST}" echo "login ${TOKEN}" echo "password x-oauth-basic" } > /mnt/etc/nix/netrc chmod 600 /mnt/etc/nix/netrc ;; *) echo "Choix invalide." >&2 exec bash ;; esac echo echo "Installation terminée." echo "Config installée dans /etc/nixos (attribut : ${INSTALLED_ATTR})." echo "Pour ajouter/enlever un paquet après le premier démarrage :" echo " 1. éditer les fichiers dans /etc/nixos" echo " 2. nixos-rebuild switch --flake /etc/nixos#${INSTALLED_ATTR}" echo "Redémarrage dans 10s (Ctrl-C pour annuler et inspecter /mnt)..." sleep 10 reboot