Skip to content

Commit

Permalink
Resolve slow key retrieval when some GPG key servers are not reachable (
Browse files Browse the repository at this point in the history
#1016)

* Reduce timeout to GPG key servers for Python feature

* Dynamically find out reachable GPG servers

* Apply fix to other features

* Fix build issues

* Fix shellcheck SC2068 by quoting array expansion

* Bump up patch version for affected features

* improve readability for keyservers_curl_map
  • Loading branch information
h3xcat authored Jul 17, 2024
1 parent 09d5632 commit f455189
Show file tree
Hide file tree
Showing 16 changed files with 354 additions and 50 deletions.
2 changes: 1 addition & 1 deletion src/git-lfs/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "git-lfs",
"version": "1.2.1",
"version": "1.2.2",
"name": "Git Large File Support (LFS)",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/git-lfs",
"description": "Installs Git Large File Support (Git LFS) along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like git and curl.",
Expand Down
43 changes: 38 additions & 5 deletions src/git-lfs/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ GIT_LFS_ARCHIVE_GPG_KEY_URI="https://packagecloud.io/github/git-lfs/gpgkey"
GIT_LFS_ARCHIVE_ARCHITECTURES="amd64 arm64"
GIT_LFS_ARCHIVE_VERSION_CODENAMES="stretch buster bullseye bionic focal jammy"
GIT_LFS_CHECKSUM_GPG_KEYS="0x88ace9b29196305ba9947552f1ba225c0223b187 0x86cd3297749375bcf8206715f54fe648088335a9 0xaa3b3450295830d2de6db90caba67be5a5795889"
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
keyserver hkp://keyserver.ubuntu.com:80
keyserver hkps://keys.openpgp.org
keyserver hkp://keyserver.pgp.com"

set -e

Expand Down Expand Up @@ -64,15 +60,52 @@ find_version_from_git_tags() {
echo "${variable_name}=${!variable_name}"
}

# Get the list of GPG key servers that are reachable
get_gpg_key_servers() {
declare -A keyservers_curl_map=(
["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371"
["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com"
["hkps://keys.openpgp.org"]="https://keys.openpgp.org"
["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371"
)

local curl_args=""
local keyserver_reachable=false # Flag to indicate if any keyserver is reachable

if [ ! -z "${KEYSERVER_PROXY}" ]; then
curl_args="--proxy ${KEYSERVER_PROXY}"
fi

for keyserver in "${!keyservers_curl_map[@]}"; do
local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}"
if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then
echo "keyserver ${keyserver}"
keyserver_reachable=true
else
echo "(*) Keyserver ${keyserver} is not reachable." >&2
fi
done

if ! $keyserver_reachable; then
echo "(!) No keyserver is reachable." >&2
exit 1
fi
}

# Import the specified key in a variable name passed in as
receive_gpg_keys() {
local keys=${!1}

# Install curl
if ! type curl > /dev/null 2>&1; then
check_packages curl
fi

# Use a temporary location for gpg keys to avoid polluting image
export GNUPGHOME="/tmp/tmp-gnupg"
mkdir -p ${GNUPGHOME}
chmod 700 ${GNUPGHOME}
echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf
echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf
# GPG key download sometimes fails for some reason and retrying fixes it.
local retry_count=0
local gpg_ok="false"
Expand Down
2 changes: 1 addition & 1 deletion src/git/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "git",
"version": "1.3.0",
"version": "1.3.1",
"name": "Git (from source)",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/git",
"description": "Install an up-to-date version of Git, built from source as needed. Useful for when you want the latest and greatest features. Auto-detects latest stable version and installs needed dependencies.",
Expand Down
43 changes: 38 additions & 5 deletions src/git/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ GIT_VERSION=${VERSION} # 'system' checks the base image first, else installs 'la
USE_PPA_IF_AVAILABLE=${PPA}

GIT_CORE_PPA_ARCHIVE_GPG_KEY=E1DD270288B4E6030699E45FA1715D88E1DF1F24
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
keyserver hkp://keyserver.ubuntu.com:80
keyserver hkps://keys.openpgp.org
keyserver hkp://keyserver.pgp.com"

if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
Expand Down Expand Up @@ -68,6 +64,38 @@ clean_up() {
}
clean_up

# Get the list of GPG key servers that are reachable
get_gpg_key_servers() {
declare -A keyservers_curl_map=(
["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371"
["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com"
["hkps://keys.openpgp.org"]="https://keys.openpgp.org"
["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371"
)

local curl_args=""
local keyserver_reachable=false # Flag to indicate if any keyserver is reachable

if [ ! -z "${KEYSERVER_PROXY}" ]; then
curl_args="--proxy ${KEYSERVER_PROXY}"
fi

for keyserver in "${!keyservers_curl_map[@]}"; do
local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}"
if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then
echo "keyserver ${keyserver}"
keyserver_reachable=true
else
echo "(*) Keyserver ${keyserver} is not reachable." >&2
fi
done

if ! $keyserver_reachable; then
echo "(!) No keyserver is reachable." >&2
exit 1
fi
}

# Import the specified key in a variable name passed in as
receive_gpg_keys() {
local keys=${!1}
Expand All @@ -77,11 +105,16 @@ receive_gpg_keys() {
keyring_args="--no-default-keyring --keyring $2"
fi

# Install curl
if ! type curl > /dev/null 2>&1; then
check_packages curl
fi

# Use a temporary location for gpg keys to avoid polluting image
export GNUPGHOME="/tmp/tmp-gnupg"
mkdir -p ${GNUPGHOME}
chmod 700 ${GNUPGHOME}
echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf
echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf
# GPG key download sometimes fails for some reason and retrying fixes it.
local retry_count=0
local gpg_ok="false"
Expand Down
2 changes: 1 addition & 1 deletion src/github-cli/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "github-cli",
"version": "1.0.12",
"version": "1.0.13",
"name": "GitHub CLI",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/github-cli",
"description": "Installs the GitHub CLI. Auto-detects latest version and installs needed dependencies.",
Expand Down
42 changes: 37 additions & 5 deletions src/github-cli/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ CLI_VERSION=${VERSION:-"latest"}
INSTALL_DIRECTLY_FROM_GITHUB_RELEASE=${INSTALLDIRECTLYFROMGITHUBRELEASE:-"true"}

GITHUB_CLI_ARCHIVE_GPG_KEY=23F3D4EA75716059
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
keyserver hkp://keyserver.ubuntu.com:80
keyserver hkps://keys.openpgp.org
keyserver hkp://keyserver.pgp.com"

set -e

Expand All @@ -26,6 +22,37 @@ if [ "$(id -u)" -ne 0 ]; then
exit 1
fi

# Get the list of GPG key servers that are reachable
get_gpg_key_servers() {
declare -A keyservers_curl_map=(
["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371"
["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com"
["hkps://keys.openpgp.org"]="https://keys.openpgp.org"
["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371"
)

local curl_args=""
local keyserver_reachable=false # Flag to indicate if any keyserver is reachable

if [ ! -z "${KEYSERVER_PROXY}" ]; then
curl_args="--proxy ${KEYSERVER_PROXY}"
fi

for keyserver in "${!keyservers_curl_map[@]}"; do
local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}"
if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then
echo "keyserver ${keyserver}"
keyserver_reachable=true
else
echo "(*) Keyserver ${keyserver} is not reachable." >&2
fi
done

if ! $keyserver_reachable; then
echo "(!) No keyserver is reachable." >&2
exit 1
fi
}

# Import the specified key in a variable name passed in as
receive_gpg_keys() {
Expand All @@ -35,11 +62,16 @@ receive_gpg_keys() {
keyring_args="--no-default-keyring --keyring $2"
fi

# Install curl
if ! type curl > /dev/null 2>&1; then
check_packages curl
fi

# Use a temporary location for gpg keys to avoid polluting image
export GNUPGHOME="/tmp/tmp-gnupg"
mkdir -p ${GNUPGHOME}
chmod 700 ${GNUPGHOME}
echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf
echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf
# GPG key download sometimes fails for some reason and retrying fixes it.
local retry_count=0
local gpg_ok="false"
Expand Down
2 changes: 1 addition & 1 deletion src/kubectl-helm-minikube/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "kubectl-helm-minikube",
"version": "1.1.9",
"version": "1.1.10",
"name": "Kubectl, Helm, and Minikube",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/kubectl-helm-minikube",
"description": "Installs latest version of kubectl, Helm, and optionally minikube. Auto-detects latest versions and installs needed dependencies.",
Expand Down
38 changes: 33 additions & 5 deletions src/kubectl-helm-minikube/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,6 @@ MINIKUBE_SHA256="${MINIKUBE_SHA256:-"automatic"}"
USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}"

HELM_GPG_KEYS_URI="https://raw.githubusercontent.com/helm/helm/main/KEYS"
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
keyserver hkp://keyserver.ubuntu.com:80
keyserver hkps://keys.openpgp.org
keyserver hkp://keyserver.pgp.com"

if [ "$(id -u)" -ne 0 ]; then
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
Expand Down Expand Up @@ -234,6 +230,38 @@ get_helm() {
curl -sSL "https://github.com/helm/helm/releases/download/${HELM_VERSION}/${helm_filename}.asc" -o "${tmp_helm_filename}.asc"
}

# Get the list of GPG key servers that are reachable
get_gpg_key_servers() {
declare -A keyservers_curl_map=(
["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371"
["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com"
["hkps://keys.openpgp.org"]="https://keys.openpgp.org"
["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371"
)

local curl_args=""
local keyserver_reachable=false # Flag to indicate if any keyserver is reachable

if [ ! -z "${KEYSERVER_PROXY}" ]; then
curl_args="--proxy ${KEYSERVER_PROXY}"
fi

for keyserver in "${!keyservers_curl_map[@]}"; do
local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}"
if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then
echo "keyserver ${keyserver}"
keyserver_reachable=true
else
echo "(*) Keyserver ${keyserver} is not reachable." >&2
fi
done

if ! $keyserver_reachable; then
echo "(!) No keyserver is reachable." >&2
exit 1
fi
}

if [ ${HELM_VERSION} != "none" ]; then
# Install Helm, verify signature and checksum
echo "Downloading Helm..."
Expand All @@ -255,7 +283,7 @@ if [ ${HELM_VERSION} != "none" ]; then
mkdir -p "${GNUPGHOME}"
chmod 700 ${GNUPGHOME}
curl -sSL "${HELM_GPG_KEYS_URI}" -o /tmp/helm/KEYS
echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf
echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf
gpg -q --import "/tmp/helm/KEYS"
if ! gpg --verify "${tmp_helm_filename}.asc" > ${GNUPGHOME}/verify.log 2>&1; then
echo "Verification failed!"
Expand Down
2 changes: 1 addition & 1 deletion src/python/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "python",
"version": "1.6.2",
"version": "1.6.3",
"name": "Python",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/python",
"description": "Installs the provided version of Python, as well as PIPX, and other common Python utilities. JupyterLab is conditionally installed with the python feature. Note: May require source code compilation.",
Expand Down
51 changes: 44 additions & 7 deletions src/python/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,7 @@ ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}"
# Comma-separated list of additional tools to be installed via pipx.
IFS="," read -r -a DEFAULT_UTILS <<< "${TOOLSTOINSTALL:-flake8,autopep8,black,yapf,mypy,pydocstyle,pycodestyle,bandit,pipenv,virtualenv,pytest}"


PYTHON_SOURCE_GPG_KEYS="64E628F8D684696D B26995E310250568 2D347EA6AA65421D FB9921286F5E1540 3A5CA953F73C700D 04C367C218ADD4FF 0EDDC5F26A45C816 6AF053F07D9DC8D2 C9BE28DEE6DF025C 126EB563A74B06BF D9866941EA5BBD71 ED9D77D5 A821E680E5FA6305"
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
keyserver hkp://keyserver.ubuntu.com:80
keyserver hkps://keys.openpgp.org
keyserver hkp://keyserver.pgp.com"

KEYSERVER_PROXY="${HTTPPROXY:-"${HTTP_PROXY:-""}"}"

Expand Down Expand Up @@ -130,6 +125,38 @@ updaterc() {
fi
}

# Get the list of GPG key servers that are reachable
get_gpg_key_servers() {
declare -A keyservers_curl_map=(
["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371"
["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com"
["hkps://keys.openpgp.org"]="https://keys.openpgp.org"
["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371"
)

local curl_args=""
local keyserver_reachable=false # Flag to indicate if any keyserver is reachable

if [ ! -z "${KEYSERVER_PROXY}" ]; then
curl_args="--proxy ${KEYSERVER_PROXY}"
fi

for keyserver in "${!keyservers_curl_map[@]}"; do
local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}"
if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then
echo "keyserver ${keyserver}"
keyserver_reachable=true
else
echo "(*) Keyserver ${keyserver} is not reachable." >&2
fi
done

if ! $keyserver_reachable; then
echo "(!) No keyserver is reachable." >&2
exit 1
fi
}

# Import the specified key in a variable name passed in as
receive_gpg_keys() {
local keys=${!1}
Expand All @@ -143,11 +170,16 @@ receive_gpg_keys() {
keyring_args="${keyring_args} --keyserver-options http-proxy=${KEYSERVER_PROXY}"
fi

# Install curl
if ! type curl > /dev/null 2>&1; then
check_packages curl
fi

# Use a temporary location for gpg keys to avoid polluting image
export GNUPGHOME="/tmp/tmp-gnupg"
mkdir -p ${GNUPGHOME}
chmod 700 ${GNUPGHOME}
echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf
echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf
# GPG key download sometimes fails for some reason and retrying fixes it.
local retry_count=0
local gpg_ok="false"
Expand Down Expand Up @@ -182,6 +214,11 @@ receive_gpg_keys_centos7() {
keyring_args="${keyring_args} --keyserver-options http-proxy=${KEYSERVER_PROXY}"
fi

# Install curl
if ! type curl > /dev/null 2>&1; then
check_packages curl
fi

# Use a temporary location for gpg keys to avoid polluting image
export GNUPGHOME="/tmp/tmp-gnupg"
mkdir -p ${GNUPGHOME}
Expand All @@ -193,7 +230,7 @@ receive_gpg_keys_centos7() {
set +e
echo "(*) Downloading GPG keys..."
until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; do
for keyserver in $(echo "${GPG_KEY_SERVERS}" | sed 's/keyserver //'); do
for keyserver in $(echo "$(get_gpg_key_servers)" | sed 's/keyserver //'); do
( echo "${keys}" | xargs -n 1 gpg -q ${keyring_args} --recv-keys --keyserver=${keyserver} ) 2>&1
downloaded_keys=$(gpg --list-keys | grep ^pub | wc -l)
if [[ ${num_keys} = ${downloaded_keys} ]]; then
Expand Down
2 changes: 1 addition & 1 deletion src/ruby/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "ruby",
"version": "1.2.2",
"version": "1.2.3",
"name": "Ruby (via rvm)",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/ruby",
"description": "Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies.",
Expand Down
Loading

0 comments on commit f455189

Please sign in to comment.