diff --git a/README.md b/README.md index 70ca8bc..4b8c0fb 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,467 @@ -## Proxmox Update Script +Proxmox Update Script -Automatisiertes Update-Skript für Proxmox VE mit Kernel-Erkennung, ZFS-Snapshots vor jedem Update, automatischer Bereinigung alter Kernel-Reste und optionalem Reboot. +Automatisiertes Update-Skript für Proxmox VE und Debian mit: -### Installation +automatischem apt-get update und dist-upgrade +ZFS-Snapshots vor Updates +optionalem rpool/pveconf +automatischer Bereinigung alter Proxmox-Kernel +Unterstützung von pve-kernel-* und proxmox-kernel-* +konfigurierbaren Kernel-Fallbacks +Bereinigung von rc-Konfigurationsresten +Prüfung von proxmox-boot-tool +optionalem automatischem Reboot +Logging nach /var/log/proxmox_update.log +definierten Exit-Codes für Monitoring -``` -nano /root/scripte/pve-update.py -chmod +x /root/scripte/pve-update.py -``` +Das Skript verwendet ausschließlich eigene Konfiguration und Standard-Systembefehle. Es verändert keine Proxmox-eigenen Dateien oder systemd-Units. -### Testlauf +Installation -``` -sudo /root/scripte/pve-update.py -``` +Das Skript kann direkt aus dem Gitea-Repository heruntergeladen werden. -### Automatisiert mit Reboot-Option (per cron oder systemd-timer) +Download mit wget +wget -O /root/pve-update https://gitea.perlbach24.de/scripte/pve-update/raw/branch/main/proxmox-update.py +chmod +x /root/pve-update -``` -REBOOT=YES /root/scripte/pve-update.py -``` +Download mit curl +curl -fsSL -o /root/pve-update https://gitea.perlbach24.de/scripte/pve-update/raw/branch/main/proxmox-update.py +chmod +x /root/pve-update -> Wichtig: `REBOOT=YES` muss als **Umgebungsvariable** gesetzt werden, nicht als Kommandozeilenargument. In einer Cron-Zeile wird das automatisch korrekt übernommen (siehe Beispiel unten). Bei manuellem Aufruf in der Shell z. B. mit: -> ``` -> sudo REBOOT=YES /root/scripte/pve-update.py -> ``` -### Funktionsweise +Das Skript wird anschließend unter /root/pve-update ausgeführt. -1. Prüft per `apt-get update` / `apt-get -s dist-upgrade`, ob Updates verfügbar sind. -2. Falls ja: Erstellt vorher ZFS-Snapshots der konfigurierten Datasets, führt `apt-get dist-upgrade -y` und `apt-get autoremove --purge -y` aus und aktualisiert den Bootloader (`proxmox-boot-tool refresh`). -3. Entfernt anschließend (bzw. auch wenn keine Updates verfügbar waren) übrig gebliebene Konfigurationsreste alter, bereits deinstallierter Kernel-Pakete (dpkg-Status `rc`) einzeln nacheinander – mit Fortschrittsanzeige im Log, z. B.: - ``` - (3/13) Loesche Reste von: proxmox-kernel-7.0.2-4-pve-signed - (3/13) Erledigt: proxmox-kernel-7.0.2-4-pve-signed - ``` -4. Vergleicht den aktiv laufenden Kernel (`uname -r`) mit dem tatsächlich **installierten** Kernel (nur `dpkg`-Status `ii`, nicht installierte oder entfernte Pakete werden ignoriert). -5. Ist ein neuerer Kernel installiert als aktiv geladen, wird ein Reboot als erforderlich markiert. -6. Bei `REBOOT=YES` wird vor dem Neustart zusätzlich `proxmox-boot-tool status` geprüft. Nur wenn der Bootloader-Status OK ist, wird der Reboot per `shutdown -r +1` ausgelöst. Schlägt die Prüfung fehl (oder ist `proxmox-boot-tool` z. B. wegen eines PATH-Problems nicht auffindbar), wird der Neustart abgebrochen und ein Fehler geloggt. +Voraussetzungen +Proxmox VE +Debian-basierte Proxmox-Installation +Python 3 +apt-get +dpkg-query +ZFS, wenn ZFS-Snapshots verwendet werden +proxmox-boot-tool für die Bootloader-Prüfung +Ausführung als root -### Konfiguration +Es werden keine zusätzlichen Python-Pakete benötigt. -Am Anfang des Skripts anpassbar: +Erster Testlauf -```python +Vor der Aktivierung des automatischen Cronjobs sollte das Skript manuell getestet werden: + +REBOOT=NO /root/pve-update + + +Anschließend das Log prüfen: + +tail -100 /var/log/proxmox_update.log + + +Zusätzlich sollte vor dem ersten produktiven Lauf die reale Kernel-Paketliste kontrolliert werden: + +dpkg-query -W -f='${db:Status-Abbrev} ${Package}\n' \ +'pve-kernel-*' 'proxmox-kernel-*' + + +und: + +uname -r + + +Damit kann überprüft werden, ob der aktuell laufende Kernel korrekt erkannt wird. + +Erst wenn die Kernel-Erkennung im Log korrekt aussieht, sollte der automatische Cronjob aktiviert werden. + +Funktionsweise + +Das Skript arbeitet grundsätzlich in folgenden Schritten: + +Prüfen, ob das Skript als root ausgeführt wird. +apt-get update ausführen. +Mit apt-get -s dist-upgrade prüfen, ob Updates verfügbar sind. +Wenn Updates vorhanden sind: +ZFS-Snapshots erstellen +apt-get dist-upgrade -y ausführen +apt-get autoremove --purge -y ausführen +alte installierte Kernel bereinigen +rc-Reste alter Kernel bereinigen +proxmox-boot-tool refresh ausführen +Wenn keine Updates vorhanden sind: +trotzdem alte installierte Kernel bereinigen +trotzdem rc-Reste alter Kernel bereinigen +Laufenden Kernel mit dem höchsten installierten Kernel vergleichen. +Falls ein Reboot erforderlich ist und REBOOT=YES gesetzt wurde: +proxmox-boot-tool status prüfen +nur bei erfolgreicher Prüfung einen Reboot mit shutdown -r +1 auslösen. + +Kernelbereinigung und Reboot-Erkennung sind dabei getrennte Funktionen. + +Konfiguration + +Die wichtigsten Einstellungen befinden sich am Anfang des Skripts. + +ZFS-Datasets ZFS_DATASETS = [ "rpool/ROOT/pve-1", "rpool/pveconf" ] + +Vor einem Update wird für jedes vorhandene Dataset ein Snapshot erstellt. + +rpool/pveconf ist optional. + +Existiert das Dataset nicht, wird lediglich eine Warnung protokolliert: + +ZFS-Dataset nicht vorhanden: rpool/pveconf - Snapshot wird übersprungen, Update läuft weiter + + +Das Update wird dadurch nicht abgebrochen. + +Snapshot-Tag SNAPSHOT_TAG = "pve-update-via-cron" + + +Damit werden die vom Skript erzeugten Snapshots eindeutig gekennzeichnet. + +Beispiel: + +rpool/ROOT/pve-1@pve-update-via-cron-2026-09-03_04-00-00 + +Anzahl der Snapshots MAX_SNAPSHOTS = 5 -LOGFILE = "/var/log/proxmox_update.log" -``` -- `ZFS_DATASETS`: Liste der Datasets, von denen vor jedem Update ein Snapshot erstellt wird. -- `MAX_SNAPSHOTS`: Anzahl der Snapshots pro Dataset, die aufbewahrt werden (ältere werden automatisch gelöscht). -- `LOGFILE`: Pfad zur Logdatei, in die zusätzlich zur Konsolenausgabe alles protokolliert wird. +Pro Dataset werden maximal fünf vom Skript erzeugte Snapshots behalten. -### Exit-Codes +Ältere Snapshots mit dem konfigurierten Snapshot-Tag werden automatisch entfernt. -| Code | Bedeutung | -|------|---------------------------------------------------------| -| 0 | Erfolg (keine oder erfolgreiche Updates, kein Reboot nötig) | -| 1 | Neuer Kernel installiert → Reboot empfohlen/erforderlich | -| 2 | Fehler (Skript nicht als root ausgeführt) | +Kernel-Fallbacks +KEEP_OLD_KERNELS = 1 -### Cronjob (z. B. täglich 4 Uhr, mit automatischem Reboot bei neuem Kernel) -``` -0 4 * * * REBOOT=YES /root/scripte/pve-update.py >/dev/null 2>&1 -``` +Diese Einstellung bestimmt, wie viele ältere Kernel zusätzlich zum aktuell laufenden Kernel erhalten bleiben. -Nur prüfen/updaten, ohne automatischen Reboot: +Beispiele: -``` -0 4 * * * /root/scripte/pve-update.py >/dev/null 2>&1 -``` +KEEP_OLD_KERNELS = 0 +→ aktiver Kernel bleibt erhalten -### Snapshots +KEEP_OLD_KERNELS = 1 +→ aktiver Kernel + 1 Fallback -Vor jedem Update werden automatisch ZFS-Snapshots der konfigurierten Datasets erstellt, z. B.: +KEEP_OLD_KERNELS = 2 +→ aktiver Kernel + 2 Fallback-Kernel -``` -rpool/ROOT/pve-1@pve-update-via-cron-2025-08-15_05-00-00 -rpool/pveconf@pve-update-via-cron-2025-08-15_05-00-00 -``` -Es werden jeweils maximal `MAX_SNAPSHOTS` Snapshots pro Dataset aufbewahrt, ältere werden automatisch entfernt. +Der Wert ist bewusst im Konfigurationsbereich am Anfang des Skripts definiert. -### Voraussetzungen +Kernelverwaltung -- Proxmox VE mit ZFS-Root (`zfs`, `proxmox-boot-tool` müssen vorhanden sein). -- Skript muss als `root` ausgeführt werden. -- Python 3 (ohne zusätzliche Abhängigkeiten, nur Standardbibliothek). \ No newline at end of file +Das Skript unterstützt sowohl historische als auch aktuelle Proxmox-Kernelpakete: + +pve-kernel-* +proxmox-kernel-* + + +Installierte Kernel werden über dpkg-query ermittelt. + +Nur Pakete mit dem Status ii gelten als tatsächlich installiert. + +Beispiel: + +ii proxmox-kernel-6.14.11-1-pve-signed +ii proxmox-kernel-6.14.10-1-pve-signed +rc proxmox-kernel-6.8.12-2-pve-signed + + +Die ersten beiden Kernel sind installiert. + +Das dritte Paket ist bereits entfernt und besitzt nur noch Konfigurationsreste. + +Aktiven Kernel schützen + +Der aktuell laufende Kernel wird über: + +uname -r + + +ermittelt. + +Der aktive Kernel wird niemals gelöscht. + +Wenn der aktive Kernel nicht eindeutig unter den tatsächlich installierten Kernelpaketen gefunden wird, führt das Skript keine Kernelbereinigung durch. + +Damit soll verhindert werden, dass durch eine fehlerhafte Kernel-Erkennung ein benötigter Kernel entfernt wird. + +Fallback-Kernel + +Beispiel: + +6.14.11 ← aktiv +6.14.10 ← Fallback +6.14.8 +6.8.x + + +Bei: + +KEEP_OLD_KERNELS = 1 + + +bleiben: + +6.14.11 +6.14.10 + + +Die älteren Kernel werden entfernt. + +Bei: + +KEEP_OLD_KERNELS = 2 + + +bleiben: + +6.14.11 +6.14.10 +6.14.8 + +Neuere Kernel + +Ein installierter Kernel, der neuer als der aktuell laufende Kernel ist, wird ebenfalls nicht durch die Kernelbereinigung gelöscht. + +Beispiel: + +6.14.11 ← aktiv +6.14.12 ← neuer installiert + + +6.14.12 bleibt erhalten. + +Damit bleibt ein möglicherweise für den nächsten Reboot vorgesehener Kernel verfügbar. + +Kernel entfernen + +Alte Kernel werden über apt-get purge entfernt. + +Vor dem Entfernen wird jeder Kernel ausführlich ins Log geschrieben. + +Fehler beim Entfernen eines einzelnen alten Kernels sollen den restlichen Update-Lauf nicht abbrechen. + +rc-Reste + +Bereits entfernte Kernelpakete können noch Konfigurationsreste mit dem dpkg-Status rc besitzen. + +Diese werden separat bereinigt. + +Die beiden Bereinigungen haben damit unterschiedliche Aufgaben: + +installierte alte Kernel + ↓ +cleanup_old_kernels() + +bereits entfernte Kernel mit rc-Resten + ↓ +cleanup_old_kernel_configs() + + +Die rc-Bereinigung wird sowohl nach einem Update als auch bei einem Lauf ohne verfügbare Updates ausgeführt. + +Reboot-Erkennung + +Die Reboot-Erkennung ist von der Kernelbereinigung getrennt. + +Das Skript vergleicht: + +laufender Kernel + ↓ +uname -r + +höchster installierter Proxmox-Kernel + ↓ +dpkg-query + + +Ist der höchste installierte Kernel neuer als der aktuell laufende Kernel, wird ein Reboot als erforderlich erkannt. + +Bei: + +REBOOT=NO + + +wird kein automatischer Reboot ausgeführt. + +Bei: + +REBOOT=YES + + +wird vor dem Reboot zusätzlich der Proxmox-Bootloader geprüft. + +Proxmox Bootloader + +Vor einem automatischen Reboot wird: + +proxmox-boot-tool status + + +ausgeführt. + +Nur wenn der Status erfolgreich ist, wird der Neustart ausgelöst. + +Nach einem erfolgreichen Upgrade wird außerdem: + +proxmox-boot-tool refresh + + +ausgeführt. + +Schlägt die Bootloader-Prüfung fehl, wird kein automatischer Neustart durchgeführt. + +Logging + +Das Skript schreibt nach: + +/var/log/proxmox_update.log + + +Zusätzlich werden Meldungen auf stdout ausgegeben. + +Das ist bei manuellen Läufen hilfreich. + +Beim Cronjob wird stdout und stderr dagegen verworfen. + +Cronjob + +Für den produktiven automatischen Lauf: + +0 4 * * * REBOOT=YES /root/pve-update >/dev/null 2>&1 + + +Damit wird das Skript täglich um 04:00 Uhr ausgeführt. + +Wenn ein neuer Kernel erkannt wird, kann das Skript nach erfolgreicher Bootloader-Prüfung automatisch einen Neustart für eine Minute später planen. + +Warum >/dev/null 2>&1? + +Das Skript schreibt bewusst Meldungen auf stdout: + +print(...) + + +Cron würde stdout und stderr normalerweise an root mailen. + +Dadurch entstanden zuvor Nachrichten wie: + +From: root@... +Subject: Cron REBOOT=YES /root/pve-update + + +Die eigentliche Protokollierung erfolgt bereits über: + +/var/log/proxmox_update.log + + +Deshalb wird die Cron-Ausgabe verworfen: + +>/dev/null 2>&1 + + +Postfix muss dafür nicht umkonfiguriert werden. + +Es ist insbesondere nicht erforderlich: + +einen relayhost einzurichten +/etc/aliases zu ändern +Proxmox-Dateien zu verändern +Postfix für externen Mailversand zu konfigurieren + +Die Änderung betrifft ausschließlich den eigenen Cronjob. + +Alte Postfix-Mailqueue + +Bereits vorhandene Deferred-Mails stammen möglicherweise von früheren Cronläufen. + +Wenn bestätigt wurde, dass keine dieser Nachrichten benötigt wird, kann die alte Queue einmalig gelöscht werden: + +postsuper -d ALL + + +Anschließend prüfen: + +postqueue -p + + +Erwartet wird: + +Mail queue is empty + + +Dieser Schritt ist nur für bereits vorhandene Nachrichten erforderlich. + +Durch den neuen Cronjob sollen keine neuen Cron-Mails mehr entstehen. + +Exit-Codes + +Die Exit-Codes sind für Monitoring-Systeme vorgesehen. + +Code Bedeutung +0 Update erfolgreich / kein Reboot erforderlich +1 Neuerer Kernel vorhanden / Reboot erforderlich +2 Skript wurde nicht als root gestartet + +Der Exit-Code 1 bedeutet nicht automatisch, dass ein Reboot tatsächlich durchgeführt wurde. + +Beispielsweise kann REBOOT=NO gesetzt sein oder die Bootloader-Prüfung kann einen automatischen Reboot verhindern. + +Upgrade-Sicherheit + +Das Skript verändert keine Proxmox-eigenen Dateien. + +Insbesondere werden nicht verändert: + +/usr/share/pve-* +Proxmox-Paketdateien +Proxmox-eigene systemd-Units +Postfix-Relay-Konfiguration +/etc/aliases + +Das Skript verwendet ausschließlich: + +das eigene Skript +den eigenen Cronjob +/var/log/proxmox_update.log +normale Debian-/Proxmox-Werkzeuge wie apt-get, dpkg-query, zfs und proxmox-boot-tool + +Dadurch soll das Setup möglichst unabhängig von späteren Proxmox-Upgrades bleiben. + +Empfohlener Ablauf + +Nach der Installation: + +Skript herunterladen. +Ausführbar machen. +Installierte Kernel prüfen. +Laufenden Kernel mit uname -r prüfen. +Manuellen Test mit REBOOT=NO durchführen. +Log kontrollieren. +Kernel-Erkennung im Log überprüfen. +Cronjob mit REBOOT=YES aktivieren. +Alte Mailqueue nur dann löschen, wenn bestätigt wurde, dass die Nachrichten nicht benötigt werden. + +Beispiel: + +wget -O /root/pve-update https://gitea.perlbach24.de/scripte/pve-update/raw/branch/main/proxmox-update.py +chmod +x /root/pve-update + +dpkg-query -W -f='${db:Status-Abbrev} ${Package}\n' \ +'pve-kernel-*' 'proxmox-kernel-*' + +uname -r + +REBOOT=NO /root/pve-update + +tail -100 /var/log/proxmox_update.log + + +Erst wenn die Kernel-Erkennung korrekt aussieht, sollte der automatische Cronjob aktiviert werden. \ No newline at end of file