zaphyra's git: nixfiles

zaphyra's nixfiles

commit 6af932acf27512430fa8cc3705527bde371e118f
parent 1630acb3fa6915f82ab65e83d861b477a035a802
Author: Katja Ramona Sophie Kwast (zaphyra) <git@zaphyra.eu>
Date: Fri, 1 Aug 2025 20:44:06 +0200

config/nixos/modules/filesystem: add `btrfs`-support
2 files changed, 104 insertions(+), 10 deletions(-)
M
config/nixos/modules/filesystem/impermanence.nix
|
52
+++++++++++++++++++++++++++++++++++++++++++---------
M
config/nixos/modules/filesystem/rootDisk.nix
|
62
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
diff --git a/config/nixos/modules/filesystem/impermanence.nix b/config/nixos/modules/filesystem/impermanence.nix
@@ -78,9 +78,9 @@ in
     (lib.mkIf cfg.home.enable {
       assertions = [
         {
-          assertion = config.modules.filesystem.rootDisk.type == "zfs";
+          assertion = builtins.elem config.modules.filesystem.rootDisk.type [ "btrfs" "zfs" ];
           message = ''
-            Impermanence is currently only available for ZFS.
+            Impermanence is currently only available for BTRFS and ZFS.
           '';
         }
       ];

@@ -91,17 +91,51 @@ in
     (lib.mkIf cfg.system.enable {
       assertions = [
         {
-          assertion = config.modules.filesystem.rootDisk.type == "zfs";
+          assertion = builtins.elem config.modules.filesystem.rootDisk.type [ "btrfs" "zfs" ];
           message = ''
-            Impermanence is currently only available for ZFS.
+            Impermanence is currently only available for BTRFS and ZFS.
           '';
         }
       ];
 
       modules.filesystem.rootDisk.parts.system = true;
-      boot.initrd.systemd.services = {
-        defenestrate = {
-          description = "Defenestrate old root";
+
+      boot.initrd.systemd.services.defenestrate = lib.mkMerge [
+        (lib.mkIf (config.modules.filesystem.rootDisk.type == "btrfs") {
+          description = "Defenestrate old btrfs-root";
+          wantedBy = [ "initrd.target" ];
+          after = [ "cryptsetup.target" ];
+          before = [ "sysroot.mount" ];
+          onFailure = [ "emergency.target" ];
+          unitConfig.DefaultDependencies = "no";
+          serviceConfig.Type = "oneshot";
+          script = ''
+            mkdir /btrfs_tmp
+            mount /dev/mapper/root /btrfs_tmp
+            if [[ -e /btrfs_tmp/root ]]; then
+                mkdir -p /btrfs_tmp/old_roots
+                timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
+                mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
+            fi
+
+            delete_subvolume_recursively() {
+                IFS=$'\n'
+                for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
+                    delete_subvolume_recursively "/btrfs_tmp/$i"
+                done
+                btrfs subvolume delete "$1"
+            }
+
+            for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do
+                delete_subvolume_recursively "$i"
+            done
+
+            btrfs subvolume create /btrfs_tmp/root
+            umount /btrfs_tmp
+          '';
+        })
+        (lib.mkIf (config.modules.filesystem.rootDisk.type == "zfs") {
+          description = "Defenestrate old zfs-root";
           wantedBy = [ "initrd.target" ];
           after = [ "zfs-import.target" ];
           before = [ "sysroot.mount" ];

@@ -122,8 +156,8 @@ in
               zfs rename ${prefix}1 ${prefix}2 || true
               zfs create -o devices=off -o exec=off -o mountpoint=legacy -o setuid=off ${prefix}1
             '';
-        };
-      };
+        })
+      ];
 
       environment.persistence."/nix/persist/system" = {
         enable = true;
diff --git a/config/nixos/modules/filesystem/rootDisk.nix b/config/nixos/modules/filesystem/rootDisk.nix
@@ -20,6 +20,7 @@ let
     if cfg.encrypt then
       {
         type = "luks";
+        settings.allowDiscards = true;
         inherit name content;
       }
     else

@@ -34,8 +35,9 @@ in
     };
     type = {
       type = types.enum [
-        "zfs"
         "ext4"
+        "btrfs"
+        "zfs"
       ];
     };
     path = {

@@ -84,6 +86,9 @@ in
 
   config = lib.mkIf cfg.enable (
     lib.mkMerge [
+      (lib.mkIf (cfg.type == "btrfs") {
+        services.btrfs.autoScrub.enable = true;
+      })
       (lib.mkIf (cfg.type == "zfs") {
         assertions = [
           {

@@ -322,6 +327,61 @@ in
                             mountpoint = "/";
                           }
                         ))
+                        (lib.mkIf (cfg.type == "btrfs") (
+                          part "root" {
+                            type = "btrfs";
+                            subvolumes = lib.mkMerge [
+                              {
+                                "/${hostConfig.hostName}/root" = {
+                                  mountpoint = "/";
+                                };
+                              }
+                              (lib.mkIf cfg.parts.nix {
+                                "/${hostConfig.hostName}/nix" = {
+                                  mountOptions = [
+                                    "compress=zstd"
+                                    "noatime"
+                                  ];
+                                  mountpoint = "/nix";
+                                };
+                              })
+                              (lib.mkIf cfg.parts.system {
+                                "/${hostConfig.hostName}/persist" = {
+                                  mountOptions = [
+                                    "compress=zstd"
+                                    "noatime"
+                                  ];
+                                  mountpoint = "/nix/persist";
+                                };
+                              })
+                              (lib.mkIf (cfg.parts.home && !cfg.parts.homePerUser) {
+                                "/${hostConfig.hostName}/home" = {
+                                  mountOptions = [ "compress=zstd" ];
+                                  mountpoint = "/home";
+                                };
+                              })
+                              (lib.mkIf cfg.parts.homePerUser (
+                                lib.listToAttrs (
+                                  lib.map (user: {
+                                    name =
+                                      if config.modules.filesystem.impermanence.home.enable then
+                                        "/${hostConfig.hostName}/persist/home/${user}"
+                                      else
+                                        "/${hostConfig.hostName}/home/${user}";
+                                    value = {
+                                      mountOptions = [ "compress=zstd" ];
+                                      mountpoint =
+                                        if config.modules.filesystem.impermanence.home.enable then
+                                          "/nix/persist/home/${user}"
+                                        else
+                                          "/home/${user}";
+                                    };
+                                  }) users
+                                )
+                              ))
+                            ];
+                          }
+                        ))
                         (lib.mkIf (cfg.type == "zfs") {
                           type = "zfs";
                           pool = hostConfig.hostName;