zyratlo opened a new pull request, #7741: URL: https://github.com/apache/texera/pull/7741
### What changes were proposed in this PR? Removes a workflow's notebook file from the Jupyter pod when the notebook is deleted, so the pod's `work/` directory no longer accumulates notebooks for workflows the user has removed. Before #7671 this was self limiting: every workflow uploaded to the same `work/notebook.ipynb`, so there was only ever one file and it was overwritten on reuse. Now that each workflow uploads to `work/notebook_<wid>.ipynb`, the file survives both a notebook delete and a workflow delete, because those paths only touched the database. `deleteNotebookAndMapping` removed the `notebook` rows (cascading to `workflow_notebook_mapping`), and deleting a workflow cascades those same rows through the `notebook.wid` foreign key, but nothing removed the file from the pod. The database is authoritative for whether a notebook exists. The pod file is a per user artifact only the frontend can reach, since the notebook migration service targets one Jupyter per process under the per user pod model. So the file cleanup is best effort from the frontend after the authoritative database delete, and a failure is logged rather than surfaced. **`NotebookMigrationResource` (new `delete-notebook` endpoint)** - Adds `POST /notebook-migration/delete-notebook`, the counterpart to `set-notebook`: it takes a `notebookName`, validates it with the same `[A-Za-z0-9._-]+\.ipynb` pattern (blocking path traversal before any network call), and issues `DELETE /api/contents/work/<name>` against the Jupyter Contents API. - A 204 or 200 reports `deleted: 1`. A 404 is treated as a no op with `deleted: 0`, so a workflow whose notebook was never uploaded still deletes cleanly, consistent with how the database delete reports `deleted: 0` when nothing was stored. Any other status is a 500. - Extracts the shared `jupyterUnavailableResponse` so the four endpoints that need a reachable Jupyter cannot drift in status or body. **`NotebookMigrationService` (frontend)** - Adds `deleteNotebookFromJupyter(notebookName)`. It posts the name to the new endpoint, returns 1 or 0, logs failures, and shows no notification because pod cleanup is best effort. **`JupyterPanelService` (panel delete button)** - `deleteJupyterNotebook()` resolves `notebookFileName(wid)` up front (so a mid flight workflow switch cannot retarget the delete), then fires the pod cleanup after the database delete succeeds. The unsaved workflow path (wid undefined or the default 0) still resets local state only, since no file was ever uploaded for it. **`UserWorkflowComponent` (dashboard delete)** - Adds a private `cleanupNotebookFiles(wids)` that fires the pod cleanup per wid, and calls it from the success handler of both single delete (`deleteWorkflow`) and bulk delete (`handleConfirmDeleteSelectedWorkflows`). It runs only after the backend delete succeeds, so a failed delete leaves the pod file in place. A deleted workflow with no notebook produces a harmless 404. ### Any related issues, documentation, discussions? Closes #7737 Parent issue #4301 Stacked on #7738, which introduces the `notebook_<wid>.ipynb` filename scheme this cleanup depends on. Until that merges, this PR's diff includes its commits. ### How was this PR tested? - `NotebookMigrationResourceSpec.scala`: `delete-notebook` issues a DELETE against the `work/<name>` contents path (verb and path pinned), reports `deleted=1` on 204, treats 404 as `deleted=0`, returns 500 when Jupyter rejects the delete or is unreachable, and returns 400 on an invalid name, a missing or non string name, or a malformed body. - `notebook-migration.service.spec.ts`: `deleteNotebookFromJupyter` posts the name to `delete-notebook` and returns 1 on success, returns 0 with no notification on failure, and makes no HTTP call when the feature flag is off. - `jupyter-panel.service.spec.ts`: the panel delete removes the pod copy under the workflow's filename, does not touch the pod when the database delete fails or for the unsaved default wid, and no ops when the flag is off. - `user-workflow.component.spec.ts`: single delete cleans up `notebook_5.ipynb`, bulk delete cleans up each checked wid in order, and neither the no wid path nor a backend delete error touches the pod. ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Claude Opus 4.8) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
