Ver Fonte

fix: db_dump — créer le tar dans tmpdir puis sudo rsync vers backup_dir

tarfile.open() échouait avec PermissionError car backup_dir est 750 root.
Le tar est maintenant créé dans le tmpdir accessible, puis copié via sudo rsync.
Idem pour le .info.json YunoHost.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cédric Hansen há 1 dia atrás
pai
commit
80533869a7
1 ficheiros alterados com 26 adições e 9 exclusões
  1. 26 9
      sources/jobs/db_dump.py

+ 26 - 9
sources/jobs/db_dump.py

@@ -219,11 +219,11 @@ def _read_backup_info(archive_path):
 
 
 def _write_tar(tmpdir, dump_path, dbname, archive_name, backup_dir, job, instance, instance_url):
-    """Crée le .tar dans backup_dir et le .info.json YunoHost à côté."""
-    archive_path = os.path.join(backup_dir, archive_name + ".tar")
-
-    # backup_info.json embarqué dans le tar (métadonnées BackupManager)
+    """Crée le .tar dans tmpdir puis le copie dans backup_dir via sudo rsync."""
     import json as _json
+    from jobs.utils import sudo_getsize
+
+    # backup_info.json embarqué dans le tar
     info = {
         "instance_name": instance,
         "instance_url": instance_url,
@@ -236,12 +236,23 @@ def _write_tar(tmpdir, dump_path, dbname, archive_name, backup_dir, job, instanc
     with open(info_path, "w") as f:
         _json.dump(info, f, indent=2)
 
-    with tarfile.open(archive_path, "w") as tar:
+    # Créer le tar dans tmpdir (accessible par backupmanager)
+    tmp_archive = os.path.join(tmpdir, archive_name + ".tar")
+    with tarfile.open(tmp_archive, "w") as tar:
         tar.add(dump_path, arcname=f"db/{dbname}.sql")
         tar.add(info_path, arcname="backup_info.json")
 
-    # .info.json YunoHost (hors tar, requis pour listing webadmin)
-    size = os.path.getsize(archive_path)
+    # Copier vers backup_dir via sudo rsync (backup_dir est 750 root)
+    archive_path = os.path.join(backup_dir, archive_name + ".tar")
+    result = subprocess.run(
+        ["sudo", "rsync", tmp_archive, archive_path],
+        capture_output=True, text=True,
+    )
+    if result.returncode != 0:
+        raise RuntimeError(f"Copie de l'archive échouée : {result.stderr.strip()}")
+
+    # .info.json YunoHost dans tmpdir puis copie via sudo rsync
+    size = sudo_getsize(archive_path)
     ynh_info = {
         "created_at": int(time.time()),
         "description": f"BackupManager: {job.type} {dbname}",
@@ -250,6 +261,12 @@ def _write_tar(tmpdir, dump_path, dbname, archive_name, backup_dir, job, instanc
         "apps": {},
         "system": {},
     }
-    ynh_info_path = os.path.join(backup_dir, archive_name + ".info.json")
-    with open(ynh_info_path, "w") as f:
+    tmp_ynh_info = os.path.join(tmpdir, archive_name + ".info.json")
+    with open(tmp_ynh_info, "w") as f:
         _json.dump(ynh_info, f, indent=2)
+
+    subprocess.run(
+        ["sudo", "rsync", tmp_ynh_info,
+         os.path.join(backup_dir, archive_name + ".info.json")],
+        capture_output=True,
+    )