Skip to content

Remove the workspace's pixi and dind volumes on delete #325

Description

@blooop

Work

Remove the two named docker volumes a workspace's devcontainer created, when that
workspace is deleted.

What leaks today

Nothing in devlaunch ever removes a docker volume — grep for a volume command
across the Rust tree returns zero hits, because the only subprocess is devpod.
lifecycle::workspace_delete
is exactly devpod delete <id> plus removing the clone directory, and devpod delete does not remove volumes a devcontainer declared. So every removal path
leaks two volumes per workspace, both named deterministically from the workspace
being deleted:

volume declared by size seen
${localWorkspaceFolderBasename}-pixi our own .devcontainer/devcontainer.json mounts (the .pixi cache) 0.4–2.7 GB
dind-var-lib-docker-${devcontainerId} the docker-in-docker:2 feature up to 4.2 GB

Both names are already knowable at delete time: the basename is the clone
directory devlaunch itself chose, and the devcontainer id is recorded in
~/.devpod/contexts/<ctx>/workspaces/<ws>/workspace_result.json.

Measured on one dev machine, cross-referencing volumes against devpod list and
the workspace result files: 39 orphaned volumes, 37.28 GB, none with a
surviving workspace — 22 pixi volumes (19.5 GB) and 17 dind volumes (17.7 GB).
About 9.5 GB of it carries current name-hash-scheme names, so this is a live leak
and not historical debt. 1.04 GB sat under e2e-* workspace ids, so the e2e suite
leaks too.

Shape of the fix

Once devpod has confirmed it let go of the workspace, remove the volumes whose
names derive from it. Best-effort: a typed notice on failure rather than a failed
delete (the workspace is gone either way, and reporting failure sends the caller
looking for a workspace that is not there — the same reasoning the existing
clone-removal arm uses), and silently skipped where docker is absent, so nothing
added here can fail on a docker-less machine. --autorm and --purge inherit it
by sharing the path.

One judgement to settle while building: whether --purge should also sweep
volumes for workspaces it did not itself delete. Today it promises a clean slate
and leaves every volume standing, which is the gap that let 37 GB accumulate — but
sweeping by name pattern is a different and less certain operation than removing
the volumes of a workspace you just deleted. Prefer the smaller thing unless the
larger one falls out for free; note the call in a breadcrumb.

The sentence that has to change with it

render::DOCKER_BOUNDARY — "devlaunch does
not manage Docker images or volumes" — is printed only through
Cleanup::with_the_boundary, which only --prune and --purge use. rm and
--autorm, the two commands that actually create the orphans, say nothing at all.
Once volumes are removed the sentence needs narrowing to images rather than
deleting: images stay out of scope deliberately (shared, expensive to rebuild,
ownership genuinely ambiguous), and that remains worth saying.

Done when

  • A workspace deleted by rm, --rm, --autorm or --purge leaves neither
    volume behind.
  • Regression test: the removal path issues the removals for both derived
    names. This is the test that would have caught the leak.
  • Regression test: a machine with no docker still deletes the workspace and its
    clone cleanly, with the removal reported as a notice rather than a failure.
  • DOCKER_BOUNDARY and its pinning tests say only what is still true.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions