Compare commits
3 commits
2c286d65fb
...
15b4851e8e
| Author | SHA1 | Date | |
|---|---|---|---|
| 15b4851e8e | |||
| 37924375a2 | |||
| 26c08000a0 |
4 changed files with 182 additions and 122 deletions
|
|
@ -10,54 +10,63 @@
|
||||||
|
|
||||||
# Create staging directory before borg service starts
|
# Create staging directory before borg service starts
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /.staging-offsite 0755 root root -"
|
"d /btrfs-subvolumes 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 = [ "/.staging-offsite" ];
|
readWritePaths = [ "/btrfs-subvolumes" ];
|
||||||
|
|
||||||
# Create staging snapshots before backup (independent from onsite)
|
preHook = /* sh */ ''
|
||||||
preHook = ''
|
# Clean up orphaned snapshots from failed runs (crash/power loss)
|
||||||
# Create read-only staging snapshots for home directory
|
[ -d "/btrfs-subvolumes/hm-sajenim" ] && \
|
||||||
|
${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" "/.staging-offsite/home"
|
"/home/sajenim" "/btrfs-subvolumes/hm-sajenim"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# 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)
|
||||||
"/.staging-offsite/home/Documents"
|
"/btrfs-subvolumes/hm-sajenim/Documents"
|
||||||
"/.staging-offsite/home/Pictures"
|
"/btrfs-subvolumes/hm-sajenim/Pictures"
|
||||||
"/.staging-offsite/home/Videos"
|
"/btrfs-subvolumes/hm-sajenim/Videos"
|
||||||
"/.staging-offsite/home/Music"
|
"/btrfs-subvolumes/hm-sajenim/Music"
|
||||||
"/.staging-offsite/home/Downloads"
|
"/btrfs-subvolumes/hm-sajenim/Downloads"
|
||||||
"/.staging-offsite/home/Academics"
|
"/btrfs-subvolumes/hm-sajenim/Academics"
|
||||||
"/.staging-offsite/home/Notes"
|
"/btrfs-subvolumes/hm-sajenim/Notes"
|
||||||
"/.staging-offsite/home/Library"
|
"/btrfs-subvolumes/hm-sajenim/Library"
|
||||||
|
|
||||||
# Dotfiles (critical user configuration)
|
# Dotfiles (critical user configuration)
|
||||||
"/.staging-offsite/home/.ssh"
|
"/btrfs-subvolumes/hm-sajenim/.ssh"
|
||||||
"/.staging-offsite/home/.gnupg"
|
"/btrfs-subvolumes/hm-sajenim/.gnupg"
|
||||||
|
|
||||||
# Files from persist.nix (restore to /persist)
|
# Persistent files (actual storage location)
|
||||||
"/etc/machine-id"
|
"/persist/etc/machine-id"
|
||||||
"/etc/ssh/ssh_host_rsa_key"
|
"/persist/etc/ssh/ssh_host_rsa_key"
|
||||||
"/etc/ssh/ssh_host_rsa_key.pub"
|
"/persist/etc/ssh/ssh_host_rsa_key.pub"
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
"/persist/etc/ssh/ssh_host_ed25519_key"
|
||||||
"/etc/ssh/ssh_host_ed25519_key.pub"
|
"/persist/etc/ssh/ssh_host_ed25519_key.pub"
|
||||||
|
|
||||||
# Directories from persist.nix (restore to /persist)
|
# Persistent directories (actual storage location)
|
||||||
"/var/lib/bluetooth"
|
"/persist/var/lib/bluetooth"
|
||||||
"/var/lib/nixos"
|
"/persist/var/lib/nixos"
|
||||||
"/var/lib/private"
|
"/persist/var/lib/private"
|
||||||
"/etc/NetworkManager/system-connections"
|
"/persist/etc/NetworkManager/system-connections"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Remove staging snapshots after backup completes
|
postHook = /* sh */ ''
|
||||||
postHook = ''
|
# Clean up snapshots after successful backup
|
||||||
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
|
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
|
||||||
"/.staging-offsite/home"
|
"/btrfs-subvolumes/hm-sajenim"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Remote repository configuration
|
# Remote repository configuration
|
||||||
|
|
@ -70,7 +79,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 = "daily";
|
startAt = "*-*-* 00:15:00"; # Daily at 12:15 AM
|
||||||
|
|
||||||
# Ensure backup runs on next boot if system was asleep
|
# Ensure backup runs on next boot if system was asleep
|
||||||
persistentTimer = true;
|
persistentTimer = true;
|
||||||
|
|
|
||||||
|
|
@ -8,54 +8,58 @@ in {
|
||||||
|
|
||||||
# Create staging directory before borg service starts
|
# Create staging directory before borg service starts
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /.staging-onsite 0755 root root -"
|
"d /btrfs-subvolumes 0755 root root -"
|
||||||
];
|
];
|
||||||
|
|
||||||
services.borgbackup.jobs."onsite" = {
|
services.borgbackup.jobs."onsite" = {
|
||||||
# Allow writing to staging directory
|
# Allow writing to staging directory
|
||||||
readWritePaths = [ "/.staging-onsite" ];
|
readWritePaths = [ "/btrfs-subvolumes" ];
|
||||||
|
|
||||||
# Create staging snapshots before backup (independent from offsite)
|
preHook = /* sh */ ''
|
||||||
preHook = ''
|
# Clean up orphaned snapshots from failed runs (crash/power loss)
|
||||||
# Create read-only staging snapshots for home directory
|
[ -d "/btrfs-subvolumes/hm-sajenim" ] && \
|
||||||
|
${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" "/.staging-onsite/home"
|
"/home/sajenim" "/btrfs-subvolumes/hm-sajenim"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# 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)
|
||||||
"/.staging-onsite/home/Documents"
|
"/btrfs-subvolumes/hm-sajenim/Documents"
|
||||||
"/.staging-onsite/home/Pictures"
|
"/btrfs-subvolumes/hm-sajenim/Pictures"
|
||||||
"/.staging-onsite/home/Videos"
|
"/btrfs-subvolumes/hm-sajenim/Videos"
|
||||||
"/.staging-onsite/home/Music"
|
"/btrfs-subvolumes/hm-sajenim/Music"
|
||||||
"/.staging-onsite/home/Downloads"
|
"/btrfs-subvolumes/hm-sajenim/Downloads"
|
||||||
"/.staging-onsite/home/Academics"
|
"/btrfs-subvolumes/hm-sajenim/Academics"
|
||||||
"/.staging-onsite/home/Notes"
|
"/btrfs-subvolumes/hm-sajenim/Notes"
|
||||||
"/.staging-onsite/home/Library"
|
"/btrfs-subvolumes/hm-sajenim/Library"
|
||||||
|
|
||||||
# Dotfiles (critical user configuration)
|
# Dotfiles (critical user configuration)
|
||||||
"/.staging-onsite/home/.ssh"
|
"/btrfs-subvolumes/hm-sajenim/.ssh"
|
||||||
"/.staging-onsite/home/.gnupg"
|
"/btrfs-subvolumes/hm-sajenim/.gnupg"
|
||||||
|
|
||||||
# Files from persist.nix (restore to /persist)
|
# Persistent files (actual storage location)
|
||||||
"/etc/machine-id"
|
"/persist/etc/machine-id"
|
||||||
"/etc/ssh/ssh_host_rsa_key"
|
"/persist/etc/ssh/ssh_host_rsa_key"
|
||||||
"/etc/ssh/ssh_host_rsa_key.pub"
|
"/persist/etc/ssh/ssh_host_rsa_key.pub"
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
"/persist/etc/ssh/ssh_host_ed25519_key"
|
||||||
"/etc/ssh/ssh_host_ed25519_key.pub"
|
"/persist/etc/ssh/ssh_host_ed25519_key.pub"
|
||||||
|
|
||||||
# Directories from persist.nix (restore to /persist)
|
# Persistent directories (actual storage location)
|
||||||
"/var/lib/bluetooth"
|
"/persist/var/lib/bluetooth"
|
||||||
"/var/lib/nixos"
|
"/persist/var/lib/nixos"
|
||||||
"/var/lib/private"
|
"/persist/var/lib/private"
|
||||||
"/etc/NetworkManager/system-connections"
|
"/persist/etc/NetworkManager/system-connections"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Remove staging snapshots after backup completes
|
postHook = /* sh */ ''
|
||||||
postHook = ''
|
# Clean up snapshots after successful backup
|
||||||
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
|
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
|
||||||
"/.staging-onsite/home"
|
"/btrfs-subvolumes/hm-sajenim"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Onsite repository configuration (backup to viridian over SSH)
|
# Onsite repository configuration (backup to viridian over SSH)
|
||||||
|
|
|
||||||
|
|
@ -10,55 +10,81 @@
|
||||||
|
|
||||||
# Create staging directory before borg service starts
|
# Create staging directory before borg service starts
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /.staging-offsite 0755 root root -"
|
"d /btrfs-subvolumes 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 = [ "/.staging-offsite" ];
|
readWritePaths = [ "/btrfs-subvolumes" ];
|
||||||
|
|
||||||
# Create staging snapshots before backup (independent from onsite)
|
preHook = let
|
||||||
preHook = ''
|
subvolumes = [
|
||||||
# Create read-only staging snapshots for each service
|
"srv-containers"
|
||||||
for subvol in containers forgejo lighttpd minecraft opengist; do
|
"srv-forgejo"
|
||||||
# Map config names to actual subvolume paths
|
"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
|
case "$subvol" in
|
||||||
containers) src="/srv/multimedia/containers" ;;
|
srv-containers) src="/srv/multimedia/containers" ;;
|
||||||
*) src="/srv/$subvol" ;;
|
srv-*) src="/srv/''${subvol#srv-}" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \
|
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \
|
||||||
"$src" "/.staging-offsite/$subvol"
|
"$src" "/btrfs-subvolumes/$subvol"
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Backup staging snapshots and explicit persistent files
|
# Backup staging snapshots and explicit persistent files
|
||||||
paths = [
|
paths = [
|
||||||
"/.staging-offsite/containers"
|
"/btrfs-subvolumes/srv-containers"
|
||||||
"/.staging-offsite/forgejo"
|
"/btrfs-subvolumes/srv-forgejo"
|
||||||
"/.staging-offsite/lighttpd"
|
"/btrfs-subvolumes/srv-lighttpd"
|
||||||
"/.staging-offsite/minecraft"
|
"/btrfs-subvolumes/srv-minecraft"
|
||||||
"/.staging-offsite/opengist"
|
"/btrfs-subvolumes/srv-opengist"
|
||||||
|
|
||||||
# Files from persist.nix (restore to /persist)
|
# Persistent files (actual storage location)
|
||||||
"/etc/machine-id"
|
"/persist/etc/machine-id"
|
||||||
"/etc/ssh/ssh_host_rsa_key"
|
"/persist/etc/ssh/ssh_host_rsa_key"
|
||||||
"/etc/ssh/ssh_host_rsa_key.pub"
|
"/persist/etc/ssh/ssh_host_rsa_key.pub"
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
"/persist/etc/ssh/ssh_host_ed25519_key"
|
||||||
"/etc/ssh/ssh_host_ed25519_key.pub"
|
"/persist/etc/ssh/ssh_host_ed25519_key.pub"
|
||||||
|
|
||||||
# Directories from persist.nix (restore to /persist)
|
# Persistent directories (actual storage location)
|
||||||
"/var/lib/bluetooth"
|
"/persist/var/lib/bluetooth"
|
||||||
"/var/lib/nixos"
|
"/persist/var/lib/nixos"
|
||||||
"/var/lib/private"
|
"/persist/var/lib/private"
|
||||||
"/etc/NetworkManager/system-connections"
|
"/persist/etc/NetworkManager/system-connections"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Remove staging snapshots after backup completes
|
postHook = let
|
||||||
postHook = ''
|
subvolumes = [
|
||||||
for subvol in containers forgejo lighttpd minecraft opengist; do
|
"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 \
|
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
|
||||||
"/.staging-offsite/$subvol"
|
"/btrfs-subvolumes/$subvol"
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
@ -72,7 +98,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 = "daily";
|
startAt = "*-*-* 00:15:00"; # Daily at 12:15 AM
|
||||||
|
|
||||||
# Ensure backup runs on next boot if system was asleep
|
# Ensure backup runs on next boot if system was asleep
|
||||||
persistentTimer = true;
|
persistentTimer = true;
|
||||||
|
|
|
||||||
|
|
@ -17,55 +17,76 @@ in {
|
||||||
|
|
||||||
# Create staging directory before borg service starts
|
# Create staging directory before borg service starts
|
||||||
systemd.tmpfiles.rules = [
|
systemd.tmpfiles.rules = [
|
||||||
"d /.staging-onsite 0755 root root -"
|
"d /btrfs-subvolumes 0755 root root -"
|
||||||
];
|
];
|
||||||
|
|
||||||
services.borgbackup.jobs."onsite" = {
|
services.borgbackup.jobs."onsite" = {
|
||||||
# Allow writing to staging directory
|
# Allow writing to staging directory
|
||||||
readWritePaths = [ "/.staging-onsite" ];
|
readWritePaths = [ "/btrfs-subvolumes" ];
|
||||||
|
|
||||||
# Create staging snapshots before backup (independent from offsite)
|
preHook = let
|
||||||
preHook = ''
|
subvolumes = [
|
||||||
# Create read-only staging snapshots for each service
|
"srv-containers"
|
||||||
for subvol in containers forgejo lighttpd minecraft opengist; do
|
"srv-forgejo"
|
||||||
# Map config names to actual subvolume paths
|
"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
|
case "$subvol" in
|
||||||
containers) src="/srv/multimedia/containers" ;;
|
srv-containers) src="/srv/multimedia/containers" ;;
|
||||||
*) src="/srv/$subvol" ;;
|
srv-*) src="/srv/''${subvol#srv-}" ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \
|
${pkgs.btrfs-progs}/bin/btrfs subvolume snapshot -r \
|
||||||
"$src" "/.staging-onsite/$subvol"
|
"$src" "/btrfs-subvolumes/$subvol"
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# Backup staging snapshots and explicit persistent files
|
# Backup staging snapshots and explicit persistent files
|
||||||
paths = [
|
paths = [
|
||||||
"/.staging-onsite/containers"
|
"/btrfs-subvolumes/srv-containers"
|
||||||
"/.staging-onsite/forgejo"
|
"/btrfs-subvolumes/srv-forgejo"
|
||||||
"/.staging-onsite/lighttpd"
|
"/btrfs-subvolumes/srv-lighttpd"
|
||||||
"/.staging-onsite/minecraft"
|
"/btrfs-subvolumes/srv-minecraft"
|
||||||
"/.staging-onsite/opengist"
|
"/btrfs-subvolumes/srv-opengist"
|
||||||
|
|
||||||
# Files from persist.nix (restore to /persist)
|
# Persistent files (actual storage location)
|
||||||
"/etc/machine-id"
|
"/persist/etc/machine-id"
|
||||||
"/etc/ssh/ssh_host_rsa_key"
|
"/persist/etc/ssh/ssh_host_rsa_key"
|
||||||
"/etc/ssh/ssh_host_rsa_key.pub"
|
"/persist/etc/ssh/ssh_host_rsa_key.pub"
|
||||||
"/etc/ssh/ssh_host_ed25519_key"
|
"/persist/etc/ssh/ssh_host_ed25519_key"
|
||||||
"/etc/ssh/ssh_host_ed25519_key.pub"
|
"/persist/etc/ssh/ssh_host_ed25519_key.pub"
|
||||||
|
|
||||||
# Directories from persist.nix (restore to /persist)
|
# Persistent directories (actual storage location)
|
||||||
"/var/lib/bluetooth"
|
"/persist/var/lib/bluetooth"
|
||||||
"/var/lib/nixos"
|
"/persist/var/lib/nixos"
|
||||||
"/var/lib/private"
|
"/persist/var/lib/private"
|
||||||
"/etc/NetworkManager/system-connections"
|
"/persist/etc/NetworkManager/system-connections"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Remove staging snapshots after backup completes
|
postHook = let
|
||||||
postHook = ''
|
subvolumes = [
|
||||||
for subvol in containers forgejo lighttpd minecraft opengist; do
|
"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 \
|
${pkgs.btrfs-progs}/bin/btrfs subvolume delete \
|
||||||
"/.staging-onsite/$subvol"
|
"/btrfs-subvolumes/$subvol"
|
||||||
done
|
done
|
||||||
'';
|
'';
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue