diff --git a/clanModules/borgbackup/default.nix b/clanModules/borgbackup/default.nix index 2e16b3b9..e4ba0d7c 100644 --- a/clanModules/borgbackup/default.nix +++ b/clanModules/borgbackup/default.nix @@ -6,6 +6,26 @@ }: let cfg = config.clan.borgbackup; + preBackupScript = '' + declare -A preCommandErrors + ${lib.concatMapStringsSep "\n" ( + state: + lib.optionalString (state.preBackupCommand != null) '' + echo "Running pre-backup command for ${state.name}" + if ! ( ${state.preBackupCommand} ) then + preCommandErrors["${state.name}"]=1 + fi + + if [[ ''${#preCommandErrors[@]} -gt 0 ]]; then + echo "PreBackupCommand failed for the following services:" + for state in "''${!preCommandErrors[@]}"; do + echo " $state" + done + exit 1 + fi + '' + ) (lib.attrValues config.clanCore.state)} + ''; in { options.clan.borgbackup.destinations = lib.mkOption { @@ -50,6 +70,16 @@ in ]; config = lib.mkIf (cfg.destinations != { }) { + systemd.services = lib.mapAttrs' ( + _: dest: + lib.nameValuePair "borgbackup-job-${dest.name}" { + # since borgbackup mounts the system read-only, we need to run in a ExecStartPre script, so we can generate additional files. + ExecStartPre = [ + (''+${pkgs.writeShellScript "borgbackup-job-${dest.name}-pre-backup-commands" preBackupScript}'') + ]; + } + ); + services.borgbackup.jobs = lib.mapAttrs (_: dest: { paths = lib.unique ( lib.flatten (map (state: state.folders) (lib.attrValues config.clanCore.state)) @@ -60,29 +90,6 @@ in compression = "auto,zstd"; startAt = "*-*-* 01:00:00"; persistentTimer = true; - preHook = '' - set -x - declare -A preCommandErrors - ${lib.concatMapStringsSep "\n" ( - state: - lib.optionalString (state.preBackupCommand != null) '' - echo "Running pre-backup command for ${state.name}" - if ! ( ${state.preBackupCommand} ) then - preCommandErrors["${state.name}"]=1 - fi - '' - ) (lib.attrValues config.clanCore.state)} - ''; - postPrune = '' - # report any preBackupCommand errors - if [[ ''${#preCommandErrors[@]} -gt 0 ]]; then - echo "PreBackupCommand failed for the following services:" - for state in "''${!preCommandErrors[@]}"; do - echo " $state" - done - exit 1 - fi - ''; encryption = { mode = "repokey";