|
7 | 7 | # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker.md
|
8 | 8 | # Maintainer: The VS Code and Codespaces Teams
|
9 | 9 | #
|
10 |
| -# Syntax: ./docker-debian.sh [enable non-root docker socket access flag] [source socket] [target socket] [non-root user] [use moby] |
| 10 | +# Syntax: ./docker-debian.sh [enable non-root docker socket access flag] [source socket] [target socket] [non-root user] [use moby] [CLI version] |
11 | 11 |
|
12 | 12 | ENABLE_NONROOT_DOCKER=${1:-"true"}
|
13 | 13 | SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"}
|
14 | 14 | TARGET_SOCKET=${3:-"/var/run/docker.sock"}
|
15 | 15 | USERNAME=${4:-"automatic"}
|
16 | 16 | USE_MOBY=${5:-"true"}
|
| 17 | +DOCKER_VERSION=${6:-"latest"} |
17 | 18 | MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
|
| 19 | +DOCKER_DASH_COMPOSE_VERSION="1" |
18 | 20 |
|
19 | 21 | set -e
|
20 | 22 |
|
@@ -74,33 +76,106 @@ check_packages() {
|
74 | 76 | fi
|
75 | 77 | }
|
76 | 78 |
|
| 79 | +# Figure out correct version of a three part version number is not passed |
| 80 | +find_version_from_git_tags() { |
| 81 | + local variable_name=$1 |
| 82 | + local requested_version=${!variable_name} |
| 83 | + if [ "${requested_version}" = "none" ]; then return; fi |
| 84 | + local repository=$2 |
| 85 | + local prefix=${3:-"tags/v"} |
| 86 | + local separator=${4:-"."} |
| 87 | + local last_part_optional=${5:-"false"} |
| 88 | + if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then |
| 89 | + local escaped_separator=${separator//./\\.} |
| 90 | + local last_part |
| 91 | + if [ "${last_part_optional}" = "true" ]; then |
| 92 | + last_part="(${escaped_separator}[0-9]+)?" |
| 93 | + else |
| 94 | + last_part="${escaped_separator}[0-9]+" |
| 95 | + fi |
| 96 | + local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" |
| 97 | + local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" |
| 98 | + if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then |
| 99 | + declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" |
| 100 | + else |
| 101 | + set +e |
| 102 | + declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" |
| 103 | + set -e |
| 104 | + fi |
| 105 | + fi |
| 106 | + if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then |
| 107 | + echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 |
| 108 | + exit 1 |
| 109 | + fi |
| 110 | + echo "${variable_name}=${!variable_name}" |
| 111 | +} |
| 112 | + |
77 | 113 | # Ensure apt is in non-interactive to avoid prompts
|
78 | 114 | export DEBIAN_FRONTEND=noninteractive
|
79 | 115 |
|
80 | 116 | # Install dependencies
|
81 | 117 | check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr
|
| 118 | +if ! type git > /dev/null 2>&1; then |
| 119 | + apt_get_update_if_needed |
| 120 | + apt-get -y install git |
| 121 | +fi |
82 | 122 |
|
83 |
| -# Install Docker / Moby CLI if not already installed |
| 123 | +# Source /etc/os-release to get OS info |
| 124 | +. /etc/os-release |
| 125 | +# Fetch host/container arch. |
84 | 126 | architecture="$(dpkg --print-architecture)"
|
| 127 | + |
| 128 | +# Set up the necessary apt repos (either Microsoft's or Docker's) |
| 129 | +if [ "${USE_MOBY}" = "true" ]; then |
| 130 | + |
| 131 | + cli_package_name="moby-cli" |
| 132 | + |
| 133 | + # Import key safely and import Microsoft apt repo |
| 134 | + get_common_setting MICROSOFT_GPG_KEYS_URI |
| 135 | + curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg |
| 136 | + 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 |
| 137 | +else |
| 138 | + # Name of proprietary engine package |
| 139 | + cli_package_name="docker-ce-cli" |
| 140 | + |
| 141 | + # Import key safely and import Docker apt repo |
| 142 | + curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg |
| 143 | + 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 |
| 144 | +fi |
| 145 | + |
| 146 | +# Refresh apt lists |
| 147 | +apt-get update |
| 148 | + |
| 149 | +# Soft version matching for CLI |
| 150 | +if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then |
| 151 | + # Empty, meaning grab whatever "latest" is in apt repo |
| 152 | + cli_version_suffix="" |
| 153 | +else |
| 154 | + # Fetch a valid version from the apt-cache (eg: the Microsoft repo appends +azure, breakfix, etc...) |
| 155 | + docker_version_dot_escaped="${DOCKER_VERSION//./\\.}" |
| 156 | + docker_version_dot_plus_escaped="${docker_version_dot_escaped//+/\\+}" |
| 157 | + # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ |
| 158 | + docker_version_regex="^(.+:)?${docker_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" |
| 159 | + set +e # Don't exit if finding version fails - will handle gracefully |
| 160 | + cli_version_suffix="=$(apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" |
| 161 | + set -e |
| 162 | + if [ -z "${cli_version_suffix}" ] || [ "${cli_version_suffix}" = "=" ]; then |
| 163 | + echo "(!) No full or partial Docker / Moby version match found for \"${DOCKER_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" |
| 164 | + apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' |
| 165 | + exit 1 |
| 166 | + fi |
| 167 | + echo "cli_version_suffix ${cli_version_suffix}" |
| 168 | +fi |
| 169 | + |
| 170 | +# Install Docker / Moby CLI if not already installed |
85 | 171 | if type docker > /dev/null 2>&1; then
|
86 | 172 | echo "Docker / Moby CLI already installed."
|
87 | 173 | else
|
88 |
| - # Source /etc/os-release to get OS info |
89 |
| - . /etc/os-release |
90 | 174 | if [ "${USE_MOBY}" = "true" ]; then
|
91 |
| - # Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install |
92 |
| - get_common_setting MICROSOFT_GPG_KEYS_URI |
93 |
| - curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg |
94 |
| - 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 |
95 |
| - apt-get update |
96 |
| - apt-get -y install --no-install-recommends moby-cli moby-buildx moby-engine |
97 |
| - apt-get -y install --no-install-recommends moby-compose || echo "(*) Package moby-compose (Docker Compose v2) not available for ${VERSION_CODENAME} ${architecture}. Skipping." |
| 175 | + apt-get -y install --no-install-recommends moby-cli${cli_version_suffix} moby-buildx |
| 176 | + apt-get -y install --no-install-recommends moby-compose || echo "(*) Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." |
98 | 177 | else
|
99 |
| - # Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install |
100 |
| - curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg |
101 |
| - 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 |
102 |
| - apt-get update |
103 |
| - apt-get -y install --no-install-recommends docker-ce-cli |
| 178 | + apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} |
104 | 179 | fi
|
105 | 180 | fi
|
106 | 181 |
|
|
131 | 206 | ${pipx_bin} install --system-site-packages --pip-args '--no-cache-dir --force-reinstall' docker-compose
|
132 | 207 | rm -rf /tmp/pip-tmp
|
133 | 208 | else
|
134 |
| - LATEST_COMPOSE_VERSION=$(basename "$(curl -fsSL -o /dev/null -w "%{url_effective}" https://github.com/docker/compose/releases/latest)") |
135 |
| - curl -fsSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-${TARGET_COMPOSE_ARCH}" -o /usr/local/bin/docker-compose |
| 209 | + find_version_from_git_tags DOCKER_DASH_COMPOSE_VERSION "https://github.com/docker/compose" "tags/" |
| 210 | + echo "(*) Installing docker-compose ${DOCKER_DASH_COMPOSE_VERSION}..." |
| 211 | + curl -fsSL "https://github.com/docker/compose/releases/download/${DOCKER_DASH_COMPOSE_VERSION}/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose |
136 | 212 | chmod +x /usr/local/bin/docker-compose
|
137 | 213 | fi
|
138 | 214 | fi
|
|
141 | 217 | if [ -f "/usr/local/share/docker-init.sh" ]; then
|
142 | 218 | exit 0
|
143 | 219 | fi
|
| 220 | +echo "docker-init doesnt exist, adding..." |
144 | 221 |
|
145 | 222 | # By default, make the source and target sockets the same
|
146 | 223 | if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then
|
|
0 commit comments