From 3d632ef02f085ef91afc3e08f67cceb8bcd93178 Mon Sep 17 00:00:00 2001 From: Joakim Persson Date: Mon, 20 Apr 2026 23:59:32 +0200 Subject: [PATCH] Detect workspace UID and GID independently in entrypoint The auto-detection block was gated on UID mismatch alone: if the host user already had UID 1000 (the container's default) but a non-default GID, the GID was never adopted. That left host-written files with a numeric GID the container couldn't resolve to a name (e.g. '1001' on Debian VMs where useradd assigns a dedicated group starting at 1001). Split UID and GID detection into independent conditions. Each dimension is adopted from /workspace if its env var is unset and the workspace value differs from the container default, regardless of the other dimension's state. Preserves existing USER_UID / USER_GID overrides. --- entrypoint.sh | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index f0ecc6d..b00dbaf 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -6,18 +6,22 @@ CURRENT_UID=$(id -u "$USER_NAME") CURRENT_GID=$(id -g "$USER_NAME") # ── UID/GID adjustment ─────────────────────────────────────────────── -# Priority: env vars > auto-detect from /workspace > default (1000) +# Priority per dimension: env var > auto-detect from /workspace > no-op +# UID and GID are detected independently so a GID-only mismatch (e.g. host +# user has UID 1000 but primary group at GID 1001) is still corrected. TARGET_UID="${USER_UID:-}" TARGET_GID="${USER_GID:-}" -# Auto-detect from /workspace owner if env vars not set -if [ -z "$TARGET_UID" ] && [ -d /workspace ]; then - WORKSPACE_UID=$(stat -c '%u' /workspace 2>/dev/null || stat -f '%u' /workspace 2>/dev/null) - WORKSPACE_GID=$(stat -c '%g' /workspace 2>/dev/null || stat -f '%g' /workspace 2>/dev/null) - # Only adjust if workspace is owned by a non-root user - if [ "$WORKSPACE_UID" != "0" ] && [ "$WORKSPACE_UID" != "$CURRENT_UID" ]; then +if [ -d /workspace ]; then + WORKSPACE_UID=$(stat -c '%u' /workspace 2>/dev/null || stat -f '%u' /workspace 2>/dev/null || echo "") + WORKSPACE_GID=$(stat -c '%g' /workspace 2>/dev/null || stat -f '%g' /workspace 2>/dev/null || echo "") + # Adopt workspace UID if env var not set and workspace is non-root-owned + if [ -z "$TARGET_UID" ] && [ -n "$WORKSPACE_UID" ] && [ "$WORKSPACE_UID" != "0" ] && [ "$WORKSPACE_UID" != "$CURRENT_UID" ]; then TARGET_UID="$WORKSPACE_UID" - TARGET_GID="${TARGET_GID:-$WORKSPACE_GID}" + fi + # Adopt workspace GID if env var not set and workspace group differs + if [ -z "$TARGET_GID" ] && [ -n "$WORKSPACE_GID" ] && [ "$WORKSPACE_GID" != "0" ] && [ "$WORKSPACE_GID" != "$CURRENT_GID" ]; then + TARGET_GID="$WORKSPACE_GID" fi fi @@ -25,12 +29,13 @@ fi if [ -n "$TARGET_GID" ] && [ "$TARGET_GID" != "$CURRENT_GID" ]; then groupmod -g "$TARGET_GID" "$USER_NAME" 2>/dev/null || true find /home/"$USER_NAME" -not -path "/home/$USER_NAME/.ssh/*" -group "$CURRENT_GID" -exec chgrp "$TARGET_GID" {} + 2>/dev/null || true + echo "Adjusted developer GID to $TARGET_GID" fi if [ -n "$TARGET_UID" ] && [ "$TARGET_UID" != "$CURRENT_UID" ]; then usermod -u "$TARGET_UID" "$USER_NAME" 2>/dev/null || true find /home/"$USER_NAME" -not -path "/home/$USER_NAME/.ssh/*" -user "$CURRENT_UID" -exec chown "$TARGET_UID" {} + 2>/dev/null || true - echo "Adjusted developer UID:GID to $TARGET_UID:${TARGET_GID:-$CURRENT_GID}" + echo "Adjusted developer UID to $TARGET_UID" fi # ── SSH key permissions ──────────────────────────────────────────────