pve-update.py hinzugefügt
This commit is contained in:
+115
@@ -0,0 +1,115 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import subprocess
|
||||||
|
import logging
|
||||||
|
import datetime
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
# ========== Einstellungen ==========
|
||||||
|
ZFS_DATASETS = ["rpool/ROOT", "rpool/pveconf"]
|
||||||
|
SNAPSHOT_TAG = "pve-update-via-rmm"
|
||||||
|
MAX_SNAPSHOTS = 5
|
||||||
|
LOGFILE = "/var/log/proxmox_update.log"
|
||||||
|
REBOOT_FLAG = os.environ.get("REBOOT", "NO").upper()
|
||||||
|
TIMESTAMP = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
|
||||||
|
# ========== Logging Setup ==========
|
||||||
|
logging.basicConfig(
|
||||||
|
filename=LOGFILE,
|
||||||
|
level=logging.INFO,
|
||||||
|
format="%(asctime)s [%(levelname)s] %(message)s",
|
||||||
|
)
|
||||||
|
|
||||||
|
def run(cmd, check=True):
|
||||||
|
"""Kommando ausführen"""
|
||||||
|
logging.debug(f"Running: {cmd}")
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
cmd, shell=True, check=check,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||||
|
)
|
||||||
|
return result.stdout.decode().strip()
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
logging.error(f"Fehler bei Befehl: {cmd}")
|
||||||
|
logging.error(e.stderr.decode().strip())
|
||||||
|
if check:
|
||||||
|
raise
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def has_updates():
|
||||||
|
"""apt update ausführen & prüfen, ob Updates vorhanden"""
|
||||||
|
try:
|
||||||
|
output = run("apt update")
|
||||||
|
if "upgradable" in output.lower():
|
||||||
|
logging.info("Updates verfügbar.")
|
||||||
|
return True
|
||||||
|
logging.info("Keine Updates verfügbar.")
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
logging.error("apt update fehlgeschlagen.")
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
def is_kernel_update_available():
|
||||||
|
"""Prüfen, ob ein Kernel-Update verfügbar ist"""
|
||||||
|
output = run("apt list --upgradable", check=False)
|
||||||
|
return any("linux-image-" in line for line in output.splitlines())
|
||||||
|
|
||||||
|
def create_snapshot(dataset):
|
||||||
|
"""Snapshot mit Tag erstellen"""
|
||||||
|
snapshot_name = f"{dataset}@{SNAPSHOT_TAG}-{TIMESTAMP}"
|
||||||
|
logging.info(f"Erstelle Snapshot: {snapshot_name}")
|
||||||
|
run(f"zfs snapshot {snapshot_name}")
|
||||||
|
|
||||||
|
def cleanup_snapshots(dataset):
|
||||||
|
"""Alte Snapshots mit dem definierten Tag löschen"""
|
||||||
|
logging.info(f"Bereinige alte Snapshots in {dataset}")
|
||||||
|
snap_list = run(f"zfs list -t snapshot -o name -s creation | grep '^{dataset}@{SNAPSHOT_TAG}-'", check=False).splitlines()
|
||||||
|
if len(snap_list) > MAX_SNAPSHOTS:
|
||||||
|
for snap in snap_list[:-MAX_SNAPSHOTS]:
|
||||||
|
logging.info(f"Lösche Snapshot: {snap}")
|
||||||
|
run(f"zfs destroy {snap}")
|
||||||
|
|
||||||
|
def upgrade_system():
|
||||||
|
"""Upgrade durchführen"""
|
||||||
|
try:
|
||||||
|
logging.info("Starte apt dist-upgrade …")
|
||||||
|
run("apt dist-upgrade -y")
|
||||||
|
logging.info("Führe apt autoremove aus …")
|
||||||
|
run("apt autoremove -y")
|
||||||
|
except Exception:
|
||||||
|
logging.error("Upgrade fehlgeschlagen.")
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
logging.info("===== Proxmox Update & Snapshot gestartet =====")
|
||||||
|
|
||||||
|
if os.geteuid() != 0:
|
||||||
|
print("Dieses Skript muss als root ausgeführt werden.")
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
if not has_updates():
|
||||||
|
logging.info("Beende – keine Updates.")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Snapshots nur bei Update
|
||||||
|
for dataset in ZFS_DATASETS:
|
||||||
|
create_snapshot(dataset)
|
||||||
|
cleanup_snapshots(dataset)
|
||||||
|
|
||||||
|
# Upgrade
|
||||||
|
upgrade_system()
|
||||||
|
|
||||||
|
# Kernel-Update erkennen
|
||||||
|
if is_kernel_update_available():
|
||||||
|
logging.warning("Kernel-Update erkannt – Neustart empfohlen.")
|
||||||
|
if REBOOT_FLAG == "YES":
|
||||||
|
logging.info("Reboot wird ausgeführt …")
|
||||||
|
run("reboot")
|
||||||
|
sys.exit(1) # Exit 1 = Neustart empfohlen
|
||||||
|
|
||||||
|
logging.info("===== Update-Vorgang abgeschlossen =====")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user