Unverified Commit f02df17a authored by Gaurav Saini's avatar Gaurav Saini Committed by GitHub

[docker-outside-of-docker] - Fix externally-managed-environment python error...

[docker-outside-of-docker] - Fix externally-managed-environment python 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: 's avatarSamruddhi Khandale <samruddhikhandale@github.com>

* 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: 's avatarSamruddhi Khandale <samruddhikhandale@github.com>
parent 1a6b7152
{ {
"id": "docker-outside-of-docker", "id": "docker-outside-of-docker",
"version": "1.5.0", "version": "1.6.0",
"name": "Docker (docker-outside-of-docker)", "name": "Docker (docker-outside-of-docker)",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/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.", "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.",
...@@ -39,6 +39,11 @@ ...@@ -39,6 +39,11 @@
"type": "boolean", "type": "boolean",
"default": true, "default": true,
"description": "Install Docker Buildx" "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", "entrypoint": "/usr/local/share/docker-init.sh",
......
...@@ -17,6 +17,7 @@ SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}" ...@@ -17,6 +17,7 @@ SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}"
TARGET_SOCKET="${TARGET_SOCKET:-"/var/run/docker.sock"}" TARGET_SOCKET="${TARGET_SOCKET:-"/var/run/docker.sock"}"
USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}"
INSTALL_DOCKER_BUILDX="${INSTALLDOCKERBUILDX:-"true"}" INSTALL_DOCKER_BUILDX="${INSTALLDOCKERBUILDX:-"true"}"
INSTALL_DOCKER_COMPOSE_SWITCH="${INSTALLDOCKERCOMPOSESWITCH:-"true"}"
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal jammy noble" DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal jammy noble"
...@@ -27,6 +28,11 @@ set -e ...@@ -27,6 +28,11 @@ set -e
# Clean up # Clean up
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
# Setup STDERR.
err() {
echo "(!) $*" >&2
}
if [ "$(id -u)" -ne 0 ]; then 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.' echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
exit 1 exit 1
...@@ -177,7 +183,7 @@ install_compose_switch_fallback() { ...@@ -177,7 +183,7 @@ install_compose_switch_fallback() {
echo -e "\n(!) Failed to fetch the latest artifacts for compose-switch v${compose_switch_version}..." 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 get_previous_version "${compose_switch_url}" "${repo_url}" compose_switch_version
echo -e "\nAttempting to install v${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 # Ensure apt is in non-interactive to avoid prompts
...@@ -273,6 +279,19 @@ if [ "${USE_MOBY}" = "true" ]; then ...@@ -273,6 +279,19 @@ if [ "${USE_MOBY}" = "true" ]; then
fi fi
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 # Install Docker / Moby CLI if not already installed
if type docker > /dev/null 2>&1; then if type docker > /dev/null 2>&1; then
echo "Docker / Moby CLI already installed." echo "Docker / Moby CLI already installed."
...@@ -302,44 +321,82 @@ fi ...@@ -302,44 +321,82 @@ fi
# If 'docker-compose' command is to be included # If 'docker-compose' command is to be included
if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then 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 # Install Docker Compose if not already installed and is on a supported architecture
if type docker-compose > /dev/null 2>&1; then if type docker-compose > /dev/null 2>&1; then
echo "Docker Compose already installed." echo "Docker Compose already installed."
elif [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then elif [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then
TARGET_COMPOSE_ARCH="$(uname -m)" 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."
if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then INSTALL_DOCKER_COMPOSE_SWITCH="false"
TARGET_COMPOSE_ARCH="x86_64"
fi if [ "${target_compose_arch}" = "x86_64" ]; then
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 # Use pip to get a version that runs on this architecture
check_packages python3-minimal python3-pip libffi-dev python3-venv check_packages python3-minimal python3-pip libffi-dev python3-venv
export PIPX_HOME=/usr/local/pipx echo "(*) Installing docker compose v1 via pip..."
mkdir -p ${PIPX_HOME} export PYTHONUSERBASE=/usr/local
export PIPX_BIN_DIR=/usr/local/bin pip3 install --disable-pip-version-check --no-cache-dir --user "Cython<3.0" pyyaml wheel docker-compose --no-build-isolation
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
fi fi
else 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_version="latest"
compose_switch_url="https://github.com/docker/compose-switch" compose_switch_url="https://github.com/docker/compose-switch"
find_version_from_git_tags compose_switch_version "${compose_switch_url}" 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}" 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/docker-compose chmod +x /usr/local/bin/compose-switch
# TODO: Verify checksum once available: https://github.com/docker/compose-switch/issues/11 # 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
fi fi
......
...@@ -112,20 +112,14 @@ get_previous_version() { ...@@ -112,20 +112,14 @@ get_previous_version() {
local variable_name=$3 local variable_name=$3
local mode=$4 local mode=$4
prev_version=${!variable_name} prev_version=${!variable_name}
output=$(curl -s "$repo_url"); output=$(curl -s "$repo_url");
check_packages jq check_packages jq
message=$(echo "$output" | jq -r '.message') 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 "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}"
echo -e "\nAttempting to find latest version using GitHub tags." echo -e "\nAttempting to find latest version using GitHub tags."
find_prev_version_from_git_tags prev_version "$url" "tags/v" find_prev_version_from_git_tags prev_version "$url" "tags/v"
......
#!/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
\ No newline at end of file
#!/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
\ No newline at end of file
#!/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
\ No newline at end of file
...@@ -142,5 +142,35 @@ ...@@ -142,5 +142,35 @@
"mobyBuildxVersion": "0.12.0" "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"
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment