fix(dev): chown cargo volumes on first run so check works without root #99

Merged
David merged 2 commits from fix/dev-cargo-volume-perms into main 2026-05-15 01:01:33 +02:00
Owner

Summary

./dev/cargo previously launched the rust:slim container with --user uid:gid, but the named volumes mounted at /usr/local/cargo/registry, /usr/local/cargo/git, /cargo-target, and /usr/local/rustup are initialised by Docker with the image-path ownership (root:root in the slim image), so cargo immediately failed with Permission denied (os error 13) trying to write the registry on a fresh clone.

The wrapper now starts as root, chowns each volume to the host user only when its current owner is not the host uid (idempotent: first run pays a one-time chown -R, subsequent runs are noops), then drops privileges via setpriv --reuid=$UID --regid=$GID --clear-groups before invoking cargo. Running as the host user is preserved for the /work bind mount so Cargo.lock and any other files written into the repo land with the right ownership on the host.

The dropped shell also forces HOME=/tmp because setpriv inherits HOME=/root from the root entrypoint, and /root is mode 700, which blocks libgit2 (invoked by cargo's build-script fingerprinting) from reading ~/.gitconfig and produces a misleading Could not read repository exclude error.

Test plan

  • On a host with the named volumes already owned by root (the bug repro), just check-server completes successfully.
  • just check-fmt runs to completion (the rustup component install path now succeeds as the dropped user).
  • Subsequent runs of just check-server do not perform another full chown -R (the ownership check skips the walk).
## Summary `./dev/cargo` previously launched the rust:slim container with `--user uid:gid`, but the named volumes mounted at `/usr/local/cargo/registry`, `/usr/local/cargo/git`, `/cargo-target`, and `/usr/local/rustup` are initialised by Docker with the image-path ownership (root:root in the slim image), so cargo immediately failed with `Permission denied (os error 13)` trying to write the registry on a fresh clone. The wrapper now starts as root, chowns each volume to the host user only when its current owner is not the host uid (idempotent: first run pays a one-time `chown -R`, subsequent runs are noops), then drops privileges via `setpriv --reuid=$UID --regid=$GID --clear-groups` before invoking cargo. Running as the host user is preserved for the `/work` bind mount so Cargo.lock and any other files written into the repo land with the right ownership on the host. The dropped shell also forces `HOME=/tmp` because `setpriv` inherits `HOME=/root` from the root entrypoint, and `/root` is mode 700, which blocks libgit2 (invoked by cargo's build-script fingerprinting) from reading `~/.gitconfig` and produces a misleading `Could not read repository exclude` error. ## Test plan - [x] On a host with the named volumes already owned by root (the bug repro), `just check-server` completes successfully. - [x] `just check-fmt` runs to completion (the rustup component install path now succeeds as the dropped user). - [x] Subsequent runs of `just check-server` do not perform another full `chown -R` (the ownership check skips the walk).
fix(dev): chown cargo volumes on first run so check works without root
Some checks failed
Check / clippy + fmt + tests (pull_request) Failing after 5s
d389c292d8
`./dev/cargo` previously launched the rust:slim container with `--user uid:gid`, but the named volumes mounted at `/usr/local/cargo/registry`, `/usr/local/cargo/git`, `/cargo-target`, and `/usr/local/rustup` are initialised by Docker with the image's path ownership (root:root), so cargo immediately failed with permission denied trying to write the registry. The wrapper now starts as root, chowns each volume to the host user only when ownership has not yet been switched, then drops to the host user via setpriv before invoking cargo so Cargo.lock and other files written into the /work bind mount still land with the right ownership. The dropped shell also forces HOME=/tmp because setpriv inherits HOME=/root, which is mode 700 and blocks libgit2 from reading global git config during cargo's build-script fingerprinting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merge branch 'main' into fix/dev-cargo-volume-perms
Some checks failed
Check / clippy + fmt + tests (pull_request) Failing after 6s
dea41ab97c
David merged commit 8f573b5bbf into main 2026-05-15 01:01:33 +02:00
David deleted branch fix/dev-cargo-volume-perms 2026-05-15 01:01:33 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/lets-chat!99
No description provided.