diff --git a/backend/app.py b/backend/app.py index 18df0ff..c92e436 100644 --- a/backend/app.py +++ b/backend/app.py @@ -162,7 +162,7 @@ def cleanup_job(job_id: str, req: CleanupRequest) -> CleanupResponse: except (IndexError, ValueError): vmid = 0 logger.info("Cleanup: job=%s vmid=%d delete=%s", job_id, vmid, req.delete_staging_files) - result = cleanup_staging(vmid, req.delete_staging_files) + result = cleanup_staging(vmid, req.delete_staging_files, req.session_id) return CleanupResponse( job_id=result["job_id"], action_taken=result["action_taken"], diff --git a/backend/models.py b/backend/models.py index f1bb243..9aa697a 100644 --- a/backend/models.py +++ b/backend/models.py @@ -62,6 +62,7 @@ class JobSubmissionRequest(BaseModel): class CleanupRequest(BaseModel): delete_staging_files: bool + session_id: str = "" # --------------------------------------------------------------------------- diff --git a/backend/provisioner.py b/backend/provisioner.py index f601a6d..6504616 100644 --- a/backend/provisioner.py +++ b/backend/provisioner.py @@ -125,9 +125,8 @@ def clone_vm(req: CloneRequest) -> JobStatusResponse: def cleanup_staging(vmid: int, delete: bool, session_id: str = "") -> dict: - """Remove staging files for a VM ID.""" - out_dir = _staging_out(session_id) / str(vmid) - + """Remove staging files. If delete=True and session_id is set, + removes the entire session directory (both in/ and out/).""" if not delete: return { "job_id": f"job_{vmid}", @@ -135,6 +134,20 @@ def cleanup_staging(vmid: int, delete: bool, session_id: str = "") -> dict: "message": f"Staging files preserved for VM {vmid}", } + # Delete the entire session tmp directory if we have a session ID + if session_id: + session_dir = STAGING_ROOT / session_id + if session_dir.exists(): + shutil.rmtree(session_dir, ignore_errors=True) + logger.info("Cleaned up session dir: %s", session_dir) + return { + "job_id": f"job_{vmid}", + "action_taken": "purged", + "message": "Session files deleted.", + } + + # Fallback: delete just the VM output dir + out_dir = _staging_out(session_id) / str(vmid) if out_dir.exists(): shutil.rmtree(out_dir, ignore_errors=True) logger.info("Cleaned up output dir: %s", out_dir) diff --git a/frontend/api_client.py b/frontend/api_client.py index 91a1930..f743a4a 100644 --- a/frontend/api_client.py +++ b/frontend/api_client.py @@ -59,9 +59,12 @@ class ApiClient: """GET /api/v1/jobs/{job_id} — poll job status.""" return self._get(f"/api/v1/jobs/{job_id}") - def cleanup_job(self, job_id: str, delete: bool) -> dict: + def cleanup_job(self, job_id: str, delete: bool, session_id: str = "") -> dict: """POST /api/v1/jobs/{job_id}/cleanup — remove or keep staging files.""" - return self._post(f"/api/v1/jobs/{job_id}/cleanup", {"delete_staging_files": delete}) + return self._post(f"/api/v1/jobs/{job_id}/cleanup", { + "delete_staging_files": delete, + "session_id": session_id, + }) def clone_vm(self, source_vmid: int, target_vmid: int, target_name: str) -> dict: """POST /api/v1/clone — clone an existing VM.""" diff --git a/frontend/app.py b/frontend/app.py index a23ae1b..4694680 100644 --- a/frontend/app.py +++ b/frontend/app.py @@ -519,7 +519,8 @@ async def session_cleanup(job_id: str, request: Request): try: body = await request.json() delete = body.get("delete_staging_files", False) - return api.cleanup_job(job_id, delete) + session_id = body.get("session_id", "") + return api.cleanup_job(job_id, delete, session_id) except ApiError as exc: return JSONResponse({"error": exc.detail}, status_code=502) diff --git a/frontend/templates/index.html b/frontend/templates/index.html index d971aa5..417d9eb 100644 --- a/frontend/templates/index.html +++ b/frontend/templates/index.html @@ -371,7 +371,7 @@ async function reuseImage(jobId, vmid, sourceFilename, keep) { try { await fetch('/session/cleanup/' + jobId, { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ delete_staging_files: true }), + body: JSON.stringify({ delete_staging_files: true, session_id: window.VM_BENCH_SID || '' }), }); window.location.href = '/'; } catch (err) { alert('Cleanup failed: ' + err.message); }