#!/usr/bin/env bash # Wiederherstellung eines mc2-state-Backups (siehe backup.sh). # Stoppt die Dienste, spielt den Zustand zurück, startet neu — und macht VORHER # automatisch ein Sicherheits-Backup des aktuellen Zustands (Restore ist reversibel). # # Nutzung: # bash restore.sh --list # vorhandene Backups zeigen # bash restore.sh --dry-run # nur anzeigen, was passieren würde # bash restore.sh [--yes] # wiederherstellen (--yes = ohne Rückfrage) set -euo pipefail MODELS_DIR="${MC_MODELS_DIR:-/srv/models}" DEST_DIR="$MODELS_DIR/mc2-backups" MEM0_DIR="${MC_MEM0_DIR:-/srv/models/mem0}" LSWAP="${MC_CONFIG_PATH:-/etc/llama-swap/config.yaml}" HERMES="${HERMES_HOME:-$HOME/.hermes}" SRC="${MC2_SRC:-$HOME/mission-control-v2}" SERVICES="mem0-service mission-control-2 hermes-gateway" usage() { echo "Nutzung: restore.sh --list | restore.sh [--dry-run] [--yes] "; } list_backups() { echo "Verfügbare Backups in $DEST_DIR:" ls -1t "$DEST_DIR"/mc2-state-*.tar.gz 2>/dev/null | while read -r f; do printf " %s (%s)\n" "$(basename "$f")" "$(du -h "$f" | cut -f1)" done [ -n "$(ls -A "$DEST_DIR"/mc2-state-*.tar.gz 2>/dev/null || true)" ] || echo " (keine)" } [ $# -eq 0 ] && { usage; exit 1; } DRY=0; YES=0; TARGET="" for a in "$@"; do case "$a" in --list) list_backups; exit 0 ;; --dry-run) DRY=1 ;; --yes) YES=1 ;; -*) usage; exit 1 ;; *) TARGET="$a" ;; esac done [ -z "$TARGET" ] && { usage; exit 1; } [ "$TARGET" = "latest" ] && TARGET="$(ls -1t "$DEST_DIR"/mc2-state-*.tar.gz 2>/dev/null | head -1 || true)" [ -f "$TARGET" ] || TARGET="$DEST_DIR/$(basename "${TARGET:-}")" [ -f "$TARGET" ] || { echo "Backup nicht gefunden: ${TARGET:-}"; echo; list_backups; exit 1; } echo "Restore-Quelle: $TARGET" STAGE="$(mktemp -d)"; trap 'rm -rf "$STAGE"' EXIT tar -xzf "$TARGET" -C "$STAGE" echo "--- Inhalt ---"; cat "$STAGE/MANIFEST.txt" 2>/dev/null || true; echo "--------------" if [ "$DRY" = 1 ]; then echo "[dry-run] würde zurücksetzen:" [ -d "$STAGE/mem0" ] && echo " • mem0 → $MEM0_DIR (wird ersetzt)" [ -f "$STAGE/hermes/config.yaml" ] && echo " • $HERMES/config.yaml" [ -f "$STAGE/hermes/.env" ] && echo " • $HERMES/.env" [ -d "$STAGE/hermes/plugins" ] && echo " • $HERMES/plugins/" [ -f "$STAGE/llama-swap/config.yaml" ] && echo " • $LSWAP" echo " • Dienste neu starten: $SERVICES" exit 0 fi if [ "$YES" != 1 ]; then echo "WARNUNG: Das überschreibt den AKTUELLEN Zustand und startet die Dienste neu." read -r -p "Fortfahren? (tippe 'ja'): " ans [ "$ans" = "ja" ] || { echo "Abgebrochen."; exit 1; } fi echo "→ Sicherheits-Backup des aktuellen Zustands…" bash "$SRC/deploy/backup.sh" || echo " (Pre-Restore-Backup fehlgeschlagen — fahre fort)" echo "→ Dienste stoppen…" systemctl --user stop $SERVICES 2>/dev/null || true if [ -d "$STAGE/mem0" ]; then rm -rf "$MEM0_DIR"; mkdir -p "$MEM0_DIR"; cp -a "$STAGE/mem0/." "$MEM0_DIR/"; fi [ -f "$STAGE/hermes/config.yaml" ] && { mkdir -p "$HERMES"; cp -a "$STAGE/hermes/config.yaml" "$HERMES/"; } [ -f "$STAGE/hermes/.env" ] && cp -a "$STAGE/hermes/.env" "$HERMES/" [ -d "$STAGE/hermes/plugins" ] && { mkdir -p "$HERMES/plugins"; cp -a "$STAGE/hermes/plugins/." "$HERMES/plugins/"; } [ -f "$STAGE/llama-swap/config.yaml" ] && cp -a "$STAGE/llama-swap/config.yaml" "$LSWAP" 2>/dev/null || true echo "→ Dienste starten…" systemctl --user start $SERVICES 2>/dev/null || true sleep 4 printf "→ Health: "; curl -sf http://127.0.0.1:9001/api/health && echo || echo "(Backend nicht erreichbar — Logs prüfen)" echo "OK — Restore abgeschlossen."