nix-config/nixos/viridian/services/borgbackup/offsite.nix
jasmine bbe464d73b
fix(borgbackup): add unencrypted repo access and refactor environment blocks
Fixes cache initialization failures on unencrypted repositories and
standardizes environment variable configuration across all backup jobs.

Changes:
- Add BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK to unencrypted repos
  (fuchsia/viridian onsite) to bypass interactive confirmation prompt
- Refactor all environment.BORG_RSH to multiline attribute set format
  for consistency and future extensibility

The cache initialization error occurred after removing persistent timers
(commit d21b36a), causing borg to treat existing repos as "previously
unknown". The bypass flag allows automated jobs to proceed without
interactive confirmation for unencrypted repositories.
2025-10-14 20:29:37 +08:00

117 lines
3.2 KiB
Nix

{
config,
pkgs,
...
}: {
# Encrypted passphrase for offsite borgbackup repository
age.secrets.borgbackup = {
rekeyFile = ./passphrase.age;
};
# Create staging directory before borg service starts
systemd.tmpfiles.rules = [
"d /btrfs-subvolumes 0755 root root -"
];
# Wait for onsite backup to complete before starting offsite
systemd.services."borgbackup-job-offsite" = {
wants = ["borgbackup-job-onsite.service"];
after = ["borgbackup-job-onsite.service"];
serviceConfig = {
Type = "oneshot";
};
};
services.borgbackup.jobs."offsite" = {
# Allow writing to staging directory
readWritePaths = [ "/btrfs-subvolumes" ];
preHook = let
subvolumes = [
"srv-containers"
"srv-forgejo"
"srv-lighttpd"
"srv-minecraft"
"srv-opengist"
];
in /* sh */ ''
# Clean up orphaned snapshots from failed runs (crash/power loss)
for subvol in ${toString subvolumes}; do
[ -d "/btrfs-subvolumes/$subvol" ] && \
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
"/btrfs-subvolumes/$subvol" 2>/dev/null || true
done
# Create read-only BTRFS snapshots for backup
for subvol in ${toString subvolumes}; do
case "$subvol" in
srv-containers) src="/srv/multimedia/containers" ;;
srv-*) src="/srv/''${subvol#srv-}" ;;
esac
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \
"$src" "/btrfs-subvolumes/$subvol"
done
'';
# Backup staging snapshots and explicit persistent files
paths = [
"/btrfs-subvolumes/srv-containers"
"/btrfs-subvolumes/srv-forgejo"
"/btrfs-subvolumes/srv-lighttpd"
"/btrfs-subvolumes/srv-minecraft"
"/btrfs-subvolumes/srv-opengist"
# Persistent files (actual storage location)
"/persist/etc/machine-id"
"/persist/etc/ssh/ssh_host_rsa_key"
"/persist/etc/ssh/ssh_host_rsa_key.pub"
"/persist/etc/ssh/ssh_host_ed25519_key"
"/persist/etc/ssh/ssh_host_ed25519_key.pub"
# Persistent directories (actual storage location)
"/persist/var/lib/bluetooth"
"/persist/var/lib/nixos"
"/persist/var/lib/private"
"/persist/etc/NetworkManager/system-connections"
];
postHook = let
subvolumes = [
"srv-containers"
"srv-forgejo"
"srv-lighttpd"
"srv-minecraft"
"srv-opengist"
];
in /* sh */ ''
# Clean up snapshots after successful backup
for subvol in ${toString subvolumes}; do
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
"/btrfs-subvolumes/$subvol"
done
'';
# Remote repository configuration
repo = "r7ag7x1w@r7ag7x1w.repo.borgbase.com:repo";
encryption = {
mode = "repokey-blake2";
passCommand = "cat ${config.age.secrets.borgbackup.path}";
};
environment = {
BORG_RSH = "ssh -i /etc/ssh/ssh_host_ed25519_key";
};
compression = "zstd,9";
startAt = "daily"; # Daily at midnight
# Retention policy for daily remote backups
prune.keep = {
daily = 7; # Keep 7 daily backups (1 week)
weekly = 4; # Keep 4 weekly backups (1 month)
monthly = 12; # Keep 12 monthly backups (1 year)
};
};
}