NixOS : Gestion des générations (rollback, suppression, ménage)
Table des matières
Dans l'article NixOS : Guide sur cette distribution déclarative, on a vu ce qu'était NixOS, et son concept.
Dans cet article, nous allons voir comment gérer les générations du système.
Avant de rentrer dans les détails dans cet article, je vais refaire un petit explicatif de ce qu'on appelle "génération" dans NixOS.
Une génération, ça représente un état du système à un instant T. Une génération est immuable, c'est à dire qui ne peut pas avoir de modifications.
A chaque fois qu'on modifie la configuration du système on va créer une génération.
C'est quand on applique ces changements avec la commande :
Ou quand on fait les mises à jour avec :
Quand on fait ça, une nouvelle "génération" du système est créée et une entrée dans le démarrage est ajoutée automatiquement.
L'avantage de ce fonctionnement permet de revenir à une génération précédente si un truc ne fonctionne pas correctement dans le système.
Les générations sont stockées dans /nix/var/nix/profiles :
Ce sont tous des liens symboliques qui pointent sur les références des différentes générations.
Pour lister les générations, on pourra le faire de 2 manières :
Ce qui renvoie :
Ou la commande :
Qui renvoie :
Les données de ces générations sont dédupliquées. Ainsi, bien que dans mon exemple au dessus il y ait 11 générations, seules les différences occupent de la place. On n'a pas 11 fois la taille complète du système.
Il est possible de faire un rollback depuis l'écran de boot en sélectionnant l'entrée qui va bien :
Le système démarrera alors sur la génération concernée. Les documents des utilisateurs ne sont pas affectés.
Ce rollback est temporaire. Au prochain reboot, on démarre sur la dernière génération.
La génération "actuelle" est toujours considérée comme étant la dernière.
Il est possible de faire un rollback depuis le système via :
Ici, on rebascule sur la génération 10 de mon exemple et cette modif est persistante? :
Si on veut basculer de manière permanente sur une autre génération (par exemple la génération 11), on pourra utiliser :
Ce qui retourne par exemple :
Ensuite, on pourra valider la bascule sans redémarrer via la commande :
Dans tous les cas, si on est revenu sur une vieille génération, la mise à jour du système se fera en partant sur la base du configuration.nix actuelle.
NixOS permet de faire du ménage dans les générations inutiles pour libérer de l'espace disque.
Il y a plusieurs manières de faire.
Si on souhaite supprimer des générations spécifiques, on pourra le faire via leur numéro.
Après avoir identifié avec les commandes ci-dessus la ou les générations à supprimer :
Par exemple pour supprimer la génération 4 :
On pourra supprimer plusieurs générations d'un coup (exemple 1 2 3 5) :
Si on veut par exemple garder les 3 dernières générations :
Il faudra penser à valider la suppression des données :
Et à refaire une génération pour mettre à jour le bootloader :
Il peut être utile de supprimer manuellement les générations après une période donnée.
Par exemple, pour supprimer les générations de plus de 30 jours :
On pensera à refaire une génération pour mettre à jour le bootloader :
Si on est sur un système stable après avoir fait plein de tests, on pourra si nécessaire supprimer toutes les anciennes générations sauf celle en cours via :
On pensera à refaire une génération pour mettre à jour le bootloader :
Pour éviter d'avoir à nettoyer manuellement, on pourra planifier le nettoyage.
Evidemment, ça va se passer dans le configuration.nix !
On y ajoutera ceci :
Quelques infos :
nix.gc.automatic : Active le nettoyage automatique
nix.gc.dates : Fait un timer qui va s'exécuter 1 fois par semaine
nix.gc.options : Indique les options souhaitées de nix-collect-garbage. Démo ici avec 15 jours.
nix.settings.auto-optimise-store : L'optimisation (auto-optimise-store) permet de passer sur les images et pour les fichiers identiques les remplacer par des liens physiques (hard link) et gagner un peu de place. Cependant c'est facultatif. Je l'indique ici, car on est dans une optique de "ménage".
Cela génèrera la configuration via un timer systemd : nix-gc.timer !
Cependant, à travers mes tests, cela ne met à jour le bootloader qu'une fois une nouvelle génération effectuée... Ca mérite d'être encore un peu paufiné
Introduction
Dans l'article NixOS : Guide sur cette distribution déclarative, on a vu ce qu'était NixOS, et son concept.
Dans cet article, nous allons voir comment gérer les générations du système.
Comprendre le concept de générations
Avant de rentrer dans les détails dans cet article, je vais refaire un petit explicatif de ce qu'on appelle "génération" dans NixOS.
Une génération, ça représente un état du système à un instant T. Une génération est immuable, c'est à dire qui ne peut pas avoir de modifications.
A chaque fois qu'on modifie la configuration du système on va créer une génération.
C'est quand on applique ces changements avec la commande :
Code BASH :
nixos-rebuild switch
Ou quand on fait les mises à jour avec :
Code BASH :
nixos-rebuild switch --upgrade
Quand on fait ça, une nouvelle "génération" du système est créée et une entrée dans le démarrage est ajoutée automatiquement.
L'avantage de ce fonctionnement permet de revenir à une génération précédente si un truc ne fonctionne pas correctement dans le système.
Les générations sont stockées dans /nix/var/nix/profiles :
Code TEXT :
per-user system -> system-11-link system-10-link -> /nix/store/dyxvsifjif1yh0knfv48j5wbj9r1zimd-nixos-system-nixos-24.11.715057.5ef6c4259808 system-11-link -> /nix/store/3vmc5b1pv2k66z93n522vcibj35gicsm-nixos-system-nixos-24.11.715057.5ef6c4259808 system-1-link -> /nix/store/dnmc1iaxbgycw2s52qr0lp50ka3f8268-nixos-system-nixos-24.11.715026.b27ba4eb322d system-2-link -> /nix/store/95ikl0shsphzcl3mjh02hyqhavkc1k49-nixos-system-nixyt-24.11.715026.b27ba4eb322d system-3-link -> /nix/store/9ncqnri91h6rcr0f63hqx5c33nyxjh2y-nixos-system-nixos-24.11.715026.b27ba4eb322d system-4-link -> /nix/store/9067n38gmwjwlr17yf45z3z82gc99b4g-nixos-system-nixos-24.11.715026.b27ba4eb322d system-5-link -> /nix/store/9ncqnri91h6rcr0f63hqx5c33nyxjh2y-nixos-system-nixos-24.11.715026.b27ba4eb322d system-6-link -> /nix/store/i4yx0ra1lm2dc2fbbqhl8m7hcg03v11s-nixos-system-nixos-24.11.715026.b27ba4eb322d system-7-link -> /nix/store/4zdy9xq7gdjk0n39lsajws8aqkqfv5y3-nixos-system-nixos-24.11.715026.b27ba4eb322d system-8-link -> /nix/store/ciqq9qx9jvlb3x8dcrnngjndcjwpiqph-nixos-system-nixos-24.11.715026.b27ba4eb322d system-9-link -> /nix/store/jaa70diakqx7jwsyjkp52jh59xlfxb4i-nixos-system-nixos-24.11.715026.b27ba4eb322d
Ce sont tous des liens symboliques qui pointent sur les références des différentes générations.
Lister les générations
Pour lister les générations, on pourra le faire de 2 manières :
Code BASH :
nix-env -p /nix/var/nix/profiles/system --list-generations
Ce qui renvoie :
Code :
1 2025-03-02 11:36:31
2 2025-03-02 11:51:17
3 2025-03-02 11:58:06
4 2025-03-02 12:06:46
5 2025-03-02 12:07:44
6 2025-03-02 18:15:56
7 2025-03-02 18:24:49
8 2025-03-02 18:40:16
9 2025-03-02 18:43:30
10 2025-03-03 18:05:26
11 2025-03-04 20:14:25 (current)
Ou la commande :
Code BASH :
nixos-rebuild list-generations
Qui renvoie :
Code :
Generation Build-date NixOS version Kernel Configuration Revision Specialisation
11 current 2025-03-04 20:14:25 24.11.715057.5ef6c4259808 6.6.80 *
10 2025-03-03 18:05:26 24.11.715057.5ef6c4259808 6.6.80 *
9 2025-03-02 18:43:30 24.11.715026.b27ba4eb322d 6.6.80 *
8 2025-03-02 18:40:16 24.11.715026.b27ba4eb322d 6.6.80 *
7 2025-03-02 18:24:49 24.11.715026.b27ba4eb322d 6.6.80 *
6 2025-03-02 18:15:56 24.11.715026.b27ba4eb322d 6.6.80 *
5 2025-03-02 12:07:44 24.11.715026.b27ba4eb322d 6.6.80 *
4 2025-03-02 12:06:46 24.11.715026.b27ba4eb322d 6.6.80 *
3 2025-03-02 11:58:06 24.11.715026.b27ba4eb322d 6.6.80 *
2 2025-03-02 11:51:17 24.11.715026.b27ba4eb322d 6.6.80 *
1 2025-03-02 11:36:31 24.11.715026.b27ba4eb322d 6.6.80 *
Les données de ces générations sont dédupliquées. Ainsi, bien que dans mon exemple au dessus il y ait 11 générations, seules les différences occupent de la place. On n'a pas 11 fois la taille complète du système.
Rollback : Revenir à une génération antérieure
Rollback depuis l'écran de boot
Il est possible de faire un rollback depuis l'écran de boot en sélectionnant l'entrée qui va bien :
Le système démarrera alors sur la génération concernée. Les documents des utilisateurs ne sont pas affectés.
Ce rollback est temporaire. Au prochain reboot, on démarre sur la dernière génération.
La génération "actuelle" est toujours considérée comme étant la dernière.
Rollback depuis le système
Il est possible de faire un rollback depuis le système via :
Code BASH :
nixos-rebuild switch --rollback
Ici, on rebascule sur la génération 10 de mon exemple et cette modif est persistante? :
Code TEXT :
1 2025-03-02 11:36:31 2 2025-03-02 11:51:17 3 2025-03-02 11:58:06 4 2025-03-02 12:06:46 5 2025-03-02 12:07:44 6 2025-03-02 18:15:56 7 2025-03-02 18:24:49 8 2025-03-02 18:40:16 9 2025-03-02 18:43:30 10 2025-03-03 18:05:26 (current) 11 2025-03-04 20:14:25
Changer la génération par défaut
Si on veut basculer de manière permanente sur une autre génération (par exemple la génération 11), on pourra utiliser :
Code BASH :
nix-env -p /nix/var/nix/profiles/system --switch-generation 11
Ce qui retourne par exemple :
Code :
switching profile from version 3 to 11
Ensuite, on pourra valider la bascule sans redémarrer via la commande :
Code BASH :
/nix/var/nix/profiles/system/bin/switch-to-configuration switch
Dans tous les cas, si on est revenu sur une vieille génération, la mise à jour du système se fera en partant sur la base du configuration.nix actuelle.
Faire du ménage dans les générations
NixOS permet de faire du ménage dans les générations inutiles pour libérer de l'espace disque.
Il y a plusieurs manières de faire.
Supprimer manuellement une ou plusieurs générations
Si on souhaite supprimer des générations spécifiques, on pourra le faire via leur numéro.
Après avoir identifié avec les commandes ci-dessus la ou les générations à supprimer :
Code BASH :
nix-env -p /nix/var/nix/profiles/system --delete-generations ID
Par exemple pour supprimer la génération 4 :
Code BASH :
nix-env -p /nix/var/nix/profiles/system --delete-generations 4
On pourra supprimer plusieurs générations d'un coup (exemple 1 2 3 5) :
Code BASH :
nix-env -p /nix/var/nix/profiles/system --delete-generations 1 2 3 5
Si on veut par exemple garder les 3 dernières générations :
Code BASH :
nix-env -p /nix/var/nix/profiles/system --delete-generations +3
Il faudra penser à valider la suppression des données :
Code BASH :
nix-collect-garbage
Et à refaire une génération pour mettre à jour le bootloader :
Code BASH :
nixos-rebuild switch
Supprimer manuellement les générations de plus de X jours
Il peut être utile de supprimer manuellement les générations après une période donnée.
Par exemple, pour supprimer les générations de plus de 30 jours :
Code BASH :
nix-collect-garbage --delete-older-than 30d
On pensera à refaire une génération pour mettre à jour le bootloader :
Code BASH :
nixos-rebuild switch
Supprimer manuellement toutes les générations sauf l'actuelle
Si on est sur un système stable après avoir fait plein de tests, on pourra si nécessaire supprimer toutes les anciennes générations sauf celle en cours via :
Code BASH :
nix-collect-garbage -d
On pensera à refaire une génération pour mettre à jour le bootloader :
Code BASH :
nixos-rebuild switch
Automatiser le nettoyage des générations
Pour éviter d'avoir à nettoyer manuellement, on pourra planifier le nettoyage.
Evidemment, ça va se passer dans le configuration.nix !
On y ajoutera ceci :
Code TEXT :
nix.settings.auto-optimise-store = true; nix.gc.automatic = true; nix.gc.dates = "weekly"; nix.gc.options = "--delete-older-than 15d";
Quelques infos :
nix.gc.automatic : Active le nettoyage automatique
nix.gc.dates : Fait un timer qui va s'exécuter 1 fois par semaine
nix.gc.options : Indique les options souhaitées de nix-collect-garbage. Démo ici avec 15 jours.
nix.settings.auto-optimise-store : L'optimisation (auto-optimise-store) permet de passer sur les images et pour les fichiers identiques les remplacer par des liens physiques (hard link) et gagner un peu de place. Cependant c'est facultatif. Je l'indique ici, car on est dans une optique de "ménage".
Cela génèrera la configuration via un timer systemd : nix-gc.timer !
Cependant, à travers mes tests, cela ne met à jour le bootloader qu'une fois une nouvelle génération effectuée... Ca mérite d'être encore un peu paufiné
