github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/docker/library-scripts/docker-in-docker-debian.sh (about) 1 #!/usr/bin/env bash 2 3 # Copyright 2021 The Dapr Authors 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # Unless required by applicable law or agreed to in writing, software 9 # distributed under the License is distributed on an "AS IS" BASIS, 10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 # See the License for the specific language governing permissions and 12 # limitations under the License. 13 # 14 # 15 # Initializes the devcontainer tasks each time the container starts. 16 # Users can edit this copy under /usr/local/share in the container to 17 # customize this as needed for their custom localhost bindings. 18 19 # Source: https://github.com/microsoft/vscode-dev-containers/blob/v0.224.3/script-library/docker-in-docker-debian.sh 20 21 #------------------------------------------------------------------------------------------------------------- 22 # Copyright (c) Microsoft Corporation. All rights reserved. 23 # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. 24 #------------------------------------------------------------------------------------------------------------- 25 # 26 # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md 27 # Maintainer: The VS Code and Codespaces Teams 28 # 29 # Syntax: ./docker-in-docker-debian.sh [enable non-root docker access flag] [non-root user] [use moby] [Engine/CLI Version] 30 31 ENABLE_NONROOT_DOCKER=${1:-"true"} 32 USERNAME=${2:-"automatic"} 33 USE_MOBY=${3:-"true"} 34 DOCKER_VERSION=${4:-"latest"} # The Docker/Moby Engine + CLI should match in version 35 MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" 36 37 set -e 38 39 if [ "$(id -u)" -ne 0 ]; then 40 echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' 41 exit 1 42 fi 43 44 # Determine the appropriate non-root user 45 if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then 46 USERNAME="" 47 POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") 48 for CURRENT_USER in ${POSSIBLE_USERS[@]}; do 49 if id -u ${CURRENT_USER} > /dev/null 2>&1; then 50 USERNAME=${CURRENT_USER} 51 break 52 fi 53 done 54 if [ "${USERNAME}" = "" ]; then 55 USERNAME=root 56 fi 57 elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then 58 USERNAME=root 59 fi 60 61 # Get central common setting 62 get_common_setting() { 63 if [ "${common_settings_file_loaded}" != "true" ]; then 64 curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." 65 common_settings_file_loaded=true 66 fi 67 if [ -f "/tmp/vsdc-settings.env" ]; then 68 local multi_line="" 69 if [ "$2" = "true" ]; then multi_line="-z"; fi 70 local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" 71 if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi 72 fi 73 echo "$1=${!1}" 74 } 75 76 # Function to run apt-get if needed 77 apt_get_update_if_needed() 78 { 79 if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then 80 echo "Running apt-get update..." 81 apt-get update 82 else 83 echo "Skipping apt-get update." 84 fi 85 } 86 87 # Checks if packages are installed and installs them if not 88 check_packages() { 89 if ! dpkg -s "$@" > /dev/null 2>&1; then 90 apt_get_update_if_needed 91 apt-get -y install --no-install-recommends "$@" 92 fi 93 } 94 95 # Ensure apt is in non-interactive to avoid prompts 96 export DEBIAN_FRONTEND=noninteractive 97 98 # Install dependencies 99 check_packages apt-transport-https curl ca-certificates pigz iptables gnupg2 dirmngr 100 if ! type git > /dev/null 2>&1; then 101 apt_get_update_if_needed 102 apt-get -y install git 103 fi 104 105 # Swap to legacy iptables for compatibility 106 if type iptables-legacy > /dev/null 2>&1; then 107 update-alternatives --set iptables /usr/sbin/iptables-legacy 108 update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy 109 fi 110 111 # Source /etc/os-release to get OS info 112 . /etc/os-release 113 # Fetch host/container arch. 114 architecture="$(dpkg --print-architecture)" 115 116 # Set up the necessary apt repos (either Microsoft's or Docker's) 117 if [ "${USE_MOBY}" = "true" ]; then 118 119 # Name of open source engine/cli 120 engine_package_name="moby-engine" 121 cli_package_name="moby-cli" 122 123 # Import key safely and import Microsoft apt repo 124 get_common_setting MICROSOFT_GPG_KEYS_URI 125 curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg 126 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 127 else 128 # Name of licensed engine/cli 129 engine_package_name="docker-ce" 130 cli_package_name="docker-ce-cli" 131 132 # Import key safely and import Docker apt repo 133 curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg 134 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 135 fi 136 137 # Refresh apt lists 138 apt-get update 139 140 # Soft version matching 141 if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then 142 # Empty, meaning grab whatever "latest" is in apt repo 143 engine_version_suffix="" 144 cli_version_suffix="" 145 else 146 # Fetch a valid version from the apt-cache (eg: the Microsoft repo appends +azure, breakfix, etc...) 147 docker_version_dot_escaped="${DOCKER_VERSION//./\\.}" 148 docker_version_dot_plus_escaped="${docker_version_dot_escaped//+/\\+}" 149 # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ 150 docker_version_regex="^(.+:)?${docker_version_dot_plus_escaped}([\\.\\+ ~:-]|$)" 151 set +e # Don't exit if finding version fails - will handle gracefully 152 cli_version_suffix="=$(apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" 153 engine_version_suffix="=$(apt-cache madison ${engine_package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${docker_version_regex}")" 154 set -e 155 if [ -z "${engine_version_suffix}" ] || [ "${engine_version_suffix}" = "=" ] || [ -z "${cli_version_suffix}" ] || [ "${cli_version_suffix}" = "=" ] ; then 156 echo "(!) No full or partial Docker / Moby version match found for \"${DOCKER_VERSION}\" on OS ${ID} ${VERSION_CODENAME} (${architecture}). Available versions:" 157 apt-cache madison ${cli_package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' 158 exit 1 159 fi 160 echo "engine_version_suffix ${engine_version_suffix}" 161 echo "cli_version_suffix ${cli_version_suffix}" 162 fi 163 164 # Install Docker / Moby CLI if not already installed 165 if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then 166 echo "Docker / Moby CLI and Engine already installed." 167 else 168 if [ "${USE_MOBY}" = "true" ]; then 169 apt-get -y install --no-install-recommends moby-cli${cli_version_suffix} moby-buildx moby-engine${engine_version_suffix} 170 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." 171 else 172 apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} docker-ce${engine_version_suffix} 173 fi 174 fi 175 176 echo "Finished installing docker / moby!" 177 178 ### Diff start 179 # Install Docker Compose if not already installed 180 if type docker-compose > /dev/null 2>&1; then 181 echo "Docker Compose already installed." 182 else 183 target_compose_arch="$(uname -m)" 184 case $target_compose_arch in 185 x86_64) target_compose_arch="x86_64";; 186 aarch64 | armv8*) target_compose_arch="aarch64";; 187 *) echo "(!) Architecture $target_compose_arch unsupported"; exit 1 ;; 188 esac 189 # Get the last version from the GitHub APIs 190 docker_dash_compose_version=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | jq -r ".tag_name") 191 echo "(*) Installing docker-compose ${docker_dash_compose_version}..." 192 curl -fsSL "${GITHUB_PROXY}https://github.com/docker/compose/releases/download/${docker_dash_compose_version}/docker-compose-linux-${target_compose_arch}" -o /usr/local/bin/docker-compose 193 chmod +x /usr/local/bin/docker-compose 194 fi 195 ### Diff end 196 197 # If init file already exists, exit 198 if [ -f "/usr/local/share/docker-init.sh" ]; then 199 echo "/usr/local/share/docker-init.sh already exists, so exiting." 200 exit 0 201 fi 202 echo "docker-init doesnt exist, adding..." 203 204 # Add user to the docker group 205 if [ "${ENABLE_NONROOT_DOCKER}" = "true" ]; then 206 if ! getent group docker > /dev/null 2>&1; then 207 groupadd docker 208 fi 209 210 usermod -aG docker ${USERNAME} 211 fi 212 213 tee /usr/local/share/docker-init.sh > /dev/null \ 214 << 'EOF' 215 #!/bin/sh 216 #------------------------------------------------------------------------------------------------------------- 217 # Copyright (c) Microsoft Corporation. All rights reserved. 218 # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. 219 #------------------------------------------------------------------------------------------------------------- 220 221 set -e 222 223 dockerd_start="$(cat << 'INNEREOF' 224 # explicitly remove dockerd and containerd PID file to ensure that it can start properly if it was stopped uncleanly 225 # ie: docker kill <ID> 226 find /run /var/run -iname 'docker*.pid' -delete || : 227 find /run /var/run -iname 'container*.pid' -delete || : 228 229 ## Dind wrapper script from docker team, adapted to a function 230 # Maintained: https://github.com/moby/moby/blob/master/hack/dind 231 232 export container=docker 233 234 if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security; then 235 mount -t securityfs none /sys/kernel/security || { 236 echo >&2 'Could not mount /sys/kernel/security.' 237 echo >&2 'AppArmor detection and --privileged mode might break.' 238 } 239 fi 240 241 # Mount /tmp (conditionally) 242 if ! mountpoint -q /tmp; then 243 mount -t tmpfs none /tmp 244 fi 245 246 # cgroup v2: enable nesting 247 if [ -f /sys/fs/cgroup/cgroup.controllers ]; then 248 # move the processes from the root group to the /init group, 249 # otherwise writing subtree_control fails with EBUSY. 250 # An error during moving non-existent process (i.e., "cat") is ignored. 251 mkdir -p /sys/fs/cgroup/init 252 xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : 253 # enable controllers 254 sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \ 255 > /sys/fs/cgroup/cgroup.subtree_control 256 fi 257 ## Dind wrapper over. 258 259 # Handle DNS 260 set +e 261 cat /etc/resolv.conf | grep -i 'internal.cloudapp.net' 262 if [ $? -eq 0 ] 263 then 264 echo "Setting dockerd Azure DNS." 265 CUSTOMDNS="--dns 168.63.129.16" 266 else 267 echo "Not setting dockerd DNS manually." 268 CUSTOMDNS="" 269 fi 270 set -e 271 272 # Start docker/moby engine 273 ( dockerd $CUSTOMDNS > /tmp/dockerd.log 2>&1 ) & 274 INNEREOF 275 )" 276 277 # Start using sudo if not invoked as root 278 if [ "$(id -u)" -ne 0 ]; then 279 sudo /bin/sh -c "${dockerd_start}" 280 else 281 eval "${dockerd_start}" 282 fi 283 284 set +e 285 286 # Execute whatever commands were passed in (if any). This allows us 287 # to set this script to ENTRYPOINT while still executing the default CMD. 288 exec "$@" 289 EOF 290 291 chmod +x /usr/local/share/docker-init.sh 292 chown ${USERNAME}:root /usr/local/share/docker-init.sh