From 8895eb3d161d28ada3a8de761a83135e811cae3d Mon Sep 17 00:00:00 2001 From: Kaniska Date: Thu, 17 Apr 2025 19:41:09 +0530 Subject: [PATCH 001/118] [dotnet] - Fixing the dotnet smoke test issue with changes in test script. (#1335) * Fixing the dotnet smoke test issue with changes in test script. * Version bump --- src/dotnet/devcontainer-feature.json | 2 +- test/dotnet/dotnet_helpers.sh | 38 ++++++++++++++++++++++++++++ test/dotnet/install_dotnet_lts.sh | 3 ++- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index 5d553bcd0..fcf480583 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "2.2.1", + "version": "2.2.2", "name": "Dotnet CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet", "description": "This Feature installs the latest .NET SDK, which includes the .NET CLI and the shared runtime. Options are provided to choose a different version or additional versions.", diff --git a/test/dotnet/dotnet_helpers.sh b/test/dotnet/dotnet_helpers.sh index 01e554f66..0373d99c7 100644 --- a/test/dotnet/dotnet_helpers.sh +++ b/test/dotnet/dotnet_helpers.sh @@ -17,6 +17,44 @@ fetch_latest_version_in_channel() { fi } +# Function to resolve the actual version from an aka.ms URL +resolve_version_from_aka_ms() { + local normalized_channel="${1:-LTS}" # defaulting to LTS channel + local normalized_product="dotnet-sdk" + local normalized_os="linux" + + # Dynamically determine the architecture + local normalized_architecture + normalized_architecture=$(uname -m) + case "$normalized_architecture" in + x86_64) normalized_architecture="x64" ;; + aarch64) normalized_architecture="arm64" ;; + arm*) normalized_architecture="arm" ;; + *) + echo "Unsupported architecture: $normalized_architecture" + return 1 + ;; + esac + + # Construct the aka.ms link + local aka_ms_link="https://aka.ms/dotnet/$normalized_channel/$normalized_product-$normalized_os-$normalized_architecture.tar.gz" + echo "Constructed aka.ms link: $aka_ms_link" + + # Resolve the redirect URL using curl + local resolved_url + resolved_url=$(curl -s -L -o /dev/null -w "%{url_effective}" "$aka_ms_link") + echo "Resolved URL: $resolved_url" + + # Extract the version from the resolved URL + IFS='/' + read -ra pathElems <<< "$resolved_url" + local count=${#pathElems[@]} + local specific_version="${pathElems[count-2]}" + unset IFS + + echo "Extracted version: $specific_version" +} + # Prints the latest dotnet version # Usage: fetch_latest_version [] # Example: fetch_latest_version diff --git a/test/dotnet/install_dotnet_lts.sh b/test/dotnet/install_dotnet_lts.sh index da9175c15..aebc8830a 100644 --- a/test/dotnet/install_dotnet_lts.sh +++ b/test/dotnet/install_dotnet_lts.sh @@ -13,7 +13,8 @@ source dev-container-features-test-lib source dotnet_env.sh source dotnet_helpers.sh -expected=$(fetch_latest_version_in_channel "LTS") +# Changing it as the dotnet SDK CDN url is not showing the right version for LTS +expected=$(resolve_version_from_aka_ms "LTS" | cut -d' ' -f3) check "Latest LTS version installed" \ is_dotnet_sdk_version_installed "$expected" From eb5d299e766b983e8dd7c7e9c8b12a130c906ff8 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Mon, 21 Apr 2025 21:34:46 +0530 Subject: [PATCH 002/118] Revert "[dotnet] - Fixing the dotnet smoke test issue with changes in test script." (#1343) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revert "[dotnet] - Fixing the dotnet smoke test issue with changes in test sc…" This reverts commit 8895eb3d161d28ada3a8de761a83135e811cae3d. --- src/dotnet/devcontainer-feature.json | 2 +- test/dotnet/dotnet_helpers.sh | 38 ---------------------------- test/dotnet/install_dotnet_lts.sh | 3 +-- 3 files changed, 2 insertions(+), 41 deletions(-) diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index fcf480583..5d553bcd0 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "2.2.2", + "version": "2.2.1", "name": "Dotnet CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet", "description": "This Feature installs the latest .NET SDK, which includes the .NET CLI and the shared runtime. Options are provided to choose a different version or additional versions.", diff --git a/test/dotnet/dotnet_helpers.sh b/test/dotnet/dotnet_helpers.sh index 0373d99c7..01e554f66 100644 --- a/test/dotnet/dotnet_helpers.sh +++ b/test/dotnet/dotnet_helpers.sh @@ -17,44 +17,6 @@ fetch_latest_version_in_channel() { fi } -# Function to resolve the actual version from an aka.ms URL -resolve_version_from_aka_ms() { - local normalized_channel="${1:-LTS}" # defaulting to LTS channel - local normalized_product="dotnet-sdk" - local normalized_os="linux" - - # Dynamically determine the architecture - local normalized_architecture - normalized_architecture=$(uname -m) - case "$normalized_architecture" in - x86_64) normalized_architecture="x64" ;; - aarch64) normalized_architecture="arm64" ;; - arm*) normalized_architecture="arm" ;; - *) - echo "Unsupported architecture: $normalized_architecture" - return 1 - ;; - esac - - # Construct the aka.ms link - local aka_ms_link="https://aka.ms/dotnet/$normalized_channel/$normalized_product-$normalized_os-$normalized_architecture.tar.gz" - echo "Constructed aka.ms link: $aka_ms_link" - - # Resolve the redirect URL using curl - local resolved_url - resolved_url=$(curl -s -L -o /dev/null -w "%{url_effective}" "$aka_ms_link") - echo "Resolved URL: $resolved_url" - - # Extract the version from the resolved URL - IFS='/' - read -ra pathElems <<< "$resolved_url" - local count=${#pathElems[@]} - local specific_version="${pathElems[count-2]}" - unset IFS - - echo "Extracted version: $specific_version" -} - # Prints the latest dotnet version # Usage: fetch_latest_version [] # Example: fetch_latest_version diff --git a/test/dotnet/install_dotnet_lts.sh b/test/dotnet/install_dotnet_lts.sh index aebc8830a..da9175c15 100644 --- a/test/dotnet/install_dotnet_lts.sh +++ b/test/dotnet/install_dotnet_lts.sh @@ -13,8 +13,7 @@ source dev-container-features-test-lib source dotnet_env.sh source dotnet_helpers.sh -# Changing it as the dotnet SDK CDN url is not showing the right version for LTS -expected=$(resolve_version_from_aka_ms "LTS" | cut -d' ' -f3) +expected=$(fetch_latest_version_in_channel "LTS") check "Latest LTS version installed" \ is_dotnet_sdk_version_installed "$expected" From 6654579de4c31cd9f9f9e19e873521f502403929 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Mon, 21 Apr 2025 22:05:52 +0530 Subject: [PATCH 003/118] Extending support of powershell feature for AlmaLinux (#1303) * rremoved shell envwhich defaults to the shell /bin/bash * adding powershell support for alma linux9 * modifications to the test cases * Delete test/common-utils/configure_zsh_as_default_shell/Dockerfile Deleting the file as it is no longer needed No modifications needed inside the Dockerfile set the containerEnv to work with default shell * remove sudo * made changes * adding -E to preserve env variables * correcting errors * made the requested changes * using dnf to check the packages * using dnf to check the packages * bumping up the version * bump up the powershell version for Almalinux support * removal of x86_64 * local tests files not required for this PR --------- Co-authored-by: Daniel Doyle --- src/powershell/install.sh | 140 ++++++++++++++++++++--- test/powershell/powershell_alma_linux.sh | 18 +++ test/powershell/scenarios.json | 6 + 3 files changed, 148 insertions(+), 16 deletions(-) create mode 100644 test/powershell/powershell_alma_linux.sh diff --git a/src/powershell/install.sh b/src/powershell/install.sh index 4953a49d8..3da7a231b 100755 --- a/src/powershell/install.sh +++ b/src/powershell/install.sh @@ -17,18 +17,89 @@ POWERSHELL_MODULES="${MODULES:-""}" POWERSHELL_PROFILE_URL="${POWERSHELLPROFILEURL}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" -POWERSHELL_ARCHIVE_ARCHITECTURES="amd64" +#MICROSOFT_GPG_KEYS_URI=$(curl https://packages.microsoft.com/keys/microsoft.asc -o /usr/share/keyrings/microsoft-archive-keyring.gpg) +POWERSHELL_ARCHIVE_ARCHITECTURES_UBUNTU="amd64" +POWERSHELL_ARCHIVE_ARCHITECTURES_ALMALINUX="x86_64" POWERSHELL_ARCHIVE_VERSION_CODENAMES="stretch buster bionic focal bullseye jammy bookworm noble" + +#These key servers are used to verify the authenticity of packages and repositories. +#keyservers for ubuntu and almalinux are different so we need to specify both 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 hkp://keyserver.pgp.com +keyserver hkp://keyserver.fedoraproject.org +keyserver hkps://keys.openpgp.org +keyserver hkp://pgp.mit.edu +keyserver hkp://keyserver.redhat.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.' exit 1 fi +# Clean up package manager cache +clean_cache() { + if [ -d "/var/cache/apt" ]; then + apt-get clean + fi + if [ -d "/var/cache/dnf" ]; then + rm -rf /var/cache/dnf/* + fi +} +# Install dependencies for RHEL/CentOS/AlmaLinux (DNF-based systems) +install_using_dnf() { + dnf remove -y curl-minimal + dnf install -y curl gnupg2 ca-certificates dnf-plugins-core + dnf clean all + dnf makecache + curl --version +} + +# Install PowerShell on RHEL/CentOS/AlmaLinux-based systems (DNF) +install_powershell_dnf() { + # Install wget, if not already installed + dnf install -y wget + + # Download Microsoft GPG key + curl https://packages.microsoft.com/keys/microsoft.asc -o /usr/share/keyrings/microsoft-archive-keyring.gpg + ls -l /usr/share/keyrings/microsoft-archive-keyring.gpg + + # Install necessary dependencies + dnf install -y krb5-libs libicu openssl-libs zlib + + # Add Microsoft PowerShell repository + curl "https://packages.microsoft.com/config/rhel/9.0/prod.repo" > /etc/yum.repos.d/microsoft.repo + + # Install PowerShell + dnf install --assumeyes powershell +} + + +# Detect the package manager and OS +detect_package_manager() { + if [ -f /etc/os-release ]; then + . /etc/os-release + if [[ "$ID" == "ubuntu" || "$ID" == "debian" ]]; then + echo "Detected Debian/Ubuntu-based system" + install_using_apt + install_pwsh + elif [[ "$ID" == "centos" || "$ID" == "rhel" || "$ID" == "almalinux" ]]; then + echo "Detected RHEL/CentOS/AlmaLinux-based system" + install_using_dnf + install_powershell_dnf + install_pwsh + else + echo "Unsupported Linux distribution: $ID" + exit 1 + fi + else + echo "Could not detect OS" + exit 1 + fi +} + # Figure out correct version of a three part version number is not passed find_version_from_git_tags() { local variable_name=$1 @@ -72,19 +143,43 @@ apt_get_update() } # Checks if packages are installed and installs them if not -check_packages() { - if ! dpkg -s "$@" > /dev/null 2>&1; then - apt_get_update - apt-get -y install --no-install-recommends "$@" - fi + check_packages() { + if command -v dpkg > /dev/null 2>&1; then + # If dpkg exists, assume APT-based system (Debian/Ubuntu) + for package in "$@"; do + if ! dpkg -s "$package" > /dev/null 2>&1; then + echo "Package $package not installed. Installing using apt-get..." + apt-get update + apt-get install -y --no-install-recommends "$package" + else + echo "Package $package is already installed (APT)." + fi + done + elif command -v dnf > /dev/null 2>&1; then + for package in "$@"; do + if ! dnf list installed "$package" > /dev/null 2>&1; then + echo "Package $package not installed. Installing using dnf..." + dnf install -y "$package" + else + echo "Package $package is already installed (DNF)." + fi + done +else + echo "Unsupported package manager. Neither APT nor DNF found." + return 1 +fi + + } install_using_apt() { # Install dependencies check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr # Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install + curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg echo "deb [arch=$(dpkg --print-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 + # Update lists apt-get update -yq @@ -201,7 +296,8 @@ install_using_github() { if ! type git > /dev/null 2>&1; then check_packages git fi - if [ "${architecture}" = "amd64" ]; then + + if [ "${architecture}" = "amd64" ]; then architecture="x64" fi pwsh_url="https://github.com/PowerShell/PowerShell" @@ -210,9 +306,13 @@ install_using_github() { if grep -q "Not Found" "${powershell_filename}"; then install_prev_pwsh $pwsh_url fi + + # downlaod the latest version of powershell and extracting the file to powershell directory + wget https://github.com/PowerShell/PowerShell/releases/download/v${POWERSHELL_VERSION}/${powershell_filename} + mkdir ~/powershell + tar -xvf powershell-${POWERSHELL_VERSION}-linux-x64.tar.gz -C ~/powershell + - # Ugly - but only way to get sha256 is to parse release HTML. Remove newlines and tags, then look for filename followed by 64 hex characters. - curl -sSL -o "release.html" "https://github.com/PowerShell/PowerShell/releases/tag/v${POWERSHELL_VERSION}" powershell_archive_sha256="$(cat release.html | tr '\n' ' ' | sed 's|<[^>]*>||g' | grep -oP "${powershell_filename}\s+\K[0-9a-fA-F]{64}" || echo '')" if [ -z "${powershell_archive_sha256}" ]; then echo "(!) WARNING: Failed to retrieve SHA256 for archive. Skipping validaiton." @@ -233,14 +333,22 @@ if ! type pwsh >/dev/null 2>&1; then # Source /etc/os-release to get OS info . /etc/os-release - architecture="$(dpkg --print-architecture)" + architecture="$(uname -m)" + if [[ "$ID" == "ubuntu" || "$ID" == "debian" ]]; then + POWERSHELL_ARCHIVE_ARCHITECTURES="${POWERSHELL_ARCHIVE_ARCHITECTURES_UBUNTU}" + elif [[ "$ID" == "centos" || "$ID" == "rhel" || "$ID" == "almalinux" ]]; then + POWERSHELL_ARCHIVE_ARCHITECTURES="${POWERSHELL_ARCHIVE_ARCHITECTURES_ALMALINUX}" + fi - if [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${architecture}"* ]] && [[ "${POWERSHELL_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]]; then + if [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${POWERSHELL_ARCHIVE_ARCHITECTURES_UBUNTU}"* ]] && [[ "${POWERSHELL_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]]; then install_using_apt || use_github="true" - else - use_github="true" - fi + elif [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${POWERSHELL_ARCHIVE_ARCHITECTURES_ALMALINUX}"* ]]; then + install_using_dnf && install_powershell_dnf || use_github="true" + else + use_github="true" + fi + if [ "${use_github}" = "true" ]; then echo "Attempting install from GitHub release..." install_using_github @@ -282,4 +390,4 @@ fi # Clean up rm -rf /var/lib/apt/lists/* -echo "Done!" +echo "Done!" \ No newline at end of file diff --git a/test/powershell/powershell_alma_linux.sh b/test/powershell/powershell_alma_linux.sh new file mode 100644 index 000000000..8b653afe5 --- /dev/null +++ b/test/powershell/powershell_alma_linux.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Extension-specific tests +check "pwsh file is symlink" bash -c "[ -L /usr/bin/pwsh ]" +check "pwsh symlink is registered as shell" bash -c "[ $(grep -c '/usr/bin/pwsh' /etc/shells) -ge 1 ]" +check "pwsh target is correct" bash -c "[ $(readlink /usr/bin/pwsh) = /opt/microsoft/powershell/7/pwsh ]" +check "pwsh owner is root" bash -c "[ $(stat -c %U /opt/microsoft/powershell/7/pwsh) = root ]" +check "pwsh group is root" bash -c "[ $(stat -c %G /opt/microsoft/powershell/7/pwsh) = root ]" +check "pwsh file mode is -rwxr-xr-x" bash -c "[ $(stat -c '%A' /opt/microsoft/powershell/7/pwsh) = '-rwxr-xr-x' ]" +check "pwsh is in PATH" bash -c "command -v pwsh" + +# Report result +reportResults \ No newline at end of file diff --git a/test/powershell/scenarios.json b/test/powershell/scenarios.json index 87a5b9d16..781ebaf86 100644 --- a/test/powershell/scenarios.json +++ b/test/powershell/scenarios.json @@ -30,5 +30,11 @@ "features": { "powershell": {} } + }, + "powershell_alma_linux": { + "image": "almalinux:9", + "features": { + "powershell": {} + } } } From 4f8a62ac92799f1baecc2991f717cc856d3911e2 Mon Sep 17 00:00:00 2001 From: Alberto Cavalcante Date: Mon, 5 May 2025 10:07:15 -0600 Subject: [PATCH 004/118] [Go] Add Go 1.24 (#1288) update version proposals to include Go 1.24 --- src/go/devcontainer-feature.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/go/devcontainer-feature.json b/src/go/devcontainer-feature.json index 4b0adb192..f98e65a7f 100644 --- a/src/go/devcontainer-feature.json +++ b/src/go/devcontainer-feature.json @@ -10,8 +10,8 @@ "proposals": [ "latest", "none", - "1.23", - "1.22" + "1.24", + "1.23" ], "default": "latest", "description": "Select or enter a Go version to install" From 94ed0bbb7de8db07ba99a2929c1042c20dab1555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Janou=C5=A1ek?= Date: Mon, 19 May 2025 18:28:54 +0200 Subject: [PATCH 005/118] fix(rust): remove rls and rust-analysis for Rust 1.87+ compatibility (#1362) * fix(rust): remove rls and rust-analysis for Rust 1.87+ compatibility Rust 1.87.0 and later have removed the long-deprecated RLS and rust-analysis components. This change updates the install script to only add rust-src, rustfmt, and clippy, preventing build errors during feature installation. See: https://github.com/rust-lang/rust/pull/126856 https://blog.rust-lang.org/2022/07/01/RLS-deprecation/ https://github.com/rust-lang/rustup/blob/a92432fc8b6d5d4e56ebd08ca1c45b7b1294c1bd/doc/user-guide/src/concepts/components.md#previous-components Fixes: https://github.com/devcontainers/features/issues/1361 * Drop support for older rust version that do not have rust-analyzer * Add rust-analyzer as replacement for rls * Update devcontainer-feature version number * Add proposed version options * test(rust): Bump pinned rust version to one incl rust-analyzer --------- Co-authored-by: neoscript --- src/rust/devcontainer-feature.json | 15 ++++++++++----- src/rust/install.sh | 2 +- test/rust/rust_at_pinned_version.sh | 2 +- test/rust/scenarios.json | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/rust/devcontainer-feature.json b/src/rust/devcontainer-feature.json index 8ee423050..ae67e0bdc 100644 --- a/src/rust/devcontainer-feature.json +++ b/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "1.3.2", + "version": "1.3.3", "name": "Rust", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust", "description": "Installs Rust, common Rust utilities, and their required dependencies", @@ -10,6 +10,14 @@ "proposals": [ "latest", "none", + "1.87", + "1.86", + "1.85", + "1.84", + "1.83", + "1.82", + "1.81", + "1.80", "1.79", "1.78", "1.77", @@ -25,10 +33,7 @@ "1.67", "1.66", "1.65", - "1.64", - "1.63", - "1.62", - "1.61" + "1.64" ], "default": "latest", "description": "Select or enter a version of Rust to install." diff --git a/src/rust/install.sh b/src/rust/install.sh index 1025e46bb..d89fbe492 100755 --- a/src/rust/install.sh +++ b/src/rust/install.sh @@ -203,7 +203,7 @@ if [ "${UPDATE_RUST}" = "true" ]; then rustup update 2>&1 fi echo "Installing common Rust dependencies..." -rustup component add rls rust-analysis rust-src rustfmt clippy 2>&1 +rustup component add rust-analyzer rust-src rustfmt clippy 2>&1 if [ -n "${RUSTUP_TARGETS}" ]; then IFS=',' read -ra targets <<< "${RUSTUP_TARGETS}" diff --git a/test/rust/rust_at_pinned_version.sh b/test/rust/rust_at_pinned_version.sh index 2954a7acb..e7adf7d1f 100644 --- a/test/rust/rust_at_pinned_version.sh +++ b/test/rust/rust_at_pinned_version.sh @@ -8,7 +8,7 @@ source dev-container-features-test-lib # Definition specific tests check "cargo version" cargo --version check "rustc version" rustc --version -check "correct rust version" rustc --version | grep 1.62.0 +check "correct rust version" rustc --version | grep 1.64.0 # Report result diff --git a/test/rust/scenarios.json b/test/rust/scenarios.json index de037cd29..c3466b29b 100644 --- a/test/rust/scenarios.json +++ b/test/rust/scenarios.json @@ -3,7 +3,7 @@ "image": "ubuntu:focal", "features": { "rust": { - "version": "1.62.0" + "version": "1.64.0" } } }, From 66c73dfb87c72bf8ae76700c40864b2d7fda9967 Mon Sep 17 00:00:00 2001 From: iTiPo Date: Tue, 3 Jun 2025 17:55:39 +0300 Subject: [PATCH 006/118] [terraform] Add Custom Download Server Support for Terraform Dev Container Feature (#1364) * Add custom download server option to download terraform * Bump Terraform version to 1.4.0 in devcontainer feature configuration * Update custom download server documentation and implementation to require full URL with protocol * Remove my changes from an auto-generated file * Remove my changes from an auto-generated file * Add security considerations for custom download servers in documentation * Update security considerations section in documentation with warning icon * Return leading empty lines back to NOTES.md * Fix formatting in custom download server scripts by ensuring consistent newline handling and invoking reportResults function. --- src/terraform/NOTES.md | 31 +++++++++++++++++++ src/terraform/devcontainer-feature.json | 7 ++++- src/terraform/install.sh | 14 ++++++--- test/terraform/custom_download_server.sh | 13 ++++++++ .../custom_download_server_with_sentinel.sh | 16 ++++++++++ test/terraform/scenarios.json | 19 ++++++++++++ 6 files changed, 95 insertions(+), 5 deletions(-) create mode 100755 test/terraform/custom_download_server.sh create mode 100755 test/terraform/custom_download_server_with_sentinel.sh diff --git a/src/terraform/NOTES.md b/src/terraform/NOTES.md index 2c1540aee..74a90639e 100644 --- a/src/terraform/NOTES.md +++ b/src/terraform/NOTES.md @@ -4,6 +4,37 @@ On August 10, 2023, HashiCorp announced a change of license for its products, including Terraform. After ~9 years of Terraform being open source under the MPL v2 license, it was to move under a non-open source BSL v1.1 license, starting from the next (1.6) version. See https://github.com/hashicorp/terraform/blob/main/LICENSE +## Custom Download Server + +The `customDownloadServer` option allows you to specify an alternative server for downloading Terraform and Sentinel packages. This is useful for organizations that maintain internal mirrors or have proxies for HashiCorp downloads. + +When using this option: +- Provide the complete URL including protocol (e.g., `https://my-mirror.example.com`) +- The server should mirror the HashiCorp releases structure + +Example: +```json +"features": { + "ghcr.io/devcontainers/features/terraform:1": { + "customDownloadServer": "https://my-mirror.example.com" + } +} +``` + +### ⚠️ Security Considerations + +When using a custom download server, be aware of the following security implications: + +- **Server Verification**: Always verify that the custom server is trustworthy and maintained by your organization or a trusted entity. Using an untrusted or compromised server could lead to downloading malicious software. + +- **Supply Chain Risks**: Malicious actors may attempt to distribute compromised versions of Terraform that contain backdoors, cryptominers, or other harmful code. + +- **Integrity Checks**: The feature performs SHA256 checks when available, but these are only as trustworthy as the source of the checksums. If both the binaries and checksums come from a compromised server, the integrity check may pass despite the software being malicious. + +- **Organizational Policy**: Ensure your custom download server adheres to your organization's security policies and implements proper access controls. + +Always use the official HashiCorp download server (https://releases.hashicorp.com) unless you have a specific need for an alternative source. + ## OS Support This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index d022f83c1..db1bacc67 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.3.10", + "version": "1.4.0", "name": "Terraform, tflint, and TFGrunt", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/terraform", "description": "Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects latest version and installs needed dependencies.", @@ -54,6 +54,11 @@ "type": "string", "default": "", "description": "Connect to a keyserver using a proxy by configuring this option" + }, + "customDownloadServer": { + "type": "string", + "default": "", + "description": "Custom server URL for downloading Terraform and Sentinel packages, including protocol (e.g., https://releases.hashicorp.com). If not provided, the default HashiCorp download server (https://releases.hashicorp.com) will be used." } }, "customizations": { diff --git a/src/terraform/install.sh b/src/terraform/install.sh index a2aace9b4..fb7abc6ee 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -18,6 +18,7 @@ TERRAGRUNT_VERSION="${TERRAGRUNT:-"latest"}" INSTALL_SENTINEL=${INSTALLSENTINEL:-false} INSTALL_TFSEC=${INSTALLTFSEC:-false} INSTALL_TERRAFORM_DOCS=${INSTALLTERRAFORMDOCS:-false} +CUSTOM_DOWNLOAD_SERVER="${CUSTOMDOWNLOADSERVER:-""}" TERRAFORM_SHA256="${TERRAFORM_SHA256:-"automatic"}" TFLINT_SHA256="${TFLINT_SHA256:-"automatic"}" @@ -26,6 +27,11 @@ SENTINEL_SHA256="${SENTINEL_SHA256:-"automatic"}" TFSEC_SHA256="${TFSEC_SHA256:-"automatic"}" TERRAFORM_DOCS_SHA256="${TERRAFORM_DOCS_SHA256:-"automatic"}" +HASHICORP_RELEASES_URL="https://releases.hashicorp.com" +if [ -n "${CUSTOM_DOWNLOAD_SERVER}" ]; then + HASHICORP_RELEASES_URL="${CUSTOM_DOWNLOAD_SERVER}" +fi + TERRAFORM_GPG_KEY="72D7468F" TFLINT_GPG_KEY_URI="https://raw.githubusercontent.com/terraform-linters/tflint/v0.46.1/8CE69160EB3F2FE9.key" KEYSERVER_PROXY="${HTTPPROXY:-"${HTTP_PROXY:-""}"}" @@ -357,7 +363,7 @@ find_version_from_git_tags TERRAGRUNT_VERSION "$terragrunt_url" install_terraform() { local TERRAFORM_VERSION=$1 terraform_filename="terraform_${TERRAFORM_VERSION}_linux_${architecture}.zip" - curl -sSL -o ${terraform_filename} "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/${terraform_filename}" + curl -sSL -o ${terraform_filename} "${HASHICORP_RELEASES_URL}/terraform/${TERRAFORM_VERSION}/${terraform_filename}" } mkdir -p /tmp/tf-downloads @@ -373,8 +379,8 @@ fi if [ "${TERRAFORM_SHA256}" != "dev-mode" ]; then if [ "${TERRAFORM_SHA256}" = "automatic" ]; then receive_gpg_keys TERRAFORM_GPG_KEY - curl -sSL -o terraform_SHA256SUMS https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_SHA256SUMS - curl -sSL -o terraform_SHA256SUMS.sig https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_SHA256SUMS.${TERRAFORM_GPG_KEY}.sig + curl -sSL -o terraform_SHA256SUMS "${HASHICORP_RELEASES_URL}/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_SHA256SUMS" + curl -sSL -o terraform_SHA256SUMS.sig "${HASHICORP_RELEASES_URL}/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_SHA256SUMS.${TERRAFORM_GPG_KEY}.sig" gpg --verify terraform_SHA256SUMS.sig terraform_SHA256SUMS else echo "${TERRAFORM_SHA256} *${terraform_filename}" > terraform_SHA256SUMS @@ -464,7 +470,7 @@ fi if [ "${INSTALL_SENTINEL}" = "true" ]; then SENTINEL_VERSION="latest" - sentinel_releases_url='https://releases.hashicorp.com/sentinel' + sentinel_releases_url="${HASHICORP_RELEASES_URL}/sentinel" find_sentinel_version_from_url SENTINEL_VERSION ${sentinel_releases_url} sentinel_filename="sentinel_${SENTINEL_VERSION}_linux_${architecture}.zip" echo "(*) Downloading Sentinel... ${sentinel_filename}" diff --git a/test/terraform/custom_download_server.sh b/test/terraform/custom_download_server.sh new file mode 100755 index 000000000..9f0fdd600 --- /dev/null +++ b/test/terraform/custom_download_server.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Import test library +source dev-container-features-test-lib + +# Check if terraform was installed correctly and it's the expected version +check "terraform installed" terraform --version +check "terraform version matches" terraform --version | grep "1.6.5" + +# Report results +reportResults diff --git a/test/terraform/custom_download_server_with_sentinel.sh b/test/terraform/custom_download_server_with_sentinel.sh new file mode 100755 index 000000000..9675b39b9 --- /dev/null +++ b/test/terraform/custom_download_server_with_sentinel.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Import test library +source dev-container-features-test-lib + +# Check if terraform was installed correctly and it's the expected version +check "terraform installed" terraform --version +check "terraform version matches" terraform --version | grep "1.6.5" + +# Check if sentinel was installed correctly +check "sentinel installed" sentinel --version + +# Report results +reportResults diff --git a/test/terraform/scenarios.json b/test/terraform/scenarios.json index 04693666c..ea6b35b09 100644 --- a/test/terraform/scenarios.json +++ b/test/terraform/scenarios.json @@ -70,5 +70,24 @@ "tflint": "0.40.0" } } + }, + "custom_download_server": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "features": { + "terraform": { + "version": "1.6.5", + "customDownloadServer": "https://releases.hashicorp.com" + } + } + }, + "custom_download_server_with_sentinel": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "features": { + "terraform": { + "version": "1.6.5", + "installSentinel": true, + "customDownloadServer": "https://releases.hashicorp.com" + } + } } } \ No newline at end of file From 540930412bfb393a335c491b657947523bcdf6b0 Mon Sep 17 00:00:00 2001 From: Mathiyarasy <157102811+Mathiyarasy@users.noreply.github.com> Date: Thu, 5 Jun 2025 20:08:10 +0530 Subject: [PATCH 007/118] kubectl version doesn't support vX.Y.Z (#1373) * Fix issue when version is passed with v * remove wcho command * update version * update test cases to check for specific versions --- .../devcontainer-feature.json | 2 +- src/kubectl-helm-minikube/install.sh | 3 +- .../install_kubectl_with_version.sh | 33 +++++++++++++++++++ .../install_kubectl_without_version.sh | 33 +++++++++++++++++++ test/kubectl-helm-minikube/scenarios.json | 22 ++++++++++++- 5 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 test/kubectl-helm-minikube/install_kubectl_with_version.sh create mode 100644 test/kubectl-helm-minikube/install_kubectl_without_version.sh diff --git a/src/kubectl-helm-minikube/devcontainer-feature.json b/src/kubectl-helm-minikube/devcontainer-feature.json index 30c621f28..410a909e4 100644 --- a/src/kubectl-helm-minikube/devcontainer-feature.json +++ b/src/kubectl-helm-minikube/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "kubectl-helm-minikube", - "version": "1.2.1", + "version": "1.2.2", "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.", diff --git a/src/kubectl-helm-minikube/install.sh b/src/kubectl-helm-minikube/install.sh index bf6c8f535..f0cf1c946 100755 --- a/src/kubectl-helm-minikube/install.sh +++ b/src/kubectl-helm-minikube/install.sh @@ -54,11 +54,12 @@ fi find_version_from_git_tags() { local variable_name=$1 local requested_version=${!variable_name} + requested_version="${requested_version#v}" if [ "${requested_version}" = "none" ]; then return; fi local repository=$2 local prefix=${3:-"tags/v"} local separator=${4:-"."} - local last_part_optional=${5:-"false"} + local last_part_optional=${5:-"false"} if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then local escaped_separator=${separator//./\\.} local last_part diff --git a/test/kubectl-helm-minikube/install_kubectl_with_version.sh b/test/kubectl-helm-minikube/install_kubectl_with_version.sh new file mode 100644 index 000000000..6e0608f59 --- /dev/null +++ b/test/kubectl-helm-minikube/install_kubectl_with_version.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Define expected versions +KUBECTL_EXPECTED_VERSION="v1.33.0" +HELM_VERSION="v3.17.3" +MINIKUBE_VERSION="v1.31.1" + +set +e + kubectl version --client --output json | jq -r '.clientVersion.gitVersion' | grep "${KUBECTL_VERSION}" + exit_code=$? + check "kubectl-version-${KUBECTL_VERSION}-installed" bash -c "echo ${exit_code} | grep 0" + echo "kubectl version:" + kubectl version --client + + helm version --short | grep "${HELM_VERSION}" + exit_code=$? + check "helm-version-${HELM_VERSION}-installed" bash -c "echo ${exit_code} | grep 0" + echo "helm version:" + helm version --short + + minikube version --short | grep "${MINIKUBE_VERSION}" + exit_code=$? + check "minikube-version-${MINIKUBE_VERSION}-installed" bash -c "echo ${exit_code} | grep 0" + echo "minikube version:" + minikube version --short +set -e + +# Report result +reportResults \ No newline at end of file diff --git a/test/kubectl-helm-minikube/install_kubectl_without_version.sh b/test/kubectl-helm-minikube/install_kubectl_without_version.sh new file mode 100644 index 000000000..8a73ff599 --- /dev/null +++ b/test/kubectl-helm-minikube/install_kubectl_without_version.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Define expected versions +KUBECTL_EXPECTED_VERSION="1.30" +HELM_VERSION="3.16" +MINIKUBE_VERSION="1.28" + +set +e + kubectl version --client --output json | jq -r '.clientVersion.gitVersion' | grep "${KUBECTL_VERSION}" + exit_code=$? + check "kubectl-version-${KUBECTL_VERSION}-installed" bash -c "echo ${exit_code} | grep 0" + echo "kubectl version:" + kubectl version --client + + helm version --short | grep "${HELM_VERSION}" + exit_code=$? + check "helm-version-${HELM_VERSION}-installed" bash -c "echo ${exit_code} | grep 0" + echo "helm version:" + helm version --short + + minikube version --short | grep "${MINIKUBE_VERSION}" + exit_code=$? + check "minikube-version-${MINIKUBE_VERSION}-installed" bash -c "echo ${exit_code} | grep 0" + echo "minikube version:" + minikube version --short +set -e + +# Report result +reportResults \ No newline at end of file diff --git a/test/kubectl-helm-minikube/scenarios.json b/test/kubectl-helm-minikube/scenarios.json index b82a9966e..f18ce0756 100644 --- a/test/kubectl-helm-minikube/scenarios.json +++ b/test/kubectl-helm-minikube/scenarios.json @@ -18,5 +18,25 @@ "minikube": "none" } } + }, + "install_kubectl_without_version": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "kubectl-helm-minikube": { + "version": "1.30", + "helm": "3.16", + "minikube": "1.28" + } + } + }, + "install_kubectl_with_version": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "kubectl-helm-minikube": { + "version": "v1.33.0", + "helm": "v3.17.3", + "minikube": "v1.31.1" + } + } } -} +} \ No newline at end of file From 1c80e5351ab0e92018b6613edecdb440f46b0d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rausell=20Guiard?= <33221237+AlvaroRausell@users.noreply.github.com> Date: Fri, 6 Jun 2025 09:55:50 +0100 Subject: [PATCH 008/118] Use `secrets.GITHUB_TOKEN` instead of `PAT` for docs generation (#1377) * Use `GITHUB_TOKEN` intead of PAT * Add custom branch for testing * nothing to see here * Back to normality --- .github/workflows/update-documentation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-documentation.yml b/.github/workflows/update-documentation.yml index d74d970d5..7be3f6130 100644 --- a/.github/workflows/update-documentation.yml +++ b/.github/workflows/update-documentation.yml @@ -25,7 +25,7 @@ jobs: - name: Create a PR for Documentation id: push_image_info env: - GITHUB_TOKEN: ${{ secrets.PAT }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -e echo "Start." From 149d30312e089acdc0cbe44225e564dc60040d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rausell=20Guiard?= <33221237+AlvaroRausell@users.noreply.github.com> Date: Fri, 6 Jun 2025 10:12:47 +0100 Subject: [PATCH 009/118] Revert "Use `secrets.GITHUB_TOKEN` instead of `PAT` for docs generation (#1377)" (#1378) This reverts commit 1c80e5351ab0e92018b6613edecdb440f46b0d0b. --- .github/workflows/update-documentation.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-documentation.yml b/.github/workflows/update-documentation.yml index 7be3f6130..d74d970d5 100644 --- a/.github/workflows/update-documentation.yml +++ b/.github/workflows/update-documentation.yml @@ -25,7 +25,7 @@ jobs: - name: Create a PR for Documentation id: push_image_info env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.PAT }} run: | set -e echo "Start." From a58d0f15de71bb2270bff731e8dbbbdadaa4547f Mon Sep 17 00:00:00 2001 From: Kaniska Date: Wed, 11 Jun 2025 21:15:44 +0530 Subject: [PATCH 010/118] Supporting dotnet 10.0 preview version (#1305) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Supporting dotnet 10.0 preview version * Changing the test to fetch actual LTS version. * To resolve the conflict * To resolve conflict again * Version bump and adding back the azureedge url's as those should be removed by the automated version update PR * To resolve conflict again * Final version bump * Reverting back the test script change as created separate PR for that. * Ubuntu EOL changes and additional info about dotnet 10.0-preview version. * Correcting the comment. * Updates based on review comments to use '-preview' in the label as suffix. * Removed reame file change as suggested. * Update src/dotnet/README.md * Inconsequential change to rerun the failed test --------- Co-authored-by: Álvaro Rausell Guiard <33221237+AlvaroRausell@users.noreply.github.com> --- src/dotnet/devcontainer-feature.json | 3 +- src/dotnet/install.sh | 4 +- src/dotnet/scripts/vendor/README.md | 1 + .../install_dotnet_multiple_versions.sh | 20 ++------ ...nstall_dotnet_multiple_versions_preview.sh | 47 +++++++++++++++++++ .../dotnet/install_dotnet_specific_release.sh | 6 +-- ...otnet_specific_release_and_feature_band.sh | 6 +-- test/dotnet/projects/net10.0/Program.cs | 32 +++++++++++++ .../projects/net10.0/example_project.csproj | 14 ++++++ test/dotnet/scenarios.json | 30 ++++++++---- 10 files changed, 130 insertions(+), 33 deletions(-) create mode 100644 test/dotnet/install_dotnet_multiple_versions_preview.sh create mode 100644 test/dotnet/projects/net10.0/Program.cs create mode 100644 test/dotnet/projects/net10.0/example_project.csproj diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index 5d553bcd0..397f9a191 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "2.2.1", + "version": "2.3.0", "name": "Dotnet CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet", "description": "This Feature installs the latest .NET SDK, which includes the .NET CLI and the shared runtime. Options are provided to choose a different version or additional versions.", @@ -11,6 +11,7 @@ "latest", "lts", "none", + "10.0-preview", "8.0", "7.0", "6.0" diff --git a/src/dotnet/install.sh b/src/dotnet/install.sh index 4e149e2f0..75f013d03 100644 --- a/src/dotnet/install.sh +++ b/src/dotnet/install.sh @@ -108,7 +108,9 @@ done check_packages wget ca-certificates icu-devtools for version in "${versions[@]}"; do - install_sdk "$version" + # Remove '-preview' from version if suffixed with the version label + clean_version="$(echo "$version" | sed 's/-preview$//')" + install_sdk "$clean_version" done for version in "${dotnetRuntimeVersions[@]}"; do diff --git a/src/dotnet/scripts/vendor/README.md b/src/dotnet/scripts/vendor/README.md index 181b53781..9e330e524 100644 --- a/src/dotnet/scripts/vendor/README.md +++ b/src/dotnet/scripts/vendor/README.md @@ -23,5 +23,6 @@ dotnet-install.sh [--version latest] --channel 6.0 [--quality GA] dotnet-install.sh [--version latest] --channel 6.0.4xx [--quality GA] dotnet-install.sh [--version latest] --channel 8.0 --quality preview dotnet-install.sh [--version latest] --channel 8.0 --quality daily +dotnet-install.sh [--version latest] --channel 10.0 --quality preview dotnet-install.sh --version 6.0.413 ``` \ No newline at end of file diff --git a/test/dotnet/install_dotnet_multiple_versions.sh b/test/dotnet/install_dotnet_multiple_versions.sh index 87bf8caf4..482c307b9 100644 --- a/test/dotnet/install_dotnet_multiple_versions.sh +++ b/test/dotnet/install_dotnet_multiple_versions.sh @@ -22,14 +22,8 @@ is_dotnet_sdk_version_installed "8.0" check ".NET SDK 7.0 installed" \ is_dotnet_sdk_version_installed "7.0" -check ".NET SDK 6.0 installed" \ -is_dotnet_sdk_version_installed "6.0" - -check ".NET SDK 5.0 installed" \ -is_dotnet_sdk_version_installed "5.0" - -check ".NET Core SDK 3.1 installed" \ -is_dotnet_sdk_version_installed "3.1" +check ".NET SDK 10.0 installed" \ +is_dotnet_sdk_version_installed "10.0" check "Build example class library" \ dotnet build projects/multitargeting @@ -43,14 +37,8 @@ dotnet run --project projects/net8.0 check "Build and run .NET 7.0 project" \ dotnet run --project projects/net7.0 -check "Build and run .NET 6.0 project" \ -dotnet run --project projects/net6.0 - -check "Build and run .NET 5.0 project" \ -dotnet run --project projects/net5.0 - -check "Build and run .NET Core 3.1 project" \ -dotnet run --project projects/netcoreapp3.1 +check "Build and run .NET 10.0 project" \ +dotnet run --project projects/net10.0 # Report results # If any of the checks above exited with a non-zero exit code, the test will fail. diff --git a/test/dotnet/install_dotnet_multiple_versions_preview.sh b/test/dotnet/install_dotnet_multiple_versions_preview.sh new file mode 100644 index 000000000..76bfd1ae3 --- /dev/null +++ b/test/dotnet/install_dotnet_multiple_versions_preview.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +set -e + +# Optional: Import test library bundled with the devcontainer CLI +# See https://github.com/devcontainers/cli/blob/HEAD/docs/features/test.md#dev-container-features-test-lib +# Provides the 'check' and 'reportResults' commands. +source dev-container-features-test-lib + +# Feature-specific tests +# The 'check' command comes from the dev-container-features-test-lib. Syntax is... +# check