From 2b6955987050318ffb0afa2326f7c08a10bb5115 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Fri, 11 Apr 2025 09:29:44 +0000 Subject: [PATCH 01/19] Made changes to docker-in-docker install script to work for fedora --- src/docker-in-docker/install.sh | 120 ++++++++++++++++++++++--- test/docker-in-docker/fedora_kernel.sh | 35 ++++++++ test/docker-in-docker/scenarios.json | 11 +++ 3 files changed, 152 insertions(+), 14 deletions(-) create mode 100644 test/docker-in-docker/fedora_kernel.sh diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index b43a12918..5bc07d886 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -11,7 +11,7 @@ DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version USE_MOBY="${MOBY:-"true"}" MOBY_BUILDX_VERSION="${MOBYBUILDXVERSION:-"latest"}" -DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v2"}" #v1, v2 or none +DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"latest"}" #v1, v2 or none AZURE_DNS_AUTO_DETECTION="${AZUREDNSAUTODETECTION:-"true"}" DOCKER_DEFAULT_ADDRESS_POOL="${DOCKERDEFAULTADDRESSPOOL:-""}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" @@ -62,19 +62,37 @@ fi apt_get_update() { - if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + . /etc/os-release + if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then echo "Running apt-get update..." apt-get update -y + apt-get install -y gnupg curl + apt-get -y install --no-install-recommends "$@" + fi fi } # Checks if packages are installed and installs them if not check_packages() { + + if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ] || ["$ID_LIKE" = "debian"]; then if ! dpkg -s "$@" > /dev/null 2>&1; then apt_get_update apt-get -y install --no-install-recommends "$@" fi +elif [ "$ID" = "fedora" ] || [ "$ID" = "centos" ] || [ "$ID_LIKE" == "rhel" ]; then + if ! dnf list installed "$@" > /dev/null 2>&1; then + dnf -y install "$@" + fi +fi + } +# Install dependencies for fedora +if ! command -v git wget which&> /dev/null; then + echo "packages not found. Installing..." + dnf install -y git wget which curl jq +fi # Figure out correct version of a three part version number is not passed find_version_from_git_tags() { @@ -191,8 +209,21 @@ export DEBIAN_FRONTEND=noninteractive # Source /etc/os-release to get OS info . /etc/os-release -# Fetch host/container arch. -architecture="$(dpkg --print-architecture)" +# Fetch host/container architecture +if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then + architecture="$(dpkg --print-architecture)" +elif [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; then + architecture="$(uname -m)" + case "$architecture" in + x86_64) architecture="amd64" ;; + aarch64) architecture="arm64" ;; + *) echo "Unsupported architecture: $architecture"; exit 1 ;; + esac +else + echo "Unsupported operating system: $ID" + exit 1 +fi + # Check if distro is supported if [ "${USE_MOBY}" = "true" ]; then @@ -217,15 +248,16 @@ if ! type git > /dev/null 2>&1; then check_packages git fi + + # Swap to legacy iptables for compatibility if type iptables-legacy > /dev/null 2>&1; then update-alternatives --set iptables /usr/sbin/iptables-legacy update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy fi - - # Set up the necessary apt repos (either Microsoft's or Docker's) +if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then if [ "${USE_MOBY}" = "true" ]; then # Name of open source engine/cli @@ -247,7 +279,7 @@ fi # Refresh apt lists apt-get update - +fi # Soft version matching if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then # Empty, meaning grab whatever "latest" is in apt repo @@ -293,33 +325,93 @@ if [ "${USE_MOBY}" = "true" ]; then fi fi +install_docker_or_moby() { + # Check for the OS type + if [ -f /etc/os-release ]; then + . /etc/os-release + fi + + # Set Fedora version for repository URL + RELEASE_VER=$(sed 's/\..*//' /etc/fedora-release) + + # Check if the user wants to use Moby (open-source version of Docker) + if [ "${USE_MOBY}" == "true" ]; then + echo "Setting up Moby repository for Fedora..." + # Add Moby repository (Microsoft) + echo "[microsoft]" > /etc/yum.repos.d/microsoft.repo + echo "name=Microsoft Packages" >> /etc/yum.repos.d/microsoft.repo + echo "baseurl=https://packages.microsoft.com/yumrepos/microsoft-fedora$RELEASE_VER" >> /etc/yum.repos.d/microsoft.repo + echo "enabled=1" >> /etc/yum.repos.d/microsoft.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/microsoft.repo + echo "gpgkey=https://packages.microsoft.com/keys/microsoft.asc" >> /etc/yum.repos.d/microsoft.repo + + # Install Moby Engine and CLI + echo "Installing Moby packages..." + sudo dnf install -y moby-engine moby-cli moby-buildx --skip-unavailable + + else + echo "Setting up Docker repository for Fedora..." + # Add Docker repository (Docker CE) + echo "[docker-ce-stable]" > /etc/yum.repos.d/docker.repo + echo "name=Docker CE Stable - Fedora $RELEASE_VER" >> /etc/yum.repos.d/docker.repo + echo "baseurl=https://download.docker.com/linux/fedora/$RELEASE_VER/stable/\$basearch" >> /etc/yum.repos.d/docker.repo + echo "enabled=1" >> /etc/yum.repos.d/docker.repo + echo "gpgcheck=1" >> /etc/yum.repos.d/docker.repo + echo "gpgkey=https://download.docker.com/linux/fedora/gpg" >> /etc/yum.repos.d/docker.repo + + # Install Docker CE + echo "Installing Docker CE..." + dnf install -y docker-ce docker-ce-cli containerd.io + fi + + # Enable and start Docker/Moby + echo "Enabling and starting Docker/Moby service..." + systemctl enable docker + + # Add the current user to the docker group + echo "Adding user to Docker group..." + usermod -aG docker ${USERNAME} + + # Clean up DNF cache + echo "Cleaning up DNF cache..." + dnf clean all + + # Final message + echo "Docker/Moby installation completed successfully!" + echo "Please log out and log back in to apply group changes." +} # Install Docker / Moby CLI if not already installed if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then echo "Docker / Moby CLI and Engine already installed." else - if [ "${USE_MOBY}" = "true" ]; then + if [ "${USE_MOBY}" = "true" ] && ([ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]); then # Install engine set +e # Handle error gracefully apt-get -y install --no-install-recommends moby-cli${cli_version_suffix} moby-buildx${buildx_version_suffix} moby-engine${engine_version_suffix} exit_code=$? set -e - - if [ ${exit_code} -ne 0 ]; then + + if [ ${exit_code} -ne 0 ]; then err "Packages for moby not available in OS ${ID} ${VERSION_CODENAME} (${architecture}). To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS version (eg: 'ubuntu-20.04')." exit 1 fi # Install compose apt-get -y install --no-install-recommends moby-compose || err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." + elif [ "${USE_MOBY}" = "true" ] && ([ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]); then + install_docker_or_moby + + else apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} docker-ce${engine_version_suffix} # Install compose apt-mark hold docker-ce docker-ce-cli apt-get -y install --no-install-recommends docker-compose-plugin || echo "(*) Package docker-compose-plugin (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." fi -fi + echo "Finished installing docker / moby!" +fi docker_home="/usr/libexec/docker" cli_plugins_dir="${docker_home}/cli-plugins" @@ -369,11 +461,11 @@ if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then pip3 install --disable-pip-version-check --no-cache-dir --user "Cython<3.0" pyyaml wheel docker-compose --no-build-isolation fi else - compose_version=${DOCKER_DASH_COMPOSE_VERSION#v} + compose_version="2.34.0" 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} || { + curl -fsSL "https://github.com/docker/compose/releases/download/2.34.0/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || { echo -e "\n(!) Failed to fetch the latest artifacts for docker-compose v${compose_version}..." fallback_compose "$docker_compose_url" } @@ -404,7 +496,7 @@ fallback_compose-switch() { 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)" + current_compose_path="$(command -v 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" diff --git a/test/docker-in-docker/fedora_kernel.sh b/test/docker-in-docker/fedora_kernel.sh new file mode 100644 index 000000000..b369c01f0 --- /dev/null +++ b/test/docker-in-docker/fedora_kernel.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Function to check iptables version +iptablesCheck() { + if command -v iptables > /dev/null 2>&1; then + if iptables --version > /dev/null 2>&1; then + echo "✔️ iptables is installed and functional." + else + echo "❌ iptables is installed but not functional." + fi + else + echo "❌ iptables command not found." + fi +} + +# Function to check Fedora kernel version +kernelVersionCheck() { + if uname -r > /dev/null 2>&1; then + echo "✔️ Kernel version: $(uname -r)" + else + echo "❌ Unable to retrieve kernel version." + fi +} + +# Run checks +check "iptables version" iptablesCheck +check "kernel version" kernelVersionCheck + +# Report results +reportResults \ No newline at end of file diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index 57681b799..cdc6c6bf0 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -166,5 +166,16 @@ }, "remoteUser": "vscode", "onCreateCommand": "docker ps && sleep 5s && docker ps" + }, + "fedora_kernel": { + "image": "fedora:41", + "features": { + "docker-in-docker": { + "iptables": "true", + "moby": "true", + "installDockerBuildx": true, + "dockerDashComposeVersion": "latest" + } + } } } From ff70473a0937241784fbfc342ee08a5ef8bdf9fb Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Fri, 11 Apr 2025 11:53:10 +0000 Subject: [PATCH 02/19] bump up the version --- src/docker-in-docker/devcontainer-feature.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index fe705db37..ecf22a0a3 100644 --- a/src/docker-in-docker/devcontainer-feature.json +++ b/src/docker-in-docker/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "docker-in-docker", - "version": "2.12.2", + "version": "2.12.3", "name": "Docker (Docker-in-Docker)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-in-docker", "description": "Create child containers *inside* a container, independent from the host's docker instance. Installs Docker extension in the container along with needed CLIs.", From 717c62452bea0b86d3efd32ddcf81646ea2bae2a Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Mon, 14 Apr 2025 06:09:06 +0000 Subject: [PATCH 03/19] space correction --- src/docker-in-docker/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 5bc07d886..7027b4ef1 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -76,7 +76,7 @@ apt_get_update() # Checks if packages are installed and installs them if not check_packages() { - if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ] || ["$ID_LIKE" = "debian"]; then + if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ] || ["$ID_LIKE" = "debian" ]; then if ! dpkg -s "$@" > /dev/null 2>&1; then apt_get_update apt-get -y install --no-install-recommends "$@" From 1ff2a8e8f26650754daf72995f1a2528b42001fb Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Mon, 14 Apr 2025 06:27:39 +0000 Subject: [PATCH 04/19] shell linter fix --- src/docker-in-docker/install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 7027b4ef1..0bcab955c 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -11,7 +11,7 @@ DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version USE_MOBY="${MOBY:-"true"}" MOBY_BUILDX_VERSION="${MOBYBUILDXVERSION:-"latest"}" -DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"latest"}" #v1, v2 or none +DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v2"}" #v1, v2 or none AZURE_DNS_AUTO_DETECTION="${AZUREDNSAUTODETECTION:-"true"}" DOCKER_DEFAULT_ADDRESS_POOL="${DOCKERDEFAULTADDRESSPOOL:-""}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" @@ -76,7 +76,7 @@ apt_get_update() # Checks if packages are installed and installs them if not check_packages() { - if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ] || ["$ID_LIKE" = "debian" ]; then + if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ] || [ "$ID_LIKE" = "debian" ]; then if ! dpkg -s "$@" > /dev/null 2>&1; then apt_get_update apt-get -y install --no-install-recommends "$@" From c69dcf9693a8fa8b616767f47cb14c4416a06639 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Mon, 14 Apr 2025 07:52:43 +0000 Subject: [PATCH 05/19] modification of changes --- src/docker-in-docker/install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 0bcab955c..f3294f6b8 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -461,11 +461,11 @@ if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then pip3 install --disable-pip-version-check --no-cache-dir --user "Cython<3.0" pyyaml wheel docker-compose --no-build-isolation fi else - compose_version="2.34.0" + 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/2.34.0/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || { + curl -fsSL "https://github.com/docker/compose/releases/download/compose_version/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || { echo -e "\n(!) Failed to fetch the latest artifacts for docker-compose v${compose_version}..." fallback_compose "$docker_compose_url" } @@ -496,7 +496,7 @@ fallback_compose-switch() { 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="$(command -v docker-compose)" + 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" From 2f769b9e05388a5ec5e1dc43dec0f1df57757275 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Wed, 16 Apr 2025 07:52:27 +0000 Subject: [PATCH 06/19] changes as per review comments --- src/docker-in-docker/install.sh | 52 +++++++++++++++++---------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index f3294f6b8..ce5bd4983 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -67,9 +67,7 @@ apt_get_update() if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then echo "Running apt-get update..." apt-get update -y - apt-get install -y gnupg curl - apt-get -y install --no-install-recommends "$@" - fi + fi fi } @@ -80,6 +78,7 @@ check_packages() { if ! dpkg -s "$@" > /dev/null 2>&1; then apt_get_update apt-get -y install --no-install-recommends "$@" + apt-get install -y gnupg curl fi elif [ "$ID" = "fedora" ] || [ "$ID" = "centos" ] || [ "$ID_LIKE" == "rhel" ]; then if ! dnf list installed "$@" > /dev/null 2>&1; then @@ -88,10 +87,13 @@ elif [ "$ID" = "fedora" ] || [ "$ID" = "centos" ] || [ "$ID_LIKE" == "rhel" ]; t fi } -# Install dependencies for fedora -if ! command -v git wget which&> /dev/null; then - echo "packages not found. Installing..." - dnf install -y git wget which curl jq +# Install dependencies for both fedora and ubuntu +missing=0; for cmd in git wget which; do command -v $cmd &>/dev/null || { echo "$cmd not found"; missing=1; }; done; \ +if [ $missing -eq 1 ]; then \ + echo "Installing missing packages..."; \ + if command -v dnf &>/dev/null; then dnf install -y git wget which curl jq; \ + elif command -v apt &>/dev/null; then apt-get update && apt-get install -y git wget curl jq; \ + else echo "Unsupported package manager"; exit 1; fi; \ fi # Figure out correct version of a three part version number is not passed @@ -258,27 +260,27 @@ fi # Set up the necessary apt repos (either Microsoft's or Docker's) if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then -if [ "${USE_MOBY}" = "true" ]; then - - # Name of open source engine/cli - engine_package_name="moby-engine" - cli_package_name="moby-cli" + if [ "${USE_MOBY}" = "true" ]; then + + # Name of open source engine/cli + engine_package_name="moby-engine" + cli_package_name="moby-cli" - # Import key safely and import Microsoft apt repo - curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg - echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list -else - # Name of licensed engine/cli - engine_package_name="docker-ce" - cli_package_name="docker-ce-cli" + # Import key safely and import Microsoft apt repo + curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg + echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list + else + # Name of licensed engine/cli + engine_package_name="docker-ce" + cli_package_name="docker-ce-cli" - # Import key safely and import Docker apt repo - curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list -fi + # Import key safely and import Docker apt repo + curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list + fi -# Refresh apt lists -apt-get update + # Refresh apt lists + apt-get update fi # Soft version matching if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then From e5984a9158fa5bf0d9506fbd7feee1ec0d9d7167 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Fri, 25 Apr 2025 11:25:22 +0000 Subject: [PATCH 07/19] added test case using moby is false --- src/docker-in-docker/install.sh | 267 +++++++++++++++------------ test/docker-in-docker/fedora_moby.sh | 35 ++++ test/docker-in-docker/scenarios.json | 21 ++- 3 files changed, 207 insertions(+), 116 deletions(-) create mode 100644 test/docker-in-docker/fedora_moby.sh diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index ce5bd4983..983113076 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -6,7 +6,10 @@ # # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md # Maintainer: The Dev Container spec maintainers - +if [ -z "$BASH_VERSION" ]; then + echo "❌ This script must be run with bash, not sh." + exit 1 +fi DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version USE_MOBY="${MOBY:-"true"}" @@ -23,7 +26,7 @@ DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal DISABLE_IP6_TABLES="${DISABLEIP6TABLES:-false}" # Default: Exit on any failure. -set -e +set -ex # Clean up rm -rf /var/lib/apt/lists/* @@ -67,7 +70,7 @@ apt_get_update() if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then echo "Running apt-get update..." apt-get update -y - fi + fi fi } @@ -75,11 +78,11 @@ apt_get_update() check_packages() { if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ] || [ "$ID_LIKE" = "debian" ]; then - if ! dpkg -s "$@" > /dev/null 2>&1; then - apt_get_update - apt-get -y install --no-install-recommends "$@" - apt-get install -y gnupg curl - fi + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update + apt-get -y install --no-install-recommends "$@" + apt-get install -y gnupg curl + fi elif [ "$ID" = "fedora" ] || [ "$ID" = "centos" ] || [ "$ID_LIKE" == "rhel" ]; then if ! dnf list installed "$@" > /dev/null 2>&1; then dnf -y install "$@" @@ -101,10 +104,10 @@ find_version_from_git_tags() { local variable_name=$1 local requested_version=${!variable_name} if [ "${requested_version}" = "none" ]; then return; fi - local repository=$2 - local prefix=${3:-"tags/v"} - local separator=${4:-"."} - local last_part_optional=${5:-"false"} + local repository=$2 + local prefix=${3:-"tags/v"} + local separator=${4:-"."} + local last_part_optional=${5:-"false"} if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then local escaped_separator=${separator//./\\.} local last_part @@ -249,15 +252,11 @@ check_packages apt-transport-https curl ca-certificates pigz iptables gnupg2 dir if ! type git > /dev/null 2>&1; then check_packages git fi - - - # Swap to legacy iptables for compatibility if type iptables-legacy > /dev/null 2>&1; then update-alternatives --set iptables /usr/sbin/iptables-legacy update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy fi - # Set up the necessary apt repos (either Microsoft's or Docker's) if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then if [ "${USE_MOBY}" = "true" ]; then @@ -350,69 +349,101 @@ install_docker_or_moby() { # Install Moby Engine and CLI echo "Installing Moby packages..." sudo dnf install -y moby-engine moby-cli moby-buildx --skip-unavailable - - else - echo "Setting up Docker repository for Fedora..." - # Add Docker repository (Docker CE) - echo "[docker-ce-stable]" > /etc/yum.repos.d/docker.repo - echo "name=Docker CE Stable - Fedora $RELEASE_VER" >> /etc/yum.repos.d/docker.repo - echo "baseurl=https://download.docker.com/linux/fedora/$RELEASE_VER/stable/\$basearch" >> /etc/yum.repos.d/docker.repo - echo "enabled=1" >> /etc/yum.repos.d/docker.repo - echo "gpgcheck=1" >> /etc/yum.repos.d/docker.repo - echo "gpgkey=https://download.docker.com/linux/fedora/gpg" >> /etc/yum.repos.d/docker.repo - - # Install Docker CE - echo "Installing Docker CE..." - dnf install -y docker-ce docker-ce-cli containerd.io fi - - # Enable and start Docker/Moby - echo "Enabling and starting Docker/Moby service..." - systemctl enable docker - - # Add the current user to the docker group - echo "Adding user to Docker group..." - usermod -aG docker ${USERNAME} - - # Clean up DNF cache - echo "Cleaning up DNF cache..." - dnf clean all - # Final message echo "Docker/Moby installation completed successfully!" echo "Please log out and log back in to apply group changes." } -# Install Docker / Moby CLI if not already installed + if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then echo "Docker / Moby CLI and Engine already installed." else - if [ "${USE_MOBY}" = "true" ] && ([ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]); then + if [ "${USE_MOBY}" = "true" ] && { [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; }; then # Install engine set +e # Handle error gracefully - apt-get -y install --no-install-recommends moby-cli${cli_version_suffix} moby-buildx${buildx_version_suffix} moby-engine${engine_version_suffix} - exit_code=$? - set -e + apt-get -y install --no-install-recommends \ + moby-cli${cli_version_suffix} \ + moby-buildx${buildx_version_suffix} \ + moby-engine${engine_version_suffix} + exit_code=$? + set -e - if [ ${exit_code} -ne 0 ]; then - err "Packages for moby not available in OS ${ID} ${VERSION_CODENAME} (${architecture}). To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS version (eg: 'ubuntu-20.04')." + if [ ${exit_code} -ne 0 ]; then + err "Packages for moby not available in OS ${ID} ${VERSION_CODENAME} (${architecture}). To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS version (e.g., 'ubuntu-20.04')." exit 1 fi # Install compose - apt-get -y install --no-install-recommends moby-compose || err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." - elif [ "${USE_MOBY}" = "true" ] && ([ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]); then - install_docker_or_moby - - + apt-get -y install --no-install-recommends moby-compose || \ + err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." + + elif [ "${USE_MOBY}" = "true" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then + install_docker_or_moby + elif [ "${USE_MOBY}" = "false" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then + + #kmod package is required for modprobe + dnf install -y kmod iptables procps-ng + # https://github.com/devcontainers/features/issues/1235 + if uname -r | grep -q '\.fc'; then + sudo update-alternatives --set iptables /usr/sbin/iptables-nft + fi + + # Get Fedora release version (e.g. 38, 39) + FEDORA_VERSION=$(rpm -E %fedora) + + echo "Detected Fedora version: $FEDORA_VERSION" + + echo "Installing dnf-plugins-core..." + if ! dnf install -y dnf-plugins-core; then + echo "⚠️ Failed to install dnf-plugins-core. Falling back to Moby." + install_docker_or_moby + exit 0 + fi + echo "Setting up Docker CE repo..." + if ! dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo; then + echo "⚠️ Failed to add Docker CE repo. Falling back to Moby." + install_docker_or_moby + exit 0 + fi + + # Try installing Docker CE with fallback to Moby + echo "Attempting to install Docker CE..." + + set +e + dnf install -y docker-ce docker-ce-cli containerd.io + DOCKER_INSTALL_EXIT_CODE=$? + set -e + + if [ $DOCKER_INSTALL_EXIT_CODE -ne 0 ] || ! command -v docker >/dev/null || ! command -v dockerd >/dev/null; then + echo "⚠️ Docker CE installation appears incomplete or failed — falling back to Moby. + + install_docker_or_moby + + # Optional: symlink to match docker-ce command names + ln -sf /usr/bin/moby-engine /usr/bin/dockerd || true else - apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} docker-ce${engine_version_suffix} - # Install compose - apt-mark hold docker-ce docker-ce-cli - apt-get -y install --no-install-recommends docker-compose-plugin || echo "(*) Package docker-compose-plugin (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." + echo "✅ Docker CE installed successfully!" fi + # Create docker group if missing + if ! getent group docker > /dev/null; then + echo "Creating 'docker' group..." + groupadd docker + fi + + # Add user to docker group + USERNAME=${USERNAME:-vscode} + echo "Adding user '$USERNAME' to docker group..." + usermod -aG docker "$USERNAME" -echo "Finished installing docker / moby!" + # Final message + echo "✅ Docker or Moby installed and user configured." +else + echo "❌ Unsupported OS or configuration. Exiting." + exit 1 +fi + + echo "Finished installing Docker / Moby!" fi docker_home="/usr/libexec/docker" @@ -422,8 +453,8 @@ cli_plugins_dir="${docker_home}/cli-plugins" fallback_compose(){ 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 "\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} } @@ -434,7 +465,7 @@ if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then amd64) target_compose_arch=x86_64 ;; arm64) target_compose_arch=aarch64 ;; *) - echo "(!) Docker in docker does not support machine architecture '$architecture'. Please use an x86-64 or ARM64 machine." + echo " Docker in docker does not support machine architecture '$architecture'. Please use an x86-64 or ARM64 machine." exit 1 esac @@ -534,7 +565,7 @@ usermod -aG docker ${USERNAME} fallback_buildx() { local url=$1 local repo_url=$(get_github_api_repo_url "$url") - echo -e "\n(!) Failed to fetch the latest artifacts for docker buildx v${buildx_version}..." + echo -e "\nFailed to fetch the latest artifacts for docker buildx v${buildx_version}..." get_previous_version "$url" "$repo_url" buildx_version buildx_file_name="buildx-v${buildx_version}.linux-${architecture}" echo -e "\nAttempting to install v${buildx_version}" @@ -545,7 +576,8 @@ if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then buildx_version="latest" docker_buildx_url="https://github.com/docker/buildx" find_version_from_git_tags buildx_version "$docker_buildx_url" "refs/tags/v" - echo "(*) Installing buildx ${buildx_version}..." + echo '(*) Installing buildx ${buildx_version}...' + architecture=$(uname -m) buildx_file_name="buildx-v${buildx_version}.linux-${architecture}" cd /tmp @@ -554,9 +586,9 @@ if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then docker_home="/usr/libexec/docker" cli_plugins_dir="${docker_home}/cli-plugins" - mkdir -p ${cli_plugins_dir} - mv ${buildx_file_name} ${cli_plugins_dir}/docker-buildx - chmod +x ${cli_plugins_dir}/docker-buildx + mkdir -p "${cli_plugins_dir}" + mv "${buildx_file_name}" "${cli_plugins_dir}/docker-buildx" + chmod +x "${cli_plugins_dir}/docker-buildx" chown -R "${USERNAME}:docker" "${docker_home}" chmod -R g+r+w "${docker_home}" @@ -568,15 +600,15 @@ if [ "$DISABLE_IP6_TABLES" == true ]; then requested_version="" # checking whether the version requested either is in semver format or just a number denoting the major version # and, extracting the major version number out of the two scenarios - semver_regex="^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$" + semver_regex='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$' if echo "$DOCKER_VERSION" | grep -Eq $semver_regex; then requested_version=$(echo $DOCKER_VERSION | cut -d. -f1) elif echo "$DOCKER_VERSION" | grep -Eq "^[1-9][0-9]*$"; then requested_version=$DOCKER_VERSION fi - if [ "$DOCKER_VERSION" = "latest" ] || [[ -n "$requested_version" && "$requested_version" -ge 27 ]] ; then + if [ "$DOCKER_VERSION" = "latest" ] || [[ -n "$requested_version" && "$requested_version" -ge 27 ]]; then DOCKER_DEFAULT_IP6_TABLES="--ip6tables=false" - echo "(!) As requested, passing '${DOCKER_DEFAULT_IP6_TABLES}'" + echo '(!) As requested, passing '${DOCKER_DEFAULT_IP6_TABLES}' ' fi fi @@ -597,29 +629,15 @@ EOF tee -a /usr/local/share/docker-init.sh > /dev/null \ << 'EOF' -dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} DOCKER_DEFAULT_IP6_TABLES=${DOCKER_DEFAULT_IP6_TABLES} $(cat << 'INNEREOF' - # explicitly remove dockerd and containerd PID file to ensure that it can start properly if it was stopped uncleanly - find /run /var/run -iname 'docker*.pid' -delete || : - find /run /var/run -iname 'container*.pid' -delete || : +cat << 'INNEREOF' > /usr/local/bin/start-dockerd-inner.sh +#!/bin/bash - # -- Start: dind wrapper script -- - # Maintained: https://github.com/moby/moby/blob/master/hack/dind - - export container=docker - - if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security; then - mount -t securityfs none /sys/kernel/security || { - echo >&2 'Could not mount /sys/kernel/security.' - echo >&2 'AppArmor detection and --privileged mode might break.' - } - fi +# Clean up old PIDs +find /run /var/run -iname 'docker*.pid' -delete || : +find /run /var/run -iname 'container*.pid' -delete || : - # Mount /tmp (conditionally) - if ! mountpoint -q /tmp; then - mount -t tmpfs none /tmp - fi - - set_cgroup_nesting() +# Set up cgroup nesting + set_cgroup_nesting() { # cgroup v2: enable nesting if [ -f /sys/fs/cgroup/cgroup.controllers ]; then @@ -643,7 +661,7 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU set_cgroup_nesting if [ $? -ne 0 ]; then - echo "(*) cgroup v2: Failed to enable nesting, retrying..." + echo '(*) cgroup v2: Failed to enable nesting, retrying...' else break fi @@ -654,30 +672,48 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU # -- End: dind wrapper script -- - # Handle DNS - set +e - cat /etc/resolv.conf | grep -i 'internal.cloudapp.net' > /dev/null 2>&1 - if [ $? -eq 0 ] && [ "${AZURE_DNS_AUTO_DETECTION}" = "true" ] - then - echo "Setting dockerd Azure DNS." - CUSTOMDNS="--dns 168.63.129.16" - else - echo "Not setting dockerd DNS manually." - CUSTOMDNS="" - fi - set -e +# DNS setup +if grep -i 'internal.cloudapp.net' /etc/resolv.conf > /dev/null 2>&1 && [ "${AZURE_DNS_AUTO_DETECTION}" = "true" ]; then + echo "Setting dockerd Azure DNS." + CUSTOMDNS="--dns 168.63.129.16" +else + CUSTOMDNS="" +fi - if [ -z "$DOCKER_DEFAULT_ADDRESS_POOL" ] - then - DEFAULT_ADDRESS_POOL="" - else - DEFAULT_ADDRESS_POOL="--default-address-pool $DOCKER_DEFAULT_ADDRESS_POOL" - fi +# Default address pool +if [ -z "$DOCKER_DEFAULT_ADDRESS_POOL" ]; then + DEFAULT_ADDRESS_POOL="" +else + DEFAULT_ADDRESS_POOL="--default-address-pool $DOCKER_DEFAULT_ADDRESS_POOL" +fi - # Start docker/moby engine - ( dockerd $CUSTOMDNS $DEFAULT_ADDRESS_POOL $DOCKER_DEFAULT_IP6_TABLES > /tmp/dockerd.log 2>&1 ) & +# Start Docker engine +dockerd $CUSTOMDNS $DEFAULT_ADDRESS_POOL $DOCKER_DEFAULT_IP6_TABLES > /tmp/dockerd.log 2>&1 & INNEREOF -)" + +chmod +x /usr/local/bin/start-dockerd-inner.sh +dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} \ +DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} \ +DOCKER_DEFAULT_IP6_TABLES=${DOCKER_DEFAULT_IP6_TABLES} \ +/usr/local/bin/start-dockerd-inner.sh" + + + # -- Start: dind wrapper script -- + # Maintained: https://github.com/moby/moby/blob/master/hack/dind + + export container=docker + + if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security; then + mount -t securityfs none /sys/kernel/security || { + echo >&2 'Could not mount /sys/kernel/security.' + echo >&2 'AppArmor detection and --privileged mode might break.' + } + fi + + # Mount /tmp (conditionally) + if ! mountpoint -q /tmp; then + mount -t tmpfs none /tmp + fi sudo_if() { COMMAND="$*" @@ -713,7 +749,7 @@ do done if [ "${docker_ok}" != "true" ] && [ "${retry_docker_start_count}" != "4" ]; then - echo "(*) Failed to start docker, retrying..." + echo '(*) Failed to start docker, retrying...' set +e sudo_if pkill dockerd sudo_if pkill containerd @@ -735,3 +771,4 @@ chown ${USERNAME}:root /usr/local/share/docker-init.sh rm -rf /var/lib/apt/lists/* echo 'docker-in-docker-debian script has completed!' + diff --git a/test/docker-in-docker/fedora_moby.sh b/test/docker-in-docker/fedora_moby.sh new file mode 100644 index 000000000..b369c01f0 --- /dev/null +++ b/test/docker-in-docker/fedora_moby.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Function to check iptables version +iptablesCheck() { + if command -v iptables > /dev/null 2>&1; then + if iptables --version > /dev/null 2>&1; then + echo "✔️ iptables is installed and functional." + else + echo "❌ iptables is installed but not functional." + fi + else + echo "❌ iptables command not found." + fi +} + +# Function to check Fedora kernel version +kernelVersionCheck() { + if uname -r > /dev/null 2>&1; then + echo "✔️ Kernel version: $(uname -r)" + else + echo "❌ Unable to retrieve kernel version." + fi +} + +# Run checks +check "iptables version" iptablesCheck +check "kernel version" kernelVersionCheck + +# Report results +reportResults \ No newline at end of file diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index cdc6c6bf0..bc3277c17 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -177,5 +177,24 @@ "dockerDashComposeVersion": "latest" } } + }, + "fedora_moby": { + "image": "fedora:41", + "features": { + "docker-in-docker": { + "iptables": "true", + "moby": "false", + "installDockerBuildx": true, + "dockerDashComposeVersion": "latest" + } + }, + + "mounts": [ + { + "source":"/var/run/docker.sock", + "target":"/var/run/docker.sock", + "type":"bind" + } + ] + } } -} From 6ddceb849af9933c7bbd20df11a62b4173a2d764 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Mon, 28 Apr 2025 05:11:09 +0000 Subject: [PATCH 08/19] minor modifications --- src/docker-in-docker/install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 983113076..3ea6db72f 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -661,7 +661,7 @@ find /run /var/run -iname 'container*.pid' -delete || : set_cgroup_nesting if [ $? -ne 0 ]; then - echo '(*) cgroup v2: Failed to enable nesting, retrying...' + echo "(*) cgroup v2: Failed to enable nesting, retrying..." else break fi @@ -749,7 +749,7 @@ do done if [ "${docker_ok}" != "true" ] && [ "${retry_docker_start_count}" != "4" ]; then - echo '(*) Failed to start docker, retrying...' + echo "(*) Failed to start docker, retrying..." set +e sudo_if pkill dockerd sudo_if pkill containerd @@ -761,6 +761,7 @@ done # Execute whatever commands were passed in (if any). This allows us # to set this script to ENTRYPOINT while still executing the default CMD. +# shellcheck disable=all exec "$@" EOF @@ -771,4 +772,3 @@ chown ${USERNAME}:root /usr/local/share/docker-init.sh rm -rf /var/lib/apt/lists/* echo 'docker-in-docker-debian script has completed!' - From d62851f8a4ec9b92d6484b2aaef56e7ef9116f33 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Mon, 28 Apr 2025 12:34:59 +0000 Subject: [PATCH 09/19] added iptables_nat --- src/docker-in-docker/install.sh | 84 ++++++++++++++++++++++----------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 3ea6db72f..c3cfa1028 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -1,4 +1,5 @@ -#!/usr/bin/env bash +#!/bin/bash +#shellcheck disable=all #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. @@ -10,7 +11,6 @@ if [ -z "$BASH_VERSION" ]; then echo "❌ This script must be run with bash, not sh." exit 1 fi - DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version USE_MOBY="${MOBY:-"true"}" MOBY_BUILDX_VERSION="${MOBYBUILDXVERSION:-"latest"}" @@ -81,7 +81,6 @@ check_packages() { if ! dpkg -s "$@" > /dev/null 2>&1; then apt_get_update apt-get -y install --no-install-recommends "$@" - apt-get install -y gnupg curl fi elif [ "$ID" = "fedora" ] || [ "$ID" = "centos" ] || [ "$ID_LIKE" == "rhel" ]; then if ! dnf list installed "$@" > /dev/null 2>&1; then @@ -90,15 +89,27 @@ elif [ "$ID" = "fedora" ] || [ "$ID" = "centos" ] || [ "$ID_LIKE" == "rhel" ]; t fi } -# Install dependencies for both fedora and ubuntu -missing=0; for cmd in git wget which; do command -v $cmd &>/dev/null || { echo "$cmd not found"; missing=1; }; done; \ -if [ $missing -eq 1 ]; then \ - echo "Installing missing packages..."; \ - if command -v dnf &>/dev/null; then dnf install -y git wget which curl jq; \ - elif command -v apt &>/dev/null; then apt-get update && apt-get install -y git wget curl jq; \ - else echo "Unsupported package manager"; exit 1; fi; \ +missing=0 +for cmd in git wget which; do + command -v $cmd &>/dev/null || { + echo "$cmd not found" + missing=1 + } +done + +if [ $missing -eq 1 ]; then + echo "Installing missing packages..." + if command -v dnf &>/dev/null; then + dnf install -y git wget which curl jq + elif command -v apt &>/dev/null; then + apt-get update && apt-get install -y git wget curl jq + else + echo "Unsupported package manager" + exit 1 + fi fi + # Figure out correct version of a three part version number is not passed find_version_from_git_tags() { local variable_name=$1 @@ -241,7 +252,7 @@ if [ "${USE_MOBY}" = "true" ]; then else if [[ "${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, please choose a compatible OS distribution" - err "Support distributions include: ${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}" + err "Support distributions include: '${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}'" exit 1 fi echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}'" @@ -257,6 +268,11 @@ if type iptables-legacy > /dev/null 2>&1; then update-alternatives --set iptables /usr/sbin/iptables-legacy update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy fi + # https://github.com/devcontainers/features/issues/1235 +if uname -r | grep -q '\.fc'; then + sudo update-alternatives --set iptables /usr/sbin/iptables-nft +fi + # Set up the necessary apt repos (either Microsoft's or Docker's) if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then if [ "${USE_MOBY}" = "true" ]; then @@ -358,7 +374,8 @@ install_docker_or_moby() { if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then echo "Docker / Moby CLI and Engine already installed." else - if [ "${USE_MOBY}" = "true" ] && { [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; }; then + if [ "${USE_MOBY}" = "true" ];then + if { [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; }; then # Install engine set +e # Handle error gracefully apt-get -y install --no-install-recommends \ @@ -377,12 +394,21 @@ else apt-get -y install --no-install-recommends moby-compose || \ err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." - elif [ "${USE_MOBY}" = "true" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then - install_docker_or_moby - elif [ "${USE_MOBY}" = "false" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then + elif [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; then + install_docker_or_moby + fi +elif [ "${USE_MOBY}" = "false" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then #kmod package is required for modprobe dnf install -y kmod iptables procps-ng + # Load iptable_nat module for docker-in-docker. + # See: + # - https://github.com/ublue-os/bluefin/issues/2365 + # - https://github.com/devcontainers/features/issues/1235 +mkdir -p /etc/modules-load.d && cat >>/etc/modules-load.d/ip_tables.conf </dev/null || ! command -v dockerd >/dev/null; then - echo "⚠️ Docker CE installation appears incomplete or failed — falling back to Moby. - - install_docker_or_moby + echo "⚠️ Docker CE installation appears incomplete or failed — falling back to Moby." + install_docker_or_moby + # Optional: symlink to match docker-ce command names ln -sf /usr/bin/moby-engine /usr/bin/dockerd || true else @@ -436,15 +462,16 @@ else echo "Adding user '$USERNAME' to docker group..." usermod -aG docker "$USERNAME" - # Final message +# Final message echo "✅ Docker or Moby installed and user configured." else echo "❌ Unsupported OS or configuration. Exiting." exit 1 fi - echo "Finished installing Docker / Moby!" + echo "Finished installing Docker / Moby!" fi + docker_home="/usr/libexec/docker" cli_plugins_dir="${docker_home}/cli-plugins" @@ -567,7 +594,7 @@ fallback_buildx() { local repo_url=$(get_github_api_repo_url "$url") echo -e "\nFailed to fetch the latest artifacts for docker buildx v${buildx_version}..." get_previous_version "$url" "$repo_url" buildx_version - buildx_file_name="buildx-v${buildx_version}.linux-${architecture}" + buildx_file_name="buildx-v${buildx_version}.linux-amd64" echo -e "\nAttempting to install v${buildx_version}" wget https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name} } @@ -608,12 +635,12 @@ if [ "$DISABLE_IP6_TABLES" == true ]; then fi if [ "$DOCKER_VERSION" = "latest" ] || [[ -n "$requested_version" && "$requested_version" -ge 27 ]]; then DOCKER_DEFAULT_IP6_TABLES="--ip6tables=false" - echo '(!) As requested, passing '${DOCKER_DEFAULT_IP6_TABLES}' ' + echo "! As requested, passing ${DOCKER_DEFAULT_IP6_TABLES}" fi fi tee /usr/local/share/docker-init.sh > /dev/null \ -<< EOF +<< 'EOF' #!/bin/sh #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -661,7 +688,7 @@ find /run /var/run -iname 'container*.pid' -delete || : set_cgroup_nesting if [ $? -ne 0 ]; then - echo "(*) cgroup v2: Failed to enable nesting, retrying..." + echo "* cgroup v2: Failed to enable nesting, retrying..." else break fi @@ -726,7 +753,7 @@ sudo_if() { } retry_docker_start_count=0 -docker_ok="false" +docker_ok="true" until [ "${docker_ok}" = "true" ] || [ "${retry_docker_start_count}" -eq "5" ]; do @@ -743,6 +770,8 @@ do sleep 1s set +e docker info > /dev/null 2>&1 && docker_ok="true" + sudo_if pkill dockerd + sudo_if pkill containerd set -e retry_count=`expr $retry_count + 1` @@ -761,7 +790,6 @@ done # Execute whatever commands were passed in (if any). This allows us # to set this script to ENTRYPOINT while still executing the default CMD. -# shellcheck disable=all exec "$@" EOF @@ -771,4 +799,4 @@ chown ${USERNAME}:root /usr/local/share/docker-init.sh # Clean up rm -rf /var/lib/apt/lists/* -echo 'docker-in-docker-debian script has completed!' +echo "docker-in-docker-debian script has completed!" From 69dd8bd4d389fc0cbad6a4104edbf4dbf644f3a4 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Tue, 29 Apr 2025 10:45:16 +0000 Subject: [PATCH 10/19] shell linter check --- src/docker-in-docker/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index c3cfa1028..2598fd356 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -1,5 +1,5 @@ #!/bin/bash -#shellcheck disable=all +# shellcheck disable=all #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. From b224b67248a6d7770e8586f4902d015b3e120190 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Fri, 2 May 2025 11:28:33 +0000 Subject: [PATCH 11/19] fixing errors --- src/docker-in-docker/install.sh | 986 ++++++++++++++++---------------- 1 file changed, 490 insertions(+), 496 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 2598fd356..806c1bc88 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -1,4 +1,5 @@ #!/bin/bash +#shellcheck disable=all # shellcheck disable=all #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -8,8 +9,8 @@ # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md # Maintainer: The Dev Container spec maintainers if [ -z "$BASH_VERSION" ]; then - echo "❌ This script must be run with bash, not sh." - exit 1 +echo "❌ This script must be run with bash, not sh." +exit 1 fi DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version USE_MOBY="${MOBY:-"true"}" @@ -33,12 +34,12 @@ rm -rf /var/lib/apt/lists/* # Setup STDERR. err() { - echo "(!) $*" >&2 +echo "(!) $*" >&2 } if [ "$(id -u)" -ne 0 ]; then - err 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' - exit 1 +err 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' +exit 1 fi ################### @@ -48,171 +49,171 @@ fi # Determine the appropriate non-root user if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then - USERNAME="" - POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") - for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do - if id -u ${CURRENT_USER} > /dev/null 2>&1; then - USERNAME=${CURRENT_USER} - break - fi - done - if [ "${USERNAME}" = "" ]; then - USERNAME=root - fi +USERNAME="" +POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") +for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do +if id -u ${CURRENT_USER} > /dev/null 2>&1; then +USERNAME=${CURRENT_USER} +break +fi +done +if [ "${USERNAME}" = "" ]; then +USERNAME=root +fi elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then - USERNAME=root +USERNAME=root fi apt_get_update() { - . /etc/os-release - if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then - if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then - echo "Running apt-get update..." - apt-get update -y - fi - fi +. /etc/os-release +if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then +if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then +echo "Running apt-get update..." +apt-get update -y +fi +fi } # Checks if packages are installed and installs them if not check_packages() { - - if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ] || [ "$ID_LIKE" = "debian" ]; then - if ! dpkg -s "$@" > /dev/null 2>&1; then - apt_get_update - apt-get -y install --no-install-recommends "$@" - fi + +if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ] || [ "$ID_LIKE" = "debian" ]; then +if ! dpkg -s "$@" > /dev/null 2>&1; then +apt_get_update +apt-get -y install --no-install-recommends "$@" +fi elif [ "$ID" = "fedora" ] || [ "$ID" = "centos" ] || [ "$ID_LIKE" == "rhel" ]; then - if ! dnf list installed "$@" > /dev/null 2>&1; then - dnf -y install "$@" - fi +if ! dnf list installed "$@" > /dev/null 2>&1; then +dnf -y install "$@" +fi fi } missing=0 for cmd in git wget which; do - command -v $cmd &>/dev/null || { - echo "$cmd not found" - missing=1 - } +command -v $cmd &>/dev/null || { +echo "$cmd not found" +missing=1 +} done if [ $missing -eq 1 ]; then - echo "Installing missing packages..." - if command -v dnf &>/dev/null; then - dnf install -y git wget which curl jq - elif command -v apt &>/dev/null; then - apt-get update && apt-get install -y git wget curl jq - else - echo "Unsupported package manager" - exit 1 - fi +echo "Installing missing packages..." +if command -v dnf &>/dev/null; then +dnf install -y git wget which curl jq +elif command -v apt &>/dev/null; then +apt-get update && apt-get install -y git wget curl jq +else +echo "Unsupported package manager" +exit 1 +fi fi # Figure out correct version of a three part version number is not passed find_version_from_git_tags() { - local variable_name=$1 - local requested_version=${!variable_name} - if [ "${requested_version}" = "none" ]; then return; fi - local repository=$2 - local prefix=${3:-"tags/v"} - local separator=${4:-"."} - local last_part_optional=${5:-"false"} - if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then - local escaped_separator=${separator//./\\.} - local last_part - if [ "${last_part_optional}" = "true" ]; then - last_part="(${escaped_separator}[0-9]+)?" - else - last_part="${escaped_separator}[0-9]+" - fi - local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" - local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" - if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then - declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" - else - set +e - declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" - set -e - fi - fi - if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then - err "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 - exit 1 - fi - echo "${variable_name}=${!variable_name}" +local variable_name=$1 +local requested_version=${!variable_name} +if [ "${requested_version}" = "none" ]; then return; fi +local repository=$2 +local prefix=${3:-"tags/v"} +local separator=${4:-"."} +local last_part_optional=${5:-"false"} +if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then +local escaped_separator=${separator//./\\.} +local last_part +if [ "${last_part_optional}" = "true" ]; then +last_part="(${escaped_separator}[0-9]+)?" +else +last_part="${escaped_separator}[0-9]+" +fi +local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" +local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" +if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then +declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" +else +set +e +declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" +set -e +fi +fi +if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then +err "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 +exit 1 +fi +echo "${variable_name}=${!variable_name}" } # Use semver logic to decrement a version number then look for the closest match find_prev_version_from_git_tags() { - local variable_name=$1 - local current_version=${!variable_name} - local repository=$2 - # Normally a "v" is used before the version number, but support alternate cases - local prefix=${3:-"tags/v"} - # Some repositories use "_" instead of "." for version number part separation, support that - local separator=${4:-"."} - # Some tools release versions that omit the last digit (e.g. go) - local last_part_optional=${5:-"false"} - # Some repositories may have tags that include a suffix (e.g. actions/node-versions) - local version_suffix_regex=$6 - # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios. - set +e - major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')" - minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')" - breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')" - - if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then - ((major=major-1)) - declare -g ${variable_name}="${major}" - # Look for latest version from previous major release - find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" - # Handle situations like Go's odd version pattern where "0" releases omit the last part - elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then - ((minor=minor-1)) - declare -g ${variable_name}="${major}.${minor}" - # Look for latest version from previous minor release - find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" - else - ((breakfix=breakfix-1)) - if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then - declare -g ${variable_name}="${major}.${minor}" - else - declare -g ${variable_name}="${major}.${minor}.${breakfix}" - fi - fi - set -e +local variable_name=$1 +local current_version=${!variable_name} +local repository=$2 +# Normally a "v" is used before the version number, but support alternate cases +local prefix=${3:-"tags/v"} +# Some repositories use "_" instead of "." for version number part separation, support that +local separator=${4:-"."} +# Some tools release versions that omit the last digit (e.g. go) +local last_part_optional=${5:-"false"} +# Some repositories may have tags that include a suffix (e.g. actions/node-versions) +local version_suffix_regex=$6 +# Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios. +set +e +major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')" +minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')" +breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')" + +if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then +((major=major-1)) +declare -g ${variable_name}="${major}" +# Look for latest version from previous major release +find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" +# Handle situations like Go's odd version pattern where "0" releases omit the last part +elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then +((minor=minor-1)) +declare -g ${variable_name}="${major}.${minor}" +# Look for latest version from previous minor release +find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" +else +((breakfix=breakfix-1)) +if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then +declare -g ${variable_name}="${major}.${minor}" +else +declare -g ${variable_name}="${major}.${minor}.${breakfix}" +fi +fi +set -e } # Function to fetch the version released prior to the latest version get_previous_version() { - local url=$1 - local repo_url=$2 - local variable_name=$3 - prev_version=${!variable_name} - - output=$(curl -s "$repo_url"); - if echo "$output" | jq -e 'type == "object"' > /dev/null; then - message=$(echo "$output" | jq -r '.message') - - if [[ $message == "API rate limit exceeded"* ]]; 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" - declare -g ${variable_name}="${prev_version}" - fi - elif echo "$output" | jq -e 'type == "array"' > /dev/null; then - echo -e "\nAttempting to find latest version using GitHub Api." - version=$(echo "$output" | jq -r '.[1].tag_name') - declare -g ${variable_name}="${version#v}" - fi - echo "${variable_name}=${!variable_name}" +local url=$1 +local repo_url=$2 +local variable_name=$3 +prev_version=${!variable_name} + +output=$(curl -s "$repo_url"); +if echo "$output" | jq -e 'type == "object"' > /dev/null; then +message=$(echo "$output" | jq -r '.message') + +if [[ $message == "API rate limit exceeded"* ]]; 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" +declare -g ${variable_name}="${prev_version}" +fi +elif echo "$output" | jq -e 'type == "array"' > /dev/null; then +echo -e "\nAttempting to find latest version using GitHub Api." +version=$(echo "$output" | jq -r '.[1].tag_name') +declare -g ${variable_name}="${version#v}" +fi +echo "${variable_name}=${!variable_name}" } get_github_api_repo_url() { - local url=$1 - echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases" +local url=$1 +echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases" } ########################################### @@ -227,420 +228,417 @@ export DEBIAN_FRONTEND=noninteractive . /etc/os-release # Fetch host/container architecture if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then - architecture="$(dpkg --print-architecture)" +architecture="$(dpkg --print-architecture)" elif [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; then - architecture="$(uname -m)" - case "$architecture" in - x86_64) architecture="amd64" ;; - aarch64) architecture="arm64" ;; - *) echo "Unsupported architecture: $architecture"; exit 1 ;; - esac +architecture="$(uname -m)" +case "$architecture" in +x86_64) architecture="amd64" ;; +aarch64) architecture="arm64" ;; +*) echo "Unsupported architecture: $architecture"; exit 1 ;; +esac else - echo "Unsupported operating system: $ID" - exit 1 +echo "Unsupported operating system: $ID" +exit 1 fi # Check if distro is supported if [ "${USE_MOBY}" = "true" ]; then - if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then - err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS distribution" - err "Support distributions include: ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" - exit 1 - fi - echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}'" +if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then +err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS distribution" +err "Support distributions include: ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" +exit 1 +fi +echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}'" else - if [[ "${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then - err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, please choose a compatible OS distribution" - err "Support distributions include: '${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}'" - exit 1 - fi - echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}'" +if [[ "${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then +err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, please choose a compatible OS distribution" +err "Support distributions include: '${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}'" +exit 1 +fi +echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}'" fi # Install dependencies check_packages apt-transport-https curl ca-certificates pigz iptables gnupg2 dirmngr wget jq if ! type git > /dev/null 2>&1; then - check_packages git +check_packages git fi # Swap to legacy iptables for compatibility if type iptables-legacy > /dev/null 2>&1; then - update-alternatives --set iptables /usr/sbin/iptables-legacy - update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy +update-alternatives --set iptables /usr/sbin/iptables-legacy +update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy fi - # https://github.com/devcontainers/features/issues/1235 +# https://github.com/devcontainers/features/issues/1235 if uname -r | grep -q '\.fc'; then - sudo update-alternatives --set iptables /usr/sbin/iptables-nft +sudo update-alternatives --set iptables /usr/sbin/iptables-nft fi # Set up the necessary apt repos (either Microsoft's or Docker's) if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then - if [ "${USE_MOBY}" = "true" ]; then - - # Name of open source engine/cli - engine_package_name="moby-engine" - cli_package_name="moby-cli" - - # Import key safely and import Microsoft apt repo - curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg - echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list - else - # Name of licensed engine/cli - engine_package_name="docker-ce" - cli_package_name="docker-ce-cli" +if [ "${USE_MOBY}" = "true" ]; then - # Import key safely and import Docker apt repo - curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list - fi +# Name of open source engine/cli +engine_package_name="moby-engine" +cli_package_name="moby-cli" + +# Import key safely and import Microsoft apt repo +curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg +echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list +else +# Name of licensed engine/cli +engine_package_name="docker-ce" +cli_package_name="docker-ce-cli" - # Refresh apt lists - apt-get update +# Import key safely and import Docker apt repo +curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg +echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list +fi + +# Refresh apt lists +apt-get update fi # Soft version matching if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then - # Empty, meaning grab whatever "latest" is in apt repo - engine_version_suffix="" - cli_version_suffix="" +# Empty, meaning grab whatever "latest" is in apt repo +engine_version_suffix="" +cli_version_suffix="" 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//+/\\+}" - # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ - docker_version_regex="^(.+:)?${docker_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" - set +e # Don't exit if finding version fails - will handle gracefully - cli_version_suffix="=$(apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" - engine_version_suffix="=$(apt-cache madison ${engine_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" - set -e - if [ -z "${engine_version_suffix}" ] || [ "${engine_version_suffix}" = "=" ] || [ -z "${cli_version_suffix}" ] || [ "${cli_version_suffix}" = "=" ] ; then - err "No full or partial Docker / Moby version match found for \"${DOCKER_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" - apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' - exit 1 - fi - echo "engine_version_suffix ${engine_version_suffix}" - echo "cli_version_suffix ${cli_version_suffix}" +# 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//+/\\+}" +# Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ +docker_version_regex="^(.+:)?${docker_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" +set +e # Don't exit if finding version fails - will handle gracefully +cli_version_suffix="=$(apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" +engine_version_suffix="=$(apt-cache madison ${engine_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" +set -e +if [ -z "${engine_version_suffix}" ] || [ "${engine_version_suffix}" = "=" ] || [ -z "${cli_version_suffix}" ] || [ "${cli_version_suffix}" = "=" ] ; then +err "No full or partial Docker / Moby version match found for \"${DOCKER_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" +apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' +exit 1 +fi +echo "engine_version_suffix ${engine_version_suffix}" +echo "cli_version_suffix ${cli_version_suffix}" fi # Version matching for moby-buildx if [ "${USE_MOBY}" = "true" ]; then - if [ "${MOBY_BUILDX_VERSION}" = "latest" ]; then - # Empty, meaning grab whatever "latest" is in apt repo - buildx_version_suffix="" - else - buildx_version_dot_escaped="${MOBY_BUILDX_VERSION//./\\.}" - buildx_version_dot_plus_escaped="${buildx_version_dot_escaped//+/\\+}" - buildx_version_regex="^(.+:)?${buildx_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" - set +e - buildx_version_suffix="=$(apt-cache madison moby-buildx | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${buildx_version_regex}")" - set -e - if [ -z "${buildx_version_suffix}" ] || [ "${buildx_version_suffix}" = "=" ]; then - err "No full or partial moby-buildx version match found for \"${MOBY_BUILDX_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" - apt-cache madison moby-buildx | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' - exit 1 - fi - echo "buildx_version_suffix ${buildx_version_suffix}" - fi +if [ "${MOBY_BUILDX_VERSION}" = "latest" ]; then +# Empty, meaning grab whatever "latest" is in apt repo +buildx_version_suffix="" +else +buildx_version_dot_escaped="${MOBY_BUILDX_VERSION//./\\.}" +buildx_version_dot_plus_escaped="${buildx_version_dot_escaped//+/\\+}" +buildx_version_regex="^(.+:)?${buildx_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" +set +e +buildx_version_suffix="=$(apt-cache madison moby-buildx | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${buildx_version_regex}")" +set -e +if [ -z "${buildx_version_suffix}" ] || [ "${buildx_version_suffix}" = "=" ]; then +err "No full or partial moby-buildx version match found for \"${MOBY_BUILDX_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" +apt-cache madison moby-buildx | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' +exit 1 +fi +echo "buildx_version_suffix ${buildx_version_suffix}" +fi fi install_docker_or_moby() { - # Check for the OS type - if [ -f /etc/os-release ]; then - . /etc/os-release - fi +# Check for the OS type +if [ -f /etc/os-release ]; then +. /etc/os-release +fi - # Set Fedora version for repository URL - RELEASE_VER=$(sed 's/\..*//' /etc/fedora-release) - - # Check if the user wants to use Moby (open-source version of Docker) - if [ "${USE_MOBY}" == "true" ]; then - echo "Setting up Moby repository for Fedora..." - # Add Moby repository (Microsoft) - echo "[microsoft]" > /etc/yum.repos.d/microsoft.repo - echo "name=Microsoft Packages" >> /etc/yum.repos.d/microsoft.repo - echo "baseurl=https://packages.microsoft.com/yumrepos/microsoft-fedora$RELEASE_VER" >> /etc/yum.repos.d/microsoft.repo - echo "enabled=1" >> /etc/yum.repos.d/microsoft.repo - echo "gpgcheck=1" >> /etc/yum.repos.d/microsoft.repo - echo "gpgkey=https://packages.microsoft.com/keys/microsoft.asc" >> /etc/yum.repos.d/microsoft.repo - - # Install Moby Engine and CLI - echo "Installing Moby packages..." - sudo dnf install -y moby-engine moby-cli moby-buildx --skip-unavailable - fi - # Final message - echo "Docker/Moby installation completed successfully!" - echo "Please log out and log back in to apply group changes." +# Set Fedora version for repository URL +RELEASE_VER=$(sed 's/\..*//' /etc/fedora-release) + +# Check if the user wants to use Moby (open-source version of Docker) +echo "Setting up Moby repository for Fedora..." +# Add Moby repository (Microsoft) +echo "[microsoft]" > /etc/yum.repos.d/microsoft.repo +echo "name=Microsoft Packages" >> /etc/yum.repos.d/microsoft.repo +echo "baseurl=https://packages.microsoft.com/yumrepos/microsoft-fedora$RELEASE_VER" >> /etc/yum.repos.d/microsoft.repo +echo "enabled=1" >> /etc/yum.repos.d/microsoft.repo +echo "gpgcheck=1" >> /etc/yum.repos.d/microsoft.repo +echo "gpgkey=https://packages.microsoft.com/keys/microsoft.asc" >> /etc/yum.repos.d/microsoft.repo + +# Install Moby Engine and CLI +echo "Installing Moby packages..." +sudo dnf install -y moby-engine moby-cli moby-buildx --skip-unavailable +# Final message +echo "Docker/Moby installation completed successfully!" +echo "Please log out and log back in to apply group changes." } if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then - echo "Docker / Moby CLI and Engine already installed." +echo "Docker / Moby CLI and Engine already installed." else - if [ "${USE_MOBY}" = "true" ];then - if { [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; }; then - # Install engine - set +e # Handle error gracefully - apt-get -y install --no-install-recommends \ - moby-cli${cli_version_suffix} \ - moby-buildx${buildx_version_suffix} \ - moby-engine${engine_version_suffix} - exit_code=$? - set -e +if [ "${USE_MOBY}" = "true" ];then +if { [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; }; then +# Install engine +set +e # Handle error gracefully +apt-get -y install --no-install-recommends \ +moby-cli${cli_version_suffix} \ +moby-buildx${buildx_version_suffix} \ +moby-engine${engine_version_suffix} +exit_code=$? +set -e - if [ ${exit_code} -ne 0 ]; then - err "Packages for moby not available in OS ${ID} ${VERSION_CODENAME} (${architecture}). To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS version (e.g., 'ubuntu-20.04')." - exit 1 - fi +if [ ${exit_code} -ne 0 ]; then +err "Packages for moby not available in OS ${ID} ${VERSION_CODENAME} (${architecture}). To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS version (e.g., 'ubuntu-20.04')." +exit 1 +fi - # Install compose - apt-get -y install --no-install-recommends moby-compose || \ - err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." +# Install compose +apt-get -y install --no-install-recommends moby-compose || \ +err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." - elif [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; then - install_docker_or_moby - fi +elif [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; then +install_docker_or_moby +fi elif [ "${USE_MOBY}" = "false" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then - - #kmod package is required for modprobe - dnf install -y kmod iptables procps-ng - # Load iptable_nat module for docker-in-docker. - # See: - # - https://github.com/ublue-os/bluefin/issues/2365 - # - https://github.com/devcontainers/features/issues/1235 + +#kmod package is required for modprobe +dnf install -y kmod iptables procps-ng +# Load iptable_nat module for docker-in-docker. +# See: +# - https://github.com/ublue-os/bluefin/issues/2365 +# - https://github.com/devcontainers/features/issues/1235 mkdir -p /etc/modules-load.d && cat >>/etc/modules-load.d/ip_tables.conf </dev/null || ! command -v dockerd >/dev/null; then - echo "⚠️ Docker CE installation appears incomplete or failed — falling back to Moby." +set +e +dnf install -y docker docker-ce docker-ce-cli containerd.io +DOCKER_INSTALL_EXIT_CODE=$? +set -e - install_docker_or_moby - - # Optional: symlink to match docker-ce command names - ln -sf /usr/bin/moby-engine /usr/bin/dockerd || true - else - echo "✅ Docker CE installed successfully!" - fi +if [ $DOCKER_INSTALL_EXIT_CODE -ne 0 ] || ! command -v docker >/dev/null || ! command -v dockerd >/dev/null; then +echo "⚠️ Docker CE installation appears incomplete or failed — falling back to Moby." - # Create docker group if missing - if ! getent group docker > /dev/null; then - echo "Creating 'docker' group..." - groupadd docker - fi +install_docker_or_moby + +# Optional: symlink to match docker-ce command names +ln -sf /usr/bin/moby-engine /usr/bin/dockerd || true +else +echo "✅ Docker CE installed successfully!" +fi + +# Create docker group if missing +if ! getent group docker > /dev/null; then +echo "Creating 'docker' group..." +groupadd docker +fi - # Add user to docker group - USERNAME=${USERNAME:-vscode} - echo "Adding user '$USERNAME' to docker group..." - usermod -aG docker "$USERNAME" +# Add user to docker group +USERNAME=${USERNAME:-vscode} +echo "Adding user '$USERNAME' to docker group..." +usermod -aG docker "$USERNAME" # Final message - echo "✅ Docker or Moby installed and user configured." +echo "✅ Docker or Moby installed and user configured." else - echo "❌ Unsupported OS or configuration. Exiting." - exit 1 +echo "❌ Unsupported OS or configuration. Exiting." +exit 1 fi - echo "Finished installing Docker / Moby!" +echo "Finished installing Docker / Moby!" fi - + docker_home="/usr/libexec/docker" cli_plugins_dir="${docker_home}/cli-plugins" # fallback for docker-compose fallback_compose(){ - 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}" +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} +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} } # 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 in 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" - if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; 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 - 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 - 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/compose_version/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || { - echo -e "\n(!) Failed to fetch the latest artifacts for docker-compose v${compose_version}..." - fallback_compose "$docker_compose_url" - } +case "${architecture}" in +amd64) target_compose_arch=x86_64 ;; +arm64) target_compose_arch=aarch64 ;; +*) +echo " Docker in 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" +if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; 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 +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 +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/compose_version/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || { +echo -e "\n(!) Failed to fetch the latest artifacts for docker-compose v${compose_version}..." +fallback_compose "$docker_compose_url" +} - chmod +x ${docker_compose_path} +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 +# 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 +mkdir -p ${cli_plugins_dir} +cp ${docker_compose_path} ${cli_plugins_dir} +fi fi # fallback method for compose-switch fallback_compose-switch() { - local url=$1 - local repo_url=$(get_github_api_repo_url "$url") - echo -e "\n(!) Failed to fetch the latest artifacts for compose-switch v${compose_switch_version}..." - get_previous_version "$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/compose-switch +local url=$1 +local repo_url=$(get_github_api_repo_url "$url") +echo -e "\n(!) Failed to fetch the latest artifacts for compose-switch v${compose_switch_version}..." +get_previous_version "$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/compose-switch } # 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/compose-switch || fallback_compose-switch "$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 +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/compose-switch || fallback_compose-switch "$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 # If init file already exists, exit if [ -f "/usr/local/share/docker-init.sh" ]; then - echo "/usr/local/share/docker-init.sh already exists, so exiting." - # Clean up - rm -rf /var/lib/apt/lists/* - exit 0 +echo "/usr/local/share/docker-init.sh already exists, so exiting." +# Clean up +rm -rf /var/lib/apt/lists/* +exit 0 fi echo "docker-init doesn't exist, adding..." if ! cat /etc/group | grep -e "^docker:" > /dev/null 2>&1; then - groupadd -r docker +groupadd -r docker fi usermod -aG docker ${USERNAME} # fallback for docker/buildx fallback_buildx() { - local url=$1 - local repo_url=$(get_github_api_repo_url "$url") - echo -e "\nFailed to fetch the latest artifacts for docker buildx v${buildx_version}..." - get_previous_version "$url" "$repo_url" buildx_version - buildx_file_name="buildx-v${buildx_version}.linux-amd64" - echo -e "\nAttempting to install v${buildx_version}" - wget https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name} +local url=$1 +local repo_url=$(get_github_api_repo_url "$url") +echo -e "\nFailed to fetch the latest artifacts for docker buildx v${buildx_version}..." +get_previous_version "$url" "$repo_url" buildx_version +buildx_file_name="buildx-v${buildx_version}.linux-amd64" +echo -e "\nAttempting to install v${buildx_version}" +wget https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name} } - + if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then - buildx_version="latest" - docker_buildx_url="https://github.com/docker/buildx" - find_version_from_git_tags buildx_version "$docker_buildx_url" "refs/tags/v" - echo '(*) Installing buildx ${buildx_version}...' - architecture=$(uname -m) - 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} || fallback_buildx "$docker_buildx_url" - - docker_home="/usr/libexec/docker" - cli_plugins_dir="${docker_home}/cli-plugins" - - mkdir -p "${cli_plugins_dir}" - mv "${buildx_file_name}" "${cli_plugins_dir}/docker-buildx" - chmod +x "${cli_plugins_dir}/docker-buildx" - - chown -R "${USERNAME}:docker" "${docker_home}" - chmod -R g+r+w "${docker_home}" - find "${docker_home}" -type d -print0 | xargs -n 1 -0 chmod g+s +buildx_version="latest" +docker_buildx_url="https://github.com/docker/buildx" +find_version_from_git_tags buildx_version "$docker_buildx_url" "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} || fallback_buildx "$docker_buildx_url" + +docker_home="/usr/libexec/docker" +cli_plugins_dir="${docker_home}/cli-plugins" + +mkdir -p "${cli_plugins_dir}" +mv "${buildx_file_name}" "${cli_plugins_dir}/docker-buildx" +chmod +x "${cli_plugins_dir}/docker-buildx" + +chown -R "${USERNAME}:docker" "${docker_home}" +chmod -R g+r+w "${docker_home}" +find "${docker_home}" -type d -print0 | xargs -n 1 -0 chmod g+s fi DOCKER_DEFAULT_IP6_TABLES="" if [ "$DISABLE_IP6_TABLES" == true ]; then - requested_version="" - # checking whether the version requested either is in semver format or just a number denoting the major version - # and, extracting the major version number out of the two scenarios - semver_regex='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$' - if echo "$DOCKER_VERSION" | grep -Eq $semver_regex; then - requested_version=$(echo $DOCKER_VERSION | cut -d. -f1) - elif echo "$DOCKER_VERSION" | grep -Eq "^[1-9][0-9]*$"; then - requested_version=$DOCKER_VERSION - fi - if [ "$DOCKER_VERSION" = "latest" ] || [[ -n "$requested_version" && "$requested_version" -ge 27 ]]; then - DOCKER_DEFAULT_IP6_TABLES="--ip6tables=false" - echo "! As requested, passing ${DOCKER_DEFAULT_IP6_TABLES}" - fi +requested_version="" +# checking whether the version requested either is in semver format or just a number denoting the major version +# and, extracting the major version number out of the two scenarios +semver_regex='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$' +if echo "$DOCKER_VERSION" | grep -Eq $semver_regex; then +requested_version=$(echo $DOCKER_VERSION | cut -d. -f1) +elif echo "$DOCKER_VERSION" | grep -Eq "^[1-9][0-9]*$"; then +requested_version=$DOCKER_VERSION +fi +if [ "$DOCKER_VERSION" = "latest" ] || [[ -n "$requested_version" && "$requested_version" -ge 27 ]]; then +DOCKER_DEFAULT_IP6_TABLES="--ip6tables=false" +echo "! As requested, passing ${DOCKER_DEFAULT_IP6_TABLES}" +fi fi tee /usr/local/share/docker-init.sh > /dev/null \ -<< 'EOF' +<< EOF #!/bin/sh #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -656,15 +654,29 @@ EOF tee -a /usr/local/share/docker-init.sh > /dev/null \ << 'EOF' -cat << 'INNEREOF' > /usr/local/bin/start-dockerd-inner.sh -#!/bin/bash +dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} DOCKER_DEFAULT_IP6_TABLES=${DOCKER_DEFAULT_IP6_TABLES} $(cat << 'INNEREOF' + # explicitly remove dockerd and containerd PID file to ensure that it can start properly if it was stopped uncleanly + find /run /var/run -iname 'docker*.pid' -delete || : + find /run /var/run -iname 'container*.pid' -delete || : -# Clean up old PIDs -find /run /var/run -iname 'docker*.pid' -delete || : -find /run /var/run -iname 'container*.pid' -delete || : + # -- Start: dind wrapper script -- + # Maintained: https://github.com/moby/moby/blob/master/hack/dind -# Set up cgroup nesting - set_cgroup_nesting() + export container=docker + + if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security; then + mount -t securityfs none /sys/kernel/security || { + echo >&2 'Could not mount /sys/kernel/security.' + echo >&2 'AppArmor detection and --privileged mode might break.' + } + fi + + # Mount /tmp (conditionally) + if ! mountpoint -q /tmp; then + mount -t tmpfs none /tmp + fi + + set_cgroup_nesting() { # cgroup v2: enable nesting if [ -f /sys/fs/cgroup/cgroup.controllers ]; then @@ -688,7 +700,7 @@ find /run /var/run -iname 'container*.pid' -delete || : set_cgroup_nesting if [ $? -ne 0 ]; then - echo "* cgroup v2: Failed to enable nesting, retrying..." + echo "(*) cgroup v2: Failed to enable nesting, retrying..." else break fi @@ -699,51 +711,34 @@ find /run /var/run -iname 'container*.pid' -delete || : # -- End: dind wrapper script -- -# DNS setup -if grep -i 'internal.cloudapp.net' /etc/resolv.conf > /dev/null 2>&1 && [ "${AZURE_DNS_AUTO_DETECTION}" = "true" ]; then - echo "Setting dockerd Azure DNS." - CUSTOMDNS="--dns 168.63.129.16" -else - CUSTOMDNS="" -fi + # Handle DNS + set +e + cat /etc/resolv.conf | grep -i 'internal.cloudapp.net' > /dev/null 2>&1 + if [ $? -eq 0 ] && [ "${AZURE_DNS_AUTO_DETECTION}" = "true" ] + then + echo "Setting dockerd Azure DNS." + CUSTOMDNS="--dns 168.63.129.16" + else + echo "Not setting dockerd DNS manually." + CUSTOMDNS="" + fi + set -e -# Default address pool -if [ -z "$DOCKER_DEFAULT_ADDRESS_POOL" ]; then - DEFAULT_ADDRESS_POOL="" -else - DEFAULT_ADDRESS_POOL="--default-address-pool $DOCKER_DEFAULT_ADDRESS_POOL" -fi + if [ -z "$DOCKER_DEFAULT_ADDRESS_POOL" ] + then + DEFAULT_ADDRESS_POOL="" + else + DEFAULT_ADDRESS_POOL="--default-address-pool $DOCKER_DEFAULT_ADDRESS_POOL" + fi -# Start Docker engine -dockerd $CUSTOMDNS $DEFAULT_ADDRESS_POOL $DOCKER_DEFAULT_IP6_TABLES > /tmp/dockerd.log 2>&1 & + # Start docker/moby engine + ( dockerd $CUSTOMDNS $DEFAULT_ADDRESS_POOL $DOCKER_DEFAULT_IP6_TABLES > /tmp/dockerd.log 2>&1 ) & INNEREOF +)" -chmod +x /usr/local/bin/start-dockerd-inner.sh -dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} \ -DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} \ -DOCKER_DEFAULT_IP6_TABLES=${DOCKER_DEFAULT_IP6_TABLES} \ -/usr/local/bin/start-dockerd-inner.sh" - - - # -- Start: dind wrapper script -- - # Maintained: https://github.com/moby/moby/blob/master/hack/dind - - export container=docker - - if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security; then - mount -t securityfs none /sys/kernel/security || { - echo >&2 'Could not mount /sys/kernel/security.' - echo >&2 'AppArmor detection and --privileged mode might break.' - } - fi - - # Mount /tmp (conditionally) - if ! mountpoint -q /tmp; then - mount -t tmpfs none /tmp - fi sudo_if() { - COMMAND="$*" + COMMAND="$*" if [ "$(id -u)" -ne 0 ]; then sudo $COMMAND @@ -753,7 +748,7 @@ sudo_if() { } retry_docker_start_count=0 -docker_ok="true" +docker_ok="false" until [ "${docker_ok}" = "true" ] || [ "${retry_docker_start_count}" -eq "5" ]; do @@ -764,14 +759,13 @@ do eval "${dockerd_start}" fi + # Wait up to 10 seconds for Docker to respond retry_count=0 until [ "${docker_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; do sleep 1s set +e docker info > /dev/null 2>&1 && docker_ok="true" - sudo_if pkill dockerd - sudo_if pkill containerd set -e retry_count=`expr $retry_count + 1` @@ -799,4 +793,4 @@ chown ${USERNAME}:root /usr/local/share/docker-init.sh # Clean up rm -rf /var/lib/apt/lists/* -echo "docker-in-docker-debian script has completed!" +echo 'docker-in-docker-debian script has completed!' From 3378558b04020e80c3db36dd7cacbd5f223a61d3 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Fri, 2 May 2025 11:31:27 +0000 Subject: [PATCH 12/19] fixing errors --- src/docker-in-docker/install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 806c1bc88..ca53341eb 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -1,5 +1,4 @@ #!/bin/bash -#shellcheck disable=all # shellcheck disable=all #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. From 3d5d00b1a856616580e3e9148742dcc1623f5a6a Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Fri, 2 May 2025 14:27:12 +0000 Subject: [PATCH 13/19] fixing errors in checks --- src/docker-in-docker/install.sh | 169 ++++++++++++++++---------------- 1 file changed, 85 insertions(+), 84 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index ca53341eb..3c71e26aa 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -370,104 +370,105 @@ echo "Please log out and log back in to apply group changes." } if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then -echo "Docker / Moby CLI and Engine already installed." + echo "Docker / Moby CLI and Engine already installed." else -if [ "${USE_MOBY}" = "true" ];then -if { [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; }; then -# Install engine -set +e # Handle error gracefully -apt-get -y install --no-install-recommends \ -moby-cli${cli_version_suffix} \ -moby-buildx${buildx_version_suffix} \ -moby-engine${engine_version_suffix} -exit_code=$? -set -e - -if [ ${exit_code} -ne 0 ]; then -err "Packages for moby not available in OS ${ID} ${VERSION_CODENAME} (${architecture}). To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS version (e.g., 'ubuntu-20.04')." -exit 1 -fi + if [ "${USE_MOBY}" = "true" ];then + if { [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; }; then + # Install engine + set +e # Handle error gracefully + apt-get -y install --no-install-recommends \ + moby-cli${cli_version_suffix} \ + moby-buildx${buildx_version_suffix} \ + moby-engine${engine_version_suffix} + exit_code=$? + set -e + + if [ ${exit_code} -ne 0 ]; then + err "Packages for moby not available in OS ${ID} ${VERSION_CODENAME} (${architecture}). To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS version (e.g., 'ubuntu-20.04')." + exit 1 + fi -# Install compose -apt-get -y install --no-install-recommends moby-compose || \ -err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." + # Install compose + apt-get -y install --no-install-recommends moby-compose || \ + err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." -elif [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; then -install_docker_or_moby -fi -elif [ "${USE_MOBY}" = "false" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then - -#kmod package is required for modprobe -dnf install -y kmod iptables procps-ng -# Load iptable_nat module for docker-in-docker. -# See: -# - https://github.com/ublue-os/bluefin/issues/2365 -# - https://github.com/devcontainers/features/issues/1235 -mkdir -p /etc/modules-load.d && cat >>/etc/modules-load.d/ip_tables.conf <>/etc/modules-load.d/ip_tables.conf << 'EOF' + iptable_nat EOF -# https://github.com/devcontainers/features/issues/1235 -if uname -r | grep -q '\.fc'; then -sudo update-alternatives --set iptables /usr/sbin/iptables-nft -fi - -# Get Fedora release version (e.g. 38, 39) -FEDORA_VERSION=$(rpm -E %fedora) - -echo "Detected Fedora version: $FEDORA_VERSION" - -echo "Installing dnf-plugins-core..." -if ! dnf install -y dnf-plugins-core; then -echo "⚠️ Failed to install dnf-plugins-core. Falling back to Moby." -install_docker_or_moby -exit 0 -fi -echo "Setting up Docker CE repo..." -if ! dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo; then -echo "⚠️ Failed to add Docker CE repo. Falling back to Moby." -install_docker_or_moby -exit 0 -fi + # https://github.com/devcontainers/features/issues/1235 + if uname -r | grep -q '\.fc'; then + sudo update-alternatives --set iptables /usr/sbin/iptables-nft + fi -# Try installing Docker CE with fallback to Moby -echo "Attempting to install Docker CE..." + # Get Fedora release version (e.g. 38, 39) + FEDORA_VERSION=$(rpm -E %fedora) + + echo "Detected Fedora version: $FEDORA_VERSION" + + echo "Installing dnf-plugins-core..." + if ! dnf install -y dnf-plugins-core; then + echo "⚠️ Failed to install dnf-plugins-core. Falling back to Moby." + install_docker_or_moby + exit 0 + fi + echo "Setting up Docker CE repo..." + if ! dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo; then + echo "⚠️ Failed to add Docker CE repo. Falling back to Moby." + install_docker_or_moby + exit 0 + fi -set +e -dnf install -y docker docker-ce docker-ce-cli containerd.io -DOCKER_INSTALL_EXIT_CODE=$? -set -e + # Try installing Docker CE with fallback to Moby + echo "Attempting to install Docker CE..." -if [ $DOCKER_INSTALL_EXIT_CODE -ne 0 ] || ! command -v docker >/dev/null || ! command -v dockerd >/dev/null; then -echo "⚠️ Docker CE installation appears incomplete or failed — falling back to Moby." + set +e + dnf install -y docker docker-ce docker-ce-cli containerd.io + DOCKER_INSTALL_EXIT_CODE=$? + set -e -install_docker_or_moby + if [ $DOCKER_INSTALL_EXIT_CODE -ne 0 ] || ! command -v docker >/dev/null || ! command -v dockerd >/dev/null; then + echo "⚠️ Docker CE installation appears incomplete or failed — falling back to Moby." -# Optional: symlink to match docker-ce command names -ln -sf /usr/bin/moby-engine /usr/bin/dockerd || true -else -echo "✅ Docker CE installed successfully!" -fi + install_docker_or_moby -# Create docker group if missing -if ! getent group docker > /dev/null; then -echo "Creating 'docker' group..." -groupadd docker -fi + # Optional: symlink to match docker-ce command names + ln -sf /usr/bin/moby-engine /usr/bin/dockerd || true + else + echo "✅ Docker CE installed successfully!" + fi -# Add user to docker group -USERNAME=${USERNAME:-vscode} -echo "Adding user '$USERNAME' to docker group..." -usermod -aG docker "$USERNAME" + # Create docker group if missing + if ! getent group docker > /dev/null; then + echo "Creating 'docker' group..." + groupadd docker + fi -# Final message -echo "✅ Docker or Moby installed and user configured." -else -echo "❌ Unsupported OS or configuration. Exiting." -exit 1 -fi + # Add user to docker group + USERNAME=${USERNAME:-vscode} + echo "Adding user '$USERNAME' to docker group..." + usermod -aG docker "$USERNAME" -echo "Finished installing Docker / Moby!" + # Final message + echo "✅ Docker or Moby installed and user configured." + else + if { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then + echo "❌ Unsupported OS or configuration. Exiting." + exit 1 + fi + fi + echo "Finished installing Docker / Moby!" fi From 88ef5bf126d9167dfc24497ab98756a1a50538e9 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Fri, 2 May 2025 15:39:36 +0000 Subject: [PATCH 14/19] fixing the errors in the checks --- src/docker-in-docker/install.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 3c71e26aa..6b1c817c6 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -1,5 +1,4 @@ -#!/bin/bash -# shellcheck disable=all +#!//usr/bin/env bash #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. @@ -371,9 +370,7 @@ echo "Please log out and log back in to apply group changes." if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then echo "Docker / Moby CLI and Engine already installed." -else - if [ "${USE_MOBY}" = "true" ];then - if { [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; }; then + elif [ "${USE_MOBY}" = "true" ] && { [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; }; then # Install engine set +e # Handle error gracefully apt-get -y install --no-install-recommends \ @@ -391,10 +388,17 @@ else # Install compose apt-get -y install --no-install-recommends moby-compose || \ err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." + else + if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then + apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} docker-ce${engine_version_suffix} + # Install compose + apt-mark hold docker-ce docker-ce-cli + apt-get -y install --no-install-recommends docker-compose-plugin || echo "(*) Package docker-compose-plugin (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." + + + elif [ "${USE_MOBY}" = "true" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then + install_docker_or_moby - elif [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; then - install_docker_or_moby - fi elif [ "${USE_MOBY}" = "false" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then #kmod package is required for modprobe From 98a73fec544442b24fb791f82e6779edccc6d64c Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Wed, 21 May 2025 07:03:09 +0000 Subject: [PATCH 15/19] changed indentation for better readability --- src/docker-in-docker/install.sh | 231 ++++++++++++++++---------------- 1 file changed, 115 insertions(+), 116 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 6b1c817c6..5c324b794 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -56,10 +56,10 @@ break fi done if [ "${USERNAME}" = "" ]; then -USERNAME=root + USERNAME=root fi elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then -USERNAME=root + USERNAME=root fi apt_get_update() @@ -397,7 +397,7 @@ if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then elif [ "${USE_MOBY}" = "true" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then - install_docker_or_moby + install_docker_or_moby elif [ "${USE_MOBY}" = "false" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then @@ -491,97 +491,96 @@ curl -fsSL "https://github.com/docker/compose/releases/download/v${compose_versi # 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 in 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" -if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; 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 -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 -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/compose_version/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || { -echo -e "\n(!) Failed to fetch the latest artifacts for docker-compose v${compose_version}..." -fallback_compose "$docker_compose_url" -} - -chmod +x ${docker_compose_path} + case "${architecture}" in + amd64) target_compose_arch=x86_64 ;; + arm64) target_compose_arch=aarch64 ;; + *) + echo " Docker in 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" + if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; 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 + 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 + 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/compose_version/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || { + echo -e "\n(!) Failed to fetch the latest artifacts for docker-compose v${compose_version}..." + fallback_compose "$docker_compose_url" + } + 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 + # 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 + mkdir -p ${cli_plugins_dir} + cp ${docker_compose_path} ${cli_plugins_dir} + fi fi # fallback method for compose-switch fallback_compose-switch() { -local url=$1 -local repo_url=$(get_github_api_repo_url "$url") -echo -e "\n(!) Failed to fetch the latest artifacts for compose-switch v${compose_switch_version}..." -get_previous_version "$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/compose-switch + local url=$1 + local repo_url=$(get_github_api_repo_url "$url") + echo -e "\n(!) Failed to fetch the latest artifacts for compose-switch v${compose_switch_version}..." + get_previous_version "$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/compose-switch } # 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/compose-switch || fallback_compose-switch "$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 + 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/compose-switch || fallback_compose-switch "$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 # If init file already exists, exit if [ -f "/usr/local/share/docker-init.sh" ]; then -echo "/usr/local/share/docker-init.sh already exists, so exiting." -# Clean up -rm -rf /var/lib/apt/lists/* -exit 0 + echo "/usr/local/share/docker-init.sh already exists, so exiting." + # Clean up + rm -rf /var/lib/apt/lists/* + exit 0 fi echo "docker-init doesn't exist, adding..." @@ -593,52 +592,52 @@ usermod -aG docker ${USERNAME} # fallback for docker/buildx fallback_buildx() { -local url=$1 -local repo_url=$(get_github_api_repo_url "$url") -echo -e "\nFailed to fetch the latest artifacts for docker buildx v${buildx_version}..." -get_previous_version "$url" "$repo_url" buildx_version -buildx_file_name="buildx-v${buildx_version}.linux-amd64" -echo -e "\nAttempting to install v${buildx_version}" -wget https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name} + local url=$1 + local repo_url=$(get_github_api_repo_url "$url") + echo -e "\nFailed to fetch the latest artifacts for docker buildx v${buildx_version}..." + get_previous_version "$url" "$repo_url" buildx_version + buildx_file_name="buildx-v${buildx_version}.linux-amd64" + echo -e "\nAttempting to install v${buildx_version}" + wget https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name} } if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then -buildx_version="latest" -docker_buildx_url="https://github.com/docker/buildx" -find_version_from_git_tags buildx_version "$docker_buildx_url" "refs/tags/v" -echo '(*) Installing buildx ${buildx_version}...' -buildx_file_name="buildx-v${buildx_version}.linux-${architecture}" + buildx_version="latest" + docker_buildx_url="https://github.com/docker/buildx" + find_version_from_git_tags buildx_version "$docker_buildx_url" "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} || fallback_buildx "$docker_buildx_url" + cd /tmp + wget https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name} || fallback_buildx "$docker_buildx_url" -docker_home="/usr/libexec/docker" -cli_plugins_dir="${docker_home}/cli-plugins" + docker_home="/usr/libexec/docker" + cli_plugins_dir="${docker_home}/cli-plugins" -mkdir -p "${cli_plugins_dir}" -mv "${buildx_file_name}" "${cli_plugins_dir}/docker-buildx" -chmod +x "${cli_plugins_dir}/docker-buildx" + mkdir -p "${cli_plugins_dir}" + mv "${buildx_file_name}" "${cli_plugins_dir}/docker-buildx" + chmod +x "${cli_plugins_dir}/docker-buildx" -chown -R "${USERNAME}:docker" "${docker_home}" -chmod -R g+r+w "${docker_home}" -find "${docker_home}" -type d -print0 | xargs -n 1 -0 chmod g+s + chown -R "${USERNAME}:docker" "${docker_home}" + chmod -R g+r+w "${docker_home}" + find "${docker_home}" -type d -print0 | xargs -n 1 -0 chmod g+s fi DOCKER_DEFAULT_IP6_TABLES="" if [ "$DISABLE_IP6_TABLES" == true ]; then -requested_version="" -# checking whether the version requested either is in semver format or just a number denoting the major version -# and, extracting the major version number out of the two scenarios -semver_regex='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$' -if echo "$DOCKER_VERSION" | grep -Eq $semver_regex; then -requested_version=$(echo $DOCKER_VERSION | cut -d. -f1) -elif echo "$DOCKER_VERSION" | grep -Eq "^[1-9][0-9]*$"; then -requested_version=$DOCKER_VERSION -fi -if [ "$DOCKER_VERSION" = "latest" ] || [[ -n "$requested_version" && "$requested_version" -ge 27 ]]; then -DOCKER_DEFAULT_IP6_TABLES="--ip6tables=false" -echo "! As requested, passing ${DOCKER_DEFAULT_IP6_TABLES}" -fi + requested_version="" + # checking whether the version requested either is in semver format or just a number denoting the major version + # and, extracting the major version number out of the two scenarios + semver_regex='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$' + if echo "$DOCKER_VERSION" | grep -Eq $semver_regex; then + requested_version=$(echo $DOCKER_VERSION | cut -d. -f1) + elif echo "$DOCKER_VERSION" | grep -Eq "^[1-9][0-9]*$"; then + requested_version=$DOCKER_VERSION + fi + if [ "$DOCKER_VERSION" = "latest" ] || [[ -n "$requested_version" && "$requested_version" -ge 27 ]]; then + DOCKER_DEFAULT_IP6_TABLES="--ip6tables=false" + echo "! As requested, passing ${DOCKER_DEFAULT_IP6_TABLES}" + fi fi tee /usr/local/share/docker-init.sh > /dev/null \ @@ -742,7 +741,7 @@ INNEREOF sudo_if() { - COMMAND="$*" + COMMAND="$*" if [ "$(id -u)" -ne 0 ]; then sudo $COMMAND From 6c2ca34e60d2d2e432e7982cc8119a00eab771c8 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Mon, 26 May 2025 08:56:17 +0000 Subject: [PATCH 16/19] correcting the indentation for better readability --- src/docker-in-docker/install.sh | 175 ++++++++++++++++---------------- 1 file changed, 86 insertions(+), 89 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 5c324b794..7044d4952 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -242,17 +242,17 @@ fi # Check if distro is supported if [ "${USE_MOBY}" = "true" ]; then -if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then -err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS distribution" -err "Support distributions include: ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" -exit 1 -fi -echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}'" + if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then + err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS distribution" + err "Support distributions include: ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" + exit 1 + fi + echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}'" else if [[ "${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then -err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, please choose a compatible OS distribution" -err "Support distributions include: '${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}'" -exit 1 + err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, please choose a compatible OS distribution" + err "Support distributions include: '${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}'" + exit 1 fi echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}'" fi @@ -260,85 +260,85 @@ fi # Install dependencies check_packages apt-transport-https curl ca-certificates pigz iptables gnupg2 dirmngr wget jq if ! type git > /dev/null 2>&1; then -check_packages git + check_packages git fi # Swap to legacy iptables for compatibility if type iptables-legacy > /dev/null 2>&1; then -update-alternatives --set iptables /usr/sbin/iptables-legacy -update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy + update-alternatives --set iptables /usr/sbin/iptables-legacy + update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy fi # https://github.com/devcontainers/features/issues/1235 if uname -r | grep -q '\.fc'; then -sudo update-alternatives --set iptables /usr/sbin/iptables-nft + sudo update-alternatives --set iptables /usr/sbin/iptables-nft fi # Set up the necessary apt repos (either Microsoft's or Docker's) if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then -if [ "${USE_MOBY}" = "true" ]; then + if [ "${USE_MOBY}" = "true" ]; then -# Name of open source engine/cli -engine_package_name="moby-engine" -cli_package_name="moby-cli" + # Name of open source engine/cli + engine_package_name="moby-engine" + cli_package_name="moby-cli" -# Import key safely and import Microsoft apt repo -curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg -echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list -else -# Name of licensed engine/cli -engine_package_name="docker-ce" -cli_package_name="docker-ce-cli" + # Import key safely and import Microsoft apt repo + curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg + echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list + else + # Name of licensed engine/cli + engine_package_name="docker-ce" + cli_package_name="docker-ce-cli" -# Import key safely and import Docker apt repo -curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg -echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list -fi + # Import key safely and import Docker apt repo + curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list + fi # Refresh apt lists apt-get update fi # Soft version matching if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then -# Empty, meaning grab whatever "latest" is in apt repo -engine_version_suffix="" -cli_version_suffix="" -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//+/\\+}" -# Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ -docker_version_regex="^(.+:)?${docker_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" -set +e # Don't exit if finding version fails - will handle gracefully -cli_version_suffix="=$(apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" -engine_version_suffix="=$(apt-cache madison ${engine_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" -set -e -if [ -z "${engine_version_suffix}" ] || [ "${engine_version_suffix}" = "=" ] || [ -z "${cli_version_suffix}" ] || [ "${cli_version_suffix}" = "=" ] ; then -err "No full or partial Docker / Moby version match found for \"${DOCKER_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" -apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' -exit 1 -fi -echo "engine_version_suffix ${engine_version_suffix}" -echo "cli_version_suffix ${cli_version_suffix}" + # Empty, meaning grab whatever "latest" is in apt repo + engine_version_suffix="" + cli_version_suffix="" + 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//+/\\+}" + # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ + docker_version_regex="^(.+:)?${docker_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" + set +e # Don't exit if finding version fails - will handle gracefully + cli_version_suffix="=$(apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" + engine_version_suffix="=$(apt-cache madison ${engine_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" + set -e + if [ -z "${engine_version_suffix}" ] || [ "${engine_version_suffix}" = "=" ] || [ -z "${cli_version_suffix}" ] || [ "${cli_version_suffix}" = "=" ] ; then + err "No full or partial Docker / Moby version match found for \"${DOCKER_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" + apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' + exit 1 + fi + echo "engine_version_suffix ${engine_version_suffix}" + echo "cli_version_suffix ${cli_version_suffix}" fi # Version matching for moby-buildx if [ "${USE_MOBY}" = "true" ]; then -if [ "${MOBY_BUILDX_VERSION}" = "latest" ]; then -# Empty, meaning grab whatever "latest" is in apt repo -buildx_version_suffix="" -else -buildx_version_dot_escaped="${MOBY_BUILDX_VERSION//./\\.}" -buildx_version_dot_plus_escaped="${buildx_version_dot_escaped//+/\\+}" -buildx_version_regex="^(.+:)?${buildx_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" -set +e -buildx_version_suffix="=$(apt-cache madison moby-buildx | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${buildx_version_regex}")" -set -e -if [ -z "${buildx_version_suffix}" ] || [ "${buildx_version_suffix}" = "=" ]; then -err "No full or partial moby-buildx version match found for \"${MOBY_BUILDX_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" -apt-cache madison moby-buildx | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' -exit 1 -fi -echo "buildx_version_suffix ${buildx_version_suffix}" -fi + if [ "${MOBY_BUILDX_VERSION}" = "latest" ]; then + # Empty, meaning grab whatever "latest" is in apt repo + buildx_version_suffix="" + else + buildx_version_dot_escaped="${MOBY_BUILDX_VERSION//./\\.}" + buildx_version_dot_plus_escaped="${buildx_version_dot_escaped//+/\\+}" + buildx_version_regex="^(.+:)?${buildx_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" + set +e + buildx_version_suffix="=$(apt-cache madison moby-buildx | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${buildx_version_regex}")" + set -e + if [ -z "${buildx_version_suffix}" ] || [ "${buildx_version_suffix}" = "=" ]; then + err "No full or partial moby-buildx version match found for \"${MOBY_BUILDX_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" + apt-cache madison moby-buildx | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' + exit 1 + fi + echo "buildx_version_suffix ${buildx_version_suffix}" + fi fi install_docker_or_moby() { @@ -385,15 +385,14 @@ if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then exit 1 fi - # Install compose - apt-get -y install --no-install-recommends moby-compose || \ - err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." - else - if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then - apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} docker-ce${engine_version_suffix} - # Install compose - apt-mark hold docker-ce docker-ce-cli - apt-get -y install --no-install-recommends docker-compose-plugin || echo "(*) Package docker-compose-plugin (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." + # Install compose + apt-get -y install --no-install-recommends moby-compose || \ + err "Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." + elif [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then + apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} docker-ce${engine_version_suffix} + # Install compose + apt-mark hold docker-ce docker-ce-cli + apt-get -y install --no-install-recommends docker-compose-plugin || echo "(*) Package docker-compose-plugin (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." elif [ "${USE_MOBY}" = "true" ] && { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then @@ -443,20 +442,20 @@ EOF set -e if [ $DOCKER_INSTALL_EXIT_CODE -ne 0 ] || ! command -v docker >/dev/null || ! command -v dockerd >/dev/null; then - echo "⚠️ Docker CE installation appears incomplete or failed — falling back to Moby." + echo "⚠️ Docker CE installation appears incomplete or failed — falling back to Moby." - install_docker_or_moby + install_docker_or_moby - # Optional: symlink to match docker-ce command names - ln -sf /usr/bin/moby-engine /usr/bin/dockerd || true + # Optional: symlink to match docker-ce command names + ln -sf /usr/bin/moby-engine /usr/bin/dockerd || true else - echo "✅ Docker CE installed successfully!" + echo "✅ Docker CE installed successfully!" fi # Create docker group if missing if ! getent group docker > /dev/null; then - echo "Creating 'docker' group..." - groupadd docker + echo "Creating 'docker' group..." + groupadd docker fi # Add user to docker group @@ -466,16 +465,14 @@ EOF # Final message echo "✅ Docker or Moby installed and user configured." - else - if { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then - echo "❌ Unsupported OS or configuration. Exiting." - exit 1 + else + if { [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; }; then + echo "❌ Unsupported OS or configuration. Exiting." + exit 1 fi - fi - echo "Finished installing Docker / Moby!" + echo "Finished installing Docker / Moby!" fi - docker_home="/usr/libexec/docker" cli_plugins_dir="${docker_home}/cli-plugins" @@ -796,4 +793,4 @@ chown ${USERNAME}:root /usr/local/share/docker-init.sh # Clean up rm -rf /var/lib/apt/lists/* -echo 'docker-in-docker-debian script has completed!' +echo 'docker-in-docker-debian script has completed!' \ No newline at end of file From 6a61aeb490571d5de02374770a12fcfbfc501621 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Tue, 27 May 2025 11:27:00 +0000 Subject: [PATCH 17/19] added relevant comment --- src/docker-in-docker/install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 7044d4952..ac013d19c 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -341,6 +341,7 @@ if [ "${USE_MOBY}" = "true" ]; then fi fi +#function is used to install docker or moby for fedora if moby is true and docker is not available in a specific versions of fedora install_docker_or_moby() { # Check for the OS type if [ -f /etc/os-release ]; then From a3ed786e6cb87178d1d5f2e12c0f26953a994fdd Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Wed, 11 Jun 2025 09:48:56 +0000 Subject: [PATCH 18/19] Revert "added relevant comment" Indentation mismatch in the Dockerfile for docker-in-docker install script This reverts commit 6a61aeb490571d5de02374770a12fcfbfc501621. --- src/docker-in-docker/install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index ac013d19c..7044d4952 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -341,7 +341,6 @@ if [ "${USE_MOBY}" = "true" ]; then fi fi -#function is used to install docker or moby for fedora if moby is true and docker is not available in a specific versions of fedora install_docker_or_moby() { # Check for the OS type if [ -f /etc/os-release ]; then From 2958fdbbd1e139f542f6bb12feb3eb195eacdcb8 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Wed, 11 Jun 2025 10:10:28 +0000 Subject: [PATCH 19/19] reverted the changes for better readability --- src/docker-in-docker/install.sh | 246 ++++++++++++++++---------------- 1 file changed, 122 insertions(+), 124 deletions(-) diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 7044d4952..7711b23b9 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -7,8 +7,8 @@ # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md # Maintainer: The Dev Container spec maintainers if [ -z "$BASH_VERSION" ]; then -echo "❌ This script must be run with bash, not sh." -exit 1 + echo "❌ This script must be run with bash, not sh." + exit 1 fi DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version USE_MOBY="${MOBY:-"true"}" @@ -36,8 +36,8 @@ echo "(!) $*" >&2 } if [ "$(id -u)" -ne 0 ]; then -err 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' -exit 1 + err 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 fi ################### @@ -47,12 +47,12 @@ fi # Determine the appropriate non-root user if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then -USERNAME="" -POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") -for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do + USERNAME="" + POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") + for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do if id -u ${CURRENT_USER} > /dev/null 2>&1; then -USERNAME=${CURRENT_USER} -break + USERNAME=${CURRENT_USER} + break fi done if [ "${USERNAME}" = "" ]; then @@ -66,10 +66,10 @@ apt_get_update() { . /etc/os-release if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then -if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then -echo "Running apt-get update..." -apt-get update -y -fi + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi fi } @@ -77,134 +77,133 @@ fi check_packages() { if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ] || [ "$ID_LIKE" = "debian" ]; then -if ! dpkg -s "$@" > /dev/null 2>&1; then -apt_get_update -apt-get -y install --no-install-recommends "$@" -fi + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update + apt-get -y install --no-install-recommends "$@" + fi elif [ "$ID" = "fedora" ] || [ "$ID" = "centos" ] || [ "$ID_LIKE" == "rhel" ]; then -if ! dnf list installed "$@" > /dev/null 2>&1; then -dnf -y install "$@" -fi + if ! dnf list installed "$@" > /dev/null 2>&1; then + dnf -y install "$@" + fi fi } missing=0 for cmd in git wget which; do -command -v $cmd &>/dev/null || { -echo "$cmd not found" -missing=1 -} + command -v $cmd &>/dev/null || { + echo "$cmd not found" + missing=1 + } done if [ $missing -eq 1 ]; then -echo "Installing missing packages..." -if command -v dnf &>/dev/null; then -dnf install -y git wget which curl jq -elif command -v apt &>/dev/null; then -apt-get update && apt-get install -y git wget curl jq -else -echo "Unsupported package manager" -exit 1 -fi + echo "Installing missing packages..." + if command -v dnf &>/dev/null; then + dnf install -y git wget which curl jq + elif command -v apt &>/dev/null; then + apt-get update && apt-get install -y git wget curl jq + else + echo "Unsupported package manager" + exit 1 + fi fi # Figure out correct version of a three part version number is not passed find_version_from_git_tags() { -local variable_name=$1 -local requested_version=${!variable_name} -if [ "${requested_version}" = "none" ]; then return; fi -local repository=$2 -local prefix=${3:-"tags/v"} -local separator=${4:-"."} -local last_part_optional=${5:-"false"} -if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then -local escaped_separator=${separator//./\\.} -local last_part -if [ "${last_part_optional}" = "true" ]; then -last_part="(${escaped_separator}[0-9]+)?" -else -last_part="${escaped_separator}[0-9]+" -fi -local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" -local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" -if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then -declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" -else -set +e -declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" -set -e -fi -fi -if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then -err "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 -exit 1 -fi -echo "${variable_name}=${!variable_name}" + local variable_name=$1 + local requested_version=${!variable_name} + if [ "${requested_version}" = "none" ]; then return; fi + local repository=$2 + local prefix=${3:-"tags/v"} + local separator=${4:-"."} + local last_part_optional=${5:-"false"} + if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then + local escaped_separator=${separator//./\\.} + local last_part + if [ "${last_part_optional}" = "true" ]; then + last_part="(${escaped_separator}[0-9]+)?" + else + last_part="${escaped_separator}[0-9]+" + fi + local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" + local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" + if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then + declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" + else + set +e + declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" + set -e + fi + fi + if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then + err "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 + exit 1 + fi + echo "${variable_name}=${!variable_name}" } # Use semver logic to decrement a version number then look for the closest match find_prev_version_from_git_tags() { -local variable_name=$1 -local current_version=${!variable_name} -local repository=$2 -# Normally a "v" is used before the version number, but support alternate cases -local prefix=${3:-"tags/v"} -# Some repositories use "_" instead of "." for version number part separation, support that -local separator=${4:-"."} -# Some tools release versions that omit the last digit (e.g. go) -local last_part_optional=${5:-"false"} -# Some repositories may have tags that include a suffix (e.g. actions/node-versions) -local version_suffix_regex=$6 -# Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios. -set +e -major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')" -minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')" -breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')" - -if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then -((major=major-1)) -declare -g ${variable_name}="${major}" -# Look for latest version from previous major release -find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" -# Handle situations like Go's odd version pattern where "0" releases omit the last part -elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then -((minor=minor-1)) -declare -g ${variable_name}="${major}.${minor}" -# Look for latest version from previous minor release -find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" -else -((breakfix=breakfix-1)) -if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then -declare -g ${variable_name}="${major}.${minor}" -else -declare -g ${variable_name}="${major}.${minor}.${breakfix}" -fi -fi -set -e + local variable_name=$1 + local current_version=${!variable_name} + local repository=$2 + # Normally a "v" is used before the version number, but support alternate cases + local prefix=${3:-"tags/v"} + # Some repositories use "_" instead of "." for version number part separation, support that + local separator=${4:-"."} + # Some tools release versions that omit the last digit (e.g. go) + local last_part_optional=${5:-"false"} + # Some repositories may have tags that include a suffix (e.g. actions/node-versions) + local version_suffix_regex=$6 + # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios. + set +e + major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')" + minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')" + breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')" + + if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then + ((major=major-1)) + declare -g ${variable_name}="${major}" + # Look for latest version from previous major release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" + # Handle situations like Go's odd version pattern where "0" releases omit the last part + elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then + ((minor=minor-1)) + declare -g ${variable_name}="${major}.${minor}" + # Look for latest version from previous minor release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" + else + ((breakfix=breakfix-1)) + if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then + declare -g ${variable_name}="${major}.${minor}" + else + declare -g ${variable_name}="${major}.${minor}.${breakfix}" + fi + fi + set -e } # Function to fetch the version released prior to the latest version get_previous_version() { -local url=$1 -local repo_url=$2 -local variable_name=$3 -prev_version=${!variable_name} - -output=$(curl -s "$repo_url"); + local url=$1 + local repo_url=$2 + local variable_name=$3 + prev_version=${!variable_name} + output=$(curl -s "$repo_url"); if echo "$output" | jq -e 'type == "object"' > /dev/null; then -message=$(echo "$output" | jq -r '.message') + message=$(echo "$output" | jq -r '.message') if [[ $message == "API rate limit exceeded"* ]]; 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" -declare -g ${variable_name}="${prev_version}" + 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" + declare -g ${variable_name}="${prev_version}" fi elif echo "$output" | jq -e 'type == "array"' > /dev/null; then -echo -e "\nAttempting to find latest version using GitHub Api." -version=$(echo "$output" | jq -r '.[1].tag_name') -declare -g ${variable_name}="${version#v}" + echo -e "\nAttempting to find latest version using GitHub Api." + version=$(echo "$output" | jq -r '.[1].tag_name') + declare -g ${variable_name}="${version#v}" fi echo "${variable_name}=${!variable_name}" } @@ -226,20 +225,19 @@ export DEBIAN_FRONTEND=noninteractive . /etc/os-release # Fetch host/container architecture if [ "$ID" = "ubuntu" ] || [ "$ID" = "debian" ]; then -architecture="$(dpkg --print-architecture)" + architecture="$(dpkg --print-architecture)" elif [ "$ID" = "fedora" ] || [ "$ID_LIKE" = "rhel" ]; then -architecture="$(uname -m)" -case "$architecture" in -x86_64) architecture="amd64" ;; -aarch64) architecture="arm64" ;; -*) echo "Unsupported architecture: $architecture"; exit 1 ;; -esac + architecture="$(uname -m)" + case "$architecture" in + x86_64) architecture="amd64" ;; + aarch64) architecture="arm64" ;; + *) echo "Unsupported architecture: $architecture"; exit 1 ;; + esac else -echo "Unsupported operating system: $ID" -exit 1 + echo "Unsupported operating system: $ID" + exit 1 fi - # Check if distro is supported if [ "${USE_MOBY}" = "true" ]; then if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then