{ config, pkgs, lib, ... }: let cfg = config.my.services.backup; excludeArg = with builtins; with pkgs; "--exclude-file=" + (writeText "excludes.txt" (concatStringsSep "\n" cfg.exclude)); in { options.my.services.backup = with lib; { enable = mkEnableOption "Enable backups for this host"; repository = mkOption { type = types.str; example = "/data/slow/backups/system"; description = "The repository to back up to"; }; passwordFile = mkOption { type = types.path; example = "/var/lib/restic/password.txt"; description = "Read the repository's password from this path"; }; paths = mkOption { type = with types; listOf str; default = [ ]; example = [ "/var/lib" "/home" ]; description = "Paths to backup"; }; exclude = mkOption { type = with types; listOf str; default = [ ]; example = [ # very large paths "/var/lib/docker" "/var/lib/systemd" "/var/lib/libvirt" # temporary files created by `cargo` and `go build` "**/target" "/home/*/go/bin" "/home/*/go/pkg" ]; description = "Paths to exclude from backup"; }; pruneOpts = mkOption { type = with types; listOf str; default = [ "--keep-last 10" "--keep-hourly 24" "--keep-daily 7" "--keep-weekly 4" "--keep-monthly 12" "--keep-yearly 100" ]; example = [ "--keep-last 5" "--keep-weekly 2" ]; description = '' List of options to give to the `forget` subcommand after a backup. ''; }; timerConfig = mkOption { # NOTE: I do not know how to cleanly set the type default = { OnCalendar = "daily"; }; example = { OnCalendar = "00:05"; RandomizedDelaySec = "5h"; }; description = '' When to run the backup. See man systemd.timer for details. ''; }; user = mkOption { type = types.str; default = "root"; description = '' As which user the backup should run. ''; example = "postgresql"; }; }; config = lib.mkIf cfg.enable { services.restic.backups.host = { # Take care of included and excluded files paths = cfg.paths; extraBackupArgs = [ "--verbose=1" "--compression=max" ] ++ lib.optional (builtins.length cfg.exclude != 0) excludeArg; # Take care of creating the repository if it doesn't exist initialize = true; inherit (cfg) passwordFile pruneOpts timerConfig repository user; }; }; }