Files
2026-05-31 17:36:33 +00:00

123 lines
4.0 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# =============================================================================
# restore-postgres.sh Wiederherstellung einer PostgreSQL-Datenbank aus Borg
# Läuft auf dem Raspberry Pi
# =============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="${SCRIPT_DIR}/../config/backup.conf"
source "$CONFIG_FILE"
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
log() { echo -e "${BLUE}[RESTORE]${NC} $*"; }
log_ok() { echo -e "${GREEN}[RESTORE] ✓${NC} $*"; }
log_warn(){ echo -e "${YELLOW}[RESTORE] ⚠${NC} $*"; }
log_err() { echo -e "${RED}[RESTORE] ✗${NC} $*" >&2; }
export BORG_PASSPHRASE
export BORG_REPO
usage() {
echo ""
echo "Verwendung: $0 [OPTIONEN]"
echo ""
echo "Optionen:"
echo " -l, --list Verfügbare Archive auflisten"
echo " -a, --archive ARCHIVE Archiv-Name (z.B. mydb-2025-01-15T02:30)"
echo " -d, --database DB Ziel-Datenbank für Wiederherstellung"
echo " -t, --target-host HOST Ziel-Host (Standard: ${PG_HOST})"
echo " -o, --output-dir DIR Nur als Datei extrahieren (kein DB-Import)"
echo " -h, --help Diese Hilfe anzeigen"
echo ""
echo "Beispiele:"
echo " $0 --list"
echo " $0 --archive mydb-2025-01-15T02:30 --database mydb_restored"
echo " $0 --archive mydb-2025-01-15T02:30 --output-dir /tmp/restore"
echo ""
exit 0
}
list_archives() {
log "Verfügbare Archive in ${BORG_REPO}:"
echo ""
borg list --short "${BORG_REPO}" | sort -r | while read -r archive; do
local info
info=$(borg info "${BORG_REPO}::${archive}" 2>/dev/null | grep -E "Time|Duration|Deduplicated" || echo "")
echo " 📦 ${archive}"
echo "$info" | sed 's/^/ /'
echo ""
done
}
restore_to_db() {
local archive="$1"
local target_db="$2"
local target_host="${3:-$PG_HOST}"
log_warn "ACHTUNG: Datenbank '${target_db}' auf '${target_host}' wird überschrieben!"
read -rp "Fortfahren? (ja/NEIN): " confirm
[[ "$confirm" != "ja" ]] && { log "Abgebrochen."; exit 0; }
log "Stelle '${archive}' → '${target_db}' auf '${target_host}' wieder her..."
# Dump aus Borg extrahieren und direkt per SSH zu pg_restore pipen
borg extract --stdout "${BORG_REPO}::${archive}" \
| ssh -i "${SSH_KEY_PATH}" \
-o StrictHostKeyChecking=accept-new \
"${PG_SSH_USER}@${target_host}" \
"sudo -u ${PG_DB_USER} pg_restore \
--dbname=${target_db} \
--no-owner \
--no-privileges \
--clean \
--if-exists \
--format=custom"
log_ok "Wiederherstellung abgeschlossen!"
}
extract_to_dir() {
local archive="$1"
local output_dir="$2"
mkdir -p "$output_dir"
log "Extrahiere '${archive}' nach '${output_dir}'..."
borg extract --destination "$output_dir" "${BORG_REPO}::${archive}"
log_ok "Datei(en) in: ${output_dir}"
ls -lh "$output_dir"
}
# --- Argumente parsen --------------------------------------------------------
LIST=false
ARCHIVE=""
DATABASE=""
TARGET_HOST="${PG_HOST}"
OUTPUT_DIR=""
while [[ $# -gt 0 ]]; do
case "$1" in
-l|--list) LIST=true ;;
-a|--archive) ARCHIVE="$2"; shift ;;
-d|--database) DATABASE="$2"; shift ;;
-t|--target-host) TARGET_HOST="$2"; shift ;;
-o|--output-dir) OUTPUT_DIR="$2"; shift ;;
-h|--help) usage ;;
*) log_err "Unbekannte Option: $1"; usage ;;
esac
shift
done
# --- Hauptlogik --------------------------------------------------------------
if $LIST; then
list_archives
elif [[ -n "$ARCHIVE" && -n "$OUTPUT_DIR" ]]; then
extract_to_dir "$ARCHIVE" "$OUTPUT_DIR"
elif [[ -n "$ARCHIVE" && -n "$DATABASE" ]]; then
restore_to_db "$ARCHIVE" "$DATABASE" "$TARGET_HOST"
else
log_err "Keine gültige Aktion angegeben."
usage
fi