{ lib, config, pkgs, ... }: let borgBackupOpts = { options = { paths = lib.mkOption { type = with lib.types; listOf str; }; deploymentName = lib.mkOption { type = lib.types.str; }; deploymentNamespace = lib.mkOption { type = lib.types.str; }; replicaCount = lib.mkOption { type = lib.types.int; default = 1; }; }; }; in { options.pim.backups = { borgBackups = lib.mkOption { type = with lib.types; attrsOf (submodule borgBackupOpts); default = {}; }; }; # TODO: should have some timeout and alerting? config = { services.borgbackup.jobs = lib.mapAttrs (name: c: { inherit (c) paths; repo = "ssh://w553a7cb@w553a7cb.repo.borgbase.com/./repo"; startAt = "*-*-* 00:00:00"; # TODO: low benefit, but we could set borgbase's host keys here as they are published online. environment.BORG_RSH = "ssh -i ${config.sops.secrets."borg/borgbasePrivateKey".path} -o StrictHostKeychecking=no"; postHook = "${pkgs.k3s}/bin/kubectl scale deployment -n ${c.deploymentNamespace} ${c.deploymentName} --replicas=${toString c.replicaCount}"; archiveBaseName = name; prune.keep = { within = "7d"; weekly = 4; monthly = 6; }; preHook = '' ${pkgs.k3s}/bin/kubectl scale deployment -n ${c.deploymentNamespace} ${c.deploymentName} --replicas=0 while [ -n "$(${pkgs.k3s}/bin/kubectl get deployment -n ${c.deploymentNamespace} ${c.deploymentName} -o jsonpath='{.status.replicas}')" ]; do echo "Waiting for replicas to scale down to 0..." sleep 2 done ''; encryption = { passCommand = "cat ${config.sops.secrets."borg/borgPassphrase".path}"; mode = "repokey-blake2"; }; }) config.pim.backups.borgBackups; systemd.timers = lib.mapAttrs' (name: _c: lib.nameValuePair "borgbackup-job-${name}" {timerConfig.RandomizedDelaySec = "5h";}) config.pim.backups.borgBackups; }; }