Add self-contained data-disk reinstall kit

This commit is contained in:
Mikei386
2026-08-23 16:20:37 +02:00
parent ddae3e9bad
commit c226af7bc7
3 changed files with 196 additions and 0 deletions
+100
View File
@@ -0,0 +1,100 @@
#!/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" <<EOF
[Unit]
Description=Resume MikeAI data-disk disaster recovery
After=network-online.target local-fs.target
Wants=network-online.target
RequiresMountsFor=/data
[Service]
Type=oneshot
ExecStart=$KIT_DIR/reinstall-athena.sh --resume
StandardOutput=append:/var/log/mike-ai-data-reinstall.log
StandardError=append:/var/log/mike-ai-data-reinstall.log
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable mike-ai-data-reinstall.service
sync
systemctl reboot
exit 0
fi
[[ $status == 0 ]] || die "Wiederherstellung ist mit Status $status fehlgeschlagen."
systemctl disable mike-ai-data-reinstall.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'