feat: nightly rsync backup to tank with rrsync-restricted key and sanoid history

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mortdecai
2026-09-15 19:09:16 -04:00
parent 0d733c77e7
commit 6643ac003c
3 changed files with 35 additions and 0 deletions
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key><string>xyz.sethpc.mac-backup</string>
<key>ProgramArguments</key><array><string>/Users/seth/mac/scripts/backup.sh</string></array>
<key>StartCalendarInterval</key><dict><key>Hour</key><integer>3</integer><key>Minute</key><integer>30</integer></dict>
<key>StandardOutPath</key><string>/Users/seth/Library/Logs/mac-backup.log</string>
<key>StandardErrorPath</key><string>/Users/seth/Library/Logs/mac-backup.log</string>
</dict></plist>
+10
View File
@@ -0,0 +1,10 @@
#!/opt/homebrew/bin/bash
# Nightly by launchd (config/xyz.sethpc.mac-backup.plist). Mirrors the DAW-relevant
# dirs to tank. History comes from sanoid snapshots of tank/backups/mac on pve173,
# which is what makes `--delete` safe.
set -euo pipefail
src=()
for d in "$HOME/Music/Ableton" "$HOME/Documents"; do [[ -d $d ]] && src+=("$d"); done
[[ ${#src[@]} -gt 0 ]] || { echo "nothing to back up yet"; exit 0; }
# Remote path is relative to the rrsync root (/tank/backups/mac) set in root's authorized_keys on pve173.
exec /opt/homebrew/bin/rsync -a --delete -e 'ssh -o BatchMode=yes' "${src[@]}" root@192.168.0.173:/
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
# Run on pve173: ssh pve173 'bash -s' -- "<pubkey>" < scripts/tank-side.sh
set -euo pipefail
PUB=${1:?pubkey line required}
[[ $PUB == ssh-ed25519* ]] || { echo "not a pubkey: $PUB"; exit 1; }
DS=tank/backups/mac; TS=$(date +%s)
zfs list "$DS" >/dev/null 2>&1 && echo "[skip] dataset $DS" || { zfs create "$DS"; echo "[set] created $DS"; }
if grep -q "^\[$DS\]" /etc/sanoid/sanoid.conf; then echo "[skip] sanoid stanza"; else
mkdir -p /etc/sanoid/.backup; cp /etc/sanoid/sanoid.conf "/etc/sanoid/.backup/sanoid.conf-$TS"
printf '\n[%s]\n\tuse_template = tank_media\n' "$DS" >> /etc/sanoid/sanoid.conf; echo "[set] sanoid stanza"
fi
KEYLINE="restrict,command=\"/usr/bin/rrsync /$DS\" $PUB"
if grep -qF "$PUB" /root/.ssh/authorized_keys; then echo "[skip] key present"; else
cp /root/.ssh/authorized_keys "/root/.ssh/authorized_keys.bak-$TS"
echo "$KEYLINE" >> /root/.ssh/authorized_keys; echo "[set] rrsync-restricted key added"
fi