diff options
Diffstat (limited to 'nixos/modules/services/backup/restic.nix')
-rw-r--r-- | nixos/modules/services/backup/restic.nix | 54 |
1 files changed, 23 insertions, 31 deletions
diff --git a/nixos/modules/services/backup/restic.nix b/nixos/modules/services/backup/restic.nix index 78220e99c3d..87595f39796 100644 --- a/nixos/modules/services/backup/restic.nix +++ b/nixos/modules/services/backup/restic.nix @@ -23,25 +23,13 @@ in environmentFile = mkOption { type = with types; nullOr str; - # added on 2021-08-28, s3CredentialsFile should - # be removed in the future (+ remember the warning) - default = config.s3CredentialsFile; + default = null; description = lib.mdDoc '' file containing the credentials to access the repository, in the format of an EnvironmentFile as described by systemd.exec(5) ''; }; - s3CredentialsFile = mkOption { - type = with types; nullOr str; - default = null; - description = lib.mdDoc '' - file containing the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY - for an S3-hosted repository, in the format of an EnvironmentFile - as described by systemd.exec(5) - ''; - }; - rcloneOptions = mkOption { type = with types; nullOr (attrsOf (oneOf [ str bool ])); default = null; @@ -113,12 +101,15 @@ in }; paths = mkOption { + # This is nullable for legacy reasons only. We should consider making it a pure listOf + # after some time has passed since this comment was added. type = types.nullOr (types.listOf types.str); - default = null; + default = [ ]; description = lib.mdDoc '' - Which paths to backup. If null or an empty array, no - backup command will be run. This can be used to create a - prune-only job. + Which paths to backup, in addition to ones specified via + `dynamicFilesFrom`. If null or an empty array and + `dynamicFilesFrom` is also null, no backup command will be run. + This can be used to create a prune-only job. ''; example = [ "/var/lib/postgresql" @@ -142,13 +133,15 @@ in }; timerConfig = mkOption { - type = types.attrsOf unitOption; + type = types.nullOr (types.attrsOf unitOption); default = { OnCalendar = "daily"; Persistent = true; }; description = lib.mdDoc '' - When to run the backup. See {manpage}`systemd.timer(5)` for details. + When to run the backup. See {manpage}`systemd.timer(5)` for + details. If null no timer is created and the backup will only + run when explicitly started. ''; example = { OnCalendar = "00:05"; @@ -231,7 +224,7 @@ in description = lib.mdDoc '' A script that produces a list of files to back up. The results of this command are given to the '--files-from' - option. + option. The result is merged with paths specified via `paths`. ''; example = "find /home/matt/git -type d -name .git"; }; @@ -297,7 +290,6 @@ in }; config = { - warnings = mapAttrsToList (n: v: "services.restic.backups.${n}.s3CredentialsFile is deprecated, please use services.restic.backups.${n}.environmentFile instead.") (filterAttrs (n: v: v.s3CredentialsFile != null) config.services.restic.backups); assertions = mapAttrsToList (n: v: { assertion = (v.repository == null) != (v.repositoryFile == null); message = "services.restic.backups.${n}: exactly one of repository or repositoryFile should be set"; @@ -310,10 +302,7 @@ in resticCmd = "${backup.package}/bin/restic${extraOptions}"; excludeFlags = optional (backup.exclude != []) "--exclude-file=${pkgs.writeText "exclude-patterns" (concatStringsSep "\n" backup.exclude)}"; filesFromTmpFile = "/run/restic-backups-${name}/includes"; - backupPaths = - if (backup.dynamicFilesFrom == null) - then optionalString (backup.paths != null) (concatStringsSep " " backup.paths) - else "--files-from ${filesFromTmpFile}"; + doBackup = (backup.dynamicFilesFrom != null) || (backup.paths != null && backup.paths != []); pruneCmd = optionals (builtins.length backup.pruneOpts > 0) [ (resticCmd + " forget --prune " + (concatStringsSep " " backup.pruneOpts)) (resticCmd + " check " + (concatStringsSep " " backup.checkOpts)) @@ -348,7 +337,7 @@ in after = [ "network-online.target" ]; serviceConfig = { Type = "oneshot"; - ExecStart = (optionals (backupPaths != "") [ "${resticCmd} backup ${concatStringsSep " " (backup.extraBackupArgs ++ excludeFlags)} ${backupPaths}" ]) + ExecStart = (optionals doBackup [ "${resticCmd} backup ${concatStringsSep " " (backup.extraBackupArgs ++ excludeFlags)} --files-from=${filesFromTmpFile}" ]) ++ pruneCmd; User = backup.user; RuntimeDirectory = "restic-backups-${name}"; @@ -358,7 +347,7 @@ in } // optionalAttrs (backup.environmentFile != null) { EnvironmentFile = backup.environmentFile; }; - } // optionalAttrs (backup.initialize || backup.dynamicFilesFrom != null || backup.backupPrepareCommand != null) { + } // optionalAttrs (backup.initialize || doBackup || backup.backupPrepareCommand != null) { preStart = '' ${optionalString (backup.backupPrepareCommand != null) '' ${pkgs.writeScript "backupPrepareCommand" backup.backupPrepareCommand} @@ -366,16 +355,19 @@ in ${optionalString (backup.initialize) '' ${resticCmd} snapshots || ${resticCmd} init ''} + ${optionalString (backup.paths != null && backup.paths != []) '' + cat ${pkgs.writeText "staticPaths" (concatStringsSep "\n" backup.paths)} >> ${filesFromTmpFile} + ''} ${optionalString (backup.dynamicFilesFrom != null) '' - ${pkgs.writeScript "dynamicFilesFromScript" backup.dynamicFilesFrom} > ${filesFromTmpFile} + ${pkgs.writeScript "dynamicFilesFromScript" backup.dynamicFilesFrom} >> ${filesFromTmpFile} ''} ''; - } // optionalAttrs (backup.dynamicFilesFrom != null || backup.backupCleanupCommand != null) { + } // optionalAttrs (doBackup || backup.backupCleanupCommand != null) { postStop = '' ${optionalString (backup.backupCleanupCommand != null) '' ${pkgs.writeScript "backupCleanupCommand" backup.backupCleanupCommand} ''} - ${optionalString (backup.dynamicFilesFrom != null) '' + ${optionalString doBackup '' rm ${filesFromTmpFile} ''} ''; @@ -388,7 +380,7 @@ in wantedBy = [ "timers.target" ]; timerConfig = backup.timerConfig; }) - config.services.restic.backups; + (filterAttrs (_: backup: backup.timerConfig != null) config.services.restic.backups); # generate wrapper scripts, as described in the createWrapper option environment.systemPackages = lib.mapAttrsToList (name: backup: let |