summaryrefslogtreecommitdiff
path: root/raveos-center/raveos_center/snapshotok.py
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-center/raveos_center/snapshotok.py')
-rw-r--r--raveos-center/raveos_center/snapshotok.py116
1 files changed, 116 insertions, 0 deletions
diff --git a/raveos-center/raveos_center/snapshotok.py b/raveos-center/raveos_center/snapshotok.py
new file mode 100644
index 0000000..f4bd097
--- /dev/null
+++ b/raveos-center/raveos_center/snapshotok.py
@@ -0,0 +1,116 @@
+import json
+import re
+import subprocess
+from pathlib import Path
+
+from raveos_center import rendszerinfo
+
+SNAP_PAC = Path("/usr/share/libalpm/hooks/05-snap-pac-pre.hook")
+TIPUSOK = {"pre": "csomagművelet előtt", "post": "csomagművelet után", "single": "kézi"}
+
+
+def _futtat(parancs, ido=30):
+ try:
+ return subprocess.run(parancs, capture_output=True, text=True, timeout=ido)
+ except (OSError, subprocess.TimeoutExpired):
+ return None
+
+
+def fajlrendszer():
+ kimenet = _futtat(["findmnt", "-no", "FSTYPE", "/"])
+ return kimenet.stdout.strip() if kimenet and kimenet.returncode == 0 else ""
+
+
+def gyoker_alvolumen():
+ kimenet = _futtat(["findmnt", "-no", "OPTIONS", "/"])
+ if not kimenet:
+ return ""
+ for opcio in kimenet.stdout.strip().split(","):
+ if opcio.startswith("subvol="):
+ return opcio[len("subvol="):]
+ return ""
+
+
+def snapshots_csatolva():
+ kimenet = _futtat(["findmnt", "-no", "SOURCE", "/.snapshots"])
+ return bool(kimenet and kimenet.returncode == 0 and kimenet.stdout.strip())
+
+
+def snap_pac():
+ return SNAP_PAC.exists()
+
+
+def _elem(nyers):
+ tipus = nyers.get("type", "single")
+ adat = nyers.get("userdata") or {}
+ return {
+ "szam": nyers.get("number", 0),
+ "datum": (nyers.get("date") or "")[:16],
+ "tipus": tipus,
+ "tipus_nev": "telepítés" if adat.get("important") == "yes" and tipus == "single" else TIPUSOK.get(tipus, tipus),
+ "leiras": nyers.get("description") or "",
+ "pre_szam": nyers.get("pre-number"),
+ "aktiv": bool(nyers.get("active")),
+ }
+
+
+def allapot():
+ fs = fajlrendszer()
+ adat = {
+ "fajlrendszer": fs,
+ "snapper": rendszerinfo.snapper_elerheto(),
+ "snap_pac": snap_pac(),
+ "alvolumen": gyoker_alvolumen(),
+ "csatolva": snapshots_csatolva(),
+ "lista": [],
+ "hiba": "",
+ }
+ if fs != "btrfs" or not adat["snapper"]:
+ return adat
+ kimenet = _futtat(["snapper", "--jsonout", "-c", "root", "list"])
+ if not kimenet or kimenet.returncode != 0:
+ adat["hiba"] = (kimenet.stderr.strip() if kimenet else "") or "A snapshotok listája nem olvasható."
+ return adat
+ try:
+ nyers = json.loads(kimenet.stdout).get("root", [])
+ except ValueError:
+ adat["hiba"] = "A snapper válasza nem értelmezhető."
+ return adat
+ adat["lista"] = [_elem(n) for n in reversed(nyers) if n.get("number", 0) != 0]
+ return adat
+
+
+def ervenyes_leiras(szoveg):
+ return 1 <= len(szoveg) <= 80 and all(c.isalnum() or c.isspace() or c in "._:,()-" for c in szoveg)
+
+
+def kernel_valtozas(szam):
+ gyoker = Path(f"/.snapshots/{int(szam)}/snapshot")
+ valtozasok = []
+ try:
+ if not (gyoker / "usr/lib/modules").is_dir():
+ return None
+ pkgbase_fajlok = list(gyoker.glob("usr/lib/modules/*/pkgbase"))
+ except OSError:
+ return None
+ for pb in pkgbase_fajlok:
+ try:
+ nev = pb.read_text().strip()
+ except OSError:
+ continue
+ if not re.fullmatch(r"[a-z0-9][a-z0-9._+-]*", nev):
+ continue
+ regi = _futtat(["pacman", "--dbpath", str(gyoker / "var/lib/pacman"), "-Q", nev])
+ most = _futtat(["pacman", "-Q", nev])
+ regi_v = regi.stdout.split()[1] if regi and regi.returncode == 0 and len(regi.stdout.split()) > 1 else ""
+ most_v = most.stdout.split()[1] if most and most.returncode == 0 and len(most.stdout.split()) > 1 else ""
+ if regi_v and regi_v != most_v:
+ cache = any(
+ not p.name.endswith(".sig") for p in Path("/var/cache/pacman/pkg").glob(f"{nev}-{regi_v}-*.pkg.tar.*")
+ )
+ valtozasok.append({"nev": nev, "regi": regi_v, "most": most_v, "cache": cache})
+ return valtozasok
+
+
+def snapper_telepitheto(adat):
+ return adat["fajlrendszer"] == "btrfs" and not adat["snapper"] and adat["alvolumen"] == "/@" and adat["csatolva"]