{ pkgs, utils, lib, config, ... }: with lib; let cfg = config.services.btrfsScrub; in { options.services.btrfsScrub = { enable = mkEnableOption "Periodically run btrfs-scrub on filesystems"; enableFailureEmail = mkOption { type = types.bool; default = true; description = mdDoc "Send e-mail on scrub failure"; }; paths = mkOption { type = with types; attrsOf (submodule { options = { onCalendar = mkOption { type = str; default = "*-*-* 02:00:00"; }; }; }); }; }; config.services.statusEmail.enable = mkIf (cfg.enable && cfg.enableFailureEmail) true; config.systemd.services."btrfs-scrub@" = mkIf cfg.enable { unitConfig = { Description = "Scrub btrfs volume %I"; OnFailure = mkIf cfg.enableFailureEmail "status-email@%n.service"; }; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.btrfs-progs}/bin/btrfs scrub start -B -d %f"; # ExecStop = "-${pkgs.btrfs-progs}/bin/btrfs scrub cancel %f"; Nice = 19; }; }; config.systemd.timers = mkIf cfg.enable (mapAttrs' (name: value: let pathEscaped = utils.escapeSystemdPath name; in nameValuePair "btrfs-scrub-${pathEscaped}" { wantedBy = [ "timers.target" ]; enable = true; timerConfig = { Unit = "btrfs-scrub@${pathEscaped}.service"; OnCalendar = value.onCalendar; RandomizedDelaySec = "1h"; Persistent = true; }; }) cfg.paths); }