Follow-up to #PR-for-uid-reconcile
Initial implementation lands in useruid.go (reconcileRemoteUserUID in fresh-create paths). Known gaps:
1. Re-attach path doesn't re-reconcile
Engine.attachExisting reuses whatever image the existing container was started against. If the workspace mount UID changes between runs, Up without Recreate: true will not pick up the new UID. Mirrors upstream behavior, but worth documenting and considering a check.
2. Alpine/BusyBox toolchain assumed Debian-ish
generateUIDDockerfile uses usermod, groupmod, getent which BusyBox-based images don't ship. On Alpine the equivalent is deluser + adduser -u <uid> -G <group>.
Options:
- Detect via the base image's
/etc/os-release (extra build step) and branch.
- Always use a portable
awk-on-/etc/passwd rewrite (closer to what some devpod variants do).
- Document the limitation and call it Debian-only for now (matches upstream's de-facto support tier).
3. Skip behavior on macOS host
statOwner succeeds on macOS but Docker Desktop typically remaps file ownership inside the VM. Reconciling against the host UID may produce a no-op rebuild every Up on Mac. Consider gating to runtime.GOOS == "linux".
4. Integration test coverage
The unit test in useruid_test.go covers skip semantics and Dockerfile shape only — there is no end-to-end test that builds the reconciled image, runs the container, and asserts id -u <user> matches the host workspace owner. Add when revisiting (2): once we have an Alpine variant, the behavioral matrix (Debian vs Alpine × reconcile vs disabled) is worth pinning. CI is Linux-only per PRD §9.2 so the test can rely on runtime.GOOS == \"linux\". Likely uses mcr.microsoft.com/devcontainers/base:debian (vscode @ uid 1000) to keep build cost down.
Follow-up to #PR-for-uid-reconcile
Initial implementation lands in
useruid.go(reconcileRemoteUserUIDin fresh-create paths). Known gaps:1. Re-attach path doesn't re-reconcile
Engine.attachExistingreuses whatever image the existing container was started against. If the workspace mount UID changes between runs,UpwithoutRecreate: truewill not pick up the new UID. Mirrors upstream behavior, but worth documenting and considering a check.2. Alpine/BusyBox toolchain assumed Debian-ish
generateUIDDockerfileusesusermod,groupmod,getentwhich BusyBox-based images don't ship. On Alpine the equivalent isdeluser+adduser -u <uid> -G <group>.Options:
/etc/os-release(extra build step) and branch.awk-on-/etc/passwdrewrite (closer to what some devpod variants do).3. Skip behavior on macOS host
statOwnersucceeds on macOS but Docker Desktop typically remaps file ownership inside the VM. Reconciling against the host UID may produce a no-op rebuild everyUpon Mac. Consider gating toruntime.GOOS == "linux".4. Integration test coverage
The unit test in
useruid_test.gocovers skip semantics and Dockerfile shape only — there is no end-to-end test that builds the reconciled image, runs the container, and assertsid -u <user>matches the host workspace owner. Add when revisiting (2): once we have an Alpine variant, the behavioral matrix (Debian vs Alpine × reconcile vs disabled) is worth pinning. CI is Linux-only per PRD §9.2 so the test can rely onruntime.GOOS == \"linux\". Likely usesmcr.microsoft.com/devcontainers/base:debian(vscode @ uid 1000) to keep build cost down.