#!/usr/bin/env bash # Self-contained Athena reinstall entry point. This file is copied into a # root-only recovery kit on /data; it is not run during normal installation. set -Eeuo pipefail umask 077 KIT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) CONFIG="$KIT_DIR/kit.env" WORK_DIR=/var/lib/mike-ai-data-reinstall SERVICE=/etc/systemd/system/mike-ai-data-reinstall.service die() { printf 'FEHLER: %s\n' "$*" >&2; exit 1; } log() { printf '\n==> %s\n' "$*"; } [[ $EUID -eq 0 ]] || die "Bitte als root ausführen." [[ -s $CONFIG ]] || die "kit.env fehlt im Recovery-Kit." # shellcheck disable=SC1090 source "$CONFIG" required=(RECOVERY_COMMIT RECOVERY_BUNDLE SOURCE_BUNDLE AGE_IDENTITY) for name in "${required[@]}"; do [[ -n ${!name:-} ]] || die "Pflichtwert $name fehlt." done for file in "$RECOVERY_BUNDLE" "$SOURCE_BUNDLE" "$AGE_IDENTITY"; do [[ -s $KIT_DIR/$file ]] || die "Recovery-Datei fehlt: $file" done log "Recovery-Kit kryptografisch prüfen" (cd "$KIT_DIR" && sha256sum -c SHA256SUMS) log "Persistenten Mount für die Data-SSD sicherstellen" [[ $(findmnt -n -o TARGET --target "$KIT_DIR") == /data ]] || \ die "Recovery-Kit liegt nicht auf dem eingehängten /data-Dateisystem." if ! findmnt -s -n -o TARGET | grep -qx /data; then source_device=$(findmnt -n -o SOURCE --target "$KIT_DIR") source_uuid=$(blkid -s UUID -o value "$source_device") source_type=$(findmnt -n -o FSTYPE --target "$KIT_DIR") [[ -n $source_uuid && -n $source_type ]] || \ die "UUID oder Dateisystemtyp der Data-SSD konnte nicht bestimmt werden." printf 'UUID=%s /data %s defaults,nofail,x-systemd.device-timeout=30 0 2\n' \ "$source_uuid" "$source_type" >>/etc/fstab systemctl daemon-reload fi log "Minimale Wiederherstellungswerkzeuge installieren" apt-get update DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ age ca-certificates git rsync install -d -m 0700 "$WORK_DIR" if [[ ! -d $WORK_DIR/repository/.git ]]; then git clone "$KIT_DIR/$SOURCE_BUNDLE" "$WORK_DIR/repository" fi git -C "$WORK_DIR/repository" checkout --detach "$RECOVERY_COMMIT" [[ $(git -C "$WORK_DIR/repository" rev-parse HEAD) == "$RECOVERY_COMMIT" ]] || \ die "Der geforderte Recovery-Commit ist nicht ausgecheckt." attempt=0 [[ ! -s $WORK_DIR/attempt ]] || attempt=$(<"$WORK_DIR/attempt") (( attempt += 1 )) printf '%s\n' "$attempt" >"$WORK_DIR/attempt" (( attempt <= 3 )) || die "Mehr als drei automatische Recovery-Versuche; Abbruch gegen Bootschleife." log "Bare-Metal-Wiederherstellung ausführen (Versuch $attempt/3)" set +e "$WORK_DIR/repository/platform/recovery/restore-recovery-bundle.sh" \ "$KIT_DIR/$RECOVERY_BUNDLE" "$KIT_DIR/$AGE_IDENTITY" status=$? set -e if [[ $status == 20 || $status == 21 ]]; then log "Ein kontrollierter Treiber-/Netzwerk-Neustart ist erforderlich" cat >"$SERVICE" </dev/null 2>&1 || true rm -f "$SERVICE" "$WORK_DIR/attempt" systemctl daemon-reload printf '\nDATA_DISK_REINSTALL_OK\n' printf 'OpenWebUI, Router, Modelle und MCPs wurden wiederhergestellt.\n'