Proxmox Update Script Automatisiertes Update-Skript für Proxmox VE und Debian mit: 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 Das Skript verwendet ausschließlich eigene Konfiguration und Standard-Systembefehle. Es verändert keine Proxmox-eigenen Dateien oder systemd-Units. Installation Das Skript kann direkt aus dem Gitea-Repository heruntergeladen werden. 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 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 Das Skript wird anschließend unter /root/pve-update ausgeführt. 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 Es werden keine zusätzlichen Python-Pakete benötigt. Erster Testlauf 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 Pro Dataset werden maximal fünf vom Skript erzeugte Snapshots behalten. Ältere Snapshots mit dem konfigurierten Snapshot-Tag werden automatisch entfernt. Kernel-Fallbacks KEEP_OLD_KERNELS = 1 Diese Einstellung bestimmt, wie viele ältere Kernel zusätzlich zum aktuell laufenden Kernel erhalten bleiben. Beispiele: KEEP_OLD_KERNELS = 0 → aktiver Kernel bleibt erhalten KEEP_OLD_KERNELS = 1 → aktiver Kernel + 1 Fallback KEEP_OLD_KERNELS = 2 → aktiver Kernel + 2 Fallback-Kernel Der Wert ist bewusst im Konfigurationsbereich am Anfang des Skripts definiert. Kernelverwaltung 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.