Comments: style plus concis (calé sur modules/anssi/, écrit par des pros)

Aucun changement fonctionnel -- juste les commentaires : essais de
justification en plusieurs paragraphes remplacés par des notes courtes,
type/quoi/pourquoi en une ou deux lignes. Corrige au passage un
commentaire obsolète dans installer-base.nix qui décrivait encore l'usage
de disko-install (abandonné depuis pour disko + nixos-install séparés).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 17:42:51 +02:00
co-authored by Claude Sonnet 5
parent bfd7ed4eed
commit fddcca0e51
5 changed files with 87 additions and 180 deletions
+44 -79
View File
@@ -1,47 +1,37 @@
# 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.
# 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 "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.
# 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.
# 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
# Installe en 4 étapes séparées (clone -> 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 RAM limitée
# (wiki.nixos.org/wiki/Swap, manuel NixOS section installation).
# 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 car la commande `disko` seule (contrairement
# à `disko-install`) n'a AUCUN mécanisme de substitution de disque nommé
# (`--disk`/diskMappings n'existe que dans install-cli.nix, utilisé
# uniquement par disko-install — vérifié dans le code source de
# nix-community/disko : fichiers disko, disko-install, cli.nix). On substitue
# donc le vrai disque directement dans une copie locale du fichier disko
# avec sed, puis on pointe `disko` ET `nixos-install` sur ce même clone
# (chemin local, pas l'URL distante) pour que le partitionnement et le
# système construit restent cohérents entre eux.
# 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"
@@ -58,21 +48,16 @@ do_install() {
sed -i "s#/dev/placeholder#$DEVICE#" "$repo_dir/$disko_rel_path"
echo "Partitionnement de $DEVICE..."
# --yes-wipe-all-disks : évite la confirmation interactive "type yes to
# continue" (vu dans le code source de la commande disko) — un install
# de flotte ne doit pas dépendre de quelqu'un présent au clavier pour
# confirmer, l'effacement est le but assumé de ce script.
# --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)..."
# Sur btrfs (notre système de fichiers), le CoW doit être désactivé
# (chattr +C) AVANT toute écriture de données dans le fichier, sinon
# swapon échoue avec "Invalid argument" (source : btrfs.readthedocs.io/
# en/latest/Swapfile.html — chattr +C sur un fichier déjà écrit ne
# s'applique pas rétroactivement).
# 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
@@ -81,49 +66,32 @@ do_install() {
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é. --flake pointe sur
# le clone local (avec le disque déjà substitué), pas l'URL distante,
# pour rester cohérent avec ce qui a été partitionné.
# --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
# Sans cette étape, la machine installée n'a AUCUNE config sur son
# disque : le clone ci-dessus vit dans /tmp de l'environnement live, en
# RAM, effacé au reboot. La convergence auto (system.autoUpgrade, voir
# hosts/common/base.nix) continue de fonctionner sans ça (elle pointe
# sur l'URL distante), mais un technicien qui arrive sur la machine
# après coup n'a alors ni /etc/nixos, ni moyen d'ajouter/enlever un
# paquet à la main. On installe donc le même clone (déjà substitué avec
# le vrai disque) à l'emplacement standard NixOS, en conservant .git
# pour que `git pull`/`git log` marchent dessus normalement ensuite.
# 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
# Une machine installée n'a besoin que de ce qui sert à rebuild/pull :
# flake.nix/flake.lock, hosts/, modules/ et les fichiers de conf disko
# (diskos/). installer/ (le script d'install lui-même, obsolète une
# fois l'install faite) et pxe-server/ (la config d'un tout autre host,
# le serveur PXE) n'ont rien à faire sur un poste client -- ça ne
# concerne que nixos_fleet (nixos_users n'a ni l'un ni l'autre, ces rm
# ne trouvent alors rien à supprimer). Nix ne lit ces fichiers que si on
# build l'attribut correspondant (#installer-netboot, #pxe-server) --
# jamais le cas ici (#usagers ou un profil nommé), donc rien ne casse.
# 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
# Le disque cible a été substitué localement (sed plus haut), et
# installer/+pxe-server/ viennent d'être retirés : tout ça diffère donc
# de ce qui est sur git. On le committe en local (jamais poussé) pour
# que `git status` reste propre sur la machine installée -- sinon
# chaque `git pull` ultérieur affiche des fichiers modifiés/supprimés,
# source de confusion pour un technicien.
# 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" \
@@ -138,9 +106,8 @@ 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.
# 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 < <(
@@ -164,14 +131,12 @@ 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" "diskos/plain.nix"
;;
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
@@ -191,8 +156,8 @@ case "$CHOICE" in
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.
# 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
@@ -204,13 +169,13 @@ case "$CHOICE" in
fi
do_install "$AUTHED_URL" "$ATTR" "$DISKO_REL_PATH"
# 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).
# 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 —
# 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
{
+15 -34
View File
@@ -1,7 +1,7 @@
# Environnement live commun aux deux formes d'image (PXE netboot / ISO
# USB). Contient juste de quoi partitionner et lancer disko-install ; la
# vraie configuration cible est toujours récupérée depuis git au moment
# de l'install (repo public nixos_fleet ou repo privé nixos_users).
# USB). Contient juste de quoi partitionner et installer ; la config
# cible est toujours récupérée depuis git au moment de l'install (repo
# public nixos_fleet ou repo privé nixos_users).
{ pkgs, lib, ... }:
let
@@ -13,22 +13,13 @@ in
"flakes"
];
# netboot.nix définit DEUX tmpfs distincts, ni l'un ni l'autre avec une
# taille explicite -> plafonnés à 50% de la RAM chacun par défaut :
# - "/" : la racine du système live lui-même (petite)
# - "/nix/.rw-store" : la vraie zone où atterrissent tous les nouveaux
# paquets téléchargés/construits pendant l'install
# (overlay au-dessus du squashfs .ro-store en
# lecture seule). C'est CELLE-LÀ qui sature en
# premier sur un système complet (Cinnamon +
# Firefox + LibreOffice + VLC...), pas "/".
#
# netboot.nix définit ces deux options via mkImageMediaOverride, qui vaut
# mkOverride 60 — une simple assignation ici (priorité 100 par défaut)
# est donc entièrement ignorée, pas fusionnée (constaté : le premier
# essai n'a eu aucun effet). Il faut lib.mkForce (priorité 50, plus
# fort que 60) pour vraiment gagner — et comme mkForce REMPLACE toute la
# liste plutôt que de la compléter, on remet mode=0755 dedans aussi.
# netboot.nix définit "/" et "/nix/.rw-store" (overlay où atterrissent
# les paquets téléchargés/construits pendant l'install) sans taille
# explicite -> 50% de la RAM chacun par défaut. .rw-store sature en
# premier sur un système complet (Cinnamon + Firefox + LibreOffice +
# VLC), pas "/". mkForce nécessaire : netboot.nix utilise
# mkImageMediaOverride (priorité 60), une assignation simple (100) est
# ignorée ; mkForce remplace toute la liste, d'où mode=0755 remis ici.
fileSystems."/".options = lib.mkForce [
"mode=0755"
"size=20%"
@@ -38,11 +29,9 @@ in
"size=90%"
];
# Certains PC du parc n'ont que 4 Go de RAM. Le disque cible ne peut pas
# servir de secours (disko-install l'efface entièrement en une seule
# opération, un swap posé dessus avant serait détruit en cours de
# route) : on utilise du swap compressé en RAM (zram) à la place, qui
# marche pareil en PXE et en USB sans dépendre d'un périphérique externe.
# Certains PC du parc n'ont que 4 Go de RAM. Le disque cible ne peut
# pas servir de secours ici (pas encore partitionné à ce stade) : swap
# compressé en RAM (zram), identique en PXE et en USB.
zramSwap = {
enable = true;
memoryPercent = 100; # jusqu'à 1x la RAM en swap compressé (~2-3x effectif)
@@ -57,22 +46,14 @@ in
installScript
];
# disko-install n'est pas préinstallé : install.sh l'invoque via
# `nix run github:nix-community/disko#disko-install`, ce qui évite de
# dépendre d'un nom de paquet nixpkgs précis (pas de package `disko`
# garanti tel quel côté nixpkgs) et reste conforme à l'usage documenté
# du projet.
networking.networkmanager.enable = true;
services.xserver.xkb.layout = "fr";
console.keyMap = "fr";
# Root autologin sur tty1, l'installeur se lance automatiquement au
# login. S'il échoue ou qu'on le quitte, on retombe sur un shell root
# normal pour dépanner à la main — pas de piège sans issue.
# login. Échec ou sortie -> shell root normal pour dépanner.
# mkForce : le profil installeur officiel (installation-device.nix)
# définit aussi cette option (autologin "nixos"), même priorité que la
# nôtre sans mkForce -> conflit sinon.
# définit aussi cette option, même priorité -> conflit sinon.
services.getty.autologinUser = lib.mkForce "root";
users.users.root.password = lib.mkForce "";