diff options
Diffstat (limited to 'sys/fs/btrfs.nix')
| -rw-r--r-- | sys/fs/btrfs.nix | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/sys/fs/btrfs.nix b/sys/fs/btrfs.nix new file mode 100644 index 0000000..87c9fca --- /dev/null +++ b/sys/fs/btrfs.nix @@ -0,0 +1,111 @@ +{ lib, config, pkgs, ... }: +with lib; let + cfg = config.local; +in { + options.local = with lib.types; { + snapperSubvols = mkOption { + type = attrsOf str; + default = {}; + }; + + fs.btrfs = mkOption { + default = []; + + type = attrsOf (submodule { + options = { + device = mkOption { + type = str; + }; + + subvol = mkOption { + type = str; + }; + + ssd = mkOption { + type = bool; + }; + + snapper = mkOption { + type = nullOr str; + default = null; + }; + }; + }); + }; + }; + + config = { + environment.systemPackages = optional (cfg.snapperSubvols != {}) pkgs.local.btclone; + + fileSystems = let + inherit (cfg) fs; + btrfs = { device, subvol, ssd, ... }: { + inherit device; + fsType = "btrfs"; + options = [ "noatime" "compress=zstd" "subvol=${subvol}" ] ++ optional ssd "ssd"; + }; + in mapAttrs (_: btrfs) cfg.fs.btrfs; + + local.snapperSubvols = let + snapperEntry = path: opts: { name = opts.snapper; value = path; }; + validEntry = _: opts: opts.snapper != null; + in mapAttrs' snapperEntry (filterAttrs validEntry cfg.fs.btrfs); + + services.snapper.configs = let + snapperConfig = _: subvolume: { + inherit subvolume; + + extraConfig = '' + # btrfs qgroup for space aware cleanup algorithms + QGROUP="" + + # fraction of the filesystems space the snapshots may use + SPACE_LIMIT="0.5" + + # fraction of the filesystems space that should be free + FREE_LIMIT="0.2" + + # users and groups allowed to work with config + ALLOW_USERS="" + ALLOW_GROUPS="" + + # sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots + # directory + SYNC_ACL="no" + + # start comparing pre- and post-snapshot in background after creating + # post-snapshot + BACKGROUND_COMPARISON="yes" + + # run daily number cleanup + NUMBER_CLEANUP="yes" + + # limit for number cleanup + NUMBER_MIN_AGE="1800" + NUMBER_LIMIT="100" + NUMBER_LIMIT_IMPORTANT="10" + + # create hourly snapshots + TIMELINE_CREATE="yes" + + # cleanup hourly snapshots after some time + TIMELINE_CLEANUP="yes" + + # limits for timeline cleanup + TIMELINE_MIN_AGE="1800" + TIMELINE_LIMIT_HOURLY="24" + TIMELINE_LIMIT_DAILY="7" + TIMELINE_LIMIT_WEEKLY="4" + TIMELINE_LIMIT_MONTHLY="12" + TIMELINE_LIMIT_YEARLY="10" + + # cleanup empty pre-post-pairs + EMPTY_PRE_POST_CLEANUP="yes" + + # limits for empty pre-post-pair cleanup + EMPTY_PRE_POST_MIN_AGE="1800" + ''; + }; + in mapAttrs snapperConfig cfg.snapperSubvols; + }; +} |
