Dateien nach "scripts" hochladen
This commit is contained in:
@@ -0,0 +1,122 @@
|
|||||||
|
#!/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
|
||||||
Reference in New Issue
Block a user