fix(user-mapping): don't chown the workspace to root (corrupts host repo)#176
Merged
Conversation
chown 0:0 on a bind-mounted workspace rewrites the HOST directory to root:root (corrupting the dev workspace). Skip the adjustment when the target user is root; non-root users still get it. Adds unit tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Keeps the workspace outside the repo so up never bind-mounts the git root into the container. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Keeps the workspace outside the repo so up never bind-mounts the git root into the container; drops the now-obsolete git-root state cleanup. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Problem
Running the test suite kept flipping
/workspaces/deacontoroot:rootownership, and it came back after every fix.Root cause
deacon upbind-mounts the host workspace into the container. Per the git-root mount default, an in-repo workspace folder resolves to the git root (/workspaces/deacon), so the whole repo gets mounted. Thenuser_mapping::set_workspace_ownershiprunschown <uid>:<gid> <workspaceFolder>as root inside the container whenever aremoteUseris set (needs_user_mapping()=remote_user.is_some()). Thefeature-and-dotfiles/single-containerfixtures set"remoteUser": "root", so it didchown 0:0 /workspace— which, on a bind mount, rewrites the host repo dir toroot:root. Theup_prebuildtests run for real in the docker integration job, so it recurred every run.Fix (two layers)
crates/core/src/user_mapping.rs): skip the workspace ownership adjustment when the target user is root (uid 0) — chowning to root is pointless (root already has full access) and actively corrupts host ownership on bind mounts. Non-root users still get the adjustment. Addstest_workspace_ownership_skipped_for_rootandtest_workspace_ownership_adjusted_for_nonroot. This protects real users and canaries, not just tests.up_prebuild.rs,up_dotfiles.rs): copy fixtures into aTempDiroutside the repo and runupthere, so the git root is never mounted regardless. Drops the now-obsolete git-root.devcontainer-statecleanup.integration_up_with_features.rsalready passed--mount-workspace-git-root=false; no other in-repouptests were unguarded.Verification
cargo test -p deacon-core --lib user_mapping— 17 passed (incl. both new tests).cargo nextest run -E 'binary(=up_prebuild)'— 8 passed; no root-owned artifacts created in/tmpor the repo during the run (TempDirs were created and cleaned by the unprivileged test user, proving no chown fired).cargo fmt --all -- --checkandcargo clippy --all-targets --all-features -- -D warningsclean.Note: the repo dir is currently still
root:rootfrom earlier (pre-fix) runs; a one-timesudo chown -R vscode:vscode /workspaces/deaconis needed, after which it will stay correct.🤖 Generated with Claude Code