166 lines
6.3 KiB
Bash
166 lines
6.3 KiB
Bash
# Pas de shebang ici : ce fichier est injecté comme corps de script par
|
|
# pkgs.writeShellScriptBin dans installer-base.nix (qui ajoute juste
|
|
# `#!...`, PAS de mode strict — d'où le `set` explicite ci-dessous : sans
|
|
# lui, une erreur (ex: DNS indisponible) n'arrête pas le script, qui
|
|
# continuait jusqu'au reboot final en masquant l'échec.
|
|
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)
|
|
# Ce script ne contient aucun secret : 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. On attend une route par
|
|
# défaut avant de continuer (jusqu'à 30s), plutôt que d'échouer trop tôt.
|
|
echo "Attente du réseau..."
|
|
for _ in $(seq 1 30); do
|
|
ip route | grep -q '^default' && break
|
|
sleep 1
|
|
done
|
|
|
|
# Installe en 3 étapes séparées (partition -> swap sur le disque cible ->
|
|
# vrai build) au lieu d'un seul `disko-install`. Raison : disko-install
|
|
# fait tout d'un coup dans le tmpfs RAM de l'environnement live, qui sature
|
|
# sur les PC à peu de RAM (4 Go) avant même de toucher le disque cible.
|
|
# Un swapfile posé sur /mnt (une fois partitionné) donne accès aux ~200 Go
|
|
# du disque comme mémoire virtuelle pendant la vraie construction — méthode
|
|
# documentée officiellement pour les machines à RAM limitée, voir
|
|
# wiki.nixos.org/wiki/Swap et le manuel NixOS (section installation).
|
|
#
|
|
# Point non confirmé à 100% : que `disko` (seul, pas `disko-install`)
|
|
# accepte le même `--disk main <device>` que `disko-install`. La doc de
|
|
# référence de disko ne montre que `--argstr`, mais disko-install n'étant
|
|
# qu'un wrapper autour de disko, c'est très probable que ça marche pareil.
|
|
# Si la commande le refuse, l'erreur sera explicite.
|
|
do_install() {
|
|
local flake_url="$1"
|
|
local attr="$2"
|
|
|
|
echo "Partitionnement de $DEVICE..."
|
|
nix run --no-write-lock-file --refresh 'github:nix-community/disko' -- \
|
|
--mode destroy,format,mount \
|
|
--flake "${flake_url}#${attr}" \
|
|
--disk main "$DEVICE"
|
|
|
|
echo "Swap temporaire sur le disque cible (RAM limitée sur certains PC du parc)..."
|
|
dd if=/dev/zero of=/mnt/.install-swapfile bs=1M count=4096 status=none
|
|
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-channel-copy, --no-root-passwd : confirmés dans le man nixos-install
|
|
# (mankier.com/8/nixos-install, miroir du manuel officiel). Le mot de
|
|
# passe root est de toute façon déjà déclaré (initialPassword) dans la
|
|
# config cible, --no-root-passwd évite juste tout risque de prompt
|
|
# interactif qui bloquerait un install non surveillé.
|
|
nixos-install --root /mnt --flake "${flake_url}#${attr}" --no-channel-copy --no-root-passwd
|
|
|
|
swapoff /mnt/.install-swapfile
|
|
rm -f /mnt/.install-swapfile
|
|
}
|
|
|
|
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 -------------------------------
|
|
# On exclut les disques amovibles (la clé USB de boot elle-même) et les
|
|
# loop/rom. S'il en reste plusieurs (rare), on prend le plus gros et on le
|
|
# signale clairement dans les logs plutôt que de bloquer sur un menu.
|
|
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)
|
|
# --- Branche flotte : rien d'autre à saisir -----------------------
|
|
echo
|
|
echo "Installation du profil générique 'usagers' sur $DEVICE..."
|
|
do_install "$FLEET_REPO" "usagers"
|
|
;;
|
|
|
|
2)
|
|
# --- Branche utilisateur nommé -------------------------------------
|
|
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
|
|
|
|
# Le token n'est utilisé qu'en mémoire/ligne de commande pour ce fetch
|
|
# ponctuel : il n'est 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..."
|
|
if [[ "$ATTR" == *-luks ]]; then
|
|
echo "Disque chiffré : disko va demander une passphrase LUKS pendant le partitionnement."
|
|
fi
|
|
do_install "$AUTHED_URL" "$ATTR"
|
|
|
|
# Le système installé doit pouvoir continuer à tirer ses mises à jour
|
|
# du repo privé tout seul : on lui laisse un netrc, jamais commité,
|
|
# jamais dans le Nix store (nix.settings.netrc-file dans le repo
|
|
# nixos_users pointe vers ce même chemin).
|
|
#
|
|
# 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. Redémarrage dans 10s (Ctrl-C pour annuler et inspecter /mnt)..."
|
|
sleep 10
|
|
reboot
|