commit 6af932acf27512430fa8cc3705527bde371e118f
parent 1630acb3fa6915f82ab65e83d861b477a035a802
Author: Katja Ramona Sophie Kwast (zaphyra) <git@zaphyra.eu>
Date: Fri, 1 Aug 2025 20:44:06 +0200
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
|
52
+++++++++++++++++++++++++++++++++++++++++++---------
M
|
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;