diff options
Diffstat (limited to 'nixos/modules/services/backup')
-rw-r--r-- | nixos/modules/services/backup/restic.nix | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/nixos/modules/services/backup/restic.nix b/nixos/modules/services/backup/restic.nix index 7e8e91e4b9c3..2388f1d6ca13 100644 --- a/nixos/modules/services/backup/restic.nix +++ b/nixos/modules/services/backup/restic.nix @@ -103,6 +103,34 @@ in Create the repository if it doesn't exist. ''; }; + + pruneOpts = mkOption { + type = types.listOf types.str; + default = []; + description = '' + A list of options (--keep-* et al.) for 'restic forget + --prune', to automatically prune old snapshots. The + 'forget' command is run *after* the 'backup' command, so + keep that in mind when constructing the --keep-* options. + ''; + example = [ + "--keep-daily 7" + "--keep-weekly 5" + "--keep-monthly 12" + "--keep-yearly 75" + ]; + }; + + dynamicFilesFrom = mkOption { + type = with types; nullOr str; + default = null; + description = '' + A script that produces a list of files to back up. The + results of this command are given to the '--files-from' + option. + ''; + example = "find /home/matt/git -type d -name .git"; + }; }; })); default = {}; @@ -134,25 +162,41 @@ in let extraOptions = concatMapStrings (arg: " -o ${arg}") backup.extraOptions; resticCmd = "${pkgs.restic}/bin/restic${extraOptions}"; + filesFromTmpFile = "/run/restic-backups-${name}/includes"; + backupPaths = if (backup.dynamicFilesFrom == null) + then concatStringsSep " " backup.paths + else "--files-from ${filesFromTmpFile}"; + pruneCmd = optionals (builtins.length backup.pruneOpts > 0) [ + ( resticCmd + " forget --prune " + (concatStringsSep " " backup.pruneOpts) ) + ( resticCmd + " check" ) + ]; in nameValuePair "restic-backups-${name}" ({ environment = { RESTIC_PASSWORD_FILE = backup.passwordFile; RESTIC_REPOSITORY = backup.repository; }; - path = with pkgs; [ - openssh - ]; + path = [ pkgs.openssh ]; restartIfChanged = false; serviceConfig = { Type = "oneshot"; - ExecStart = "${resticCmd} backup ${concatStringsSep " " backup.extraBackupArgs} ${concatStringsSep " " backup.paths}"; + ExecStart = [ "${resticCmd} backup ${concatStringsSep " " backup.extraBackupArgs} ${backupPaths}" ] ++ pruneCmd; User = backup.user; + RuntimeDirectory = "restic-backups-${name}"; } // optionalAttrs (backup.s3CredentialsFile != null) { EnvironmentFile = backup.s3CredentialsFile; }; - } // optionalAttrs backup.initialize { + } // optionalAttrs (backup.initialize || backup.dynamicFilesFrom != null) { preStart = '' - ${resticCmd} snapshots || ${resticCmd} init + ${optionalString (backup.initialize) '' + ${resticCmd} snapshots || ${resticCmd} init + ''} + ${optionalString (backup.dynamicFilesFrom != null) '' + ${pkgs.writeScript "dynamicFilesFromScript" backup.dynamicFilesFrom} > ${filesFromTmpFile} + ''} + ''; + } // optionalAttrs (backup.dynamicFilesFrom != null) { + postStart = '' + rm ${filesFromTmpFile} ''; }) ) config.services.restic.backups; |