Repository navigation
Conversation
dl rm swept only two hard-coded volume names (<basename>-pixi and
dind-var-lib-docker-<devcontainerId>). A devcontainer that names its
volume any other way, such as
kinisi-ansible-pixi-${localWorkspaceFolderBasename}, leaked one volume
per workspace.
Read the volume mounts from the merged config devpod records in
workspace_result.json. A recorded source that holds the workspace's
substituted basename or devcontainer id is scoped to that workspace and
is removed with it. A fixed-name volume is shared between workspaces
and is left alone. The names stay devpod's record, never a pattern over
docker volume ls.
A plain substring test let a short basename such as kr match a shared volume such as kros-cache. Require the basename or devcontainer id to be bounded by the ends of the name or by a non-alphanumeric character.
Reviewer's GuideUpdates workspace cleanup to derive additional Docker volumes from devpod's recorded MergedConfig.mounts, removing only names scoped to the workspace basename or devcontainer ID while preserving shared fixed-name volumes. Parsing, token-boundary filtering, kept-copy pruning, lifecycle behavior, tests, and documentation are updated consistently. Sequence diagram for workspace-scoped volume cleanupsequenceDiagram
participant User
participant DL as dl
participant Record as workspace_result.json
participant Sweep as VolumeSweep
participant Docker
User->>DL: rm
DL->>Record: substitutions_in(document)
Record-->>DL: basename, devcontainerId, MergedConfig.mounts
DL->>DL: volume_names()
DL->>DL: holds_token(source, scope)
DL->>Sweep: sweep_volumes(named)
Sweep->>Docker: docker volume rm scoped names
Docker-->>Sweep: removal result
Sweep-->>User: workspace removed
Flow diagram for selecting workspace-scoped volumesflowchart TD
A[Read MergedConfig.mounts] --> B{Mount is type=volume?}
B -- No --> Z[Ignore mount]
B -- Yes --> C[Read recorded source]
C --> D{Source holds basename or devcontainerId as a whole token?}
D -- Yes --> E[Include recorded source]
D -- No --> F[Preserve shared fixed-name volume]
E --> G[Deduplicate and keep order]
F --> G
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Codecov Report❌ Patch coverage is
Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
dl <ws> rmnow removes every Docker volume that a devcontainer named after the workspace, not only<basename>-pixianddind-var-lib-docker-<id>.Evidence
A real run on one host, docker 29, with this branch's
dl(release build):Before: the same two commands with released
dl0.62.0 leftkinisi-ansible-pixi-kinisi-ansible-main-sll1on the host. That repository's devcontainer declaressource=kinisi-ansible-pixi-${localWorkspaceFolderBasename},…,type=volume, and the name does not match either hard-coded template. So everydlworkspace of that repository leaked one volume. Another workspace of the same repository (kinisi-ansible-devcontainer-prebuild-jghy) was on the host during the run and stayed.What this changes
Substitutionsalso reads thesourceof eachtype=volumeentry inMergedConfig.mountsfrom devpod'sworkspace_result.json. It reads both mount spellings: the object and the--mount-style string.volume_names()adds a recorded source when it holds the substituted basename or devcontainer id as a whole token. A whole token starts and ends at an end of the name or at a non-alphanumeric character. So the basenamekrmatcheskr-cacheanddata.kr, but notkros-cache.myrepo-pip-cache) is not removed. Every workspace of the repository mounts the same one, and that sharing is usually on purpose.docker volume ls, so devlaunch#451's rule holds. The kept copy that--prunereads uses the same parser, so--prunegets the same names.docs/cleanup.mdgets a third row in the volume table.Where this fits
How I checked it
New tests that failed before the fix and pass now:
a_recorded_volume_mount_scoped_to_the_workspace_is_named: a record with scoped volumes, fixed-name volumes and binds in both spellings → only the scoped volumes are named.a_scope_inside_a_longer_word_names_nothing: basenamekr, idabc→kros-cache,shared-kr2-cacheandbeefcake-abc1are not named.a_recorded_volume_mount_with_no_substitution_names_nothing.a_removed_workspaces_devcontainer_volumes_go_with_itand the purge test indl/tests/lifecycle.rs: the fixture record now has a scoped string-form volume and a shared one. Thedocker volume rmargv gains only the scoped one.Commands, with the pinned 1.97.1 toolchain from the pixi env:
cargo test --workspace --no-fail-fast: 3132 passed, 5 failed. The same 5 fail onmainat 9af13ca on this host, and the change does not touch them (*pushed_by_url*,a_remote_that_cannot_be_reached_*,a_host_that_prunes_on_fetch_*). They depend on the host's git config.cargo clippy --locked --all-targets -- -D warnings,cargo fmt --check,prek run --from-ref origin/main: clean.pixi run test-e2e. The real-devpod run above replaces it for this path.Merge danger
Door: two-way. A revert gives back the two-template behavior. No file format changes, and the kept-copy JSON keeps its shape.
Blast radius: small. If the scope test is wrong,
dl rmcan remove a volume that another workspace's devcontainer also mounts. Docker refuses to remove a volume that a container uses, anddl rmreports that as a warning. A stopped workspace's volume does not have that protection. The whole-token rule limits the risk to a basename or id that is a full token of the other volume's name.dlworkspace ids end in a random 4-character suffix, so this needs a non-dlworkspace with a short name.Review notes
dl rmstill prints no line for each volume that it removes. A successful sweep is silent by design (VolumeSweep::Removed). A line for each volume would change thermand--purgeoutput and the public-API snapshot, so I left it for a separate PR.🤖 Generated with Claude Code
Summary by Sourcery
Clean up all recorded devcontainer volumes associated with a workspace without removing intentionally shared volumes.
Bug Fixes:
Enhancements:
Documentation:
Tests: