{ config, lib, pkgs, ... }: with lib; let cfg = config.local.btrfs; in { options.local.btrfs = { snapper = mkOption { type = with lib.types; attrsOf str; default = {}; }; }; config = mkIf (cfg.snapper != {}) { environment.systemPackages = [pkgs.local.btclone]; services.snapper.configs = let snapperConfig = _: subvolume: { SUBVOLUME = subvolume; # 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 = true; # cleanup hourly snapshots after some time TIMELINE_CLEANUP = true; # 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.snapper; }; }