refactor: move backup/restore worker scripts to extras/ as source files
Replace embedded heredocs in the three backup service installers with cp from versioned source files in extras/: extras/backup_kopia.sh — Kopia worker (was inline in services/backup.sh) extras/backup_borg.sh — Borg worker (was inline in services/borg-backup.sh) extras/backup_gaming.sh — gaming saves worker (was inline in services/gaming-backup.sh) extras/restore_kopia.sh — unified Kopia restore (multi-dest + single-dest) extras/restore_borg.sh — unified Borg restore with destination picker Each installer now does `cp extras/<script>.sh $DIR/<script>.sh` instead of writing the script inline. Workers and restore scripts are now readable in the repo rather than buried in heredocs. Restore scripts are installed flat into the service directory root: ~/docker/backup/backup_kopia.sh ~/docker/backup/restore_kopia.sh ~/docker/borg-backup/backup_borg.sh ~/docker/borg-backup/restore_borg.sh ~/docker/gaming-backup/backup_gaming.sh ~/docker/gaming-backup/restore_kopia.sh The new restore scripts handle destination selection internally, so a single script replaces the old per-destination restore/<dest>/ layout. Also fixes `local` used outside a function in restore_kopia.sh and restore_borg.sh (destination picker loop), and removes the now-superseded extras/restore_kopia_backup.sh and extras/restore_borg_backup.sh. https://claude.ai/code/session_019XgsQ13XKm4Zj3cNsDNwHj
This commit is contained in:
+11
-96
@@ -26,7 +26,7 @@ install_gaming_backup() {
|
||||
# ── Repo-conventional paths ──────────────────────────────────────────────
|
||||
local BACKUP_DIR="$DOCKER_DIR/gaming-backup"
|
||||
local CONF_FILE="$BACKUP_DIR/backup.conf" # editable settings
|
||||
local WORKER="$BACKUP_DIR/gaming-backup.sh" # generated worker
|
||||
local WORKER="$BACKUP_DIR/backup_gaming.sh" # worker script
|
||||
local KOPIA_CONFIG="/etc/gaming-backup/repository.config"
|
||||
local CACHE_DIR="/var/cache/gaming-backup"
|
||||
local SVC_NAME="post-install-gaming-backup"
|
||||
@@ -273,108 +273,23 @@ CONFEOF
|
||||
|| log_warning "Could not pre-set Steam ignore policy (applies on first snapshot)."
|
||||
fi
|
||||
|
||||
# ── 7. Generate the worker script ────────────────────────────────────────
|
||||
log_info "Writing worker $WORKER ..."
|
||||
cat > "$WORKER" << 'WORKEREOF'
|
||||
#!/bin/bash
|
||||
# Generated by the gaming-backup service — frequent game-save snapshots via Kopia.
|
||||
# Nothing is stopped: Minecraft worlds are flushed to disk (save-all) first.
|
||||
#
|
||||
# sudo ./gaming-backup.sh run a backup now
|
||||
# sudo ./gaming-backup.sh snapshots list snapshots
|
||||
# sudo ./gaming-backup.sh policy show retention/ignore policy
|
||||
#
|
||||
# Reads settings from backup.conf next to this script.
|
||||
set -uo pipefail
|
||||
|
||||
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
CONF="${BACKUP_CONF:-$HERE/backup.conf}"
|
||||
[ -f "$CONF" ] || { echo "Config not found: $CONF (re-run the gaming-backup service)"; exit 1; }
|
||||
# shellcheck source=/dev/null
|
||||
source "$CONF"
|
||||
|
||||
export KOPIA_PASSWORD
|
||||
log() { echo "[$(date '+%F %T')] $*"; }
|
||||
k() { "$KOPIA" --config-file="$KOPIA_CONFIG" "$@"; }
|
||||
|
||||
if ! k repository status >/dev/null 2>&1; then
|
||||
log "ERROR: not connected to a repository — re-run the gaming-backup service"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "${1:-run}" in
|
||||
snapshots) k snapshot list; exit 0 ;;
|
||||
policy) k policy show --global; exit 0 ;;
|
||||
esac
|
||||
|
||||
log "===== Gaming backup starting ====="
|
||||
|
||||
# Flush each running Minecraft world to disk first so snapshots are consistent.
|
||||
if [ -n "${MC_BASE_DIR:-}" ] && command -v docker >/dev/null 2>&1; then
|
||||
_flushed=0
|
||||
for d in "$MC_BASE_DIR"/*/; do
|
||||
[ -f "${d}Dockerfile" ] && grep -qs itzg "${d}Dockerfile" || continue
|
||||
name="$(basename "$d")"
|
||||
if docker ps --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
||||
log "Flushing Minecraft world '$name' (save-all)..."
|
||||
docker exec "$name" mc-send-to-console save-all flush 2>/dev/null \
|
||||
|| docker exec "$name" rcon-cli save-all 2>/dev/null || true
|
||||
_flushed=1
|
||||
fi
|
||||
done
|
||||
[ "$_flushed" = 1 ] && sleep 5
|
||||
fi
|
||||
|
||||
rc=0
|
||||
snap() {
|
||||
local label="$1" path="$2"
|
||||
if [ -z "$path" ] || [ ! -e "$path" ]; then
|
||||
log "skip $label — not found: ${path:-<unset>}"; return
|
||||
fi
|
||||
log "Snapshotting $label: $path"
|
||||
if ! k snapshot create --description="gaming: $label" "$path"; then
|
||||
log "WARNING: snapshot failed for $label"; rc=1
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -n "${MC_BASE_DIR:-}" ]; then
|
||||
for d in "$MC_BASE_DIR"/*/; do
|
||||
[ -f "${d}Dockerfile" ] && grep -qs itzg "${d}Dockerfile" && [ -d "${d}data" ] || continue
|
||||
nm="$(basename "$d")"
|
||||
case "$nm" in minecraft*) lbl="$nm" ;; *) lbl="minecraft-$nm" ;; esac
|
||||
snap "$lbl" "${d}data"
|
||||
done
|
||||
fi
|
||||
[ "${BACKUP_SAVES:-no}" = yes ] && snap "emulator-saves" "$GAME_STORAGE_DIR/saves"
|
||||
[ "${BACKUP_STEAM:-no}" = yes ] && snap "steam-userdata" "$GAME_STORAGE_DIR/steam"
|
||||
[ "${BACKUP_MEDIA:-no}" = yes ] && snap "es-de-media" "$GAME_STORAGE_DIR/media"
|
||||
[ "${BACKUP_WOLF:-no}" = yes ] && snap "wolf-state" "$WOLF_STATE_DIR"
|
||||
|
||||
if [ "${REMOTE_TYPE:-none}" != "none" ] && [ -n "${REMOTE_TYPE:-}" ]; then
|
||||
log "Mirroring repository to remote ($REMOTE_TYPE)..."
|
||||
# shellcheck disable=SC2086
|
||||
if ! k repository sync-to "$REMOTE_TYPE" $REMOTE_ARGS; then
|
||||
log "WARNING: remote mirror failed"; rc=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$rc" -eq 0 ]; then log "===== Gaming backup complete ====="; else log "===== Gaming backup finished WITH WARNINGS ====="; fi
|
||||
exit "$rc"
|
||||
WORKEREOF
|
||||
# ── 7. Install the worker script ─────────────────────────────────────────
|
||||
log_info "Installing worker $WORKER ..."
|
||||
cp "${HERE:-}/extras/backup_gaming.sh" "$WORKER"
|
||||
chmod +x "$WORKER"
|
||||
chown root:root "$WORKER" 2>/dev/null || true
|
||||
log_success "gaming-backup.sh written"
|
||||
log_success "backup_gaming.sh installed"
|
||||
|
||||
# ── Copy the interactive restore script ───────────────────────────────────
|
||||
local RESTORE_SRC="${HERE:-}/extras/restore_kopia_backup.sh"
|
||||
local RESTORE_DEST="$BACKUP_DIR/restore_kopia_backup.sh"
|
||||
local RESTORE_SRC="${HERE:-}/extras/restore_kopia.sh"
|
||||
local RESTORE_DEST="$BACKUP_DIR/restore_kopia.sh"
|
||||
if [ -f "$RESTORE_SRC" ]; then
|
||||
cp "$RESTORE_SRC" "$RESTORE_DEST"
|
||||
chmod +x "$RESTORE_DEST"
|
||||
chown root:root "$RESTORE_DEST" 2>/dev/null || true
|
||||
log_success "restore_kopia_backup.sh installed"
|
||||
log_success "restore_kopia.sh installed"
|
||||
else
|
||||
log_warning "extras/restore_kopia_backup.sh not found — restore script not installed"
|
||||
log_warning "extras/restore_kopia.sh not found — restore script not installed"
|
||||
fi
|
||||
|
||||
# ── 8. Install systemd timer (fallback: cron) ────────────────────────────
|
||||
@@ -452,8 +367,8 @@ UNITEOF
|
||||
echo " Commands:"
|
||||
echo " sudo $WORKER back up now"
|
||||
echo " sudo $WORKER snapshots list snapshots"
|
||||
echo " sudo $RESTORE_DEST interactive restore"
|
||||
echo " sudo $RESTORE_DEST --list list all snapshot sources"
|
||||
echo " sudo $RESTORE_DEST interactive restore"
|
||||
echo " sudo $RESTORE_DEST --list list all snapshot sources"
|
||||
echo " $AUTORUN"
|
||||
echo ""
|
||||
echo " Tip: also install the 'backup' service for nightly full-service recovery."
|
||||
|
||||
Reference in New Issue
Block a user