Disk mounts not writable due to UID mapping #1

Open
opened 2026-04-12 14:02:30 +00:00 by daniel · 0 comments
Owner

Summary

Directories mounted as read-write into containers are not actually
writable by the dev user. This affects both the reviewer and developer
containers.

Affected mounts

For the reviewer container:

  • ~/issues/ — should be read-write, is read-only
  • ~/reviewer-comments/ — should be read-write, is read-only

For the developer container (expected, not yet verified):

  • ~/code-repo/ — should be read-write, likely read-only
  • ~/developer-comments/ — should be read-write, likely read-only

Root cause

The incus-add-device call in degudev.el correctly omits the
readonly=true flag for writable mounts. The mount logic is correct.

The problem is UID mapping. Inside the container the directories appear
owned by nobody:nogroup:

drwxrwsr-x+ 2 nobody nogroup 4096 Apr 11 15:12 issues
drwxrwsr-x+ 2 nobody nogroup 4096 Apr 11 05:07 reviewer-comments

The host UID that owns these directories does not map to the dev user
(UID 1000) inside the unprivileged container. Without UID shifting, the
container's dev user has no write permission.

Proposed fix

Add shift=true to writable disk devices in incus-add-device or at
the degudev.el level. The shift=true option enables Incus's idmap
shifting so the host UID is transparently mapped to the container UID.

Alternatively, degudev--setup-container could set raw.idmap on the
container to explicitly map the host user to container UID 1000.

The shift=true approach is simpler and more portable.

Where to fix

This should be fixed in degudev.el, not incus.el. The
incus-add-device function is a generic low-level wrapper — not all
callers will want UID shifting. degudev.el knows which mounts need to
be writable by the container user and should pass the appropriate
option.

This means incus-add-device needs to be extended to accept additional
device options (like shift=true), or degudev.el should call
incus--run directly with the extra parameter.

Idempotency requirement

Re-running degudev-create-containers on an existing container MUST fix
the permissions on already-mounted devices.

Currently, mount setup is guarded by
(unless (incus-device-exists-p ...)), which skips devices that already
exist — even if their configuration is wrong. The fix must update
existing device config in place rather than skip or remove/re-add.
Concretely:

  • If a device already exists but lacks shift=true, set it via
    incus config device set <container> <device> shift=true.
  • This requires a new function in incus.el (e.g., incus-device-set)
    or direct use of incus--run from degudev.el.
  • The mount setup logic should change from "skip if exists" to "create
    if missing, update config if exists".

Reproduction

Inside the reviewer container:

touch ~/issues/test        # Permission denied
touch ~/reviewer-comments/test  # Permission denied
# Summary Directories mounted as read-write into containers are not actually writable by the `dev` user. This affects both the reviewer and developer containers. # Affected mounts For the reviewer container: - `~/issues/` — should be read-write, is read-only - `~/reviewer-comments/` — should be read-write, is read-only For the developer container (expected, not yet verified): - `~/code-repo/` — should be read-write, likely read-only - `~/developer-comments/` — should be read-write, likely read-only # Root cause The `incus-add-device` call in `degudev.el` correctly omits the `readonly=true` flag for writable mounts. The mount logic is correct. The problem is UID mapping. Inside the container the directories appear owned by `nobody:nogroup`: ``` example drwxrwsr-x+ 2 nobody nogroup 4096 Apr 11 15:12 issues drwxrwsr-x+ 2 nobody nogroup 4096 Apr 11 05:07 reviewer-comments ``` The host UID that owns these directories does not map to the `dev` user (UID 1000) inside the unprivileged container. Without UID shifting, the container's `dev` user has no write permission. # Proposed fix Add `shift=true` to writable disk devices in `incus-add-device` or at the `degudev.el` level. The `shift=true` option enables Incus's idmap shifting so the host UID is transparently mapped to the container UID. Alternatively, `degudev--setup-container` could set `raw.idmap` on the container to explicitly map the host user to container UID 1000. The `shift=true` approach is simpler and more portable. # Where to fix This should be fixed in `degudev.el`, not `incus.el`. The `incus-add-device` function is a generic low-level wrapper — not all callers will want UID shifting. `degudev.el` knows which mounts need to be writable by the container user and should pass the appropriate option. This means `incus-add-device` needs to be extended to accept additional device options (like `shift=true`), or `degudev.el` should call `incus--run` directly with the extra parameter. # Idempotency requirement Re-running `degudev-create-containers` on an existing container MUST fix the permissions on already-mounted devices. Currently, mount setup is guarded by `(unless (incus-device-exists-p ...))`, which skips devices that already exist — even if their configuration is wrong. The fix must update existing device config in place rather than skip or remove/re-add. Concretely: - If a device already exists but lacks `shift=true`, set it via `incus config device set <container> <device> shift=true`. - This requires a new function in `incus.el` (e.g., `incus-device-set`) or direct use of `incus--run` from `degudev.el`. - The mount setup logic should change from "skip if exists" to "create if missing, update config if exists". # Reproduction Inside the reviewer container: ``` bash touch ~/issues/test # Permission denied touch ~/reviewer-comments/test # Permission denied ```
Sign in to join this conversation.
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
daniel/degudev.el#1
No description provided.