diff --git a/src/create-remote-user/devcontainer-feature.json b/src/create-remote-user/devcontainer-feature.json index b7da95269..8c3b669f6 100644 --- a/src/create-remote-user/devcontainer-feature.json +++ b/src/create-remote-user/devcontainer-feature.json @@ -1,8 +1,8 @@ { "name": "Create Remote User", "id": "create-remote-user", - "version": "0.0.4", - "description": "A to assert the configured remote user exists in the container", + "version": "0.0.5", + "description": "A feature to assert the configured remote user exists in the container and optionally add them to additional groups", "licenseURL": "https://github.com/nils-geistmann/devcontainers-features/blob/main/LICENSE", "options": { "create": { @@ -24,6 +24,11 @@ "description": "Configures sudo to allow the remote user to elevate permissions without password", "type": "boolean", "default": false + }, + "additionalGroups": { + "description": "Comma-separated list of additional groups to add the user to (e.g., 'audio,video,docker')", + "type": "string", + "default": "" } } } diff --git a/src/create-remote-user/functions.sh b/src/create-remote-user/functions.sh index 2076f7ec4..2e6785e92 100644 --- a/src/create-remote-user/functions.sh +++ b/src/create-remote-user/functions.sh @@ -14,6 +14,39 @@ check_and_install() { done } +# Adds user to specified groups if they exist +add_user_to_groups() { + local user="$1" + local groups="$2" + + if [ -z "$groups" ]; then + return 0 + fi + + # Convert comma-separated string to array + IFS=',' read -ra GROUP_ARRAY <<< "$groups" + + for group in "${GROUP_ARRAY[@]}"; do + # Trim whitespace + group=$(echo "$group" | xargs) + + if [ -n "$group" ]; then + # Check if group exists + if getent group "$group" >/dev/null 2>&1; then + # Check if user is already in the group + if ! id -nG "$user" | grep -qw "$group"; then + echo "Adding user $user to group $group" + usermod -a -G "$group" "$user" + else + echo "User $user is already in group $group" + fi + else + echo "Warning: Group $group does not exist, skipping" + fi + fi + done +} + # Cleans APT's cache to keep devcontainer layers small clean_package_cache() { apt-get clean diff --git a/src/create-remote-user/install.sh b/src/create-remote-user/install.sh index 626f381c0..3493fc666 100755 --- a/src/create-remote-user/install.sh +++ b/src/create-remote-user/install.sh @@ -33,5 +33,9 @@ if [ "$PASSWORDLESSSUDO" = "true" ]; then echo "$_REMOTE_USER" ALL=\(root\) NOPASSWD:ALL > "/etc/sudoers.d/$_REMOTE_USER" fi +if [ -n "$ADDITIONALGROUPS" ]; then + echo "Adding user to additional groups: $ADDITIONALGROUPS" + add_user_to_groups "$_REMOTE_USER" "$ADDITIONALGROUPS" +fi clean_package_cache diff --git a/test/create-remote-user/scenarios.json b/test/create-remote-user/scenarios.json index deebf0839..2a0f9e867 100644 --- a/test/create-remote-user/scenarios.json +++ b/test/create-remote-user/scenarios.json @@ -24,5 +24,14 @@ } }, "remoteUser": "remote" + }, + "with_additional_groups": { + "image": "debian:bookworm-slim", + "features": { + "create-remote-user": { + "additionalGroups": "audio,video,plugdev" + } + }, + "remoteUser": "remote" } } diff --git a/test/create-remote-user/with_additional_groups.sh b/test/create-remote-user/with_additional_groups.sh new file mode 100644 index 000000000..aacf92401 --- /dev/null +++ b/test/create-remote-user/with_additional_groups.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +source test_functions.sh + +# Test if the user is added to the specified additional groups +check "user exists" bash -c "id remote" +check "user in audio group" bash -c "id -nG remote | grep -q audio" +check "user in video group" bash -c "id -nG remote | grep -q video" +check "user in plugdev group" bash -c "id -nG remote | grep -q plugdev" + +# Verify groups exist first +check "audio group exists" bash -c "getent group audio" +check "video group exists" bash -c "getent group video" +check "plugdev group exists" bash -c "getent group plugdev" + +reportResults \ No newline at end of file