From 8c24e298f1db3c46bcc6063e29943375e9f11d6a Mon Sep 17 00:00:00 2001 From: Christoph Urlacher Date: Wed, 16 Jul 2025 13:11:30 +0200 Subject: [PATCH] Modules/Impermanence: Cleanup subvolumes on boot (root + home) --- system/modules/impermanence/default.nix | 63 +++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/system/modules/impermanence/default.nix b/system/modules/impermanence/default.nix index 4c19d932..779c9787 100644 --- a/system/modules/impermanence/default.nix +++ b/system/modules/impermanence/default.nix @@ -128,5 +128,68 @@ in { ]; }; }; + + # Because we have a LUKS encrypted drive + # we use a systemd service to cleanup the volumes + boot.initrd.systemd = { + enable = true; + + services.btrfs-volume-cleanup = let + backupDuration = "7"; # Days + mountDir = "/btrfs_tmp"; + in { + description = "Clean btrfs subvolumes for impermanence"; + wantedBy = ["initrd.target"]; + after = ["dev-mapper-crypted.device"]; + before = ["sysroot.mount"]; + unitConfig.DefaultDependencies = "no"; + serviceConfig.Type = "oneshot"; + path = ["/bin" config.system.build.extraUtils]; + + script = '' + mkdir -p ${mountDir} + mount -o subvol=/ /dev/mapper/crypted ${mountDir} + + # Backup old root subvolume + if [[ -e ${mountDir}/root ]]; then + mkdir -p ${mountDir}/old_roots + timestamp=$(date --date="@$(stat -c %Y ${mountDir}/root)" "+%Y-%m-%-d_%H:%M:%S") + mv ${mountDir}/root "${mountDir}/old_roots/$timestamp" + fi + + # Backup old home subvolume + if [[ -e ${mountDir}/home ]]; then + mkdir -p ${mountDir}/old_homes + timestamp=$(date --date="@$(stat -c %Y ${mountDir}/home)" "+%Y-%m-%-d_%H:%M:%S") + mv ${mountDir}/home "${mountDir}/old_homes/$timestamp" + fi + + delete_subvolume_recursively() { + IFS=$'\n' + for subvol in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do + delete_subvolume_recursively "${mountDir}/$subvol" + done + btrfs subvolume delete "$1" + } + + # Delete old roots + for old_root in $(find ${mountDir}/old_roots/ -maxdepth 1 -mtime +${backupDuration}); do + delete_subvolume_recursively "$old_root" + done + + # Delete old homes + for old_home in $(find ${mountDir}/old_homes/ -maxdepth 1 -mtime +${backupDuration}); do + delete_subvolume_recursively "$old_home" + done + + # Create new root + home subvolumes + btrfs subvolume create ${mountDir}/root + btrfs subvolume create ${mountDir}/home + + umount ${mountDir} + rmdir ${mountDir} + ''; + }; + }; }; }