fix(podman): chown workspace for non-root remoteUser on macOS/Windows#528
Conversation
The in-container SSH server (which VS Code Remote-SSH connects through) failed with "start command: fork/exec /usr/bin/bash: permission denied" for Podman workspaces with a non-root remoteUser on macOS/Windows hosts. Root cause: rootless `podman machine` surfaces the host workspace bind mount as root-owned (root:root 0750) inside the container. Go's exec performs chdir(cmd.Dir) in the forked child before execve; the non-root remote user cannot enter the workspace folder, so the chdir returns EACCES, which Go reports against the shell path. addChownFlag previously gated `--chown-workspace` on `runtime.GOOS == "linux" || !isDockerDriver`. Podman uses the docker driver, so on a macOS/Windows host neither clause held and the workspace was never chowned to the remote user. Extend the condition to also chown for the Podman runtime regardless of host OS. devsy's own terminal was unaffected because the podman provider runs commands through the in-process emulated shell (`devsy internal sh`), which never execs a real /usr/bin/bash. Tests: - Unit: shouldChownWorkspace and isPodmanRuntime tables. - E2E: new rootless-podman spec with a non-root remoteUser fixture asserting the workspace folder is owned by the remote user.
✅ Deploy Preview for devsydev canceled.
|
|
Warning Review limit reached
More reviews will be available in 50 minutes and 57 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughThe PR updates workspace ownership handling for Podman, adds unit tests for the chown and runtime checks, and adds an e2e regression using a non-root devcontainer fixture to verify SSH user identity and workspace ownership. ChangesRootless Podman workspace ownership
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Deploy Preview for images-devsy-sh canceled.
|
Satisfy goconst: replace repeated "linux"/"darwin"/"windows" string literals with goosLinux/goosDarwin/goosWindows constants, and use the existing docker.Runtime* constants in the runtime table test.
Summary
Podman workspaces with a non-root
remoteUserfailed to open from VS Code Remote-SSH on macOS/Windows hosts, with:The container launched fine and devsy's own terminal worked, but VS Code (and
devsy workspace ssh) could not start a shell.Root cause
Rootless
podman machinesurfaces the host workspace bind mount as root-owned (root:root 0750) inside the container. Go'sos/execperformschdir(cmd.Dir)in the forked child beforeexecve; the non-root remote user cannot enter the workspace folder, so thechdirreturnsEACCES— which Go reports against the shell path, producing the misleading "fork/exec /usr/bin/bash: permission denied".addChownFlaggated--chown-workspaceonruntime.GOOS == "linux" || !isDockerDriver. Podman runs through the docker driver, so on a macOS/Windows host neither clause held and the workspace was never chowned to the remote user. The fix extends the condition to also chown for the Podman runtime regardless of host OS.devsy's own terminal was unaffected because the podman provider runs commands through the in-process emulated shell (
devsy internal sh), which never execs a real/usr/bin/bash.Spec alignment
The Dev Container spec scopes UID/GID syncing to "an optional task for Linux (only)" whose purpose is "to avoid permission problems with bind mounts," and explicitly lets implementations handle the case themselves when the engine does not translate automatically. This fix serves that exact goal for rootless Podman on macOS, where the reference CLI's Linux-only UID-remap mechanism does not apply. The chown writes through the bind mount to the host inode (cf. loft-sh/devpod#1879); it is scoped to non-root remote users, so root-user containers are unaffected.
Tests
shouldChownWorkspaceandisPodmanRuntimetable tests.remoteUserfixture (docker-nonroot-user) asserting the workspace folder is owned by the remote user. Validated end-to-end against real rootless Podman (fails without the fix, passes with it).Operational note
The
chownWorkspacesetup step is guarded by a one-time marker file, so existing broken workspaces need a Recreate (or a fresh workspace) to pick up the chown. New workspaces work immediately.UI
No UI changes required — the desktop's
workspace_upIPC handler shells out to the sameworkspace upCLI path, so this fix applies once the bundled CLI binary is built from this branch.Summary by CodeRabbit
remoteUsersessions start with the correct identity.