Welle 2 · „Was ist neu?“ vor dem Knopf: Release Notes, Debian-Änderungslisten und Lucys Kurzfassung

Vor einem App-Update sammelt der Orchestrator die Release Notes aller Versionen zwischen installiert und neu (GitHub),
beim Proxmox-Host die Debian-Änderungslisten der wichtigsten Pakete (neue Ausführer-Aktion changelog, nur lesend, nur
für anstehende Pakete). Lucy fasst sie über das Modell fast der KI-Box auf Deutsch zusammen: Handarbeit ganz oben,
höchstens fünf Stichpunkte, Brüche zuerst. Die Update-Tabelle hat „Was ist neu?“ je Gerät, und die Rückfrage vor dem
Update zeigt die Kurzfassung gleich mit. Gemerkt je Version; der Ausführer braucht ausfuehrer-einrichten.sh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-25 17:47:04 +02:00
co-authored by Claude Opus 5.5
parent 0190c25d5a
commit 45f11bc3dc
11 changed files with 604 additions and 7 deletions
+37 -2
View File
@@ -34,6 +34,8 @@ Container des Homelab-Teils braucht keinen Proxmox-Schlüssel.
• Zertifikate im Bericht (seit 25.09.2026, höchstens alle 30 Minuten neu gelesen): die https-Zertifikate von
NPMplus samt dem, was es für den Namen gerade ausliefert, das des Proxmox-Hosts und das des PBS —
Laufzeit, Aussteller, Namen. Nur lesend.
• Changelog (seit 25.09.2026, „Was ist neu?“ vor einem Host-Update): die Debian-Änderungslisten einzelner Pakete
aus der Update-Liste, jeweils bis zur installierten Version. Nur lesend.
• Etikett (seit 25.09.2026, Knopf „Übernehmen“ bei neu entdeckten Geräten): setzt oder entfernt genau eines der
beiden Etiketten watcher und watcher-aus — die beiden schließen sich aus, alle anderen Etiketten
bleiben, wie sie sind. Das geht auch bei Gästen ohne Freigabe: Es IST die Freigabe.
@@ -1230,6 +1232,39 @@ def a_host_neustart(p: dict) -> tuple[int, str]:
return _laufen(["systemctl", "reboot"], 30)
_PAKETNAME = re.compile(r"[a-z0-9][a-z0-9+.-]{1,80}")
_KOPF = re.compile(r"^\S+ \(([^)]+)\) ", re.MULTILINE)
def changelog_neu(text: str, installiert: str | None) -> str:
"""Die Einträge einer Debian-Änderungsliste, die neuer sind als die installierte Version (sie steht oben)."""
if installiert:
for m in _KOPF.finditer(text):
if m.group(1) == installiert:
return text[:m.start()].strip()
return text.strip()
def a_changelog(p: dict) -> tuple[int, str]:
"""Änderungslisten für „Was ist neu?“ (seit 25.09.2026), nur lesend: nur Pakete, die gerade zum Update anstehen."""
pakete = p.get("pakete")
if not isinstance(pakete, list) or not 1 <= len(pakete) <= 12 \
or not all(isinstance(x, str) and _PAKETNAME.fullmatch(x) for x in pakete):
raise ValueError("ungültige Paketliste")
anstehend = {u.get("Package"): u.get("OldVersion") for u in _pvesh(f"/nodes/{NODE}/apt/update") or []}
ergebnis = {}
for name in pakete:
if name not in anstehend:
continue
try:
text = _pvesh(f"/nodes/{NODE}/apt/changelog", "--name", name)
except Exception as exc:
ergebnis[name] = f"(Änderungsliste nicht lesbar: {str(exc)[:120]})"
continue
ergebnis[name] = changelog_neu(str(text or ""), anstehend[name])[:6000]
return 0, json.dumps(ergebnis, ensure_ascii=False)
# Die einzigen Etiketten, die der Server setzen oder entfernen lassen kann (seit 25.09.2026).
SETZBARE_ETIKETTEN = ("watcher", AUSGENOMMEN)
@@ -1300,9 +1335,9 @@ AKTIONEN = {"snapshot": a_snapshot, "update": a_update, "os_update": a_os_update
"host_neustart": a_host_neustart, "bericht": a_bericht,
"sichern": a_sichern, "sicherung_zurueck": a_sicherung_zurueck, "sicherung_loeschen": a_sicherung_loeschen,
"kernel_aufraeumen": a_kernel_aufraeumen, "sicherung_probe": a_sicherung_probe,
"etikett_setzen": a_etikett_setzen}
"etikett_setzen": a_etikett_setzen, "changelog": a_changelog}
# Was auch im Nur-Lesen-Modus geht: Es liest nur.
NUR_LESEND = {a_bericht, a_sicherung_probe}
NUR_LESEND = {a_bericht, a_sicherung_probe, a_changelog}
def ausfuehren(auftrag: dict) -> dict: