77# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md
88# Maintainer: The Dev Container spec maintainers
99if [ -z " $BASH_VERSION " ]; then
10- echo " ❌ This script must be run with bash, not sh."
11- exit 1
10+ echo " ❌ This script must be run with bash, not sh."
11+ exit 1
1212fi
1313DOCKER_VERSION=" ${VERSION:- " latest" } " # The Docker/Moby Engine + CLI should match in version
1414USE_MOBY=" ${MOBY:- " true" } "
@@ -36,8 +36,8 @@ echo "(!) $*" >&2
3636}
3737
3838if [ " $( id -u) " -ne 0 ]; then
39- err ' Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
40- exit 1
39+ err ' Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
40+ exit 1
4141fi
4242
4343# ##################
4747
4848# Determine the appropriate non-root user
4949if [ " ${USERNAME} " = " auto" ] || [ " ${USERNAME} " = " automatic" ]; then
50- USERNAME=" "
51- POSSIBLE_USERS=(" vscode" " node" " codespace" " $( awk -v val=1000 -F " :" ' $3==val{print $1}' /etc/passwd) " )
52- for CURRENT_USER in " ${POSSIBLE_USERS[@]} " ; do
50+ USERNAME=" "
51+ POSSIBLE_USERS=(" vscode" " node" " codespace" " $( awk -v val=1000 -F " :" ' $3==val{print $1}' /etc/passwd) " )
52+ for CURRENT_USER in " ${POSSIBLE_USERS[@]} " ; do
5353if id -u ${CURRENT_USER} > /dev/null 2>&1 ; then
54- USERNAME=${CURRENT_USER}
55- break
54+ USERNAME=${CURRENT_USER}
55+ break
5656fi
5757done
5858if [ " ${USERNAME} " = " " ]; then
@@ -66,145 +66,144 @@ apt_get_update()
6666{
6767. /etc/os-release
6868if [ " $ID " = " ubuntu" ] || [ " $ID " = " debian" ]; then
69- if [ " $( find /var/lib/apt/lists/* | wc -l) " = " 0" ]; then
70- echo " Running apt-get update..."
71- apt-get update -y
72- fi
69+ if [ " $( find /var/lib/apt/lists/* | wc -l) " = " 0" ]; then
70+ echo " Running apt-get update..."
71+ apt-get update -y
72+ fi
7373fi
7474}
7575
7676# Checks if packages are installed and installs them if not
7777check_packages () {
7878
7979if [ " $ID " = " ubuntu" ] || [ " $ID " = " debian" ] || [ " $ID_LIKE " = " debian" ]; then
80- if ! dpkg -s " $@ " > /dev/null 2>&1 ; then
81- apt_get_update
82- apt-get -y install --no-install-recommends " $@ "
83- fi
80+ if ! dpkg -s " $@ " > /dev/null 2>&1 ; then
81+ apt_get_update
82+ apt-get -y install --no-install-recommends " $@ "
83+ fi
8484elif [ " $ID " = " fedora" ] || [ " $ID " = " centos" ] || [ " $ID_LIKE " == " rhel" ]; then
85- if ! dnf list installed " $@ " > /dev/null 2>&1 ; then
86- dnf -y install " $@ "
87- fi
85+ if ! dnf list installed " $@ " > /dev/null 2>&1 ; then
86+ dnf -y install " $@ "
87+ fi
8888fi
8989
9090}
9191missing=0
9292for cmd in git wget which; do
93- command -v $cmd & > /dev/null || {
94- echo " $cmd not found"
95- missing=1
96- }
93+ command -v $cmd & > /dev/null || {
94+ echo " $cmd not found"
95+ missing=1
96+ }
9797done
9898
9999if [ $missing -eq 1 ]; then
100- echo " Installing missing packages..."
101- if command -v dnf & > /dev/null; then
102- dnf install -y git wget which curl jq
103- elif command -v apt & > /dev/null; then
104- apt-get update && apt-get install -y git wget curl jq
105- else
106- echo " Unsupported package manager"
107- exit 1
108- fi
100+ echo " Installing missing packages..."
101+ if command -v dnf & > /dev/null; then
102+ dnf install -y git wget which curl jq
103+ elif command -v apt & > /dev/null; then
104+ apt-get update && apt-get install -y git wget curl jq
105+ else
106+ echo " Unsupported package manager"
107+ exit 1
108+ fi
109109fi
110110
111111
112112# Figure out correct version of a three part version number is not passed
113113find_version_from_git_tags () {
114- local variable_name=$1
115- local requested_version=${! variable_name}
116- if [ " ${requested_version} " = " none" ]; then return ; fi
117- local repository=$2
118- local prefix=${3:- " tags/v" }
119- local separator=${4:- " ." }
120- local last_part_optional=${5:- " false" }
121- if [ " $( echo " ${requested_version} " | grep -o " ." | wc -l) " != " 2" ]; then
122- local escaped_separator=${separator// ./ \\ .}
123- local last_part
124- if [ " ${last_part_optional} " = " true" ]; then
125- last_part=" (${escaped_separator} [0-9]+)?"
126- else
127- last_part=" ${escaped_separator} [0-9]+"
128- fi
129- local regex=" ${prefix} \\ K[0-9]+${escaped_separator} [0-9]+${last_part} $"
130- local version_list=" $( git ls-remote --tags ${repository} | grep -oP " ${regex} " | tr -d ' ' | tr " ${separator} " " ." | sort -rV) "
131- if [ " ${requested_version} " = " latest" ] || [ " ${requested_version} " = " current" ] || [ " ${requested_version} " = " lts" ]; then
132- declare -g ${variable_name} =" $( echo " ${version_list} " | head -n 1) "
133- else
134- set +e
135- declare -g ${variable_name} =" $( echo " ${version_list} " | grep -E -m 1 " ^${requested_version// ./ \\ .} ([\\ .\\ s]|$)" ) "
136- set -e
137- fi
138- fi
139- if [ -z " ${! variable_name} " ] || ! echo " ${version_list} " | grep " ^${! variable_name// ./ \\ .} $" > /dev/null 2>&1 ; then
140- err " Invalid ${variable_name} value: ${requested_version} \nValid values:\n${version_list} " >&2
141- exit 1
142- fi
143- echo " ${variable_name} =${! variable_name} "
114+ local variable_name=$1
115+ local requested_version=${! variable_name}
116+ if [ " ${requested_version} " = " none" ]; then return ; fi
117+ local repository=$2
118+ local prefix=${3:- " tags/v" }
119+ local separator=${4:- " ." }
120+ local last_part_optional=${5:- " false" }
121+ if [ " $( echo " ${requested_version} " | grep -o " ." | wc -l) " != " 2" ]; then
122+ local escaped_separator=${separator// ./ \\ .}
123+ local last_part
124+ if [ " ${last_part_optional} " = " true" ]; then
125+ last_part=" (${escaped_separator} [0-9]+)?"
126+ else
127+ last_part=" ${escaped_separator} [0-9]+"
128+ fi
129+ local regex=" ${prefix} \\ K[0-9]+${escaped_separator} [0-9]+${last_part} $"
130+ local version_list=" $( git ls-remote --tags ${repository} | grep -oP " ${regex} " | tr -d ' ' | tr " ${separator} " " ." | sort -rV) "
131+ if [ " ${requested_version} " = " latest" ] || [ " ${requested_version} " = " current" ] || [ " ${requested_version} " = " lts" ]; then
132+ declare -g ${variable_name} =" $( echo " ${version_list} " | head -n 1) "
133+ else
134+ set +e
135+ declare -g ${variable_name} =" $( echo " ${version_list} " | grep -E -m 1 " ^${requested_version// ./ \\ .} ([\\ .\\ s]|$)" ) "
136+ set -e
137+ fi
138+ fi
139+ if [ -z " ${! variable_name} " ] || ! echo " ${version_list} " | grep " ^${! variable_name// ./ \\ .} $" > /dev/null 2>&1 ; then
140+ err " Invalid ${variable_name} value: ${requested_version} \nValid values:\n${version_list} " >&2
141+ exit 1
142+ fi
143+ echo " ${variable_name} =${! variable_name} "
144144}
145145
146146# Use semver logic to decrement a version number then look for the closest match
147147find_prev_version_from_git_tags () {
148- local variable_name=$1
149- local current_version=${! variable_name}
150- local repository=$2
151- # Normally a "v" is used before the version number, but support alternate cases
152- local prefix=${3:- " tags/v" }
153- # Some repositories use "_" instead of "." for version number part separation, support that
154- local separator=${4:- " ." }
155- # Some tools release versions that omit the last digit (e.g. go)
156- local last_part_optional=${5:- " false" }
157- # Some repositories may have tags that include a suffix (e.g. actions/node-versions)
158- local version_suffix_regex=$6
159- # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios.
160- set +e
161- major=" $( echo " ${current_version} " | grep -oE ' ^[0-9]+' || echo ' ' ) "
162- minor=" $( echo " ${current_version} " | grep -oP ' ^[0-9]+\.\K[0-9]+' || echo ' ' ) "
163- breakfix=" $( echo " ${current_version} " | grep -oP ' ^[0-9]+\.[0-9]+\.\K[0-9]+' 2> /dev/null || echo ' ' ) "
164-
165- if [ " ${minor} " = " 0" ] && [ " ${breakfix} " = " 0" ]; then
166- (( major= major- 1 ))
167- declare -g ${variable_name} =" ${major} "
168- # Look for latest version from previous major release
169- find_version_from_git_tags " ${variable_name} " " ${repository} " " ${prefix} " " ${separator} " " ${last_part_optional} "
170- # Handle situations like Go's odd version pattern where "0" releases omit the last part
171- elif [ " ${breakfix} " = " " ] || [ " ${breakfix} " = " 0" ]; then
172- (( minor= minor- 1 ))
173- declare -g ${variable_name} =" ${major} .${minor} "
174- # Look for latest version from previous minor release
175- find_version_from_git_tags " ${variable_name} " " ${repository} " " ${prefix} " " ${separator} " " ${last_part_optional} "
176- else
177- (( breakfix= breakfix- 1 ))
178- if [ " ${breakfix} " = " 0" ] && [ " ${last_part_optional} " = " true" ]; then
179- declare -g ${variable_name} =" ${major} .${minor} "
180- else
181- declare -g ${variable_name} =" ${major} .${minor} .${breakfix} "
182- fi
183- fi
184- set -e
148+ local variable_name=$1
149+ local current_version=${! variable_name}
150+ local repository=$2
151+ # Normally a "v" is used before the version number, but support alternate cases
152+ local prefix=${3:- " tags/v" }
153+ # Some repositories use "_" instead of "." for version number part separation, support that
154+ local separator=${4:- " ." }
155+ # Some tools release versions that omit the last digit (e.g. go)
156+ local last_part_optional=${5:- " false" }
157+ # Some repositories may have tags that include a suffix (e.g. actions/node-versions)
158+ local version_suffix_regex=$6
159+ # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios.
160+ set +e
161+ major=" $( echo " ${current_version} " | grep -oE ' ^[0-9]+' || echo ' ' ) "
162+ minor=" $( echo " ${current_version} " | grep -oP ' ^[0-9]+\.\K[0-9]+' || echo ' ' ) "
163+ breakfix=" $( echo " ${current_version} " | grep -oP ' ^[0-9]+\.[0-9]+\.\K[0-9]+' 2> /dev/null || echo ' ' ) "
164+
165+ if [ " ${minor} " = " 0" ] && [ " ${breakfix} " = " 0" ]; then
166+ (( major= major- 1 ))
167+ declare -g ${variable_name} =" ${major} "
168+ # Look for latest version from previous major release
169+ find_version_from_git_tags " ${variable_name} " " ${repository} " " ${prefix} " " ${separator} " " ${last_part_optional} "
170+ # Handle situations like Go's odd version pattern where "0" releases omit the last part
171+ elif [ " ${breakfix} " = " " ] || [ " ${breakfix} " = " 0" ]; then
172+ (( minor= minor- 1 ))
173+ declare -g ${variable_name} =" ${major} .${minor} "
174+ # Look for latest version from previous minor release
175+ find_version_from_git_tags " ${variable_name} " " ${repository} " " ${prefix} " " ${separator} " " ${last_part_optional} "
176+ else
177+ (( breakfix= breakfix- 1 ))
178+ if [ " ${breakfix} " = " 0" ] && [ " ${last_part_optional} " = " true" ]; then
179+ declare -g ${variable_name} =" ${major} .${minor} "
180+ else
181+ declare -g ${variable_name} =" ${major} .${minor} .${breakfix} "
182+ fi
183+ fi
184+ set -e
185185}
186186
187187# Function to fetch the version released prior to the latest version
188188get_previous_version () {
189- local url=$1
190- local repo_url=$2
191- local variable_name=$3
192- prev_version=${! variable_name}
193-
194- output=$( curl -s " $repo_url " ) ;
189+ local url=$1
190+ local repo_url=$2
191+ local variable_name=$3
192+ prev_version=${! variable_name}
193+ output=$( curl -s " $repo_url " ) ;
195194if echo " $output " | jq -e ' type == "object"' > /dev/null; then
196- message=$( echo " $output " | jq -r ' .message' )
195+ message=$( echo " $output " | jq -r ' .message' )
197196
198197if [[ $message == " API rate limit exceeded" * ]]; then
199- echo -e " \nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message} "
200- echo -e " \nAttempting to find latest version using GitHub tags."
201- find_prev_version_from_git_tags prev_version " $url " " tags/v"
202- declare -g ${variable_name} =" ${prev_version} "
198+ echo -e " \nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message} "
199+ echo -e " \nAttempting to find latest version using GitHub tags."
200+ find_prev_version_from_git_tags prev_version " $url " " tags/v"
201+ declare -g ${variable_name} =" ${prev_version} "
203202fi
204203elif echo " $output " | jq -e ' type == "array"' > /dev/null; then
205- echo -e " \nAttempting to find latest version using GitHub Api."
206- version=$( echo " $output " | jq -r ' .[1].tag_name' )
207- declare -g ${variable_name} =" ${version# v} "
204+ echo -e " \nAttempting to find latest version using GitHub Api."
205+ version=$( echo " $output " | jq -r ' .[1].tag_name' )
206+ declare -g ${variable_name} =" ${version# v} "
208207fi
209208echo " ${variable_name} =${! variable_name} "
210209}
@@ -226,20 +225,19 @@ export DEBIAN_FRONTEND=noninteractive
226225. /etc/os-release
227226# Fetch host/container architecture
228227if [ " $ID " = " ubuntu" ] || [ " $ID " = " debian" ]; then
229- architecture=" $( dpkg --print-architecture) "
228+ architecture=" $( dpkg --print-architecture) "
230229elif [ " $ID " = " fedora" ] || [ " $ID_LIKE " = " rhel" ]; then
231- architecture=" $( uname -m) "
232- case " $architecture " in
233- x86_64) architecture=" amd64" ;;
234- aarch64) architecture=" arm64" ;;
235- * ) echo " Unsupported architecture: $architecture " ; exit 1 ;;
236- esac
230+ architecture=" $( uname -m) "
231+ case " $architecture " in
232+ x86_64) architecture=" amd64" ;;
233+ aarch64) architecture=" arm64" ;;
234+ * ) echo " Unsupported architecture: $architecture " ; exit 1 ;;
235+ esac
237236else
238- echo " Unsupported operating system: $ID "
239- exit 1
237+ echo " Unsupported operating system: $ID "
238+ exit 1
240239fi
241240
242-
243241# Check if distro is supported
244242if [ " ${USE_MOBY} " = " true" ]; then
245243 if [[ " ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES} " != * " ${VERSION_CODENAME} " * ]]; then
0 commit comments