diff --git a/deploy/autoupdate.sh b/deploy/autoupdate.sh index b841993..0419c44 100644 --- a/deploy/autoupdate.sh +++ b/deploy/autoupdate.sh @@ -165,6 +165,63 @@ Wahrscheinliche Ursache/Fix (Box-Diagnose): $sugg}" notify "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 ───────────────────────────────────── +# Kernel- und libc-Updates werden erst nach einem Neustart wirksam; bis dahin +# laeuft die Box weiter auf dem alten Kernel. Das faellt niemandem auf — am +# 27.08.2026 lag die Box 7 Wochen mit drei ungenutzten Kerneln da. +# +# Der Neustart haengt bewusst am WOECHENTLICHEN Lauf (So 04:30) und nicht an +# einem eigenen Timer: ein Ort fuer alle Automatik (Lehre vom 20.08.). +# Er passiert NUR, wenn Ubuntu ihn selbst anfordert (/var/run/reboot-required). +# +# WICHTIG: Die Linger-Pruefung ist die entscheidende Zeile hier. Ohne Linger=yes +# startet systemd die User-Dienste nach einem Neustart NICHT — die Box kaeme ohne +# Steuerpult, Gateway und Waechter hoch, und niemand koennte sie aus der Ferne +# wieder anschalten. Im Zweifel lieber nicht neustarten. +# +# Abschalten: MC_AUTOUPDATE_REBOOT=0 in der Umgebung des Cron-Jobs. +reboot_wenn_noetig(){ + [ "${MC_AUTOUPDATE_REBOOT:-1}" = "1" ] || { say "Neustart per Env abgeschaltet."; return 0; } + [ -f /var/run/reboot-required ] || { say "Kein Neustart noetig."; return 0; } + + local pakete; pakete="$(sort -u /var/run/reboot-required.pkgs 2>/dev/null | tr " +" " ")" + + # Sicherung 1: kommen die Dienste ohne Login von selbst wieder hoch? + # $USER ist in systemd-/Cron-Umgebungen NICHT gesetzt — mit set -u waere das ein + # sofortiger Abbruch des ganzen Update-Laufs. id -un funktioniert immer. + local nutzer; nutzer="$(id -un)" + if [ "$(loginctl show-user "$nutzer" -p Linger --value 2>/dev/null)" != "yes" ]; then + notify "Neustart NICHT ausgefuehrt: die Box laeuft ohne linger — nach einem Neustart wuerden Steuerpult, Gateway und Waechter nicht von selbst starten. Erst 'loginctl enable-linger $nutzer' setzen, dann von Hand neustarten. Ausstehend: ${pakete:-Kernel/libc}" + return 0 + fi + + # Sicherung 2: kein halbfertiges Update mitten im Neustart abwuergen. + local laufend + laufend="$(curl -sf --max-time 20 "$API/api/jobs" | jq -r '[.jobs[]? | select(.state=="running")] | length' 2>/dev/null || echo 0)" + if [ "${laufend:-0}" -gt 0 ]; then + notify "Neustart verschoben: es laufen noch $laufend Job(s). Ausstehend: ${pakete:-Kernel/libc}. Naechster Versuch beim Lauf in einer Woche." + return 0 + fi + + # Sicherung 3: die Dienste muessen fuer den Autostart vorgemerkt sein. + local fehlend="" + for dienst in mission-control-2 mc2-gateway mc2-steward; do + systemctl --user is-enabled "$dienst" >/dev/null 2>&1 || fehlend="$fehlend $dienst" + done + if [ -n "$fehlend" ]; then + notify "Neustart NICHT ausgefuehrt: diese Dienste sind nicht fuer den Autostart eingetragen —$fehlend. Erst 'systemctl --user enable' nachholen. Ausstehend: ${pakete:-Kernel/libc}" + return 0 + fi + + notify "Die Box startet jetzt neu — das OS verlangt es nach dem Update (${pakete:-Kernel/libc}). Sie ist ein paar Minuten weg und meldet sich, sobald alles wieder laeuft. Die Modelle muessen danach neu geladen werden, die erste Anfrage dauert also laenger." + say "Neustart wird ausgeloest (ausstehend: ${pakete:-Kernel/libc})." + sleep 20 # der Meldung Zeit lassen, rauszugehen + sudo -n systemctl reboot || { + notify "Neustart FEHLGESCHLAGEN: 'sudo systemctl reboot' wurde abgelehnt. Bitte von Hand neustarten. Ausstehend: ${pakete:-Kernel/libc}" + } +} + # ── Lauf ───────────────────────────────────────────────────────────────────── say "Auto-Update-Lauf startet ($(date '+%F %H:%M'))." pins_init @@ -180,3 +237,7 @@ check_hermes notify "Commander, die Wochenpflege der Box ist durch — kurz für dich: $(printf '• %s\n' "${SUMMARY[@]}")" say "Fertig." + +# Ganz zuletzt: der Neustart wuerde die Abschlussmeldung oben sonst verschlucken. +# Die Funktion meldet in jedem Fall selbst, ob sie neustartet oder warum nicht. +reboot_wenn_noetig