From 1cb8e365bba5fd83edca0433f069cb58f1be8bf6 Mon Sep 17 00:00:00 2001 From: Roemer Date: Tue, 11 Nov 2025 15:49:14 +0000 Subject: [PATCH 1/3] feat: Use socat for the Docker socket if needed --- features/src/docker-out/README.md | 4 +- .../src/docker-out/devcontainer-feature.json | 8 +- features/src/docker-out/docker-init.sh | 83 +++++++++++++++---- 3 files changed, 75 insertions(+), 20 deletions(-) diff --git a/features/src/docker-out/README.md b/features/src/docker-out/README.md index 8eabf7f..99ad6b8 100755 --- a/features/src/docker-out/README.md +++ b/features/src/docker-out/README.md @@ -6,7 +6,7 @@ Installs a Docker client which re-uses the host Docker socket. ```json "features": { - "ghcr.io/postfinance/devcontainer-features/docker-out:0.3.0": { + "ghcr.io/postfinance/devcontainer-features/docker-out:0.4.0": { "version": "latest", "composeVersion": "latest", "buildxVersion": "latest", @@ -36,7 +36,7 @@ Installs a Docker client which re-uses the host Docker socket. ### VS Code Extensions -- `ms-azuretools.vscode-docker` +- `ms-azuretools.vscode-containers` ## Notes diff --git a/features/src/docker-out/devcontainer-feature.json b/features/src/docker-out/devcontainer-feature.json index 98f85c0..0bf84f4 100644 --- a/features/src/docker-out/devcontainer-feature.json +++ b/features/src/docker-out/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "docker-out", - "version": "0.3.0", + "version": "0.4.0", "name": "Docker outside Docker", "description": "Installs a Docker client which re-uses the host Docker socket.", "options": { @@ -51,7 +51,7 @@ "default": "", "description": "The download URL to use for Docker binaries." }, - "versionsUrl":{ + "versionsUrl": { "type": "string", "default": "", "description": "The URL to use for checking available versions." @@ -70,14 +70,14 @@ "customizations": { "vscode": { "extensions": [ - "ms-azuretools.vscode-docker" + "ms-azuretools.vscode-containers" ] } }, "mounts": [ { "source": "/var/run/docker.sock", - "target": "/var/run/docker.sock", + "target": "/var/run/docker-host.sock", "type": "bind" } ], diff --git a/features/src/docker-out/docker-init.sh b/features/src/docker-out/docker-init.sh index d4fca5e..15b0620 100755 --- a/features/src/docker-out/docker-init.sh +++ b/features/src/docker-out/docker-init.sh @@ -1,17 +1,19 @@ #!/usr/bin/env bash set -e -# Find the GID of the socket -SOCKET_GID=$(stat -c '%g' /var/run/docker.sock) - -# Find an existing group with the same GID -# This is needed eg. for alpine which already has GID 999 (ping) -# If this breaks some things, we might need to implement a solution based on socat -EXISTING_GROUP=$(getent group $SOCKET_GID | cut -d: -f1) -if [ -n "$EXISTING_GROUP" ]; then - # Delete this group - sudo groupdel $EXISTING_GROUP -fi +# Wrapper function to only use sudo if not already root +sudoIf() { + if [ "$(id -u)" -ne 0 ]; then + sudo "$@" + else + "$@" + fi +} + +# Source socket (socket on the host) +SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}" +# Target socket (socket in the container) +TARGET_SOCKET="${TARGET_SOCKET:-"/var/run/docker.sock"}" # Determine the correct user USERNAME="${USERNAME:-"${_REMOTE_USER:-"auto"}"}" @@ -19,9 +21,62 @@ if [ "${USERNAME}" = "auto" ]; then USERNAME=$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd) fi -# Create a matching docker group in the container and add the current user to it -sudo groupadd -g $SOCKET_GID docker -sudo usermod -a -G docker $USERNAME +# Check if the docker group exists +if ! getent group docker > /dev/null 2>&1; then + # Create the docker group + echo "Adding missing docker group" + sudoIf groupadd --system docker +fi + +# Add the user to the docker group +sudoIf usermod -a -G docker $USERNAME + +# By default, make the source and target sockets the same +if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then + sudoIf touch "${SOURCE_SOCKET}" + sudoIf ln -s "${SOURCE_SOCKET}" "${TARGET_SOCKET}" +fi + +# Get the id of the docker group +DOCKER_GID=$(getent group docker | cut -d: -f3) + +# Find the GID of the source socket +SOCKET_GID=$(stat -c '%g' ${SOURCE_SOCKET}) + +# If the group ids don't match, we need to adjust +if [ "$DOCKER_GID" = "$SOCKET_GID" ]; then + echo "Docker group GID matches socket GID ($DOCKER_GID), no changes needed." +else + # Find an existing group with the same GID as the source socket + EXISTING_GROUP=$(getent group $SOCKET_GID | cut -d: -f1) + # If no group is found, just adjust the docker group to match the socket GID + if [ -z "$EXISTING_GROUP" ]; then + echo "Adjusting docker group GID ($DOCKER_GID) to match socket GID ($SOCKET_GID)." + sudoIf groupmod -g $SOCKET_GID docker + else + # Use socat + echo "Using socat to bridge socket from GID $SOCKET_GID to docker GID $DOCKER_GID." + sudoIf rm -rf ${TARGET_SOCKET} + # Check if socat is installed + if command -v socat > /dev/null 2>&1; then + echo "socat is already installed." + else + echo "socat is not installed. Installing socat." + if command -v apt-get > /dev/null 2>&1; then + # Apt-based + sudoIf apt-get update && sudoIf apt-get install -y socat + elif command -v apk > /dev/null 2>&1; then + # Apk-based + sudoIf apk add socat + else + echo "Error: socat is required but could not be installed. Please install socat manually." + exit 1 + fi + fi + # Create the socat bridge + sudoIf socat UNIX-CONNECT:${SOURCE_SOCKET} UNIX-LISTEN:${TARGET_SOCKET},fork,user=${USERNAME},group=docker,mode=660 + fi +fi # Execute whatever commands were passed in (if any). This allows us # to set this script to ENTRYPOINT while still executing the default CMD. From 3c31c5733df3bf86595f3ace5c506f7347aeef39 Mon Sep 17 00:00:00 2001 From: Roemer Date: Wed, 12 Nov 2025 08:58:18 +0000 Subject: [PATCH 2/3] fix: Generate docker init script --- .../{docker-init.sh => docker-init.sh.tmpl} | 6 ++++-- features/src/docker-out/installer.go | 20 +++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) rename features/src/docker-out/{docker-init.sh => docker-init.sh.tmpl} (95%) diff --git a/features/src/docker-out/docker-init.sh b/features/src/docker-out/docker-init.sh.tmpl similarity index 95% rename from features/src/docker-out/docker-init.sh rename to features/src/docker-out/docker-init.sh.tmpl index 15b0620..b42e33b 100755 --- a/features/src/docker-out/docker-init.sh +++ b/features/src/docker-out/docker-init.sh.tmpl @@ -16,11 +16,13 @@ SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}" TARGET_SOCKET="${TARGET_SOCKET:-"/var/run/docker.sock"}" # Determine the correct user -USERNAME="${USERNAME:-"${_REMOTE_USER:-"auto"}"}" -if [ "${USERNAME}" = "auto" ]; then +USERNAME="{{ .User }}" +if [ "${USERNAME}" = "" ]; then USERNAME=$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd) fi +echo "Initializing Docker socket permissions for user ${USERNAME}." + # Check if the docker group exists if ! getent group docker > /dev/null 2>&1; then # Create the docker group diff --git a/features/src/docker-out/installer.go b/features/src/docker-out/installer.go index 66faafc..948d5a1 100644 --- a/features/src/docker-out/installer.go +++ b/features/src/docker-out/installer.go @@ -2,6 +2,7 @@ package main import ( "builder/installer" + "bytes" "flag" "fmt" "os" @@ -9,6 +10,7 @@ import ( "path/filepath" "regexp" "strconv" + "text/template" "github.com/roemer/gotaskr/execr" "github.com/roemer/gover" @@ -138,8 +140,22 @@ func (c *dockerCliComponent) InstallVersion(version *gover.Version) error { return err } - // Copy the startup file - if err := execr.Run(true, "cp", "-prf", "docker-init.sh", "/usr/local/share/docker-init.sh"); err != nil { + // Generate the startup script + t1, err := template.New("docker-init.sh.tmpl").ParseFiles("./docker-init.sh.tmpl") + if err != nil { + return err + } + data := struct { + User string + }{ + User: os.Getenv("_REMOTE_USER"), + } + var buf bytes.Buffer + if err := t1.Execute(&buf, data); err != nil { + return err + } + content := buf.String() + if err := os.WriteFile("/usr/local/share/docker-init.sh", []byte(content), os.ModePerm); err != nil { return err } // Copy the default config.json From 98cac5989a7531256966f989aa3baab46e7f2aa1 Mon Sep 17 00:00:00 2001 From: Roemer Date: Wed, 12 Nov 2025 10:55:12 +0000 Subject: [PATCH 3/3] chore: Update chrome version for the tests --- features/src/browsers/NOTES.md | 4 ++++ features/src/browsers/README.md | 4 ++++ features/test/browsers/chrome-testing.sh | 2 +- features/test/browsers/chrome.sh | 2 +- features/test/browsers/scenarios.json | 4 ++-- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/features/src/browsers/NOTES.md b/features/src/browsers/NOTES.md index a71cef3..13dc188 100644 --- a/features/src/browsers/NOTES.md +++ b/features/src/browsers/NOTES.md @@ -12,3 +12,7 @@ Needs access to the following URL for downloading and resolving: * https://googlechromelabs.github.io * https://download-installer.cdn.mozilla.net * https://product-details.mozilla.org + +### Old Chrome Versions + +It seems Google deletes old packages from time to time. So if you use a fixed version, make sure to keep it updated. diff --git a/features/src/browsers/README.md b/features/src/browsers/README.md index bfbe8bc..a4b623c 100755 --- a/features/src/browsers/README.md +++ b/features/src/browsers/README.md @@ -48,3 +48,7 @@ Needs access to the following URL for downloading and resolving: * https://googlechromelabs.github.io * https://download-installer.cdn.mozilla.net * https://product-details.mozilla.org + +### Old Chrome Versions + +It seems Google deletes old packages from time to time. So if you use a fixed version, make sure to keep it updated. diff --git a/features/test/browsers/chrome-testing.sh b/features/test/browsers/chrome-testing.sh index 0e0ce7e..88c2ee6 100644 --- a/features/test/browsers/chrome-testing.sh +++ b/features/test/browsers/chrome-testing.sh @@ -4,7 +4,7 @@ set -e [[ -f "$(dirname "$0")/../functions.sh" ]] && source "$(dirname "$0")/../functions.sh" [[ -f "$(dirname "$0")/functions.sh" ]] && source "$(dirname "$0")/functions.sh" -check_version "$(chrome --version)" "Google Chrome for Testing 130.0.6723.69" +check_version "$(chrome --version)" "Google Chrome for Testing 142.0.7444.162" check_command_not_exists "google-chrome" check_command_not_exists "firefox" diff --git a/features/test/browsers/chrome.sh b/features/test/browsers/chrome.sh index b077dbe..c1cb313 100644 --- a/features/test/browsers/chrome.sh +++ b/features/test/browsers/chrome.sh @@ -4,7 +4,7 @@ set -e [[ -f "$(dirname "$0")/../functions.sh" ]] && source "$(dirname "$0")/../functions.sh" [[ -f "$(dirname "$0")/functions.sh" ]] && source "$(dirname "$0")/functions.sh" -check_version "$(google-chrome --version)" "Google Chrome 130.0.6723.69" +check_version "$(google-chrome --version)" "Google Chrome 142.0.7444.162" check_command_not_exists "chrome" check_command_not_exists "firefox" diff --git a/features/test/browsers/scenarios.json b/features/test/browsers/scenarios.json index 1a6121f..071c452 100644 --- a/features/test/browsers/scenarios.json +++ b/features/test/browsers/scenarios.json @@ -8,7 +8,7 @@ }, "features": { "./browsers": { - "chromeVersion": "130.0.6723.69", + "chromeVersion": "142.0.7444.162", "useChromeForTesting": "false", "firefoxVersion": "none" } @@ -23,7 +23,7 @@ }, "features": { "./browsers": { - "chromeVersion": "130.0.6723.69", + "chromeVersion": "142.0.7444.162", "useChromeForTesting": "true", "firefoxVersion": "none" }