#!/bin/bash # Nightly wiz-war ledger backup to DigitalOcean Spaces. # current/ - exact mirror of /var/lib/wizwar # snapshots/ - one dated copy per day, pruned after 90 days # Ledgers are append-only JSONL; the game server never needs stopping. set -u BUCKET="kestrel-wizwar-backups" SRC="/var/lib/wizwar" LOG="/var/log/wizwar/backup.log" STAMP=$(date +%Y-%m-%d) # Sentry Crons check-in: /root/.wizwar-sentry-cron holds the check-in URL # (auto-creates the monitor on first ping). Absent file = no check-ins. CRON_URL=$(cat /root/.wizwar-sentry-cron 2>/dev/null || true) checkin() { [ -n "$CRON_URL" ] && curl -sf -o /dev/null "$CRON_URL?status=$1" || true; } if grep -q CHANGE_ME /root/.config/rclone/rclone.conf; then echo "$(date -Is) skipped: Spaces credentials not configured yet" >> "$LOG" exit 0 fi { echo "=== $(date -Is) backup start" checkin in_progress if rclone sync "$SRC" "spaces:$BUCKET/wizwar/current" 2>&1 && rclone copy "$SRC" "spaces:$BUCKET/wizwar/snapshots/$STAMP" 2>&1; then checkin ok else checkin error fi # Prune dated snapshots older than 90 days (by directory name). CUTOFF=$(date -d "90 days ago" +%Y-%m-%d) rclone lsf "spaces:$BUCKET/wizwar/snapshots/" --dirs-only 2>/dev/null | \ while read -r d; do day="${d%/}" if [[ "$day" < "$CUTOFF" ]]; then echo "pruning snapshot $day" rclone purge "spaces:$BUCKET/wizwar/snapshots/$day" 2>&1 fi done echo "=== $(date -Is) backup done" } >> "$LOG"