arch-system/docs/backup.md

7.3 KiB
Raw Blame History

Export système pour revue

scripts/backup.sh produit un candidat privé hors du dépôt. La commande sans argument ne met plus à jour pkglist/, inventory/, rootfs/ ni templates/ suivis par Git. Elle ne sauvegarde ni données personnelles, dotfiles, clés Secure Boot, connexions réseau, secrets, ni fichiers Trainlog. La zone locale d’export n’est pas une preuve de sauvegarde hors disque ou de restauration possible. Ce code n’a été testé ici que sur des fixtures.

Interface et destination

backup.sh [--output-dir REPERTOIRE_PARENT]
backup.sh --dry-run [--output-dir REPERTOIRE_PARENT]
backup.sh --help

--output-dir désigne un parent : chaque invocation crée un sous-répertoire unique. Par défaut, le parent est ${XDG_STATE_HOME:-$HOME/.local/state}/arch-system/exports. Un XDG_STATE_HOME relatif est ignoré avec diagnostic, selon la spécification XDG ; le chemin par défaut sous HOME est alors employé. Un parent explicite relatif est résolu depuis le répertoire courant. Les chemins sont normalisés ; la destination égale au dépôt ou située dedans, les alias vers celui-ci et les parents traversant un lien symbolique sont refusés. Un parent final existant doit appartenir à l’utilisateur et ne pas être ouvert au groupe ou aux autres. Les nouveaux répertoires sont créés privés, sans chmod/chown des ancêtres. Un parent contenant des espaces ou un antislash littéral reste accepté ; le calcul des empreintes ne dépend pas de la représentation de son nom.

--dry-run affiche les sources, les catégories obligatoire/facultatif, le parent et les transformations ; il ne crée rien et ne lance ni sudo, ni collecteur, ni demande de mot de passe. Il ne prouve pas la réussite des lectures futures. La collecte refuse une invocation en root ; les fichiers de sortie sont écrits par l’utilisateur sous umask 077. Les lectures privilégiées utilisent sudo -n, un contrôle d’état strict et seulement les sources explicitement autorisées. Aucun résultat n’est installé avec sudo.

Collecteurs et états

Classe Collecteurs Raison
Obligatoire pacman -Qqen, -Qqem ; unités système activées, en cours et timers ; lsblk, findmnt, /etc/fstab, Btrfs subvolumes/usage, mémoire et swap ; pacman.conf, makepkg.conf, mkinitcpio.conf Sans ces éléments, le candidat annoncé manquerait son noyau d’inventaire et de configuration.
Facultatif pacman -Qdtq ; unités en échec et unités utilisateur ; scrub Btrfs ; SMART de /dev/nvme0 ; nftables.conf, limine-snapper-sync, TLP, zram-generator, Snapper, deux helpers root ; modèle Limine Leur absence ou indisponibilité peut être légitime selon la machine, l’utilisateur ou le matériel. Elle reste visible dans le manifeste.

SUCCESS indique un fichier collecté non vide ; EMPTY, une commande réussie avec résultat vide permis ; ABSENT, une absence effectivement établie pour une source facultative ; UNAVAILABLE, un outil ou nvme0 indisponible ; CHECK_ERROR, un contrôle impossible ou une réponse invalide ; COLLECT_ERROR, une commande ou lecture échouée. PORTABILITY_REVIEW marque le modèle Limine à relire, même après une transformation reconnue. Une erreur obligatoire interdit la finalisation ; une erreur facultative produit COMPLETE_WITH_WARNINGS si le noyau obligatoire a réussi. COMPLETE est réservé à un ensemble sans avertissement. En pratique, un modèle Limine présent entraîne une alerte de portabilité.

Les listes sont des observations : « natif » ne prouve pas dans tous les cas « dépôt officiel », et « étranger » ne prouve pas « AUR ». pacman -Qdtq désigne les dépendances orphelines selon pacman(8). La documentation primaire ne justifie pas une règle générale « code 1 = aucun orphelin » : une sortie vide avec code non nul reste COLLECT_ERROR, avec une cause à examiner. Les résultats vides de commandes revenues avec succès sont distingués. Le relevé SMART éventuel concerne seulement /dev/nvme0, pas tous les disques.

Finalisation, manifeste et limites

La collecte commence dans un répertoire .incomplete.* privé, doté d’un manifest.tsv au statut INCOMPLETE. Les sorties sont d’abord reçues dans une zone de travail privée ; une commande qui écrit partiellement puis échoue ne publie pas ce fichier comme relevé valide. Après les éléments obligatoires, le manifeste est terminé et le répertoire est renommé localement en export-* sans remplacer un nom existant. Chaque invocation a son espace ; avant un renommage réussi, une erreur ou un INT/TERM conserve son reliquat marqué INCOMPLETE et annoncé. Après le renommage réussi, un INT/TERM conserve le candidat complet et annonce son chemin avec le diagnostic « finalisation acquise, terminaison interrompue ». L'exporteur reconnaît ce renommage par la disparition du staging et l'identité de l'objet au chemin final ; la simple présence d'une destination préexistante ne suffit pas. Une collision conserve le staging incomplet sans revendiquer cet autre export. Les exports antérieurs ne sont ni supprimés ni remplacés. Les codes sont 0 pour simulation ou candidat finalisé, 1 pour erreur, 2 pour usage invalide, 130/143 pour INT/TERM. SIGKILL et une coupure d’alimentation ne sont pas interceptés ; aucune garantie de durabilité après coupure n’est revendiquée.

Le manifeste contient version, début/fin UTC, révision source, statut global, état de chaque collecteur et SHA-256 des fichiers de sortie finalisés. Chaque empreinte est calculée via l'entrée standard, après vérification de l'ouverture du fichier et du succès de la commande ; seule une réponse de 64 chiffres hexadécimaux est acceptée. Un échec ou une réponse malformée interdit la finalisation. Le manifeste ne contient pas son propre hash. Vérifier les empreintes et lire le contenu avant toute utilisation. Les lectures ne forment pas un instantané atomique : services et fichiers peuvent changer pendant la collecte. Les vérifications de chemins réduisent les risques d’alias et de liens ; elles ne remplacent pas une exclusion des modifications concurrentes de la machine.

Le modèle Limine candidat est produit uniquement dans l’export. La section commençant par ### Auto-generated by limine-snapper-sync est retirée. Les formes root=UUID=<hexadécimal/tirets> et root=PARTUUID=<hexadécimal/tirets> deviennent des placeholders distincts. Une forme root= non reconnue est signalée ; tous les autres champs demeurent soumis à revue. Ni ESP_PATH, ni signatures, ni snapshots ne sont changés. Le modèle n’est pas déclaré universellement portable.

Revue avant toute promotion manuelle

Examiner les fichiers et le manifeste hors du dépôt, particulièrement identifiants de stockage, noms de services, nftables.conf, fstab et Limine. Aucun filtrage simple ne certifie l’absence de secrets ; ne pas publier automatiquement. Les listes de déploiement et la politique réseau restent des décisions de reconstruction distinctes de l’état observé. Une éventuelle reprise manuelle dans Git demande une revue spécifique des contenus et de leur portée. L’existence du candidat n’apporte ni copie externe, ni restauration testée.