Skip to content

Commit 1f614b1

Browse files
authored
Merge branch 'main' into revert-autopep8
2 parents 38564f3 + 31f99a0 commit 1f614b1

File tree

8 files changed

+246
-35
lines changed

8 files changed

+246
-35
lines changed

src/azure-cli/devcontainer-feature.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"id": "azure-cli",
3-
"version": "1.2.8",
3+
"version": "1.2.9",
44
"name": "Azure CLI",
55
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/azure-cli",
66
"description": "Installs the Azure CLI along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.",

src/azure-cli/install.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,15 @@ install_using_apt() {
9898
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
9999
curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
100100
echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/azure-cli/ ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/azure-cli.list
101-
apt-get update
101+
102+
# This is a workaround for the fact that Azure CLI is not yet a supported package for debian trixie. Once Azure CLI is supported we should revert to avoid script failure for non Azure CLI packages
103+
if ! (apt-get update); then
104+
echo "(!) Failed to update apt cache, removing repository file"
105+
rm -f /etc/apt/sources.list.d/azure-cli.list
106+
else
107+
echo "WARNING: apt-get update succeeded. The workaround for broken Azure CLI install on Debian Trixie may no longer be needed."
108+
echo "TODO: Consider reverting to a simple `apt-get update` if the Azure CLI repo works reliably for debian trixie"
109+
fi
102110

103111
if [ "${AZ_VERSION}" = "latest" ] || [ "${AZ_VERSION}" = "lts" ] || [ "${AZ_VERSION}" = "stable" ]; then
104112
# Empty, meaning grab the "latest" in the apt repo
@@ -135,7 +143,7 @@ install_using_pip_strategy() {
135143

136144
install_with_pipx() {
137145
echo "(*) Attempting to install globally with pipx..."
138-
local ver="$1"
146+
local ver="$1"
139147
export
140148
local
141149

src/common-utils/devcontainer-feature.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"id": "common-utils",
3-
"version": "2.5.4",
3+
"version": "2.5.5",
44
"name": "Common Utilities",
55
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/common-utils",
66
"description": "Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-root user.",
@@ -64,6 +64,11 @@
6464
"type": "boolean",
6565
"default": false,
6666
"description": "Add packages from non-free Debian repository? (Debian only)"
67+
},
68+
"installSsl": {
69+
"type": "boolean",
70+
"default": true,
71+
"description": "Install SSL?"
6772
}
6873
}
6974
}

src/common-utils/install.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ USERNAME="${USERNAME:-"automatic"}"
1818
USER_UID="${UID:-"automatic"}"
1919
USER_GID="${GID:-"automatic"}"
2020
ADD_NON_FREE_PACKAGES="${NONFREEPACKAGES:-"false"}"
21+
INSTALL_SSL="${INSTALLSSL:-"true"}"
2122

2223
MARKER_FILE="/usr/local/etc/vscode-dev-containers/common"
2324

src/common-utils/main.sh

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ USERNAME="${USERNAME:-"automatic"}"
1818
USER_UID="${USERUID:-"automatic"}"
1919
USER_GID="${USERGID:-"automatic"}"
2020
ADD_NON_FREE_PACKAGES="${NONFREEPACKAGES:-"false"}"
21+
INSTALL_SSL="${INSTALLSSL:-"true"}"
2122

2223
MARKER_FILE="/usr/local/etc/vscode-dev-containers/common"
2324

@@ -75,25 +76,27 @@ install_debian_packages() {
7576
manpages-dev \
7677
init-system-helpers"
7778

78-
# Include libssl1.1 if available
79-
if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then
80-
package_list="${package_list} libssl1.1"
81-
fi
79+
if [ "${INSTALL_SSL}" = "true" ]; then
80+
# Include libssl1.1 if available
81+
if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then
82+
package_list="${package_list} libssl1.1"
83+
fi
8284

83-
# Include libssl3 if available
84-
if [[ ! -z $(apt-cache --names-only search ^libssl3$) ]]; then
85-
package_list="${package_list} libssl3"
86-
fi
85+
# Include libssl3 if available
86+
if [[ ! -z $(apt-cache --names-only search ^libssl3$) ]]; then
87+
package_list="${package_list} libssl3"
88+
fi
8789

88-
# Include appropriate version of libssl1.0.x if available
89-
local libssl_package=$(dpkg-query -f '${db:Status-Abbrev}\t${binary:Package}\n' -W 'libssl1\.0\.?' 2>&1 || echo '')
90-
if [ "$(echo "$libssl_package" | grep -o 'libssl1\.0\.[0-9]:' | uniq | sort | wc -l)" -eq 0 ]; then
91-
if [[ ! -z $(apt-cache --names-only search ^libssl1.0.2$) ]]; then
92-
# Debian 9
93-
package_list="${package_list} libssl1.0.2"
94-
elif [[ ! -z $(apt-cache --names-only search ^libssl1.0.0$) ]]; then
95-
# Ubuntu 18.04
96-
package_list="${package_list} libssl1.0.0"
90+
# Include appropriate version of libssl1.0.x if available
91+
local libssl_package=$(dpkg-query -f '${db:Status-Abbrev}\t${binary:Package}\n' -W 'libssl1\.0\.?' 2>&1 || echo '')
92+
if [ "$(echo "$libssl_package" | grep -o 'libssl1\.0\.[0-9]:' | uniq | sort | wc -l)" -eq 0 ]; then
93+
if [[ ! -z $(apt-cache --names-only search ^libssl1.0.2$) ]]; then
94+
# Debian 9
95+
package_list="${package_list} libssl1.0.2"
96+
elif [[ ! -z $(apt-cache --names-only search ^libssl1.0.0$) ]]; then
97+
# Ubuntu 18.04
98+
package_list="${package_list} libssl1.0.0"
99+
fi
97100
fi
98101
fi
99102

@@ -172,7 +175,7 @@ install_redhat_packages() {
172175
else
173176
echo "Unable to find 'tdnf', 'dnf', or 'yum' package manager. Exiting."
174177
exit 1
175-
fi
178+
fi
176179

177180
if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then
178181
package_list="${package_list} \
@@ -228,7 +231,7 @@ fi
228231
fi
229232

230233
# Install EPEL repository if needed (required to install 'jq' for CentOS)
231-
if ! ${install_cmd} -q list jq >/dev/null 2>&1; then
234+
if [[ "${ID}" = "centos" ]] && ! rpm -q jq >/dev/null 2>&1; then
232235
${install_cmd} -y install epel-release
233236
remove_epel="true"
234237
fi
@@ -240,11 +243,18 @@ fi
240243
fi
241244

242245
if [ -n "${package_list}" ]; then
243-
${install_cmd} -y install ${package_list}
246+
echo "Packages to verify are installed: ${package_list}"
247+
echo "Running ${install_cmd} install..."
248+
if [ "${install_cmd}" = "dnf" ]; then
249+
${install_cmd} -y install --allowerasing ${package_list}
250+
else
251+
${install_cmd} -y install ${package_list}
252+
fi
244253
fi
245254

246255
# Get to latest versions of all packages
247256
if [ "${UPGRADE_PACKAGES}" = "true" ]; then
257+
echo "Running ${install_cmd} upgrade..."
248258
${install_cmd} upgrade -y
249259
fi
250260

src/python/install.sh

Lines changed: 167 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then
6969
fi
7070

7171
# To find some devel packages, some rhel need to enable specific extra repos, but not on RedHat ubi images...
72-
INSTALL_CMD_ADDL_REPO=""
72+
INSTALL_CMD_ADDL_REPOS=""
7373
if [ ${ADJUSTED_ID} = "rhel" ] && [ ${ID} != "rhel" ]; then
7474
if [ ${MAJOR_VERSION_ID} = "8" ]; then
7575
INSTALL_CMD_ADDL_REPOS="--enablerepo powertools"
@@ -93,6 +93,27 @@ else
9393
INSTALL_CMD="${PKG_MGR_CMD} ${INSTALL_CMD_ADDL_REPOS} -y install --noplugins --setopt=install_weak_deps=0"
9494
fi
9595

96+
# Install Time::Piece Perl module required by OpenSSL 3.0.18+ build system on CentOS 7/RHEL 7
97+
install_time_piece() {
98+
echo "(*) Ensuring Time::Piece Perl module is available for OpenSSL 3.0.18+ build..."
99+
100+
# Check if Time::Piece is already available (it's usually in Perl core)
101+
if perl -MTime::Piece -e 'exit 0' 2>/dev/null; then
102+
echo "(*) Time::Piece already available"
103+
return 0
104+
fi
105+
106+
echo "(*) Time::Piece not found, installing perl-Time-Piece package..."
107+
108+
# Install perl-Time-Piece package for CentOS 7/RHEL 7
109+
if ${INSTALL_CMD} perl-Time-Piece; then
110+
echo "(*) perl-Time-Piece installed for OpenSSL 3.0.18+ build"
111+
else
112+
echo "(!) Failed to install perl-Time-Piece package. This will cause OpenSSL 3.0.18+ build to fail"
113+
return 1
114+
fi
115+
}
116+
96117
# Clean up
97118
clean_up() {
98119
case ${ADJUSTED_ID} in
@@ -478,6 +499,130 @@ install_cpython() {
478499
curl -sSL -o "/tmp/python-src/${cpython_tgz_filename}" "${cpython_tgz_url}"
479500
fi
480501
}
502+
# Get system architecture for downloads
503+
get_architecture() {
504+
local architecture=""
505+
case $(uname -m) in
506+
x86_64) architecture="amd64" ;;
507+
aarch64 | armv8*) architecture="arm64" ;;
508+
aarch32 | armv7* | armvhf*) architecture="armhf" ;;
509+
i?86) architecture="386" ;;
510+
*) echo "(!) Architecture $(uname -m) unsupported"; exit 1 ;;
511+
esac
512+
echo ${architecture}
513+
}
514+
515+
# Install cosign with multi-distro support
516+
install_cosign() {
517+
518+
COSIGN_VERSION="latest"
519+
local cosign_url='https://github.com/sigstore/cosign'
520+
local architecture=$(get_architecture)
521+
522+
find_version_from_git_tags COSIGN_VERSION "${cosign_url}"
523+
524+
# Remove 'v' prefix if present for download URL
525+
local version_for_url="${COSIGN_VERSION#v}"
526+
527+
local cosign_filename="/tmp/cosign_${version_for_url}_${architecture}.deb"
528+
local cosign_url="https://github.com/sigstore/cosign/releases/download/v${version_for_url}/cosign_${version_for_url}_${architecture}.deb"
529+
530+
echo "Downloading cosign from: ${cosign_url}"
531+
532+
if curl -L -f --fail-with-body "${cosign_url}" -o "$cosign_filename" 2>/dev/null; then
533+
echo "(*) Successfully downloaded cosign v${COSIGN_VERSION}"
534+
else
535+
echo -e "\n(!) Failed to fetch cosign v${COSIGN_VERSION}..."
536+
# Try previous version
537+
find_prev_version_from_git_tags COSIGN_VERSION "https://github.com/sigstore/cosign"
538+
echo -e "\nAttempting to install previous cosign ${COSIGN_VERSION} version as fallback mechanism"
539+
540+
version_for_url="${COSIGN_VERSION#v}"
541+
cosign_filename="/tmp/cosign_${version_for_url}_${architecture}.deb"
542+
cosign_url="https://github.com/sigstore/cosign/releases/download/v${version_for_url}/cosign_${version_for_url}_${architecture}.deb"
543+
544+
if ! curl -L -f --fail-with-body "${cosign_url}" -o "$cosign_filename" 2>/dev/null; then
545+
echo "(!) Failed to download cosign v${COSIGN_VERSION} as fallback"
546+
return 1
547+
fi
548+
fi
549+
550+
# Install the package
551+
if [ -f "$cosign_filename" ]; then
552+
dpkg -i "$cosign_filename"
553+
rm "$cosign_filename"
554+
echo "Installation of cosign succeeded with ${COSIGN_VERSION}."
555+
else
556+
echo "(!) Failed to install cosign package"
557+
return 1
558+
fi
559+
560+
}
561+
562+
# COSIGN signature verification for python versions >= 3.14
563+
cosign_verification() {
564+
local VERSION="$1"
565+
566+
# Ensure cosign is installed
567+
if ! type cosign > /dev/null 2>&1; then
568+
echo "(*) cosign not found, installing..."
569+
if ! install_cosign; then
570+
echo "(!) Failed to install cosign"
571+
return 1
572+
fi
573+
else
574+
echo "(*) cosign is already available on the system"
575+
fi
576+
577+
echo "(*) Attempting COSIGN verification for Python ${VERSION}..."
578+
579+
# Check if COSIGN signature files exist (these don't exist yet for Python releases)
580+
local cosign_sig_url="${cpython_tgz_url}.sig"
581+
local cosign_cert_url="${cpython_tgz_url}.pem"
582+
583+
# Download COSIGN signature and certificate files with proper error handling
584+
echo "(*) Checking for cosign signature files..."
585+
if ! curl -sSL -f --fail-with-body -o "/tmp/python-src/${cpython_tgz_filename}.sig" "${cosign_sig_url}" 2>/dev/null; then
586+
echo "(!) COSIGN signature file not available for Python ${VERSION}"
587+
echo " Signature URL: ${cosign_sig_url}"
588+
return 1
589+
fi
590+
591+
if ! curl -sSL -f --fail-with-body -o "/tmp/python-src/${cpython_tgz_filename}.pem" "${cosign_cert_url}" 2>/dev/null; then
592+
echo "(!) COSIGN certificate file not available for Python ${VERSION}"
593+
echo " Certificate URL: ${cosign_cert_url}"
594+
return 1
595+
fi
596+
597+
# Perform COSIGN verification
598+
if cosign verify-blob \
599+
--certificate "/tmp/python-src/${cpython_tgz_filename}.pem" \
600+
--signature "/tmp/python-src/${cpython_tgz_filename}.sig" \
601+
--certificate-identity-regexp=".*" \
602+
--certificate-oidc-issuer-regexp=".*" \
603+
"/tmp/python-src/${cpython_tgz_filename}"; then
604+
echo "(*) COSIGN signature verification successful"
605+
return 0
606+
else
607+
echo "(!) COSIGN signature verification failed"
608+
return 1
609+
fi
610+
}
611+
612+
# GPG verification for python versions < 3.14
613+
gpg_verification() {
614+
echo "(*) Using GPG signature verification..."
615+
if [[ ${VERSION_CODENAME} = "centos7" ]] || [[ ${VERSION_CODENAME} = "rhel7" ]]; then
616+
receive_gpg_keys_centos7 PYTHON_SOURCE_GPG_KEYS
617+
else
618+
receive_gpg_keys PYTHON_SOURCE_GPG_KEYS
619+
fi
620+
echo "Downloading ${cpython_tgz_filename}.asc..."
621+
curl -sSL -o "/tmp/python-src/${cpython_tgz_filename}.asc" "${cpython_tgz_url}.asc"
622+
gpg --verify "${cpython_tgz_filename}.asc"
623+
echo "(*) GPG signature verification successful"
624+
}
625+
481626

482627
install_from_source() {
483628
VERSION=$1
@@ -496,6 +641,8 @@ install_from_source() {
496641
case ${VERSION_CODENAME} in
497642
centos7|rhel7)
498643
check_packages perl-IPC-Cmd
644+
# Install Time::Piece Perl module required by OpenSSL 3.0.18+ build system
645+
install_time_piece
499646
install_openssl3
500647
ADDL_CONFIG_ARGS="--with-openssl=${SSL_INSTALL_PATH} --with-openssl-rpath=${SSL_INSTALL_PATH}/lib"
501648
;;
@@ -507,15 +654,27 @@ install_from_source() {
507654
install_prev_vers_cpython "${VERSION}"
508655
fi
509656
fi;
510-
# Verify signature
511-
if [[ ${VERSION_CODENAME} = "centos7" ]] || [[ ${VERSION_CODENAME} = "rhel7" ]]; then
512-
receive_gpg_keys_centos7 PYTHON_SOURCE_GPG_KEYS
657+
658+
# Discontinuation of PGP signatures for releases of Python 3.14 or future versions
659+
# CPython release artifacts are additionally signed with Sigstore starting with the Python 3.11.0
660+
local major_version=$(echo "$VERSION" | cut -d. -f1)
661+
local minor_version=$(echo "$VERSION" | cut -d. -f2)
662+
echo "(*) Detected Python version: ${major_version}.${minor_version}"
663+
if (( major_version > 3 )) || { (( major_version == 3 )) && (( minor_version >= 14 )); }; then
664+
echo "(*) Python 3.14+ detected. Attempting cosign verification..."
665+
if cosign_verification "$VERSION"; then
666+
echo "(*) COSIGN verification successful."
667+
else
668+
echo "(*) COSIGN verification failed or not available for Python ${VERSION}"
669+
echo "(*) WARNING: Installing Python ${VERSION} without signature verification"
670+
echo "(*) This is expected for newly released versions where cosign signatures are not yet available"
671+
echo "(*) Python 3.14+ discontinued PGP signatures in favor of cosign, but cosign signatures may take time to be published"
672+
fi
513673
else
514-
receive_gpg_keys PYTHON_SOURCE_GPG_KEYS
674+
echo "(*) Python < 3.14 detected. Using GPG signature verification..."
675+
gpg_verification
676+
echo "(*) GPG verification successful."
515677
fi
516-
echo "Downloading ${cpython_tgz_filename}.asc..."
517-
curl -sSL -o "/tmp/python-src/${cpython_tgz_filename}.asc" "${cpython_tgz_url}.asc"
518-
gpg --verify "${cpython_tgz_filename}.asc"
519678

520679
# Update min protocol for testing only - https://bugs.python.org/issue41561
521680
if [ -f /etc/pki/tls/openssl.cnf ]; then
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Import test library for `check` command
6+
source dev-container-features-test-lib
7+
8+
check "version" az --version
9+
10+
check "docker installed" bash -c "type docker"
11+
12+
# Report result
13+
reportResults

0 commit comments

Comments
 (0)