phase0: Nachtmeldungen kommen wieder an, Sicherung mit Lucys Gedaechtnis, Token-Datei raus
Ampel / ampel (push) Successful in 26s
Ampel / ampel (push) Successful in 26s
- notify.sh sammelt nachts (00-07 Uhr) wie bisher, aber jetzt liefert mc2-morgenmeldung.timer um 07:00 alles als eine Telegram-Nachricht aus. Seit dem 21.08. las niemand die Warteschlange, alle Nachtmeldungen (auch die Sonntags-Updates) gingen verloren. Dringendes (-d, Betreff Alarm/Notfall, Text beginnt mit KRITISCH) geht sofort raus; autoupdate.sh markiert seine KRITISCH-Meldungen ausdruecklich. - backup.sh sichert zusaetzlich ~/.hermes/memories, SOUL.md, skills/, scripts/, den Box-Wart-Zustand (/srv/models/mc2-*.json), User-Units, llama-swap-Drop-ins und Lucys Stimmreferenz. restore.sh spielt Gedaechtnis und Zustand nur zurueck, wenn sie fehlen oder --mit-gedaechtnis gesetzt ist. - Update-Verlauf zaehlt die Morgenmeldung nicht als eigenen Lauf. - Waechter und Flugplan kennen den neuen Timer; deploy.sh installiert ihn. - .claude/settings.local.json aus dem Repo genommen (lokal behalten), .gitignore ergaenzt. - ruff wieder gruen (4x RUF100), AGENTS.md: Deploy macht git pull, Remote ist SSH. Tests: 86 gruen (neu: Nachtruhe, Dringendes, Morgenmeldung inkl. Telegram-Ausfall). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
4a05bc2a05
commit
648be33d21
@@ -26,6 +26,8 @@ export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
|
||||
|
||||
say(){ echo "[autoupdate] $*"; }
|
||||
notify(){ bash "$SRC_DIR/notify.sh" -s "[Box-Update]" "$1" || true; }
|
||||
# Dringend = geht auch nachts sofort raus (sonst sammelt notify.sh bis zur Morgenmeldung um 07:00).
|
||||
notify_dringend(){ bash "$SRC_DIR/notify.sh" -d -s "[Box-Update]" "$1" || true; }
|
||||
|
||||
SUMMARY=() # eine Zeile je Ebene für die Abschluss-Meldung
|
||||
|
||||
@@ -59,7 +61,7 @@ run_root_update(){ # $1 komponente(swap|engine) $2 skript $3 anzeigename $4
|
||||
SUMMARY+=("$name: $latest FEHLGESCHLAGEN → zurückgerollt auf $installed + GEPINNT.")
|
||||
notify "$name-Update auf $latest fehlgeschlagen (Stack-Check rot). Automatisch zurückgerollt auf $installed — läuft wieder. Ebene ist jetzt GEPINNT, künftige Läufe überspringen sie." ;;
|
||||
*) SUMMARY+=("$name: KRITISCH — Update UND Rollback fehlgeschlagen!")
|
||||
notify "KRITISCH: $name-Update auf $latest UND Rollback fehlgeschlagen — Stack möglicherweise kaputt. Bitte melden, ich brauche Hilfe (Backup liegt bereit, restore.sh existiert)." ;;
|
||||
notify_dringend "KRITISCH: $name-Update auf $latest UND Rollback fehlgeschlagen — Stack möglicherweise kaputt. Bitte melden, ich brauche Hilfe (Backup liegt bereit, restore.sh existiert)." ;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -162,7 +164,7 @@ Wahrscheinliche Ursache/Fix (Box-Diagnose): $sugg}"
|
||||
fi
|
||||
fi
|
||||
SUMMARY+=("$name: KRITISCH — Update UND Rollback fehlgeschlagen!")
|
||||
notify "KRITISCH: Hermes-Update UND Rollback fehlgeschlagen — Gehirn-Check bleibt rot. Bitte melden. (Voll-Restore: deploy/restore.sh mit dem letzten Backup.)"
|
||||
notify_dringend "KRITISCH: Hermes-Update UND Rollback fehlgeschlagen — Gehirn-Check bleibt rot. Bitte melden. (Voll-Restore: deploy/restore.sh mit dem letzten Backup.)"
|
||||
}
|
||||
|
||||
# ── Neustart, wenn das OS einen verlangt ─────────────────────────────────────
|
||||
|
||||
+22
-3
@@ -3,8 +3,10 @@
|
||||
# zurückkommt. Erzeugt EIN Tarball mc2-state-<ts>.tar.gz, behält die letzten N.
|
||||
# Läuft per systemd-Timer (täglich), manuell, oder über den UI-Snapshot-Button.
|
||||
#
|
||||
# Inhalt: ~/.hermes (config.yaml, .env, plugins/) · /etc/llama-swap/config.yaml ·
|
||||
# known-good/ (Versions-Manifest, s. u.)
|
||||
# Inhalt: ~/.hermes (config.yaml, .env, plugins/, cron/, state/) · /etc/llama-swap/config.yaml ·
|
||||
# seit 24.09.2026 auch Lucys Gedächtnis (memories/), SOUL.md, skills/, scripts/,
|
||||
# der Box-Wart-Zustand (/srv/models/mc2-*.json), User-Units, llama-swap-Drop-ins und
|
||||
# Lucys Stimmreferenz · known-good/ (Versions-Manifest, s. u.)
|
||||
# Das abgeloeste Gedaechtnis-Sidecar (/srv/models, Port 8765) faellt seit 27.08.2026 weg —
|
||||
# sein Datenverzeichnis existiert nicht mehr (Hintergrund: docs/wissen/VERDIKTE.md).
|
||||
# NICHT enthalten (bewusst): GGUF-Modelle (riesig, neu ladbar), MC2-Code (Git), venvs.
|
||||
@@ -47,6 +49,23 @@ _TOKDROPIN="$HOME/.config/systemd/user/hermes-builtin-ui.service.d/session-token
|
||||
# Release-Radar) still:
|
||||
[ -d "$HERMES/cron" ] && cp -a "$HERMES/cron" "$STAGE/hermes/cron" || true
|
||||
[ -d "$HERMES/state" ] && cp -a "$HERMES/state" "$STAGE/hermes/state" || true
|
||||
# Lucys Gedächtnis, Seele, Skills und Cron-Skripte (24.09.2026). Hermes ist die alleinige
|
||||
# Gedächtnis-Wahrheit — bis hierher fehlte das Gedächtnis in jeder Sicherung, ein Plattenausfall
|
||||
# hätte es gelöscht. restore.sh spielt diese Teile nur zurück, wenn sie fehlen oder ausdrücklich
|
||||
# gewünscht (--mit-gedaechtnis), damit ein Restore keine neueren Erinnerungen überschreibt.
|
||||
[ -d "$HERMES/memories" ] && cp -a "$HERMES/memories" "$STAGE/hermes/memories" || true
|
||||
[ -f "$HERMES/SOUL.md" ] && cp -a "$HERMES/SOUL.md" "$STAGE/hermes/" || true
|
||||
[ -d "$HERMES/skills" ] && cp -a "$HERMES/skills" "$STAGE/hermes/skills" || true
|
||||
[ -d "$HERMES/scripts" ] && cp -a "$HERMES/scripts" "$STAGE/hermes/scripts" || true
|
||||
# Box-Wart-Zustand: Radar, Wächter, Pins, Erinnerungen, Briefkasten.
|
||||
mkdir -p "$STAGE/box-wart"
|
||||
cp -a "$MODELS_DIR"/mc2-*.json "$STAGE/box-wart/" 2>/dev/null || true
|
||||
# Units und Drop-ins als Nachschlagewerk für einen Wiederaufbau (restore.sh fasst sie nicht an).
|
||||
mkdir -p "$STAGE/systemd"
|
||||
[ -d "$HOME/.config/systemd/user" ] && cp -a "$HOME/.config/systemd/user" "$STAGE/systemd/user" || true
|
||||
[ -d /etc/systemd/system/llama-swap.service.d ] && cp -a /etc/systemd/system/llama-swap.service.d "$STAGE/systemd/" || true
|
||||
# Lucys Stimmreferenz (nur die Aufnahme, das Programm drumherum ist neu installierbar).
|
||||
[ -f "$HOME/.lucy-stimme/app/ref.wav" ] && { mkdir -p "$STAGE/lucy-stimme"; cp -a "$HOME/.lucy-stimme/app/ref.wav" "$STAGE/lucy-stimme/"; } || true
|
||||
|
||||
# --- Known-Good-Manifest -----------------------------------------------------
|
||||
# Versions-Schnappschuss des LAUFENDEN Stacks: pip freeze je venv, Engine-Build,
|
||||
@@ -91,7 +110,7 @@ cat > "$STAGE/MANIFEST.txt" <<EOF
|
||||
mc2-state backup
|
||||
created : $TS
|
||||
host : $(hostname)
|
||||
inhalt : hermes (config.yaml, .env, plugins/), llama-swap (config.yaml), known-good/ (Versions-Manifest: pip freeze, Engine, Modelle)
|
||||
inhalt : hermes (config.yaml, .env, plugins/, cron/, state/, memories/, SOUL.md, skills/, scripts/), llama-swap (config.yaml), box-wart/ (mc2-*.json), systemd/ (Units, Drop-ins), lucy-stimme/ (ref.wav), known-good/ (Versions-Manifest: pip freeze, Engine, Modelle)
|
||||
restore : bash ~/mission-control-v2/deploy/restore.sh mc2-state-$TS.tar.gz
|
||||
EOF
|
||||
|
||||
|
||||
+3
-1
@@ -51,8 +51,10 @@ main() {
|
||||
# Das Modell-Radar (09/2026) ist die erste Unit, die deploy.sh selbst einspielt: Sie gehört ganz dem
|
||||
# Repo, auf der Box wird an ihr nichts von Hand gedreht. Die übrigen Units bleiben wie bisher Handarbeit.
|
||||
install -m 644 deploy/mc2-radar.service deploy/mc2-radar.timer "$HOME/.config/systemd/user/"
|
||||
# Morgenmeldung (24.09.2026): schickt um 07:00, was notify.sh nachts gesammelt hat.
|
||||
install -m 644 deploy/mc2-morgenmeldung.service deploy/mc2-morgenmeldung.timer "$HOME/.config/systemd/user/"
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now mc2-radar.timer
|
||||
systemctl --user enable --now mc2-radar.timer mc2-morgenmeldung.timer
|
||||
|
||||
# 4.5 Hermes Skills synchronisieren
|
||||
echo "Synchronisiere Hermes Skills..."
|
||||
|
||||
@@ -151,12 +151,12 @@ def main() -> int:
|
||||
print("UPSTREAM (Watchlist — was hat sich draussen getan?)")
|
||||
try:
|
||||
eintraege = json.loads(WATCHLIST.read_text(encoding="utf-8")).get("eintraege", [])
|
||||
except Exception as exc: # noqa: BLE001
|
||||
except Exception as exc:
|
||||
warn(f"Watchlist {WATCHLIST} nicht lesbar: {exc}")
|
||||
return 0
|
||||
try:
|
||||
state = json.loads(STATE.read_text(encoding="utf-8")) if STATE.exists() else {}
|
||||
except Exception: # noqa: BLE001
|
||||
except Exception:
|
||||
state = {}
|
||||
|
||||
for e in eintraege:
|
||||
@@ -170,7 +170,7 @@ def main() -> int:
|
||||
except urllib.error.HTTPError as exc:
|
||||
warn(f"{key}: nicht abrufbar (HTTP {exc.code})")
|
||||
continue
|
||||
except Exception as exc: # noqa: BLE001
|
||||
except Exception as exc:
|
||||
warn(f"{key}: nicht abrufbar ({type(exc).__name__}: {str(exc)[:60]})")
|
||||
continue
|
||||
|
||||
@@ -192,7 +192,7 @@ def main() -> int:
|
||||
tmp = STATE.with_suffix(".tmp")
|
||||
tmp.write_text(json.dumps(state, ensure_ascii=False, indent=1), encoding="utf-8")
|
||||
os.replace(tmp, STATE)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
except Exception as exc:
|
||||
warn(f"Zustand nicht speicherbar ({exc}) — naechster Lauf meldet alles erneut")
|
||||
return 0
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=MC2 Morgenmeldung (nachts gesammelte Meldungen als eine Telegram-Nachricht)
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/bin/bash %h/mission-control-v2/deploy/morgenmeldung.sh
|
||||
TimeoutStartSec=600
|
||||
@@ -0,0 +1,9 @@
|
||||
[Unit]
|
||||
Description=Täglich 07:00 die Morgenmeldung schicken
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 07:00:00
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
# Morgenmeldung (07:00, mc2-morgenmeldung.timer): schickt die nachts gesammelten Meldungen als
|
||||
# EINE Telegram-Nachricht. notify.sh parkt zwischen 00:00 und 06:59 alles Nicht-Dringende in der
|
||||
# Nacht-Warteschlange; ohne diesen Lauf käme es nie an (so geschehen vom 21.08. bis 24.09.2026).
|
||||
#
|
||||
# Scheitert Telegram dreimal, bleibt der Stapel liegen und kommt mit der nächsten Morgenmeldung —
|
||||
# verloren geht nichts. Leere Warteschlange = keine Nachricht.
|
||||
set -uo pipefail
|
||||
|
||||
QUEUE="${MC_NIGHT_QUEUE:-$HOME/.hermes/night-queue.txt}"
|
||||
ARBEIT="$QUEUE.senden"
|
||||
SRC_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
MAX_ZEICHEN="${MC_MORGENMELDUNG_MAX:-3500}" # Telegram erlaubt 4096 Zeichen je Nachricht
|
||||
VERSUCHE="${MC_MORGENMELDUNG_VERSUCHE:-3}"
|
||||
PAUSE="${MC_MORGENMELDUNG_PAUSE:-60}"
|
||||
|
||||
[ -s "$QUEUE" ] || [ -s "$ARBEIT" ] || exit 0
|
||||
|
||||
# Warteschlange übernehmen. mv ist atomar: Was notify.sh währenddessen anhängt, landet entweder
|
||||
# noch im übernommenen Stapel oder in einer frischen Warteschlange. Ein Stapel, der beim letzten
|
||||
# Mal nicht rausging, steht vorne.
|
||||
if [ -s "$QUEUE" ]; then
|
||||
mv "$QUEUE" "$QUEUE.uebernahme" && cat "$QUEUE.uebernahme" >> "$ARBEIT" && rm -f "$QUEUE.uebernahme"
|
||||
fi
|
||||
|
||||
ANZAHL="$(grep -c '^- ' "$ARBEIT" || true)"
|
||||
[ "$ANZAHL" = "1" ] && WORT="Meldung" || WORT="Meldungen"
|
||||
TEXT="$(head -c "$MAX_ZEICHEN" "$ARBEIT")"
|
||||
if [ "$(wc -c < "$ARBEIT")" -gt "$MAX_ZEICHEN" ]; then
|
||||
TEXT="$TEXT
|
||||
… gekürzt. Alle Meldungen stehen im Cockpit unter Meldungen."
|
||||
fi
|
||||
NACHRICHT="Guten Morgen, Commander. Heute Nacht gab es $ANZAHL $WORT:
|
||||
$TEXT"
|
||||
|
||||
for ((i = 1; i <= VERSUCHE; i++)); do
|
||||
# Als 07:00 senden (außerhalb der Nachtruhe); NO_ANNOUNCE, weil jede Meldung schon einzeln im
|
||||
# Briefkasten liegt.
|
||||
if MC_NOTIFY_STRICT=1 MC_NOTIFY_NO_ANNOUNCE=1 MC_NOTIFY_STUNDE=07 \
|
||||
bash "$SRC_DIR/notify.sh" -s "[Morgenmeldung]" "$NACHRICHT"; then
|
||||
mv -f "$ARBEIT" "$QUEUE.zuletzt-gesendet"
|
||||
exit 0
|
||||
fi
|
||||
[ "$i" -lt "$VERSUCHE" ] && sleep "$PAUSE"
|
||||
done
|
||||
|
||||
echo "Morgenmeldung: Telegram nicht erreichbar, $ANZAHL $WORT bleiben für den nächsten Lauf liegen." >&2
|
||||
exit 1
|
||||
+37
-20
@@ -5,16 +5,30 @@
|
||||
#
|
||||
# Nutzung: notify.sh "Nachricht" (oder via stdin: echo msg | notify.sh)
|
||||
# notify.sh -s "[Update]" "Text" (Betreffzeile voranstellen)
|
||||
# Exit 0 = zugestellt (Telegram ODER Fallback-Log geschrieben).
|
||||
# notify.sh -d -s "[Update]" "…" (dringend: geht auch nachts sofort raus)
|
||||
#
|
||||
# Nachtruhe (User-Entscheid 24.09.2026): Zwischen 00:00 und 06:59 wird alles, was nicht dringend
|
||||
# ist, in der Nacht-Warteschlange gesammelt und um 07:00 von morgenmeldung.sh als EINE Meldung
|
||||
# verschickt. Dringend ist: -d, ein Betreff mit „Alarm“/„Notfall“ oder ein Text, der mit
|
||||
# „KRITISCH“ beginnt. (Bis 24.09. lieferte niemand die Warteschlange aus — seit dem 21.08.
|
||||
# gingen so alle Nachtmeldungen verloren, auch die Sonntags-Updates.)
|
||||
#
|
||||
# Exit 0 = zugestellt (Telegram, Fallback-Log oder Nacht-Warteschlange).
|
||||
# MC_NOTIFY_STRICT=1: Exit 1, wenn Telegram scheitert (für morgenmeldung.sh, damit nichts verloren geht).
|
||||
# Test-Schalter: MC_NOTIFY_STUNDE (Stunde vortäuschen), MC_NIGHT_QUEUE, MC_NOTIFY_HERMES (hermes-Befehl).
|
||||
set -uo pipefail
|
||||
|
||||
LOG="${MC_NOTIFY_LOG:-$HOME/mc2-notify.log}"
|
||||
NIGHT_QUEUE="${MC_NIGHT_QUEUE:-$HOME/.hermes/night-queue.txt}"
|
||||
HERMES_BIN="${MC_NOTIFY_HERMES:-hermes}"
|
||||
SUBJECT=""
|
||||
DRINGEND=0
|
||||
|
||||
while getopts ":s:" opt; do
|
||||
while getopts ":s:d" opt; do
|
||||
case "$opt" in
|
||||
s) SUBJECT="$OPTARG" ;;
|
||||
*) echo "usage: notify.sh [-s subject] <nachricht>" >&2; exit 2 ;;
|
||||
d) DRINGEND=1 ;;
|
||||
*) echo "usage: notify.sh [-d] [-s subject] <nachricht>" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
@@ -41,28 +55,30 @@ PY
|
||||
)" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
# Nachtweiche: Zwischen 00:00 und 06:59 Uhr (inklusive) fangen wir Telegram-Nachrichten ab
|
||||
# und sammeln sie für den Morgen-Digest, ES SEI DENN es ist ein Alarm.
|
||||
HOUR="$(date +%H)"
|
||||
if [ "$HOUR" -ge 0 ] && [ "$HOUR" -lt 7 ]; then
|
||||
case "${SUBJECT,,}" in
|
||||
*alarm*|*notfall*)
|
||||
;; # Alarme gehen immer sofort durch
|
||||
*)
|
||||
# Sammeln für Morgen-Digest
|
||||
NIGHT_QUEUE="$HOME/.hermes/night-queue.txt"
|
||||
echo "- ${SUBJECT:+$SUBJECT: }$MSG" >> "$NIGHT_QUEUE"
|
||||
echo "$TS QUEUED für Morgen-Digest: $MSG" >> "$LOG"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
# Dringend ist, was nicht bis zum Morgen warten darf.
|
||||
case "${SUBJECT,,}" in
|
||||
*alarm*|*notfall*) DRINGEND=1 ;;
|
||||
esac
|
||||
case "$MSG" in
|
||||
KRITISCH*) DRINGEND=1 ;;
|
||||
esac
|
||||
|
||||
# Nachtruhe: 00:00–06:59 sammeln, außer es ist dringend. 10#… verhindert, dass „08“/„09“ als
|
||||
# Oktalzahl gelesen werden.
|
||||
HOUR="${MC_NOTIFY_STUNDE:-$(date +%H)}"
|
||||
if [ "$DRINGEND" != "1" ] && [ "$((10#$HOUR))" -lt 7 ]; then
|
||||
mkdir -p "$(dirname "$NIGHT_QUEUE")"
|
||||
printf -- '- %s%s\n' "${SUBJECT:+$SUBJECT: }" "$MSG" >> "$NIGHT_QUEUE"
|
||||
# Wortlaut „QUEUED für Morgen-Digest“ nicht ändern: services/update_verlauf.py liest ihn.
|
||||
echo "$TS QUEUED für Morgen-Digest: $MSG" >> "$LOG"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Primärweg: Telegram via hermes send (Login-Shell-PATH, falls aus Timer/cron aufgerufen).
|
||||
if [ -n "$SUBJECT" ]; then
|
||||
SEND_OUT="$(bash -lc 'hermes send --to telegram --subject "$1" -- "$2"' _ "$SUBJECT" "$MSG" 2>&1)"
|
||||
SEND_OUT="$(bash -lc '"$1" send --to telegram --subject "$2" -- "$3"' _ "$HERMES_BIN" "$SUBJECT" "$MSG" 2>&1)"
|
||||
else
|
||||
SEND_OUT="$(bash -lc 'hermes send --to telegram -- "$1"' _ "$MSG" 2>&1)"
|
||||
SEND_OUT="$(bash -lc '"$1" send --to telegram -- "$2"' _ "$HERMES_BIN" "$MSG" 2>&1)"
|
||||
fi
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "$TS OK telegram: $MSG" >> "$LOG"
|
||||
@@ -73,4 +89,5 @@ fi
|
||||
echo "$TS FALLBACK (telegram fehlgeschlagen: $SEND_OUT): $MSG" >> "$LOG"
|
||||
printf '%s\n' "MC2-Meldung: ${SUBJECT:+$SUBJECT }$MSG" | wall 2>/dev/null || true
|
||||
echo "WARN: Telegram fehlgeschlagen, in $LOG protokolliert" >&2
|
||||
[ "${MC_NOTIFY_STRICT:-0}" = "1" ] && exit 1
|
||||
exit 0
|
||||
|
||||
+28
-2
@@ -7,6 +7,8 @@
|
||||
# bash restore.sh --list # vorhandene Backups zeigen (lokal + Off-Box)
|
||||
# bash restore.sh --dry-run <datei|latest> # nur anzeigen, was passieren würde
|
||||
# bash restore.sh [--yes] <datei|latest> # wiederherstellen (--yes = ohne Rückfrage)
|
||||
# bash restore.sh --mit-gedaechtnis … # Lucys Gedächtnis, SOUL, Skills, Cron-Skripte und
|
||||
# # Box-Wart-Zustand auch dann zurückspielen, wenn sie da sind
|
||||
# bash restore.sh --pull-offsite # Off-Box-Kopie (Proxmox) nach lokal holen
|
||||
#
|
||||
# Off-Box (C12): fehlt ein Backup lokal (z. B. Box-Platte neu), wird es automatisch
|
||||
@@ -40,7 +42,7 @@ offsite_fetch() {
|
||||
rsync -a -e "$OFFSITE_SSH" "$OFFSITE/$1" "$DEST_DIR/"
|
||||
}
|
||||
|
||||
usage() { echo "Nutzung: restore.sh --list | restore.sh --pull-offsite | restore.sh [--dry-run] [--yes] <datei|latest>"; }
|
||||
usage() { echo "Nutzung: restore.sh --list | restore.sh --pull-offsite | restore.sh [--dry-run] [--yes] [--mit-gedaechtnis] <datei|latest>"; }
|
||||
list_backups() {
|
||||
echo "Verfügbare Backups in $DEST_DIR:"
|
||||
local found=0 f
|
||||
@@ -57,9 +59,10 @@ list_backups() {
|
||||
}
|
||||
|
||||
[ $# -eq 0 ] && { usage; exit 1; }
|
||||
DRY=0; YES=0; TARGET=""
|
||||
DRY=0; YES=0; FULL=0; TARGET=""
|
||||
for a in "$@"; do
|
||||
case "$a" in
|
||||
--mit-gedaechtnis) FULL=1 ;;
|
||||
--list) list_backups; exit 0 ;;
|
||||
--pull-offsite)
|
||||
mkdir -p "$DEST_DIR"
|
||||
@@ -104,6 +107,11 @@ if [ "$DRY" = 1 ]; then
|
||||
[ -f "$STAGE/hermes/.env" ] && echo " • $HERMES/.env"
|
||||
[ -d "$STAGE/hermes/plugins" ] && echo " • $HERMES/plugins/"
|
||||
[ -f "$STAGE/llama-swap/config.yaml" ] && echo " • $LSWAP"
|
||||
for teil in memories SOUL.md skills scripts; do
|
||||
[ -e "$STAGE/hermes/$teil" ] || continue
|
||||
if [ "$FULL" = 1 ] || [ ! -e "$HERMES/$teil" ]; then echo " • $HERMES/$teil"
|
||||
else echo " – $HERMES/$teil bleibt (vorhanden; --mit-gedaechtnis spielt es zurück)"; fi
|
||||
done
|
||||
echo " • Dienste neu starten: $SERVICES"
|
||||
exit 0
|
||||
fi
|
||||
@@ -136,6 +144,24 @@ systemctl --user stop $SERVICES 2>/dev/null || true
|
||||
# lädt die wiederhergestellten Jobs:
|
||||
[ -d "$STAGE/hermes/cron" ] && { mkdir -p "$HERMES/cron"; cp -a "$STAGE/hermes/cron/." "$HERMES/cron/"; }
|
||||
[ -d "$STAGE/hermes/state" ] && { mkdir -p "$HERMES/state"; cp -a "$STAGE/hermes/state/." "$HERMES/state/"; }
|
||||
# Lucys Gedächtnis, Seele, Skills, Cron-Skripte und Box-Wart-Zustand (Gegenstück zu backup.sh,
|
||||
# 24.09.2026): nur zurückspielen, wenn sie fehlen (neue Platte) oder --mit-gedaechtnis gesetzt ist.
|
||||
# Sonst würde ein Restore wegen einer kaputten Config Lucys neuere Erinnerungen überschreiben.
|
||||
zurueck_wenn_noetig() { # $1 = Quelle im Backup, $2 = Ziel
|
||||
[ -e "$1" ] || return 0
|
||||
if [ "$FULL" = 1 ] || [ ! -e "$2" ]; then
|
||||
mkdir -p "$(dirname "$2")"
|
||||
if [ -d "$1" ]; then mkdir -p "$2"; cp -a "$1/." "$2/"; else cp -a "$1" "$2"; fi
|
||||
echo " • zurückgespielt: $2"
|
||||
fi
|
||||
}
|
||||
zurueck_wenn_noetig "$STAGE/hermes/memories" "$HERMES/memories"
|
||||
zurueck_wenn_noetig "$STAGE/hermes/SOUL.md" "$HERMES/SOUL.md"
|
||||
zurueck_wenn_noetig "$STAGE/hermes/skills" "$HERMES/skills"
|
||||
zurueck_wenn_noetig "$STAGE/hermes/scripts" "$HERMES/scripts"
|
||||
for f in "$STAGE"/box-wart/mc2-*.json; do
|
||||
[ -e "$f" ] && zurueck_wenn_noetig "$f" "$MODELS_DIR/$(basename "$f")"
|
||||
done
|
||||
|
||||
echo "→ Dienste starten…"
|
||||
systemctl --user start $SERVICES 2>/dev/null || true
|
||||
|
||||
Reference in New Issue
Block a user