From 8b2bdebb3fdab64aea93fc59e3f63baba20b1436 Mon Sep 17 00:00:00 2001 From: maziggy Date: Tue, 3 Feb 2026 12:42:55 +0100 Subject: [PATCH] Sync --- backend/app/api/routes/settings.py | 37 ++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/backend/app/api/routes/settings.py b/backend/app/api/routes/settings.py index 0f9015a6a..1f25269ad 100644 --- a/backend/app/api/routes/settings.py +++ b/backend/app/api/routes/settings.py @@ -341,11 +341,15 @@ async def restore_backup( raise HTTPException(400, "Invalid backup: missing bambuddy.db") try: + import asyncio + # 3. Stop virtual printer if running (releases file locks) try: if virtual_printer_manager.is_enabled: logger.info("Stopping virtual printer for restore...") await virtual_printer_manager.configure(enabled=False) + # Give it time to fully release file handles + await asyncio.sleep(1) except Exception as e: logger.warning(f"Failed to stop virtual printer: {e}") @@ -358,6 +362,7 @@ async def restore_backup( shutil.copy2(backup_db, db_path) # 6. Replace data directories + # For Docker compatibility: clear contents then copy (don't delete mount points) dirs_to_restore = [ ("archive", base_dir / "archive"), ("virtual_printer", base_dir / "virtual_printer"), @@ -366,21 +371,45 @@ async def restore_backup( ("projects", base_dir / "projects"), ] + skipped_dirs = [] for name, dest_dir in dirs_to_restore: src_dir = temp_path / name if src_dir.exists(): logger.info(f"Restoring {name} directory...") - if dest_dir.exists(): - shutil.rmtree(dest_dir) - shutil.copytree(src_dir, dest_dir) + try: + # Clear destination contents (not the dir itself - may be Docker mount) + if dest_dir.exists(): + for item in dest_dir.iterdir(): + try: + if item.is_dir(): + shutil.rmtree(item) + else: + item.unlink() + except OSError as e: + logger.warning(f"Could not delete {item}: {e}") + else: + dest_dir.mkdir(parents=True, exist_ok=True) + # Copy contents from backup + for item in src_dir.iterdir(): + dest_item = dest_dir / item.name + if item.is_dir(): + shutil.copytree(item, dest_item) + else: + shutil.copy2(item, dest_item) + except OSError as e: + logger.warning(f"Could not restore {name} directory: {e}") + skipped_dirs.append(name) # 7. Note: Virtual printer and database will be reinitialized on restart # Do NOT try to restart services here - the database session is closed logger.info("Restore complete - restart required") + message = "Backup restored successfully. Please restart Bambuddy for changes to take effect." + if skipped_dirs: + message += f" Note: Some directories could not be restored ({', '.join(skipped_dirs)})." return { "success": True, - "message": "Backup restored successfully. Please restart Bambuddy for changes to take effect.", + "message": message, } except Exception as e: