Compare commits

..

No commits in common. "15b4851e8e848ef6bcda5f07eda8eaae2c72e532" and "2c286d65fb0b5885f33c4d89ba814d0ec0ef218b" have entirely different histories.

4 changed files with 122 additions and 182 deletions

View file

@ -10,63 +10,54 @@
# Create staging directory before borg service starts # Create staging directory before borg service starts
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d /btrfs-subvolumes 0755 root root -" "d /.staging-offsite 0755 root root -"
]; ];
# Wait for onsite backup to complete before starting offsite
systemd.services."borgbackup-job-offsite" = {
after = ["borgbackup-job-onsite.service"];
};
services.borgbackup.jobs."offsite" = { services.borgbackup.jobs."offsite" = {
# Allow writing to staging directory # Allow writing to staging directory
readWritePaths = [ "/btrfs-subvolumes" ]; readWritePaths = [ "/.staging-offsite" ];
preHook = /* sh */ '' # Create staging snapshots before backup (independent from onsite)
# Clean up orphaned snapshots from failed runs (crash/power loss) preHook = ''
[ -d "/btrfs-subvolumes/hm-sajenim" ] && \ # Create read-only staging snapshots for home directory
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
"/btrfs-subvolumes/hm-sajenim" 2>/dev/null || true
# Create read-only BTRFS snapshot for backup
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \ ${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \
"/home/sajenim" "/btrfs-subvolumes/hm-sajenim" "/home/sajenim" "/.staging-offsite/home"
''; '';
# Backup explicit home directories and persistent files # Backup explicit home directories and persistent files
paths = [ paths = [
# Home directories (valuable user data only) # Home directories (valuable user data only)
"/btrfs-subvolumes/hm-sajenim/Documents" "/.staging-offsite/home/Documents"
"/btrfs-subvolumes/hm-sajenim/Pictures" "/.staging-offsite/home/Pictures"
"/btrfs-subvolumes/hm-sajenim/Videos" "/.staging-offsite/home/Videos"
"/btrfs-subvolumes/hm-sajenim/Music" "/.staging-offsite/home/Music"
"/btrfs-subvolumes/hm-sajenim/Downloads" "/.staging-offsite/home/Downloads"
"/btrfs-subvolumes/hm-sajenim/Academics" "/.staging-offsite/home/Academics"
"/btrfs-subvolumes/hm-sajenim/Notes" "/.staging-offsite/home/Notes"
"/btrfs-subvolumes/hm-sajenim/Library" "/.staging-offsite/home/Library"
# Dotfiles (critical user configuration) # Dotfiles (critical user configuration)
"/btrfs-subvolumes/hm-sajenim/.ssh" "/.staging-offsite/home/.ssh"
"/btrfs-subvolumes/hm-sajenim/.gnupg" "/.staging-offsite/home/.gnupg"
# Persistent files (actual storage location) # Files from persist.nix (restore to /persist)
"/persist/etc/machine-id" "/etc/machine-id"
"/persist/etc/ssh/ssh_host_rsa_key" "/etc/ssh/ssh_host_rsa_key"
"/persist/etc/ssh/ssh_host_rsa_key.pub" "/etc/ssh/ssh_host_rsa_key.pub"
"/persist/etc/ssh/ssh_host_ed25519_key" "/etc/ssh/ssh_host_ed25519_key"
"/persist/etc/ssh/ssh_host_ed25519_key.pub" "/etc/ssh/ssh_host_ed25519_key.pub"
# Persistent directories (actual storage location) # Directories from persist.nix (restore to /persist)
"/persist/var/lib/bluetooth" "/var/lib/bluetooth"
"/persist/var/lib/nixos" "/var/lib/nixos"
"/persist/var/lib/private" "/var/lib/private"
"/persist/etc/NetworkManager/system-connections" "/etc/NetworkManager/system-connections"
]; ];
postHook = /* sh */ '' # Remove staging snapshots after backup completes
# Clean up snapshots after successful backup postHook = ''
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \ ${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
"/btrfs-subvolumes/hm-sajenim" "/.staging-offsite/home"
''; '';
# Remote repository configuration # Remote repository configuration
@ -79,7 +70,7 @@
environment.BORG_RSH = "ssh -i /etc/ssh/ssh_host_ed25519_key"; environment.BORG_RSH = "ssh -i /etc/ssh/ssh_host_ed25519_key";
compression = "zstd,9"; compression = "zstd,9";
startAt = "*-*-* 00:15:00"; # Daily at 12:15 AM startAt = "daily";
# Ensure backup runs on next boot if system was asleep # Ensure backup runs on next boot if system was asleep
persistentTimer = true; persistentTimer = true;

View file

@ -8,58 +8,54 @@ in {
# Create staging directory before borg service starts # Create staging directory before borg service starts
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d /btrfs-subvolumes 0755 root root -" "d /.staging-onsite 0755 root root -"
]; ];
services.borgbackup.jobs."onsite" = { services.borgbackup.jobs."onsite" = {
# Allow writing to staging directory # Allow writing to staging directory
readWritePaths = [ "/btrfs-subvolumes" ]; readWritePaths = [ "/.staging-onsite" ];
preHook = /* sh */ '' # Create staging snapshots before backup (independent from offsite)
# Clean up orphaned snapshots from failed runs (crash/power loss) preHook = ''
[ -d "/btrfs-subvolumes/hm-sajenim" ] && \ # Create read-only staging snapshots for home directory
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
"/btrfs-subvolumes/hm-sajenim" 2>/dev/null || true
# Create read-only BTRFS snapshot for backup
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \ ${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \
"/home/sajenim" "/btrfs-subvolumes/hm-sajenim" "/home/sajenim" "/.staging-onsite/home"
''; '';
# Backup explicit home directories and persistent files # Backup explicit home directories and persistent files
paths = [ paths = [
# Home directories (valuable user data only) # Home directories (valuable user data only)
"/btrfs-subvolumes/hm-sajenim/Documents" "/.staging-onsite/home/Documents"
"/btrfs-subvolumes/hm-sajenim/Pictures" "/.staging-onsite/home/Pictures"
"/btrfs-subvolumes/hm-sajenim/Videos" "/.staging-onsite/home/Videos"
"/btrfs-subvolumes/hm-sajenim/Music" "/.staging-onsite/home/Music"
"/btrfs-subvolumes/hm-sajenim/Downloads" "/.staging-onsite/home/Downloads"
"/btrfs-subvolumes/hm-sajenim/Academics" "/.staging-onsite/home/Academics"
"/btrfs-subvolumes/hm-sajenim/Notes" "/.staging-onsite/home/Notes"
"/btrfs-subvolumes/hm-sajenim/Library" "/.staging-onsite/home/Library"
# Dotfiles (critical user configuration) # Dotfiles (critical user configuration)
"/btrfs-subvolumes/hm-sajenim/.ssh" "/.staging-onsite/home/.ssh"
"/btrfs-subvolumes/hm-sajenim/.gnupg" "/.staging-onsite/home/.gnupg"
# Persistent files (actual storage location) # Files from persist.nix (restore to /persist)
"/persist/etc/machine-id" "/etc/machine-id"
"/persist/etc/ssh/ssh_host_rsa_key" "/etc/ssh/ssh_host_rsa_key"
"/persist/etc/ssh/ssh_host_rsa_key.pub" "/etc/ssh/ssh_host_rsa_key.pub"
"/persist/etc/ssh/ssh_host_ed25519_key" "/etc/ssh/ssh_host_ed25519_key"
"/persist/etc/ssh/ssh_host_ed25519_key.pub" "/etc/ssh/ssh_host_ed25519_key.pub"
# Persistent directories (actual storage location) # Directories from persist.nix (restore to /persist)
"/persist/var/lib/bluetooth" "/var/lib/bluetooth"
"/persist/var/lib/nixos" "/var/lib/nixos"
"/persist/var/lib/private" "/var/lib/private"
"/persist/etc/NetworkManager/system-connections" "/etc/NetworkManager/system-connections"
]; ];
postHook = /* sh */ '' # Remove staging snapshots after backup completes
# Clean up snapshots after successful backup postHook = ''
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \ ${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
"/btrfs-subvolumes/hm-sajenim" "/.staging-onsite/home"
''; '';
# Onsite repository configuration (backup to viridian over SSH) # Onsite repository configuration (backup to viridian over SSH)

View file

@ -10,81 +10,55 @@
# Create staging directory before borg service starts # Create staging directory before borg service starts
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d /btrfs-subvolumes 0755 root root -" "d /.staging-offsite 0755 root root -"
]; ];
# Wait for onsite backup to complete before starting offsite
systemd.services."borgbackup-job-offsite" = {
after = ["borgbackup-job-onsite.service"];
};
services.borgbackup.jobs."offsite" = { services.borgbackup.jobs."offsite" = {
# Allow writing to staging directory # Allow writing to staging directory
readWritePaths = [ "/btrfs-subvolumes" ]; readWritePaths = [ "/.staging-offsite" ];
preHook = let # Create staging snapshots before backup (independent from onsite)
subvolumes = [ preHook = ''
"srv-containers" # Create read-only staging snapshots for each service
"srv-forgejo" for subvol in containers forgejo lighttpd minecraft opengist; do
"srv-lighttpd" # Map config names to actual subvolume paths
"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 case "$subvol" in
srv-containers) src="/srv/multimedia/containers" ;; containers) src="/srv/multimedia/containers" ;;
srv-*) src="/srv/''${subvol#srv-}" ;; *) src="/srv/$subvol" ;;
esac esac
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \ ${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \
"$src" "/btrfs-subvolumes/$subvol" "$src" "/.staging-offsite/$subvol"
done done
''; '';
# Backup staging snapshots and explicit persistent files # Backup staging snapshots and explicit persistent files
paths = [ paths = [
"/btrfs-subvolumes/srv-containers" "/.staging-offsite/containers"
"/btrfs-subvolumes/srv-forgejo" "/.staging-offsite/forgejo"
"/btrfs-subvolumes/srv-lighttpd" "/.staging-offsite/lighttpd"
"/btrfs-subvolumes/srv-minecraft" "/.staging-offsite/minecraft"
"/btrfs-subvolumes/srv-opengist" "/.staging-offsite/opengist"
# Persistent files (actual storage location) # Files from persist.nix (restore to /persist)
"/persist/etc/machine-id" "/etc/machine-id"
"/persist/etc/ssh/ssh_host_rsa_key" "/etc/ssh/ssh_host_rsa_key"
"/persist/etc/ssh/ssh_host_rsa_key.pub" "/etc/ssh/ssh_host_rsa_key.pub"
"/persist/etc/ssh/ssh_host_ed25519_key" "/etc/ssh/ssh_host_ed25519_key"
"/persist/etc/ssh/ssh_host_ed25519_key.pub" "/etc/ssh/ssh_host_ed25519_key.pub"
# Persistent directories (actual storage location) # Directories from persist.nix (restore to /persist)
"/persist/var/lib/bluetooth" "/var/lib/bluetooth"
"/persist/var/lib/nixos" "/var/lib/nixos"
"/persist/var/lib/private" "/var/lib/private"
"/persist/etc/NetworkManager/system-connections" "/etc/NetworkManager/system-connections"
]; ];
postHook = let # Remove staging snapshots after backup completes
subvolumes = [ postHook = ''
"srv-containers" for subvol in containers forgejo lighttpd minecraft opengist; do
"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 \ ${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
"/btrfs-subvolumes/$subvol" "/.staging-offsite/$subvol"
done done
''; '';
@ -98,7 +72,7 @@
environment.BORG_RSH = "ssh -i /etc/ssh/ssh_host_ed25519_key"; environment.BORG_RSH = "ssh -i /etc/ssh/ssh_host_ed25519_key";
compression = "zstd,9"; compression = "zstd,9";
startAt = "*-*-* 00:15:00"; # Daily at 12:15 AM startAt = "daily";
# Ensure backup runs on next boot if system was asleep # Ensure backup runs on next boot if system was asleep
persistentTimer = true; persistentTimer = true;

View file

@ -17,76 +17,55 @@ in {
# Create staging directory before borg service starts # Create staging directory before borg service starts
systemd.tmpfiles.rules = [ systemd.tmpfiles.rules = [
"d /btrfs-subvolumes 0755 root root -" "d /.staging-onsite 0755 root root -"
]; ];
services.borgbackup.jobs."onsite" = { services.borgbackup.jobs."onsite" = {
# Allow writing to staging directory # Allow writing to staging directory
readWritePaths = [ "/btrfs-subvolumes" ]; readWritePaths = [ "/.staging-onsite" ];
preHook = let # Create staging snapshots before backup (independent from offsite)
subvolumes = [ preHook = ''
"srv-containers" # Create read-only staging snapshots for each service
"srv-forgejo" for subvol in containers forgejo lighttpd minecraft opengist; do
"srv-lighttpd" # Map config names to actual subvolume paths
"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 case "$subvol" in
srv-containers) src="/srv/multimedia/containers" ;; containers) src="/srv/multimedia/containers" ;;
srv-*) src="/srv/''${subvol#srv-}" ;; *) src="/srv/$subvol" ;;
esac esac
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \ ${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \
"$src" "/btrfs-subvolumes/$subvol" "$src" "/.staging-onsite/$subvol"
done done
''; '';
# Backup staging snapshots and explicit persistent files # Backup staging snapshots and explicit persistent files
paths = [ paths = [
"/btrfs-subvolumes/srv-containers" "/.staging-onsite/containers"
"/btrfs-subvolumes/srv-forgejo" "/.staging-onsite/forgejo"
"/btrfs-subvolumes/srv-lighttpd" "/.staging-onsite/lighttpd"
"/btrfs-subvolumes/srv-minecraft" "/.staging-onsite/minecraft"
"/btrfs-subvolumes/srv-opengist" "/.staging-onsite/opengist"
# Persistent files (actual storage location) # Files from persist.nix (restore to /persist)
"/persist/etc/machine-id" "/etc/machine-id"
"/persist/etc/ssh/ssh_host_rsa_key" "/etc/ssh/ssh_host_rsa_key"
"/persist/etc/ssh/ssh_host_rsa_key.pub" "/etc/ssh/ssh_host_rsa_key.pub"
"/persist/etc/ssh/ssh_host_ed25519_key" "/etc/ssh/ssh_host_ed25519_key"
"/persist/etc/ssh/ssh_host_ed25519_key.pub" "/etc/ssh/ssh_host_ed25519_key.pub"
# Persistent directories (actual storage location) # Directories from persist.nix (restore to /persist)
"/persist/var/lib/bluetooth" "/var/lib/bluetooth"
"/persist/var/lib/nixos" "/var/lib/nixos"
"/persist/var/lib/private" "/var/lib/private"
"/persist/etc/NetworkManager/system-connections" "/etc/NetworkManager/system-connections"
]; ];
postHook = let # Remove staging snapshots after backup completes
subvolumes = [ postHook = ''
"srv-containers" for subvol in containers forgejo lighttpd minecraft opengist; do
"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 \ ${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
"/btrfs-subvolumes/$subvol" "/.staging-onsite/$subvol"
done done
''; '';