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 <root@...> 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.