This commit is contained in:
2026-02-12 07:38:16 +01:00
parent f9082f1e5b
commit 42cd021b9c
8 changed files with 300 additions and 15 deletions

View File

@@ -1,21 +1,24 @@
import os
import shutil
import tempfile
import pyzipper
from indexer.config import BACKUP_PASSWORD
def blob_path(backup_root: str, content_hash: bytes) -> str:
"""Vrátí cestu k blob souboru: BACKUP/ab/cd/abcdef...blob"""
"""Vrátí cestu k ZIP souboru: BACKUP/ab/cd/abcdef...zip"""
hex_hash = content_hash.hex()
return os.path.join(backup_root, hex_hash[:2], hex_hash[2:4], hex_hash + ".blob")
return os.path.join(backup_root, hex_hash[:2], hex_hash[2:4], hex_hash + ".zip")
def ensure_backed_up(files_with_hash: list, backup_root: str) -> int:
"""
Zkopíruje soubory do content-addressable storage.
Vytvoří AES-256 šifrovaný ZIP pro každý soubor v content-addressable storage.
files_with_hash: [(full_path, content_hash_bytes), ...]
Přeskočí soubory, jejichž blob už existuje (deduplikace).
Přeskočí soubory, jejichž zip už existuje (deduplikace).
Returns: počet nově zálohovaných souborů.
"""
password = BACKUP_PASSWORD.encode("utf-8")
backed_up = 0
for full_path, content_hash in files_with_hash:
target = blob_path(backup_root, content_hash)
@@ -25,17 +28,26 @@ def ensure_backed_up(files_with_hash: list, backup_root: str) -> int:
target_dir = os.path.dirname(target)
os.makedirs(target_dir, exist_ok=True)
tmp_path = None
try:
# Atomický zápis: temp soubor + přejmenování
fd, tmp_path = tempfile.mkstemp(dir=target_dir, suffix=".tmp")
os.close(fd)
shutil.copy2(full_path, tmp_path)
hex_hash = content_hash.hex()
with pyzipper.AESZipFile(
tmp_path, "w",
compression=pyzipper.ZIP_DEFLATED,
encryption=pyzipper.WZ_AES,
) as zf:
zf.setpassword(password)
zf.write(full_path, arcname=hex_hash + ".blob")
os.replace(tmp_path, target)
backed_up += 1
except (FileNotFoundError, PermissionError, OSError) as e:
print(f" WARN: backup failed for {full_path}: {e}")
# Uklidíme temp soubor pokud existuje
if os.path.exists(tmp_path):
if tmp_path and os.path.exists(tmp_path):
os.remove(tmp_path)
continue