diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index b0fd2f3b0..6ecd090f9 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -422,7 +422,7 @@ elif [ "${USERNAME}" = "none" ]; then USER_GID=0 fi # Create or update a non-root user to match UID/GID. -group_name="${USERNAME}" +group_name="$(id -gn "$USERNAME" 2>/dev/null || echo "$USERNAME")" if id -u ${USERNAME} > /dev/null 2>&1; then # User exists, update if needed if [ "${USER_GID}" != "automatic" ] && [ "$USER_GID" != "$(id -g $USERNAME)" ]; then @@ -430,8 +430,18 @@ if id -u ${USERNAME} > /dev/null 2>&1; then groupmod --gid $USER_GID ${group_name} usermod --gid $USER_GID $USERNAME fi + # Check if the target UID is different from current user's UID before modifying if [ "${USER_UID}" != "automatic" ] && [ "$USER_UID" != "$(id -u $USERNAME)" ]; then - usermod --uid $USER_UID $USERNAME + # Additional safety check: ensure target UID isn't already taken by another user + # This prevents "UID already exists" errors when multiple users have the same UID + if id -u $USER_UID > /dev/null 2>&1; then + existing_user=$(id -nu $USER_UID) + if [ "$existing_user" != "$USERNAME" ]; then + echo "Warning: UID $USER_UID is already in use by user '$existing_user'. Skipping UID modification." + fi + else + usermod --uid $USER_UID $USERNAME + fi fi else # Create user diff --git a/test/common-utils/devcontainer-custom-user.sh b/test/common-utils/devcontainer-custom-user.sh new file mode 100644 index 000000000..8e1a6e18b --- /dev/null +++ b/test/common-utils/devcontainer-custom-user.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Check current user +current_user=$(whoami) +echo "Current user: $current_user" + +# Check user's primary group ID +user_gid=$(id -g) +echo "User's primary GID: $user_gid" + +# Check user's primary group name +user_group_name=$(id -gn) +echo "User's primary group name: $user_group_name" + +# Check if user exists and get their info +if id -u vscode > /dev/null 2>&1; then + echo "vscode user exists" + vscode_uid=$(id -u vscode) + vscode_gid=$(id -g vscode) + vscode_group_name=$(id -gn vscode) + + echo "vscode UID: $vscode_uid" + echo "vscode GID: $vscode_gid" + echo "vscode group name: $vscode_group_name" +else + echo "vscode user does not exist" +fi + +# Check what group has GID 100 +if getent group 100 >/dev/null 2>&1; then + group_100_info=$(getent group 100) + echo "GID 100 belongs to: $group_100_info" +else + echo "No group found with GID 100" +fi + +# Check all groups the user belongs to +echo "All groups for $current_user: $(groups)" + +# Definition specific tests based on the scenario +check "user is vscode" grep "vscode" <(whoami) +check "vscode user exists" id -u vscode +check "vscode primary group exists" id -g vscode + +# If the test is specifically for GID 100, check that +if [ "$(id -g vscode)" = "100" ]; then + check "vscode has GID 100" [ "$(id -g vscode)" = "100" ] + check "GID 100 group name" getent group 100 +fi + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/devcontainer-custom-user/Dockerfile b/test/common-utils/devcontainer-custom-user/Dockerfile new file mode 100644 index 000000000..1065a106a --- /dev/null +++ b/test/common-utils/devcontainer-custom-user/Dockerfile @@ -0,0 +1,13 @@ +FROM ubuntu:noble +ARG USERNAME=vscode +ARG USER_UID=1000 +ARG USER_GID=100 +RUN if ! getent group users > /dev/null 2>&1; then groupadd --gid $USER_GID users; fi \ + && if ! id -u $USERNAME > /dev/null 2>&1; then \ + if ! id -u $USER_UID > /dev/null 2>&1; then \ + useradd --uid $USER_UID --gid $USER_GID -m $USERNAME; \ + else \ + echo "UID $USER_UID already exists, creating user without specifying UID"; \ + useradd --gid $USER_GID -m $USERNAME; \ + fi; \ + fi \ No newline at end of file diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index ee138ca22..61856a9c3 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -284,5 +284,18 @@ "features": { "common-utils": {} } + }, + "devcontainer-custom-user": { + "build": { + "dockerfile": "Dockerfile" + }, + "remoteUser": "vscode", + "features": { + "common-utils": { + "username": "vscode", + "userUid": "1000", + "userGid": "100" // Test GID 100 conflict resolution (users group) + } + } } } \ No newline at end of file