diff options
author | Felipe Santos <felipecassiors@gmail.com> | 2023-04-05 21:21:36 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-05 21:21:36 +0300 |
commit | 7f605b9452ac43316a0b81d78118c5dbe00ee26e (patch) | |
tree | a8eb37fb9914186c70b28d0f0d3cba8f77a307fe | |
parent | f0dd470ba898bb62eb0fa425aa81e86072454167 (diff) |
Fix several issues with docker-outside-of-docker (#443)feature_docker-outside-of-docker_1.2.0
* Fix several issues with docker-outside-of-docker
* Add initial tests and bump version
* Add two tests
* Fix docker buildx conflict
* Fix possible test issue
* Add tests for moby
* Add buildx test to init
* Fix inconsistency
* Many fixes and improvements
* Make dockeDashCompose v2 by default
16 files changed, 178 insertions, 90 deletions
diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index 79bc9fe..841bb62 100644 --- a/src/docker-outside-of-docker/devcontainer-feature.json +++ b/src/docker-outside-of-docker/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "docker-outside-of-docker", - "version": "1.1.0", + "version": "1.2.0", "name": "Docker (docker-outside-of-docker)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker", "description": "Re-use the host docker socket, adding the Docker CLI to a container. Feature invokes a script to enable using a forwarded Docker socket within a container to run Docker commands.", @@ -26,7 +26,7 @@ "v1", "v2" ], - "default": "v1", + "default": "v2", "description": "Compose version to use for docker-compose (v1 or v2)" }, "installDockerBuildx": { @@ -36,9 +36,6 @@ } }, "entrypoint": "/usr/local/share/docker-init.sh", - "containerEnv": { - "DOCKER_BUILDKIT": "1" - }, "customizations": { "vscode": { "extensions": [ diff --git a/src/docker-outside-of-docker/install.sh b/src/docker-outside-of-docker/install.sh index 6352410..9d8433a 100755 --- a/src/docker-outside-of-docker/install.sh +++ b/src/docker-outside-of-docker/install.sh @@ -9,7 +9,7 @@ DOCKER_VERSION="${VERSION:-"latest"}" USE_MOBY="${MOBY:-"true"}" -DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2 +DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v2"}" # v1 or v2 ENABLE_NONROOT_DOCKER="${ENABLE_NONROOT_DOCKER:-"true"}" SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}" @@ -87,7 +87,7 @@ find_version_from_git_tags() { local repository=$2 local prefix=${3:-"tags/v"} local separator=${4:-"."} - local last_part_optional=${5:-"false"} + local last_part_optional=${5:-"false"} if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then local escaped_separator=${separator//./\\.} local last_part @@ -172,7 +172,7 @@ apt-get update if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then # Empty, meaning grab whatever "latest" is in apt repo cli_version_suffix="" -else +else # Fetch a valid version from the apt-cache (eg: the Microsoft repo appends +azure, breakfix, etc...) docker_version_dot_escaped="${DOCKER_VERSION//./\\.}" docker_version_dot_plus_escaped="${docker_version_dot_escaped//+/\\+}" @@ -194,17 +194,32 @@ if type docker > /dev/null 2>&1; then echo "Docker / Moby CLI already installed." else if [ "${USE_MOBY}" = "true" ]; then - apt-get -y install --no-install-recommends moby-cli${cli_version_suffix} moby-buildx + buildx=() + if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then + buildx=(moby-buildx) + fi + apt-get -y install --no-install-recommends ${cli_package_name}${cli_version_suffix} "${buildx[@]}" apt-get -y install --no-install-recommends moby-compose || echo "(*) Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." else - apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} + buildx=() + if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then + buildx=(docker-buildx-plugin) + fi + apt-get -y install --no-install-recommends ${cli_package_name}${cli_version_suffix} "${buildx[@]}" docker-compose-plugin + buildx_path="/usr/libexec/docker/cli-plugins/docker-buildx" + # Older versions of Docker CE installs buildx as part of the CLI package + if [ "${INSTALL_DOCKER_BUILDX}" = "false" ] && [ -f "${buildx_path}" ]; then + echo "(*) Removing docker-buildx installed from docker-ce-cli since installDockerBuildx is disabled..." + rm -f "${buildx_path}" + fi fi + unset buildx buildx_path fi # Install Docker Compose if not already installed and is on a supported architecture if type docker-compose > /dev/null 2>&1; then echo "Docker Compose already installed." -else +elif [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then TARGET_COMPOSE_ARCH="$(uname -m)" if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then TARGET_COMPOSE_ARCH="x86_64" @@ -224,60 +239,36 @@ else fi ${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' docker-compose rm -rf /tmp/pip-tmp - else + else compose_v1_version="1" find_version_from_git_tags compose_v1_version "https://github.com/docker/compose" "tags/" echo "(*) Installing docker-compose ${compose_v1_version}..." curl -fsSL "https://github.com/docker/compose/releases/download/${compose_v1_version}/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose fi -fi - -# Install docker-compose switch if not already installed - https://github.com/docker/compose-switch#manual-installation -current_v1_compose_path="$(which docker-compose)" -target_v1_compose_path="$(dirname "${current_v1_compose_path}")/docker-compose-v1" -if ! type compose-switch > /dev/null 2>&1; then - echo "(*) Installing compose-switch..." +else + echo "(*) Installing compose-switch as docker-compose..." compose_switch_version="latest" find_version_from_git_tags compose_switch_version "https://github.com/docker/compose-switch" - curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch - chmod +x /usr/local/bin/compose-switch + curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/docker-compose + chmod +x /usr/local/bin/docker-compose # TODO: Verify checksum once available: https://github.com/docker/compose-switch/issues/11 - - # Setup v1 CLI as alternative in addition to compose-switch (which maps to v2) - mv "${current_v1_compose_path}" "${target_v1_compose_path}" - update-alternatives --install /usr/local/bin/docker-compose docker-compose /usr/local/bin/compose-switch 99 - update-alternatives --install /usr/local/bin/docker-compose docker-compose "${target_v1_compose_path}" 1 -fi -if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then - update-alternatives --set docker-compose "${target_v1_compose_path}" -else - update-alternatives --set docker-compose /usr/local/bin/compose-switch fi # Setup a docker group in the event the docker socket's group is not root if ! grep -qE '^docker:' /etc/group; then + echo "(*) Creating missing docker group..." groupadd --system docker fi -usermod -aG docker "${USERNAME}" - -if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then - buildx_version="latest" - find_version_from_git_tags buildx_version "https://github.com/docker/buildx" "refs/tags/v" - echo "(*) Installing buildx ${buildx_version}..." - buildx_file_name="buildx-v${buildx_version}.linux-${architecture}" - cd /tmp && wget "https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name}" - - mkdir -p ${_REMOTE_USER_HOME}/.docker/cli-plugins - mv ${buildx_file_name} ${_REMOTE_USER_HOME}/.docker/cli-plugins/docker-buildx - chmod +x ${_REMOTE_USER_HOME}/.docker/cli-plugins/docker-buildx - - chown -R "${USERNAME}:docker" "${_REMOTE_USER_HOME}/.docker" - chmod -R g+r+w "${_REMOTE_USER_HOME}/.docker" - find "${_REMOTE_USER_HOME}/.docker" -type d -print0 | xargs -n 1 -0 chmod g+s +# Ensure docker group gid is 999 +if [ "$(getent group docker | cut -d: -f3)" != "999" ]; then + echo "(*) Updating docker group gid to 999..." + groupmod -g 999 docker fi +usermod -aG docker "${USERNAME}" + # If init file already exists, exit if [ -f "/usr/local/share/docker-init.sh" ]; then # Clean up @@ -304,10 +295,10 @@ fi DOCKER_GID="$(grep -oP '^docker:x:\K[^:]+' /etc/group)" # If enabling non-root access and specified user is found, setup socat and add script -chown -h "${USERNAME}":root "${TARGET_SOCKET}" +chown -h "${USERNAME}":root "${TARGET_SOCKET}" check_packages socat tee /usr/local/share/docker-init.sh > /dev/null \ -<< EOF +<< EOF #!/usr/bin/env bash #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -339,8 +330,8 @@ log() echo -e "\n** \$(date) **" | sudoIf tee -a \${SOCAT_LOG} > /dev/null log "Ensuring ${USERNAME} has access to ${SOURCE_SOCKET} via ${TARGET_SOCKET}" -# If enabled, try to update the docker group with the right GID. If the group is root, -# fall back on using socat to forward the docker socket to another unix socket so +# If enabled, try to update the docker group with the right GID. If the group is root, +# fall back on using socat to forward the docker socket to another unix socket so # that we can set permissions on it without affecting the host. if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ] && [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "0" ]; then SOCKET_GID=\$(stat -c '%g' ${SOURCE_SOCKET}) @@ -360,7 +351,7 @@ if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_ log "Success" fi -# Execute whatever commands were passed in (if any). This allows us +# Execute whatever commands were passed in (if any). This allows us # to set this script to ENTRYPOINT while still executing the default CMD. set +e exec "\$@" diff --git a/test/docker-outside-of-docker/docker_build_moby.sh b/test/docker-outside-of-docker/docker_build_moby.sh new file mode 120000 index 0000000..0b420db --- /dev/null +++ b/test/docker-outside-of-docker/docker_build_moby.sh @@ -0,0 +1 @@ +./docker_build.sh
\ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_build_2.sh b/test/docker-outside-of-docker/docker_build_no_buildx.sh index 742b222..7b3870d 100644 --- a/test/docker-outside-of-docker/docker_build_2.sh +++ b/test/docker-outside-of-docker/docker_build_no_buildx.sh @@ -6,7 +6,7 @@ set -e source dev-container-features-test-lib # Definition specific tests -check "docker-buildx" docker buildx version +check "no buildx" bash -c "docker buildx version 2>&1 | grep 'not a docker command'" check "docker-build" docker build ./ # Report result diff --git a/test/docker-outside-of-docker/docker_build_no_buildx_moby.sh b/test/docker-outside-of-docker/docker_build_no_buildx_moby.sh new file mode 120000 index 0000000..00b72a3 --- /dev/null +++ b/test/docker-outside-of-docker/docker_build_no_buildx_moby.sh @@ -0,0 +1 @@ +./docker_build_no_buildx.sh
\ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_build_older.sh b/test/docker-outside-of-docker/docker_build_older.sh deleted file mode 100644 index 742b222..0000000 --- a/test/docker-outside-of-docker/docker_build_older.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -set -e - -# Optional: Import test library -source dev-container-features-test-lib - -# Definition specific tests -check "docker-buildx" docker buildx version -check "docker-build" docker build ./ - -# Report result -reportResults diff --git a/test/docker-outside-of-docker/docker_dash_compose_v1.sh b/test/docker-outside-of-docker/docker_dash_compose_v1.sh new file mode 100755 index 0000000..d95f3cf --- /dev/null +++ b/test/docker-outside-of-docker/docker_dash_compose_v1.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker compose" bash -c "docker compose version | grep -E '2.[0-9]+.[0-9]+'" +check "docker-compose" bash -c "docker-compose --version | grep -E '1.[0-9]+.[0-9]+'" + +# Report result +reportResults diff --git a/test/docker-outside-of-docker/docker_dash_compose_v1_moby.sh b/test/docker-outside-of-docker/docker_dash_compose_v1_moby.sh new file mode 120000 index 0000000..51dc7d2 --- /dev/null +++ b/test/docker-outside-of-docker/docker_dash_compose_v1_moby.sh @@ -0,0 +1 @@ +./docker_dash_compose_v1.sh
\ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_dash_compose_v2.sh b/test/docker-outside-of-docker/docker_dash_compose_v2.sh new file mode 100755 index 0000000..8f2a104 --- /dev/null +++ b/test/docker-outside-of-docker/docker_dash_compose_v2.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker compose" bash -c "docker compose version | grep -E '2.[0-9]+.[0-9]+'" +check "docker-compose" bash -c "docker-compose --version | grep -E '2.[0-9]+.[0-9]+'" + +# Report result +reportResults diff --git a/test/docker-outside-of-docker/docker_dash_compose_v2_moby.sh b/test/docker-outside-of-docker/docker_dash_compose_v2_moby.sh new file mode 120000 index 0000000..78ae9bc --- /dev/null +++ b/test/docker-outside-of-docker/docker_dash_compose_v2_moby.sh @@ -0,0 +1 @@ +./docker_dash_compose_v2.sh
\ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_init.sh b/test/docker-outside-of-docker/docker_init.sh index 2164921..b47285e 100644 --- a/test/docker-outside-of-docker/docker_init.sh +++ b/test/docker-outside-of-docker/docker_init.sh @@ -5,11 +5,15 @@ set -e # Optional: Import test library source dev-container-features-test-lib +check "docker buildx" bash -c "docker buildx version" +check "docker compose" bash -c "docker compose version" +check "docker-compose" bash -c "docker-compose --version" + check "docker-init-exists" bash -c "ls /usr/local/share/docker-init.sh" check "log-exists" bash -c "ls /tmp/vscr-docker-from-docker.log" check "log-contents-for-success" bash -c "cat /tmp/vscr-docker-from-docker.log | grep 'Success'" check "log-contents" bash -c "cat /tmp/vscr-docker-from-docker.log | grep 'Proxying /var/run/docker-host.sock to /var/run/docker.sock for vscode'" -check "docker-ps" bash -c "docker ps" +check "docker-ps" bash -c "docker ps >/dev/null" # Report result reportResults
\ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_init_debian.sh b/test/docker-outside-of-docker/docker_init_debian.sh new file mode 120000 index 0000000..7458cc9 --- /dev/null +++ b/test/docker-outside-of-docker/docker_init_debian.sh @@ -0,0 +1 @@ +./docker_init.sh
\ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_init_moby.sh b/test/docker-outside-of-docker/docker_init_moby.sh new file mode 120000 index 0000000..7458cc9 --- /dev/null +++ b/test/docker-outside-of-docker/docker_init_moby.sh @@ -0,0 +1 @@ +./docker_init.sh
\ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_init_ubuntu_22.sh b/test/docker-outside-of-docker/docker_init_ubuntu_22.sh new file mode 120000 index 0000000..7458cc9 --- /dev/null +++ b/test/docker-outside-of-docker/docker_init_ubuntu_22.sh @@ -0,0 +1 @@ +./docker_init.sh
\ No newline at end of file diff --git a/test/docker-outside-of-docker/scenarios.json b/test/docker-outside-of-docker/scenarios.json index ad9b072..be63470 100644 --- a/test/docker-outside-of-docker/scenarios.json +++ b/test/docker-outside-of-docker/scenarios.json @@ -1,44 +1,119 @@ { + "docker_init_moby": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": true + } + }, + "containerUser": "vscode" + }, "docker_init": { - "image": "mcr.microsoft.com/devcontainers/base", - "remoteUser": "vscode", + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": false + } + }, + "containerUser": "vscode" + }, + "docker_init_ubuntu_22": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-22.04", "features": { "docker-outside-of-docker": { - "version": "latest" + "moby": false } - } + }, + "containerUser": "vscode" + }, + "docker_init_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "docker-outside-of-docker": { + "moby": false + } + }, + "containerUser": "vscode" }, "docker_build": { - "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", "features": { "docker-outside-of-docker": { - "version": "latest", - "installDockerBuildx": true, - "moby": "false", + "moby": false, "dockerDashComposeVersion": "v2" } }, - "remoteUser": "node" + "containerUser": "vscode" }, - "docker_build_2": { - "image": "ubuntu:focal", + "docker_build_moby": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", "features": { "docker-outside-of-docker": { - "version": "latest", - "moby": "false", - "dockerDashComposeVersion": "v2" + "moby": true } - } + }, + "containerUser": "vscode" }, - "docker_build_older": { - "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "docker_build_no_buildx": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", "features": { "docker-outside-of-docker": { "version": "20", - "moby": "false", + "moby": false, + "installDockerBuildx": false + } + }, + "containerUser": "vscode" + }, + "docker_build_no_buildx_moby": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "version": "20", + "moby": true, + "installDockerBuildx": false + } + }, + "containerUser": "vscode" + }, + "docker_dash_compose_v1": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": false, + "dockerDashComposeVersion": "v1" + } + }, + "containerUser": "vscode" + }, + "docker_dash_compose_v1_moby": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": true, + "dockerDashComposeVersion": "v1" + } + }, + "containerUser": "vscode" + }, + "docker_dash_compose_v2": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": false, + "dockerDashComposeVersion": "v2" + } + }, + "containerUser": "vscode" + }, + "docker_dash_compose_v2_moby": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": true, "dockerDashComposeVersion": "v2" } }, - "remoteUser": "node" + "containerUser": "vscode" } } diff --git a/test/docker-outside-of-docker/test.sh b/test/docker-outside-of-docker/test.sh index 517737a..fe9098e 100755..100644 --- a/test/docker-outside-of-docker/test.sh +++ b/test/docker-outside-of-docker/test.sh @@ -5,10 +5,11 @@ set -e # Optional: Import test library source dev-container-features-test-lib -# Definition specific tests -check "version" docker --version -check "docker-init-exists" bash -c "ls /usr/local/share/docker-init.sh" -check "docker-ps" bash -c "docker ps" +check "docker buildx" bash -c "docker buildx version" +check "docker compose" bash -c "docker compose version" +check "docker-compose" bash -c "docker-compose --version" + +check "docker-ps" bash -c "docker ps >/dev/null" # Report result reportResults
\ No newline at end of file |