summaryrefslogtreecommitdiff
path: root/raveos-center/raveos_center/mentesek.py
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-center/raveos_center/mentesek.py')
-rw-r--r--raveos-center/raveos_center/mentesek.py156
1 files changed, 156 insertions, 0 deletions
diff --git a/raveos-center/raveos_center/mentesek.py b/raveos-center/raveos_center/mentesek.py
new file mode 100644
index 0000000..7afae01
--- /dev/null
+++ b/raveos-center/raveos_center/mentesek.py
@@ -0,0 +1,156 @@
+import io
+import json
+import subprocess
+import tarfile
+import time
+from pathlib import Path
+
+from raveos_center import katalogus
+from raveos_center.muveletek import HELPER
+
+JEGYZEK = "raveos-mentes.json"
+JEGYZEK_VERZIO = 1
+
+
+def csoportok():
+ utvonal = katalogus.adat_mappa() / "mentes" / "backup-paths.json"
+ return json.loads(utvonal.read_text(encoding="utf-8")).get("groups", [])
+
+
+def elemek():
+ lista = []
+ for csoport in csoportok():
+ for elem in csoport.get("items", []):
+ lista.append(dict(elem, csoport=csoport["id"]))
+ return lista
+
+
+def abszolut(elem):
+ if elem.get("scope") == "system":
+ return Path(elem["path"])
+ return Path.home() / elem["path"]
+
+
+class Megszakitva(Exception):
+ pass
+
+
+def _pkexec_hiba(kimenet):
+ if kimenet.returncode in (126, 127):
+ raise Megszakitva("a hitelesítés elmaradt, a további rendszerelemek kimaradnak")
+
+
+def _root_tar(elem_id):
+ kimenet = subprocess.run(["pkexec", HELPER, "mentes-root", elem_id], capture_output=True, timeout=600)
+ _pkexec_hiba(kimenet)
+ if kimenet.returncode != 0:
+ raise RuntimeError(kimenet.stderr.decode(errors="replace").strip()[:200] or "a rendszerelem mentése nem sikerült")
+ return kimenet.stdout
+
+
+def mentes(cel, kivalasztott, naplo, haladas):
+ jegyzek = {"verzio": JEGYZEK_VERZIO, "letrehozva": int(time.time()), "elemek": []}
+ megszakitva = False
+ with tarfile.open(cel, "w:gz") as tar:
+ for i, elem in enumerate(kivalasztott):
+ ut = abszolut(elem)
+ naplo(f"+ {katalogus.loc(elem.get('label'))} ({ut})")
+ try:
+ if elem.get("scope") == "system":
+ if megszakitva:
+ naplo(" kihagyva, mert a hitelesítés elmaradt")
+ continue
+ adat = _root_tar(elem["id"])
+ info = tarfile.TarInfo(f"rendszer/{elem['id']}.tar")
+ info.size = len(adat)
+ info.mtime = int(time.time())
+ tar.addfile(info, io.BytesIO(adat))
+ elif ut.exists():
+ tar.add(ut.resolve() if ut.is_symlink() else ut, arcname=f"home/{elem['path']}")
+ else:
+ naplo(" nincs ilyen mappa ezen a gépen, kihagyva")
+ continue
+ jegyzek["elemek"].append(
+ {"id": elem["id"], "label": elem.get("label"), "scope": elem.get("scope", "home"), "path": elem["path"]}
+ )
+ except Megszakitva as e:
+ naplo(f" MEGSZAKÍTVA: {e}")
+ megszakitva = True
+ except Exception as e:
+ naplo(f" HIBA, kihagyva: {e}")
+ haladas(int((i + 1) * 100 / max(1, len(kivalasztott))))
+ adat = json.dumps(jegyzek, ensure_ascii=False, indent=2).encode()
+ info = tarfile.TarInfo(JEGYZEK)
+ info.size = len(adat)
+ info.mtime = int(time.time())
+ tar.addfile(info, io.BytesIO(adat))
+ return len(jegyzek["elemek"])
+
+
+def tartalom(forras):
+ with tarfile.open(forras, "r:gz") as tar:
+ try:
+ tag = tar.getmember(JEGYZEK)
+ except KeyError:
+ return _regi_tartalom(tar)
+ return json.load(tar.extractfile(tag))["elemek"]
+
+
+def _regi_tartalom(tar):
+ nevek = {t.name.split("/")[0] for t in tar.getmembers()}
+ talalt = []
+ for elem in elemek():
+ if Path(elem["path"]).name in nevek:
+ talalt.append(
+ {"id": elem["id"], "label": elem.get("label"), "scope": elem.get("scope", "home"), "path": elem["path"], "regi": True}
+ )
+ return talalt
+
+
+def _home_tagok(tar, elem):
+ if elem.get("regi"):
+ elotag = Path(elem["path"]).name
+ cel_szulo = (Path.home() / elem["path"]).parent
+ else:
+ elotag = f"home/{elem['path']}"
+ cel_szulo = Path.home()
+ for tag in tar.getmembers():
+ if tag.name == elotag or tag.name.startswith(elotag + "/"):
+ if not elem.get("regi"):
+ tag.name = tag.name[len("home/"):]
+ if tag.islnk() and tag.linkname.startswith("home/"):
+ tag.linkname = tag.linkname[len("home/"):]
+ yield tag, cel_szulo
+
+
+def visszaallitas(forras, kivalasztott, naplo, haladas):
+ kesz = 0
+ megszakitva = False
+ with tarfile.open(forras, "r:gz") as tar:
+ for i, elem in enumerate(kivalasztott):
+ naplo(f"< {katalogus.loc(elem.get('label'))}")
+ try:
+ if elem.get("scope") == "system":
+ if elem.get("regi"):
+ raise RuntimeError("régi formátumú mentésből a rendszerelemek nem állíthatók vissza")
+ adat = tar.extractfile(tar.getmember(f"rendszer/{elem['id']}.tar")).read()
+ if megszakitva:
+ naplo(" kihagyva, mert a hitelesítés elmaradt")
+ continue
+ kimenet = subprocess.run(
+ ["pkexec", HELPER, "visszaallit-root", elem["id"]], input=adat, capture_output=True, timeout=600
+ )
+ _pkexec_hiba(kimenet)
+ if kimenet.returncode != 0:
+ raise RuntimeError(kimenet.stderr.decode(errors="replace").strip()[:200] or "sikertelen")
+ else:
+ for tag, cel_szulo in _home_tagok(tar, elem):
+ tar.extract(tag, path=cel_szulo, filter="data")
+ kesz += 1
+ except Megszakitva as e:
+ naplo(f" MEGSZAKÍTVA: {e}")
+ megszakitva = True
+ except Exception as e:
+ naplo(f" HIBA, kihagyva: {e}")
+ haladas(int((i + 1) * 100 / max(1, len(kivalasztott))))
+ return kesz