Haelt __pycache__, Sicherungskopien der Konfiguration und Laufzeitdateien (state.json, Sperrdateien) aus dem Repository heraus. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
pvesnap — automatische Snapshots für Proxmox VE
Ein systemd-Dienst, der nach frei definierbaren Zeitplänen Snapshots von VMs und Containern anlegt und alte Snapshots nach einer einstellbaren Vorhaltezeit wieder löscht. Alles wird über eine INI-Datei gesteuert, die sich auch bequem in einem ncurses-Editor bearbeiten lässt.
- Beliebig viele Gruppen — z. B. „diese VMs stündlich, jene täglich, der Rest monatlich“
- VM-Auswahl nach VMID, Name (mit
*-Mustern), Tag, Pool oder einfach „alle“ - Vorhaltezeit je Gruppe nach Anzahl und/oder Alter
- Jeder Snapshot bekommt eine Beschreibung, an der er sich wiedererkennen lässt
- Läuft cluster-weit (alle Nodes) über
pvesh - Nur Python-Standardbibliothek — keine zusätzlichen Pakete nötig
Installation
Auf dem Proxmox-Host als root:
git clone <dieses-repo> pvesnap && cd pvesnap
./install.sh
Das Skript legt an:
| Pfad | Inhalt |
|---|---|
/usr/lib/pvesnap/ |
Programmcode |
/usr/local/bin/pvesnap |
Startbefehl |
/etc/pvesnap/pvesnap.conf |
Konfiguration (wird bei Updates nicht überschrieben) |
/var/lib/pvesnap/state.json |
merkt sich die letzten Läufe |
/etc/systemd/system/pvesnap.service |
systemd-Unit |
In der mitgelieferten Beispielkonfiguration sind alle Gruppen auf enabled = no
gesetzt — es passiert also erst etwas, wenn du eine Gruppe aktivierst.
Deinstallation:
./uninstall.sh # Programm und Dienst entfernen, Konfiguration bleibt
./uninstall.sh --purge # zusätzlich /etc/pvesnap und /var/lib/pvesnap löschen
Bereits angelegte Snapshots werden dabei nie angerührt.
Konfiguration im ncurses-Editor
pvesnap config
- Gruppenliste —
Enterbearbeiten,nneu,ckopieren,dlöschen,Leertastean/aus,gglobale Einstellungen,vÜbersicht welche VM in welcher Gruppe landet,sspeichern,qEnde - Gruppe bearbeiten — Feld auswählen,
Enterändern,Leertasteumschalten. Ganz unten steht live, auf wie viele Gäste die Auswahl gerade zutrifft. - VM-Auswahl (
v) — Liste aller VMs und Container mit Node, Status und Tags;Leertasteauswählen,aalle,nkeine,iumkehren,/filtern,Enterübernehmen.
Beim Speichern wird die INI-Datei neu geschrieben. Eigene Kommentare und ein
[defaults]-Abschnitt gehen dabei verloren (die Werte bleiben inhaltlich erhalten, sie stehen danach in jeder Gruppe einzeln). Eine Sicherung wird alspvesnap.conf.bakabgelegt.
Konfiguration von Hand
[global]
prefix = auto # Namenspräfix aller pvesnap-Snapshots
check_interval = 60s # wie oft der Dienst nach Fälligem schaut
state_file = /var/lib/pvesnap/state.json
log_level = INFO
task_timeout = 15m
run_on_start = no # beim Start sofort einen Durchlauf machen?
dry_run = no # yes = nichts wirklich tun, nur protokollieren
description = pvesnap | Gruppe: {group} | erstellt: {datetime} | Vorhaltezeit: {keep_time}
[defaults] # Vorgaben für alle Gruppen (optional)
skip_stopped = no
[group:stündlich]
interval = 1h
align = yes # an der Uhr ausrichten: 00:00, 01:00, ...
keep_count = 24 # höchstens 24 Snapshots je VM
keep_time = 2d # nichts älter als 2 Tage
tags = stuendlich # alle VMs mit diesem Tag
skip_stopped = yes
[group:täglich]
schedule = daily
at = 02:30
keep_count = 14
keep_time = 21d
names = web-*, db-*
[group:monatlich]
schedule = monthly
day_of_month = 1
at = 04:00
keep_count = 6
all = yes
exclude_tags = nosnap
Nach jeder Änderung:
pvesnap check # Konfiguration prüfen
systemctl reload pvesnap # Dienst übernimmt die Änderung ohne Neustart
Zeitplan
Entweder ein Intervall …
interval = 30m # 30m, 1h, 6h, 2d12h, 1w ...
align = yes # yes: an der Uhr ausgerichtet (00:00, 00:30, 01:00, ...)
# no: 30 Minuten nach dem letzten Lauf
… oder ein fester Termin:
schedule |
zusätzliche Angaben | Beispiel |
|---|---|---|
hourly |
minute = 15 |
jede Stunde um :15 |
daily |
at = 02:30 |
täglich um 02:30 |
weekly |
at, day_of_week = so |
sonntags um 03:00 |
monthly |
at, day_of_month = 1 |
am 1. jedes Monats |
yearly |
at, day_of_month, month |
einmal jährlich |
day_of_month = 31 wird in kürzeren Monaten automatisch auf den letzten Tag
gezogen. Läuft der Host zum Termin nicht, wird der Lauf beim nächsten Start
nachgeholt.
Vorhaltezeit
keep_count = 24 # höchstens 24 Snapshots je VM und Gruppe (0 = unbegrenzt)
keep_time = 7d # nichts älter als 7 Tage (0 = unbegrenzt)
keep_min = 1 # so viele bleiben in jedem Fall stehen
Beides ist kombinierbar — gelöscht wird, was eine der beiden Grenzen reißt.
Mindestens eine der beiden Angaben muss gesetzt sein, sonst würde die Zahl der
Snapshots unbegrenzt wachsen (pvesnap check weist darauf hin).
Welche VMs?
Alle Angaben wirken als ODER, Ausschlüsse gewinnen immer:
all = yes # alle VMs und Container
vmids = 100,101,105-110 # nach ID, auch Bereiche
names = web-*, db-0? # nach Name, mit Platzhaltern
tags = prod, wichtig # nach Proxmox-Tag
pools = Kunden # nach Proxmox-Pool
types = qemu # nur VMs (bzw. lxc = nur Container; leer = beides)
exclude_vmids = 999
exclude_names = *-test
exclude_tags = nosnap
Snapshot-Optionen
vmstate = yes # RAM mitsichern (nur QEMU und nur bei laufender VM)
skip_stopped = yes # gestoppte Gäste überspringen
description = Sicherung von {name} ({vmid}) vom {date}
Platzhalter der Beschreibung: {group} {group_slug} {vmid} {name} {node}
{type} {pool} {tags} {date} {time} {datetime} {timestamp}
{keep_time} {keep_count} {schedule}
Namensschema und Sicherheit
auto-taeglich-20260730-023000
│ │ │ └── Uhrzeit
│ │ └────────── Datum
│ └──────────────────── Kurzname der Gruppe
└─────────────────────────── prefix aus [global]
pvesnap löscht ausschließlich Snapshots, deren Name exakt auf dieses Muster passt und deren Gruppen-Kurzname zur jeweiligen Gruppe gehört. Von Hand oder von anderen Werkzeugen angelegte Snapshots bleiben garantiert unangetastet.
Umlaute und Sonderzeichen im Gruppennamen werden für den Kurznamen umgeschrieben
(täglich → taeglich). Wenn zwei Gruppen denselben Kurznamen ergäben, meldet
das pvesnap check.
Befehle
pvesnap status # Übersicht: Gruppen, letzte und nächste Läufe
pvesnap vms # alle VMs und die Gruppen, in denen sie stecken
pvesnap list # vorhandene pvesnap-Snapshots (-a = auch fremde)
pvesnap check # Konfiguration prüfen
pvesnap config # ncurses-Editor
pvesnap run # jetzt fällige Gruppen ausführen
pvesnap run --force -g täglich # eine Gruppe sofort ausführen
pvesnap run --force --dry-run # Probelauf, ändert nichts
pvesnap prune -g stündlich # nur aufräumen, keine neuen Snapshots
systemctl status pvesnap
systemctl reload pvesnap # Konfiguration neu einlesen (SIGHUP)
journalctl -u pvesnap -f # Protokoll mitlesen
Ein manueller pvesnap run ist auch möglich, während der Dienst läuft — beide
teilen sich eine Sperre und kommen sich nicht in die Quere.
Mit -c /pfad/zur.conf lässt sich jederzeit eine andere Konfiguration verwenden,
z. B. zum Ausprobieren.
Hinweise aus der Praxis
- Snapshot ist kein Backup. Snapshots liegen auf demselben Storage wie die VM.
Für echte Sicherungen zusätzlich
vzdump/ Proxmox Backup Server verwenden. - Speicherplatz: Jeder Snapshot hält alte Blöcke fest. Bei schreibfreudigen VMs lieber kurze Vorhaltezeiten wählen und den Storage im Auge behalten.
- Nicht jedes Storage kann Snapshots — LVM-thick und Verzeichnis-Storage mit
raw-Images können es nicht. Solche VMs melden einen Fehler im Protokoll; die übrigen laufen normal weiter. vmstate = yesfriert die VM kurz ein und braucht Platz in Höhe des zugewiesenen RAM. Für regelmäßige Läufe meist unnötig.- Gruppe umbenennen: Der neue Name bekommt einen eigenen Kurznamen. Snapshots unter dem alten Namen werden dann nicht mehr automatisch aufgeräumt — vorher aufräumen lassen oder die alten Snapshots von Hand entfernen.
- Zeitumstellung: Es wird mit lokaler Zeit gerechnet. Ein täglicher Termin um 02:30 kann in der Umstellungsnacht ausfallen oder doppelt anstehen.
Aufbau
pvesnap/
config.py INI lesen und schreiben, Gruppen- und Globaleinstellungen
schedule.py Berechnung des nächsten Termins
naming.py Namensschema und Beschreibungs-Vorlagen
proxmox.py pvesh-Anbindung (Inventar, Snapshots anlegen/löschen)
engine.py Auswahl der Gäste, Anlegen, Aufräumen
daemon.py Hauptschleife, Signale, Sperren
state.py merkt sich die letzten Läufe
tui.py ncurses-Editor
cli.py Kommandozeile
config/pvesnap.conf.example
systemd/pvesnap.service
install.sh uninstall.sh