Skip to content

Commit

Permalink
[docker-outside-of-docker] - Fix externally-managed-environment pytho…
Browse files Browse the repository at this point in the history
…n error for "bookworm" - solution to issue #1120 (#1121)

* [docker-outside-of-docker] - solution to issue #1120

* minor changes

* err fn addition

* changes as required

* Update src/docker-outside-of-docker/devcontainer-feature.json

Co-authored-by: Samruddhi Khandale <[email protected]>

* remove debugging code

* missed this change

* reverting changes

* keeping docker_compose_install to be false for v1 installs

* changes as requested

* changes as required

---------

Co-authored-by: Samruddhi Khandale <[email protected]>
  • Loading branch information
gauravsaini04 and samruddhikhandale authored Sep 24, 2024
1 parent 1a6b715 commit f02df17
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 36 deletions.
7 changes: 6 additions & 1 deletion src/docker-outside-of-docker/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "docker-outside-of-docker",
"version": "1.5.0",
"version": "1.6.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.",
Expand Down Expand Up @@ -39,6 +39,11 @@
"type": "boolean",
"default": true,
"description": "Install Docker Buildx"
},
"installDockerComposeSwitch": {
"type": "boolean",
"default": true,
"description": "Install Compose Switch (provided docker compose is available) which is a replacement to the Compose V1 docker-compose (python) executable. It translates the command line into Compose V2 docker compose then runs the latter."
}
},
"entrypoint": "/usr/local/share/docker-init.sh",
Expand Down
111 changes: 84 additions & 27 deletions src/docker-outside-of-docker/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}"
TARGET_SOCKET="${TARGET_SOCKET:-"/var/run/docker.sock"}"
USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}"
INSTALL_DOCKER_BUILDX="${INSTALLDOCKERBUILDX:-"true"}"
INSTALL_DOCKER_COMPOSE_SWITCH="${INSTALLDOCKERCOMPOSESWITCH:-"true"}"

MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal jammy noble"
Expand All @@ -27,6 +28,11 @@ set -e
# Clean up
rm -rf /var/lib/apt/lists/*

# Setup STDERR.
err() {
echo "(!) $*" >&2
}

if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1
Expand Down Expand Up @@ -177,7 +183,7 @@ install_compose_switch_fallback() {
echo -e "\n(!) Failed to fetch the latest artifacts for compose-switch v${compose_switch_version}..."
get_previous_version "${compose_switch_url}" "${repo_url}" compose_switch_version
echo -e "\nAttempting to install v${compose_switch_version}"
curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/docker-compose
curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch
}

# Ensure apt is in non-interactive to avoid prompts
Expand Down Expand Up @@ -273,6 +279,19 @@ if [ "${USE_MOBY}" = "true" ]; then
fi
fi


docker_home="/usr/libexec/docker"
cli_plugins_dir="${docker_home}/cli-plugins"

install_compose_fallback(){
local url=$1
local repo_url=$(get_github_api_repo_url "$url")
echo -e "\n(!) Failed to fetch the latest artifacts for docker-compose v${compose_version}..."
get_previous_version "${url}" "${repo_url}" compose_version
echo -e "\nAttempting to install v${compose_version}"
curl -fsSL "https://github.com/docker/compose/releases/download/v${compose_version}/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path}
}

# Install Docker / Moby CLI if not already installed
if type docker > /dev/null 2>&1; then
echo "Docker / Moby CLI already installed."
Expand Down Expand Up @@ -302,44 +321,82 @@ fi

# If 'docker-compose' command is to be included
if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then
case "${architecture}" in
amd64) target_compose_arch=x86_64 ;;
arm64) target_compose_arch=aarch64 ;;
*)
echo "(!) Docker outside of docker does not support machine architecture '$architecture'. Please use an x86-64 or ARM64 machine."
exit 1
esac
docker_compose_path="/usr/local/bin/docker-compose"
# 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."
elif [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then
TARGET_COMPOSE_ARCH="$(uname -m)"
if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then
TARGET_COMPOSE_ARCH="x86_64"
fi
if [ "${TARGET_COMPOSE_ARCH}" != "x86_64" ]; then
err "The final Compose V1 release, version 1.29.2, was May 10, 2021. These packages haven't received any security updates since then. Use at your own risk."
INSTALL_DOCKER_COMPOSE_SWITCH="false"

if [ "${target_compose_arch}" = "x86_64" ]; then
echo "(*) Installing docker compose v1..."
curl -fsSL "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64" -o ${docker_compose_path}
chmod +x ${docker_compose_path}

# Download the SHA256 checksum
DOCKER_COMPOSE_SHA256="$(curl -sSL "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64.sha256" | awk '{print $1}')"
echo "${DOCKER_COMPOSE_SHA256} ${docker_compose_path}" > docker-compose.sha256sum
sha256sum -c docker-compose.sha256sum --ignore-missing
elif [ "${VERSION_CODENAME}" = "bookworm" ]; then
err "Docker compose v1 is unavailable for 'bookworm' on Arm64. Kindly switch to use v2"
exit 1
else
# Use pip to get a version that runs on this architecture
check_packages python3-minimal python3-pip libffi-dev python3-venv
export PIPX_HOME=/usr/local/pipx
mkdir -p ${PIPX_HOME}
export PIPX_BIN_DIR=/usr/local/bin
export PYTHONUSERBASE=/tmp/pip-tmp
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
pipx_bin=pipx
if ! type pipx > /dev/null 2>&1; then
pip3 install --disable-pip-version-check --no-cache-dir --user pipx
pipx_bin=/tmp/pip-tmp/bin/pipx
fi
${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' docker-compose
rm -rf /tmp/pip-tmp
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
echo "(*) Installing docker compose v1 via pip..."
export PYTHONUSERBASE=/usr/local
pip3 install --disable-pip-version-check --no-cache-dir --user "Cython<3.0" pyyaml wheel docker-compose --no-build-isolation
fi
else
echo "(*) Installing compose-switch as docker-compose..."
compose_version=${DOCKER_DASH_COMPOSE_VERSION#v}
docker_compose_url="https://github.com/docker/compose"
find_version_from_git_tags compose_version "$docker_compose_url" "tags/v"
echo "(*) Installing docker-compose ${compose_version}..."
curl -fsSL "https://github.com/docker/compose/releases/download/v${compose_version}/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || {
if [[ $DOCKER_DASH_COMPOSE_VERSION == "latest" ]]; then
install_compose_fallback "$docker_compose_url" "$compose_version" "$target_compose_arch" "$docker_compose_path"
else
echo -e "Error: Failed to install docker-compose v${compose_version}"
fi
}
chmod +x ${docker_compose_path}

# Download the SHA256 checksum
DOCKER_COMPOSE_SHA256="$(curl -sSL "https://github.com/docker/compose/releases/download/v${compose_version}/docker-compose-linux-${target_compose_arch}.sha256" | awk '{print $1}')"
echo "${DOCKER_COMPOSE_SHA256} ${docker_compose_path}" > docker-compose.sha256sum
sha256sum -c docker-compose.sha256sum --ignore-missing

mkdir -p ${cli_plugins_dir}
cp ${docker_compose_path} ${cli_plugins_dir}
fi
fi

# Install docker-compose switch if not already installed - https://github.com/docker/compose-switch#manual-installation
if [ "${INSTALL_DOCKER_COMPOSE_SWITCH}" = "true" ] && ! type compose-switch > /dev/null 2>&1; then
if type docker-compose > /dev/null 2>&1; then
echo "(*) Installing compose-switch..."
current_compose_path="$(which docker-compose)"
target_compose_path="$(dirname "${current_compose_path}")/docker-compose-v1"
compose_switch_version="latest"
compose_switch_url="https://github.com/docker/compose-switch"
find_version_from_git_tags compose_switch_version "${compose_switch_url}"
curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/docker-compose || install_compose_switch_fallback "${compose_switch_url}"
chmod +x /usr/local/bin/docker-compose
curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch || install_compose_switch_fallback "${compose_switch_url}"
chmod +x /usr/local/bin/compose-switch
# 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_compose_path}" "${target_compose_path}"
update-alternatives --install ${docker_compose_path} docker-compose /usr/local/bin/compose-switch 99
update-alternatives --install ${docker_compose_path} docker-compose "${target_compose_path}" 1
else
err "Skipping installation of compose-switch as docker compose is unavailable..."
fi
fi

Expand Down
10 changes: 2 additions & 8 deletions test/docker-outside-of-docker/docker_build_compose_fallback.sh
Original file line number Diff line number Diff line change
Expand Up @@ -112,20 +112,14 @@ get_previous_version() {
local variable_name=$3
local mode=$4
prev_version=${!variable_name}

output=$(curl -s "$repo_url");

check_packages jq

message=$(echo "$output" | jq -r '.message')

if [[ $mode == 'mode1' ]]; then
message="API rate limit exceeded"
else
message=""
fi

if [[ $message == "API rate limit exceeded"* ]]; then
if [[ $message == "API rate limit exceeded"* ]] || [[ $mode == 'mode1' ]]; then
echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}"
echo -e "\nAttempting to find latest version using GitHub tags."
find_prev_version_from_git_tags prev_version "$url" "tags/v"
Expand Down
29 changes: 29 additions & 0 deletions test/docker-outside-of-docker/docker_install_compose_switch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

set -e

# Optional: Import test library
source dev-container-features-test-lib

# Check if compose-switch is installed
check_compose_switch_installation() {
COMPOSE_SWITCH_BINARY="/usr/local/bin/compose-switch"
# Check if the binary exists
if [ ! -x "$COMPOSE_SWITCH_BINARY" ]; then
echo "compose-switch binary not found at $COMPOSE_SWITCH_BINARY"
exit 1
else
compose_switch_version=$("$COMPOSE_SWITCH_BINARY" --version | awk '{print $4}')
if [ -z "$compose_switch_version" ]; then
echo "Unable to determine compose-switch version"
else
echo "compose-switch version: $compose_switch_version"
echo -e "\n✅ compose-switch is installed"
fi
fi
}

check "Check whether compose-switch is installed" check_compose_switch_installation

reportResults

29 changes: 29 additions & 0 deletions test/docker-outside-of-docker/docker_not_install_compose_switch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

set -e

# Optional: Import test library
source dev-container-features-test-lib

# Check if compose-switch is installed
check_compose_switch_installation() {
COMPOSE_SWITCH_BINARY="/usr/local/bin/compose-switch"
# Check if the binary exists
if [ ! -x "$COMPOSE_SWITCH_BINARY" ]; then
echo "compose-switch binary not found at $COMPOSE_SWITCH_BINARY"
echo -e "\n❎ compose-switch is not installed"
else
compose_switch_version=$("$COMPOSE_SWITCH_BINARY" --version | awk '{print $4}')
if [ -z "$compose_switch_version" ]; then
echo "Unable to determine compose-switch version"
else
echo "compose-switch version: $compose_switch_version"
fi
exit 1
fi
}

check "Check whether compose-switch is installed" check_compose_switch_installation

reportResults

22 changes: 22 additions & 0 deletions test/docker-outside-of-docker/docker_python_bookworm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

set -e

# Optional: Import test library
source dev-container-features-test-lib

# Definition specific tests
check "docker-buildx" bash -c "docker buildx version"
check "docker-buildx-path" bash -c "ls -la /usr/libexec/docker/cli-plugins/docker-buildx"

check "docker-buildx" docker buildx version
check "docker-build" docker build ./

check "installs docker-compose v2 install" bash -c "type docker-compose"
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]+'"

check "installs compose-switch as docker-compose" bash -c "[[ -f /usr/local/bin/docker-compose ]]"

# Report result
reportResults
30 changes: 30 additions & 0 deletions test/docker-outside-of-docker/scenarios.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,5 +142,35 @@
"mobyBuildxVersion": "0.12.0"
}
}
},
"docker_python_bookworm": {
"image": "mcr.microsoft.com/devcontainers/base:bookworm",
"features": {
"docker-outside-of-docker": {
"moby": true,
"installDockerBuildx": true,
"dockerDashComposeVersion": "v2"
}
}
},
"docker_not_install_compose_switch": {
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04",
"features": {
"docker-outside-of-docker": {
"dockerDashComposeVersion": "latest",
"installDockerComposeSwitch": false
}
},
"containerUser": "vscode"
},
"docker_install_compose_switch": {
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04",
"features": {
"docker-outside-of-docker": {
"dockerDashComposeVersion": "latest",
"installDockerComposeSwitch": true
}
},
"containerUser": "vscode"
}
}

0 comments on commit f02df17

Please sign in to comment.