From 9a4639409a19ec122904cd67fb04a6c2e66e5b80 Mon Sep 17 00:00:00 2001 From: Mathiyarasy <157102811+Mathiyarasy@users.noreply.github.com> Date: Mon, 2 Dec 2024 22:44:22 +0530 Subject: [PATCH 001/138] Exclude unsupported image scenarios for Oryx (#1209) * Update test-pr.yaml * Update test-pr.yaml for Oryx feature --- .github/workflows/test-pr.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index 79a34fb66..758ab2b74 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -57,6 +57,11 @@ jobs: "mcr.microsoft.com/devcontainers/base:debian", "mcr.microsoft.com/devcontainers/base:noble" ] + exclude: + - features: oryx + baseImage: ubuntu:jammy + - features: oryx + baseImage: mcr.microsoft.com/devcontainers/base:ubuntu steps: - uses: actions/checkout@v4 From f8e7e275b7ba2808e14a035afd753b83be68e2d9 Mon Sep 17 00:00:00 2001 From: Mathiyarasy <157102811+Mathiyarasy@users.noreply.github.com> Date: Tue, 3 Dec 2024 22:28:40 +0530 Subject: [PATCH 002/138] Oryx Issue (#1181) Universal Image Latest Version: Caused issue in a Pipeline Azure DevOps Pipeline generate-kitchensink-automated Failed This PR aims to do things: The pinned dotnet version now is 8.0.202 : Oryx: Unpin .NET version 8.0.101 Publish oryx app with --self-contained true tag . Without this tag oryx fails to launch stating compatible .net runtime version not found --- src/oryx/devcontainer-feature.json | 2 +- src/oryx/install.sh | 29 +++++++++++++++-------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json index 39b9a7103..1a3ee1b2f 100644 --- a/src/oryx/devcontainer-feature.json +++ b/src/oryx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oryx", - "version": "1.3.6", + "version": "1.3.7", "name": "Oryx", "description": "Installs the oryx CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/oryx", diff --git a/src/oryx/install.sh b/src/oryx/install.sh index 6c193f863..cf67db6b1 100755 --- a/src/oryx/install.sh +++ b/src/oryx/install.sh @@ -149,6 +149,7 @@ DOTNET_BINARY="" if dotnet --version > /dev/null ; then DOTNET_BINARY=$(which dotnet) + RUNTIME_VERSIONS=$(dotnet --list-runtimes | awk '{print $2}' | sort | uniq) fi MAJOR_VERSION_ID=$(echo $(dotnet --version) | cut -d . -f 1) @@ -156,20 +157,17 @@ PATCH_VERSION_ID=$(echo $(dotnet --version) | cut -d . -f 3) PINNED_SDK_VERSION="" # Oryx needs to be built with .NET 8 -if [[ "${DOTNET_BINARY}" = "" ]] || [[ $MAJOR_VERSION_ID != "8" ]] || [[ $MAJOR_VERSION_ID = "8" && ${PATCH_VERSION_ID} -ge "101" ]] ; then +if [[ "${DOTNET_BINARY}" = "" ]] || [[ $MAJOR_VERSION_ID != "8" ]] || [[ $MAJOR_VERSION_ID = "8" && ${PATCH_VERSION_ID} -ne "202" ]] ; then echo "'dotnet 8' was not detected. Attempting to install .NET 8 to build oryx." - # The oryx build fails with .Net 8.0.201, see https://github.com/devcontainers/images/issues/974 # Pinning it to a working version until the upstream Oryx repo updates the dependency # install_dotnet_using_apt - PINNED_SDK_VERSION="8.0.101" + PINNED_SDK_VERSION="8.0.202" install_dotnet_with_script ${PINNED_SDK_VERSION} - if ! dotnet --version > /dev/null ; then echo "(!) Please install Dotnet before installing Oryx" exit 1 fi - fi BUILD_SCRIPT_GENERATOR=/usr/local/buildscriptgen @@ -192,8 +190,8 @@ echo "Building solution '$SOLUTION_FILE_NAME'..." cd $GIT_ORYX ${DOTNET_BINARY} build "$SOLUTION_FILE_NAME" -c Debug -${DOTNET_BINARY} publish -property:ValidateExecutableReferencesMatchSelfContained=false -r linux-x64 -o ${BUILD_SCRIPT_GENERATOR} -c Release $GIT_ORYX/src/BuildScriptGeneratorCli/BuildScriptGeneratorCli.csproj -${DOTNET_BINARY} publish -r linux-x64 -o ${BUILD_SCRIPT_GENERATOR} -c Release $GIT_ORYX/src/BuildServer/BuildServer.csproj +${DOTNET_BINARY} publish -property:ValidateExecutableReferencesMatchSelfContained=false -r linux-x64 -o ${BUILD_SCRIPT_GENERATOR} -c Release $GIT_ORYX/src/BuildScriptGeneratorCli/BuildScriptGeneratorCli.csproj --self-contained true +${DOTNET_BINARY} publish -r linux-x64 -o ${BUILD_SCRIPT_GENERATOR} -c Release $GIT_ORYX/src/BuildServer/BuildServer.csproj --self-contained true chmod a+x ${BUILD_SCRIPT_GENERATOR}/GenerateBuildScript @@ -236,16 +234,19 @@ fi if [[ "${PINNED_SDK_VERSION}" != "" ]]; then rm -f ${GIT_ORYX}/global.json rm -rf /usr/share/dotnet/sdk/$PINNED_SDK_VERSION - - # Extract the major, minor version and the first digit of the patch version - MAJOR_MINOR_PATCH1_VERSION=${PINNED_SDK_VERSION%??} - rm -rf /usr/share/dotnet/shared/Microsoft.NETCore.App/$MAJOR_MINOR_PATCH1_VERSION - rm -rf /usr/share/dotnet/shared/Microsoft.AspNetCore.App/$MAJOR_MINOR_PATCH1_VERSION - rm -rf /usr/share/dotnet/templates/$MAJOR_MINOR_PATCH1_VERSION + NEW_RUNTIME_VERSIONS=$(dotnet --list-runtimes | awk '{print $2}' | sort | uniq) + if [ -n "${RUNTIME_VERSIONS:-}" ]; then + SDK_INSTALLED_RUNTIME=$(echo "$NEW_RUNTIME_VERSIONS" | grep -vxFf <(echo "$RUNTIME_VERSIONS")) + else + SDK_INSTALLED_RUNTIME="$NEW_RUNTIME_VERSIONS" + fi + rm -rf /usr/share/dotnet/shared/Microsoft.NETCore.App/$SDK_INSTALLED_RUNTIME + rm -rf /usr/share/dotnet/shared/Microsoft.AspNetCore.App/$SDK_INSTALLED_RUNTIME + rm -rf /usr/share/dotnet/templates/$SDK_INSTALLED_RUNTIME fi # Clean up rm -rf /var/lib/apt/lists/* -echo "Done!" +echo "Done!" \ No newline at end of file From 8e8e14f6fbb1f1c30e7794aff293960caba2945a Mon Sep 17 00:00:00 2001 From: Mathiyarasy <157102811+Mathiyarasy@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:31:43 +0530 Subject: [PATCH 003/138] Codespace unable to start in Jupyter using python feature with option "installJupyterLab": true (#1199) * Add path for JupyterLab * Remove unwanted code --- src/python/devcontainer-feature.json | 12 +++++------ src/python/install.sh | 20 +++++++------------ test/python/install_jupyterlab.sh | 4 ++-- .../Dockerfile | 5 ----- .../sudoers.test | 2 -- test/python/scenarios.json | 13 ------------ 6 files changed, 15 insertions(+), 41 deletions(-) delete mode 100644 test/python/install_jupyterlab_existing_sudoers_file/Dockerfile delete mode 100644 test/python/install_jupyterlab_existing_sudoers_file/sudoers.test diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index 64b02fd34..64976fc63 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.6.5", + "version": "1.7.0", "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.", @@ -67,7 +67,7 @@ "PYTHON_PATH": "/usr/local/python/current", "PIPX_HOME": "/usr/local/py-utils", "PIPX_BIN_DIR": "/usr/local/py-utils/bin", - "PATH": "/usr/local/python/current/bin:/usr/local/py-utils/bin:${PATH}" + "PATH": "/usr/local/python/current/bin:/usr/local/py-utils/bin:/usr/local/jupyter:${PATH}" }, "customizations": { "vscode": { @@ -78,9 +78,9 @@ ], "settings": { "python.defaultInterpreterPath": "/usr/local/python/current/bin/python", - "[python]": { - "editor.defaultFormatter": "ms-python.autopep8" - } + "[python]": { + "editor.defaultFormatter": "ms-python.autopep8" + } } } }, @@ -88,4 +88,4 @@ "ghcr.io/devcontainers/features/common-utils", "ghcr.io/devcontainers/features/oryx" ] -} +} \ No newline at end of file diff --git a/src/python/install.sh b/src/python/install.sh index ead55cc8a..b3311c7c6 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -912,21 +912,15 @@ if [ "${INSTALL_JUPYTERLAB}" = "true" ]; then install_user_package $INSTALL_UNDER_ROOT jupyterlab install_user_package $INSTALL_UNDER_ROOT jupyterlab-git + # Create a symlink to the JupyterLab binary for non root users if [ "$INSTALL_UNDER_ROOT" = false ]; then - # JupyterLab would have installed into /home/${USERNAME}/.local/bin - # Adding it to default path for Codespaces which use non-login shells - SUDOERS_FILE="/etc/sudoers.d/$USERNAME" - SEARCH_STR="Defaults secure_path=" - REPLACE_STR="Defaults secure_path=/home/${USERNAME}/.local/bin" - - if grep -qs ${SEARCH_STR} ${SUDOERS_FILE}; then - # string found and file is present - sed -i "s|${SEARCH_STR}|${REPLACE_STR}:|g" "${SUDOERS_FILE}" - else - # either string is not found, or file is not present - # In either case take same action, note >> places at end of file - echo "${REPLACE_STR}:${PATH}" >> ${SUDOERS_FILE} + JUPYTER_INPATH=/home/${USERNAME}/.local/bin + if [ ! -d "$JUPYTER_INPATH" ]; then + echo "Error: $JUPYTER_INPATH does not exist." + exit 1 fi + JUPYTER_PATH=/usr/local/jupyter + ln -s "$JUPYTER_INPATH" "$JUPYTER_PATH" fi # Configure JupyterLab if needed diff --git a/test/python/install_jupyterlab.sh b/test/python/install_jupyterlab.sh index 033b44edd..255b4e896 100755 --- a/test/python/install_jupyterlab.sh +++ b/test/python/install_jupyterlab.sh @@ -22,8 +22,8 @@ check "jupyterlab_git" grep jupyterlab_git <<< "$packages" # Check for correct JupyterLab configuration check "config" grep ".*.allow_origin = '*'" /home/vscode/.jupyter/jupyter_server_config.py -# Check for PATH modification -check "default path has jupyterlab" sudo grep "/home/${user}/.local/bin" /etc/sudoers.d/$user +#check "default path has jupyterlab symlink" +check "default path has jupyterlab" test -L "/usr/local/jupyter" # Report result reportResults diff --git a/test/python/install_jupyterlab_existing_sudoers_file/Dockerfile b/test/python/install_jupyterlab_existing_sudoers_file/Dockerfile deleted file mode 100644 index 5acb58a37..000000000 --- a/test/python/install_jupyterlab_existing_sudoers_file/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -# Builds an image with a preconfigured SUDOERS file -# Used to test the install script for JupyterLab which modifies this file -FROM mcr.microsoft.com/devcontainers/base:focal - -COPY --chown=root sudoers.test /etc/sudoers.d/vscode diff --git a/test/python/install_jupyterlab_existing_sudoers_file/sudoers.test b/test/python/install_jupyterlab_existing_sudoers_file/sudoers.test deleted file mode 100644 index 9a26d777b..000000000 --- a/test/python/install_jupyterlab_existing_sudoers_file/sudoers.test +++ /dev/null @@ -1,2 +0,0 @@ -# Sudoers File for testing, after install script runs the Defaults secure_path should be appended to -Defaults secure_path=/original_content_of_sudoers_file \ No newline at end of file diff --git a/test/python/scenarios.json b/test/python/scenarios.json index e4fe0f0cd..be37869df 100644 --- a/test/python/scenarios.json +++ b/test/python/scenarios.json @@ -68,19 +68,6 @@ } } }, - "install_jupyterlab_existing_sudoers_file": { - "build": { - "dockerfile": "Dockerfile" - }, - "remoteUser": "vscode", - "features": { - "python": { - "version": "latest", - "installJupyterlab": true, - "configureJupyterlabAllowOrigin": "*" - } - } - }, "install_jupyterlab_rhel_family": { "image": "almalinux:8", "remoteUser": "vscode", From 978aa3f8b8a49d4e8a8bc0f7e5fdb55eb94a09fa Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 9 Jan 2025 19:09:12 +0100 Subject: [PATCH 004/138] Use new CDN for dotnet builds (#1230) The azureedge.net domain might stop working as detailed in dotnet/core#9671 Changes in this PR: dotnet: update the logic to determine the latest version dotnet and oryx: copy latest dotnet-install script from https://github.com/dotnet/install-scripts/blob/main/src/dotnet-install.sh (Normally this happens automatically by a GitHub Action, but there is a sense of urgency here, so I did it manually) Additional context https://devblogs.microsoft.com/dotnet/critical-dotnet-install-links-are-changing/ https://build5nines.com/retirement-of-azureedge-net-dns-edg-io-business-closure-and-what-you-need-to-know/ --- src/dotnet/devcontainer-feature.json | 2 +- src/dotnet/scripts/dotnet-helpers.sh | 6 +- src/dotnet/scripts/vendor/dotnet-install.sh | 123 +++++++++++++++--- src/oryx/devcontainer-feature.json | 2 +- src/oryx/scripts/vendor/dotnet-install.sh | 123 +++++++++++++++--- test/dotnet/dotnet_helpers.sh | 6 +- ...all_dotnet_latest_when_version_is_empty.sh | 3 - test/dotnet/install_dotnet_lts.sh | 3 - .../install_dotnet_multiple_versions.sh | 27 ++++ .../multitargeting/example_classlib.csproj | 2 +- .../projects/net5.0/example_project.csproj | 2 +- .../projects/net6.0/example_project.csproj | 2 +- .../projects/net7.0/example_project.csproj | 2 +- .../projects/net8.0/example_project.csproj | 2 +- test/dotnet/projects/net9.0/Program.cs | 32 +++++ .../projects/net9.0/example_project.csproj | 14 ++ .../netcoreapp3.1/example_project.csproj | 3 +- test/dotnet/scenarios.json | 9 +- test/dotnet/test.sh | 3 - 19 files changed, 307 insertions(+), 59 deletions(-) create mode 100644 test/dotnet/projects/net9.0/Program.cs create mode 100644 test/dotnet/projects/net9.0/example_project.csproj diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index f6e0c39ab..600997dde 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "2.1.3", + "version": "2.2.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.", diff --git a/src/dotnet/scripts/dotnet-helpers.sh b/src/dotnet/scripts/dotnet-helpers.sh index 26e29fa36..84a674917 100644 --- a/src/dotnet/scripts/dotnet-helpers.sh +++ b/src/dotnet/scripts/dotnet-helpers.sh @@ -18,11 +18,11 @@ fetch_latest_version_in_channel() { local channel="$1" local runtime="$2" if [ "$runtime" = "dotnet" ]; then - wget -qO- "https://dotnetcli.azureedge.net/dotnet/Runtime/$channel/latest.version" + wget -qO- "https://builds.dotnet.microsoft.com/dotnet/Runtime/$channel/latest.version" elif [ "$runtime" = "aspnetcore" ]; then - wget -qO- "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/$channel/latest.version" + wget -qO- "https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/$channel/latest.version" else - wget -qO- "https://dotnetcli.azureedge.net/dotnet/Sdk/$channel/latest.version" + wget -qO- "https://builds.dotnet.microsoft.com/dotnet/Sdk/$channel/latest.version" fi } diff --git a/src/dotnet/scripts/vendor/dotnet-install.sh b/src/dotnet/scripts/vendor/dotnet-install.sh index 38a160cf1..122ee68ed 100755 --- a/src/dotnet/scripts/vendor/dotnet-install.sh +++ b/src/dotnet/scripts/vendor/dotnet-install.sh @@ -423,11 +423,17 @@ get_normalized_architecture_for_specific_sdk_version() { # args: # version or channel - $1 is_arm64_supported() { - #any channel or version that starts with the specified versions - case "$1" in - ( "1"* | "2"* | "3"* | "4"* | "5"*) - echo false - return 0 + # Extract the major version by splitting on the dot + major_version="${1%%.*}" + + # Check if the major version is a valid number and less than 6 + case "$major_version" in + [0-9]*) + if [ "$major_version" -lt 6 ]; then + echo false + return 0 + fi + ;; esac echo true @@ -950,6 +956,37 @@ get_absolute_path() { return 0 } +# args: +# override - $1 (boolean, true or false) +get_cp_options() { + eval $invocation + + local override="$1" + local override_switch="" + + if [ "$override" = false ]; then + override_switch="-n" + + # create temporary files to check if 'cp -u' is supported + tmp_dir="$(mktemp -d)" + tmp_file="$tmp_dir/testfile" + tmp_file2="$tmp_dir/testfile2" + + touch "$tmp_file" + + # use -u instead of -n if it's available + if cp -u "$tmp_file" "$tmp_file2" 2>/dev/null; then + override_switch="-u" + fi + + # clean up + rm -f "$tmp_file" "$tmp_file2" + rm -rf "$tmp_dir" + fi + + echo "$override_switch" +} + # args: # input_files - stdin # root_path - $1 @@ -961,15 +998,7 @@ copy_files_or_dirs_from_list() { local root_path="$(remove_trailing_slash "$1")" local out_path="$(remove_trailing_slash "$2")" local override="$3" - local osname="$(get_current_os_name)" - local override_switch=$( - if [ "$override" = false ]; then - if [ "$osname" = "linux-musl" ]; then - printf -- "-u"; - else - printf -- "-n"; - fi - fi) + local override_switch="$(get_cp_options "$override")" cat | uniq | while read -r file_path; do local path="$(remove_beginning_slash "${file_path#$root_path}")" @@ -1243,6 +1272,61 @@ downloadwget() { return 0 } +extract_stem() { + local url="$1" + # extract the protocol + proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')" + # remove the protocol + url="${1/$proto/}" + # extract the path (if any) - since we know all of our feeds have a first path segment, we can skip the first one. otherwise we'd use -f2- to get the full path + full_path="$(echo $url | grep / | cut -d/ -f2-)" + path="$(echo $full_path | cut -d/ -f2-)" + echo $path +} + +check_url_exists() { + eval $invocation + local url="$1" + + local code="" + if machine_has "curl" + then + code=$(curl --head -o /dev/null -w "%{http_code}" -s --fail "$url"); + elif machine_has "wget" + then + # get the http response, grab the status code + server_response=$(wget -qO- --method=HEAD --server-response "$url" 2>&1) + code=$(echo "$server_response" | grep "HTTP/" | awk '{print $2}') + fi + if [ $code = "200" ]; then + return 0 + else + return 1 + fi +} + +sanitize_redirect_url() { + eval $invocation + + local url_stem + url_stem=$(extract_stem "$1") + say_verbose "Checking configured feeds for the asset at ${yellow:-}$url_stem${normal:-}" + + for feed in "${feeds[@]}" + do + local trial_url="$feed/$url_stem" + say_verbose "Checking ${yellow:-}$trial_url${normal:-}" + if check_url_exists "$trial_url"; then + say_verbose "Found a match at ${yellow:-}$trial_url${normal:-}" + echo "$trial_url" + return 0 + else + say_verbose "No match at ${yellow:-}$trial_url${normal:-}" + fi + done + return 1 +} + get_download_link_from_aka_ms() { eval $invocation @@ -1295,6 +1379,11 @@ get_download_link_from_aka_ms() { return 1 fi + sanitized_redirect_url=$(sanitize_redirect_url "$aka_ms_download_link") + if [[ -n "$sanitized_redirect_url" ]]; then + aka_ms_download_link="$sanitized_redirect_url" + fi + say_verbose "The redirect location retrieved: '$aka_ms_download_link'." return 0 else @@ -1306,7 +1395,9 @@ get_download_link_from_aka_ms() { get_feeds_to_use() { feeds=( + "https://builds.dotnet.microsoft.com/dotnet" "https://dotnetcli.azureedge.net/dotnet" + "https://ci.dot.net/public" "https://dotnetbuilds.azureedge.net/public" ) @@ -1735,7 +1826,7 @@ do zip_path="$1" ;; -?|--?|-h|--help|-[Hh]elp) - script_name="$(basename "$0")" + script_name="dotnet-install.sh" echo ".NET Tools Installer" echo "Usage:" echo " # Install a .NET SDK of a given Quality from a given Channel" @@ -1865,4 +1956,4 @@ fi say "Note that the script does not resolve dependencies during installation." say "To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section." -say "Installation finished successfully." +say "Installation finished successfully." \ No newline at end of file diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json index 1a3ee1b2f..ab9a8e782 100644 --- a/src/oryx/devcontainer-feature.json +++ b/src/oryx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oryx", - "version": "1.3.7", + "version": "1.4.0", "name": "Oryx", "description": "Installs the oryx CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/oryx", diff --git a/src/oryx/scripts/vendor/dotnet-install.sh b/src/oryx/scripts/vendor/dotnet-install.sh index 38a160cf1..122ee68ed 100755 --- a/src/oryx/scripts/vendor/dotnet-install.sh +++ b/src/oryx/scripts/vendor/dotnet-install.sh @@ -423,11 +423,17 @@ get_normalized_architecture_for_specific_sdk_version() { # args: # version or channel - $1 is_arm64_supported() { - #any channel or version that starts with the specified versions - case "$1" in - ( "1"* | "2"* | "3"* | "4"* | "5"*) - echo false - return 0 + # Extract the major version by splitting on the dot + major_version="${1%%.*}" + + # Check if the major version is a valid number and less than 6 + case "$major_version" in + [0-9]*) + if [ "$major_version" -lt 6 ]; then + echo false + return 0 + fi + ;; esac echo true @@ -950,6 +956,37 @@ get_absolute_path() { return 0 } +# args: +# override - $1 (boolean, true or false) +get_cp_options() { + eval $invocation + + local override="$1" + local override_switch="" + + if [ "$override" = false ]; then + override_switch="-n" + + # create temporary files to check if 'cp -u' is supported + tmp_dir="$(mktemp -d)" + tmp_file="$tmp_dir/testfile" + tmp_file2="$tmp_dir/testfile2" + + touch "$tmp_file" + + # use -u instead of -n if it's available + if cp -u "$tmp_file" "$tmp_file2" 2>/dev/null; then + override_switch="-u" + fi + + # clean up + rm -f "$tmp_file" "$tmp_file2" + rm -rf "$tmp_dir" + fi + + echo "$override_switch" +} + # args: # input_files - stdin # root_path - $1 @@ -961,15 +998,7 @@ copy_files_or_dirs_from_list() { local root_path="$(remove_trailing_slash "$1")" local out_path="$(remove_trailing_slash "$2")" local override="$3" - local osname="$(get_current_os_name)" - local override_switch=$( - if [ "$override" = false ]; then - if [ "$osname" = "linux-musl" ]; then - printf -- "-u"; - else - printf -- "-n"; - fi - fi) + local override_switch="$(get_cp_options "$override")" cat | uniq | while read -r file_path; do local path="$(remove_beginning_slash "${file_path#$root_path}")" @@ -1243,6 +1272,61 @@ downloadwget() { return 0 } +extract_stem() { + local url="$1" + # extract the protocol + proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')" + # remove the protocol + url="${1/$proto/}" + # extract the path (if any) - since we know all of our feeds have a first path segment, we can skip the first one. otherwise we'd use -f2- to get the full path + full_path="$(echo $url | grep / | cut -d/ -f2-)" + path="$(echo $full_path | cut -d/ -f2-)" + echo $path +} + +check_url_exists() { + eval $invocation + local url="$1" + + local code="" + if machine_has "curl" + then + code=$(curl --head -o /dev/null -w "%{http_code}" -s --fail "$url"); + elif machine_has "wget" + then + # get the http response, grab the status code + server_response=$(wget -qO- --method=HEAD --server-response "$url" 2>&1) + code=$(echo "$server_response" | grep "HTTP/" | awk '{print $2}') + fi + if [ $code = "200" ]; then + return 0 + else + return 1 + fi +} + +sanitize_redirect_url() { + eval $invocation + + local url_stem + url_stem=$(extract_stem "$1") + say_verbose "Checking configured feeds for the asset at ${yellow:-}$url_stem${normal:-}" + + for feed in "${feeds[@]}" + do + local trial_url="$feed/$url_stem" + say_verbose "Checking ${yellow:-}$trial_url${normal:-}" + if check_url_exists "$trial_url"; then + say_verbose "Found a match at ${yellow:-}$trial_url${normal:-}" + echo "$trial_url" + return 0 + else + say_verbose "No match at ${yellow:-}$trial_url${normal:-}" + fi + done + return 1 +} + get_download_link_from_aka_ms() { eval $invocation @@ -1295,6 +1379,11 @@ get_download_link_from_aka_ms() { return 1 fi + sanitized_redirect_url=$(sanitize_redirect_url "$aka_ms_download_link") + if [[ -n "$sanitized_redirect_url" ]]; then + aka_ms_download_link="$sanitized_redirect_url" + fi + say_verbose "The redirect location retrieved: '$aka_ms_download_link'." return 0 else @@ -1306,7 +1395,9 @@ get_download_link_from_aka_ms() { get_feeds_to_use() { feeds=( + "https://builds.dotnet.microsoft.com/dotnet" "https://dotnetcli.azureedge.net/dotnet" + "https://ci.dot.net/public" "https://dotnetbuilds.azureedge.net/public" ) @@ -1735,7 +1826,7 @@ do zip_path="$1" ;; -?|--?|-h|--help|-[Hh]elp) - script_name="$(basename "$0")" + script_name="dotnet-install.sh" echo ".NET Tools Installer" echo "Usage:" echo " # Install a .NET SDK of a given Quality from a given Channel" @@ -1865,4 +1956,4 @@ fi say "Note that the script does not resolve dependencies during installation." say "To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section." -say "Installation finished successfully." +say "Installation finished successfully." \ No newline at end of file diff --git a/test/dotnet/dotnet_helpers.sh b/test/dotnet/dotnet_helpers.sh index a24bd1ce2..01e554f66 100644 --- a/test/dotnet/dotnet_helpers.sh +++ b/test/dotnet/dotnet_helpers.sh @@ -9,11 +9,11 @@ fetch_latest_version_in_channel() { local channel="$1" local runtime="$2" if [ "$runtime" = "dotnet" ]; then - wget -qO- "https://dotnetcli.azureedge.net/dotnet/Runtime/$channel/latest.version" + wget -qO- "https://builds.dotnet.microsoft.com/dotnet/Runtime/$channel/latest.version" elif [ "$runtime" = "aspnetcore" ]; then - wget -qO- "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/$channel/latest.version" + wget -qO- "https://builds.dotnet.microsoft.com/dotnet/aspnetcore/Runtime/$channel/latest.version" else - wget -qO- "https://dotnetcli.azureedge.net/dotnet/Sdk/$channel/latest.version" + wget -qO- "https://builds.dotnet.microsoft.com/dotnet/Sdk/$channel/latest.version" fi } diff --git a/test/dotnet/install_dotnet_latest_when_version_is_empty.sh b/test/dotnet/install_dotnet_latest_when_version_is_empty.sh index cd23edcf1..b28c45a2f 100644 --- a/test/dotnet/install_dotnet_latest_when_version_is_empty.sh +++ b/test/dotnet/install_dotnet_latest_when_version_is_empty.sh @@ -18,9 +18,6 @@ expected=$(fetch_latest_version) check "Latest .NET SDK version installed" \ is_dotnet_sdk_version_installed "$expected" -check "Build and run example project" \ -dotnet run --project projects/net8.0 - # Report results # If any of the checks above exited with a non-zero exit code, the test will fail. reportResults \ No newline at end of file diff --git a/test/dotnet/install_dotnet_lts.sh b/test/dotnet/install_dotnet_lts.sh index bc2d40782..da9175c15 100644 --- a/test/dotnet/install_dotnet_lts.sh +++ b/test/dotnet/install_dotnet_lts.sh @@ -18,9 +18,6 @@ expected=$(fetch_latest_version_in_channel "LTS") check "Latest LTS version installed" \ is_dotnet_sdk_version_installed "$expected" -check "Build and run example project" \ -dotnet run --project projects/net8.0 - # Report results # If any of the checks above exited with a non-zero exit code, the test will fail. reportResults \ 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 5f0f12533..87bf8caf4 100644 --- a/test/dotnet/install_dotnet_multiple_versions.sh +++ b/test/dotnet/install_dotnet_multiple_versions.sh @@ -13,6 +13,9 @@ source dev-container-features-test-lib source dotnet_env.sh source dotnet_helpers.sh +check ".NET SDK 9.0 installed" \ +is_dotnet_sdk_version_installed "9.0" + check ".NET SDK 8.0 installed" \ is_dotnet_sdk_version_installed "8.0" @@ -22,9 +25,33 @@ 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 "Build example class library" \ dotnet build projects/multitargeting +check "Build and run .NET 9.0 project" \ +dotnet run --project projects/net9.0 + +check "Build and run .NET 8.0 project" \ +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 + # Report results # If any of the checks above exited with a non-zero exit code, the test will fail. reportResults \ No newline at end of file diff --git a/test/dotnet/projects/multitargeting/example_classlib.csproj b/test/dotnet/projects/multitargeting/example_classlib.csproj index ba47b0f46..8a8ca0c32 100644 --- a/test/dotnet/projects/multitargeting/example_classlib.csproj +++ b/test/dotnet/projects/multitargeting/example_classlib.csproj @@ -1,7 +1,7 @@ - net8.0;net7.0;net6.0 + net9.0;net8.0;net7.0;net6.0 enable enable diff --git a/test/dotnet/projects/net5.0/example_project.csproj b/test/dotnet/projects/net5.0/example_project.csproj index 63450c349..9fa0cf3f7 100644 --- a/test/dotnet/projects/net5.0/example_project.csproj +++ b/test/dotnet/projects/net5.0/example_project.csproj @@ -7,7 +7,7 @@ - + \ No newline at end of file diff --git a/test/dotnet/projects/net6.0/example_project.csproj b/test/dotnet/projects/net6.0/example_project.csproj index aa2434cb7..48c9b4e8a 100644 --- a/test/dotnet/projects/net6.0/example_project.csproj +++ b/test/dotnet/projects/net6.0/example_project.csproj @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/test/dotnet/projects/net7.0/example_project.csproj b/test/dotnet/projects/net7.0/example_project.csproj index 424f54ae7..11953d275 100644 --- a/test/dotnet/projects/net7.0/example_project.csproj +++ b/test/dotnet/projects/net7.0/example_project.csproj @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/test/dotnet/projects/net8.0/example_project.csproj b/test/dotnet/projects/net8.0/example_project.csproj index 2f1f60891..ddac9409e 100644 --- a/test/dotnet/projects/net8.0/example_project.csproj +++ b/test/dotnet/projects/net8.0/example_project.csproj @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/test/dotnet/projects/net9.0/Program.cs b/test/dotnet/projects/net9.0/Program.cs new file mode 100644 index 000000000..59fb426af --- /dev/null +++ b/test/dotnet/projects/net9.0/Program.cs @@ -0,0 +1,32 @@ +using Newtonsoft.Json; + +string json = """ +{ + "Name": "Inception", + "ReleaseDate": "2010-07-08T00:00:00", + "Genres": [ + "Action", + "Thriller" + ] +} +"""; + +Movie? m = JsonConvert.DeserializeObject(json); + +if (m == default) +{ + Console.WriteLine("Decoding failed!"); +} +else +{ + Console.WriteLine($"Movie name: {m.Name}"); + Console.WriteLine($"Release Date: {m.ReleaseDate}"); + Console.WriteLine($"Genres: {string.Join(", ", m.Genres)}"); +} + +class Movie(string? name, DateTime releaseDate, List? genres) +{ + public string Name { get; set; } = name ?? "Default Name"; + public DateTime ReleaseDate { get; set; } = releaseDate; + public List Genres { get; set; } = genres ?? []; +} \ No newline at end of file diff --git a/test/dotnet/projects/net9.0/example_project.csproj b/test/dotnet/projects/net9.0/example_project.csproj new file mode 100644 index 000000000..6cc1da0d0 --- /dev/null +++ b/test/dotnet/projects/net9.0/example_project.csproj @@ -0,0 +1,14 @@ + + + + Exe + net9.0 + enable + enable + + + + + + + \ No newline at end of file diff --git a/test/dotnet/projects/netcoreapp3.1/example_project.csproj b/test/dotnet/projects/netcoreapp3.1/example_project.csproj index e2e909c17..f8859db8b 100644 --- a/test/dotnet/projects/netcoreapp3.1/example_project.csproj +++ b/test/dotnet/projects/netcoreapp3.1/example_project.csproj @@ -3,12 +3,11 @@ Exe netcoreapp3.1 - enable enable - + \ No newline at end of file diff --git a/test/dotnet/scenarios.json b/test/dotnet/scenarios.json index 2fd74f587..641753632 100644 --- a/test/dotnet/scenarios.json +++ b/test/dotnet/scenarios.json @@ -40,10 +40,13 @@ "remoteUser": "vscode", "features": { "dotnet": { - "version": "8.0.100-preview.6.23330.14", + "version": "9.0", "additionalVersions": [ + "8.0", "7.0", - "6.0" + "6.0", + "5.0", + "3.1" ] } } @@ -92,4 +95,4 @@ } } } -} +} \ No newline at end of file diff --git a/test/dotnet/test.sh b/test/dotnet/test.sh index 50d79941f..11cc73126 100644 --- a/test/dotnet/test.sh +++ b/test/dotnet/test.sh @@ -24,9 +24,6 @@ expected=$(fetch_latest_version) check "Latest .NET SDK version installed" \ is_dotnet_sdk_version_installed "$expected" -check "Build and run example project" \ -dotnet run --project projects/net8.0 - # Report results # If any of the checks above exited with a non-zero exit code, the test will fail. reportResults \ No newline at end of file From d9c2de0cd12443406048e81bc859a5f09e7d23ef Mon Sep 17 00:00:00 2001 From: Prathamesh Zarkar <159782310+prathameshzarkar9@users.noreply.github.com> Date: Wed, 15 Jan 2025 22:36:35 +0530 Subject: [PATCH 005/138] auto find cudnn version (#1126) * auto find cudnn version * auto finding libcudnn8 and libcudnn9 packages * removed unused files * nvidia-cuda feature patch version bumped * review comments addressed * review comments addressed * --fix-missing added for apt-get update * test cases fixed for libcudnn check * test updatedfor cudnnVersion without automatic --- src/nvidia-cuda/devcontainer-feature.json | 5 ++-- src/nvidia-cuda/install.sh | 21 +++++++++++---- test/nvidia-cuda/install_cuda_12_3_version.sh | 15 +++++++++++ test/nvidia-cuda/install_cuda_12_4_version.sh | 15 +++++++++++ test/nvidia-cuda/install_cuda_12_5_version.sh | 15 +++++++++++ test/nvidia-cuda/install_cudnn_123_version.sh | 16 ------------ test/nvidia-cuda/install_cudnn_124_version.sh | 16 ------------ .../install_cudnn_latest_version.sh | 16 ------------ test/nvidia-cuda/scenarios.json | 26 +++++++------------ 9 files changed, 74 insertions(+), 71 deletions(-) create mode 100644 test/nvidia-cuda/install_cuda_12_3_version.sh create mode 100644 test/nvidia-cuda/install_cuda_12_4_version.sh create mode 100644 test/nvidia-cuda/install_cuda_12_5_version.sh delete mode 100644 test/nvidia-cuda/install_cudnn_123_version.sh delete mode 100644 test/nvidia-cuda/install_cudnn_124_version.sh delete mode 100644 test/nvidia-cuda/install_cudnn_latest_version.sh diff --git a/src/nvidia-cuda/devcontainer-feature.json b/src/nvidia-cuda/devcontainer-feature.json index b46d7c433..d29074fd9 100644 --- a/src/nvidia-cuda/devcontainer-feature.json +++ b/src/nvidia-cuda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nvidia-cuda", - "version": "1.1.3", + "version": "1.2.0", "name": "NVIDIA CUDA", "description": "Installs shared libraries for NVIDIA CUDA.", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/nvidia-cuda", @@ -48,6 +48,7 @@ "cudnnVersion": { "type": "string", "proposals": [ + "automatic", "8.9.5.29", "8.9.4.25", "8.9.3.28", @@ -79,7 +80,7 @@ "9.3.0.75", "9.4.0.58" ], - "default": "8.6.0.163", + "default": "automatic", "description": "Version of cuDNN to install" } }, diff --git a/src/nvidia-cuda/install.sh b/src/nvidia-cuda/install.sh index 37ba7f0f4..1cfc7668e 100644 --- a/src/nvidia-cuda/install.sh +++ b/src/nvidia-cuda/install.sh @@ -59,8 +59,6 @@ apt-get update -yq cuda_pkg="cuda-libraries-${CUDA_VERSION/./-}" nvtx_pkg="cuda-nvtx-${CUDA_VERSION/./-}" toolkit_pkg="cuda-toolkit-${CUDA_VERSION/./-}" -major_cudnn_version=$(echo "${CUDNN_VERSION}" | cut -d '.' -f 1) -major_cuda_version=$(echo "${CUDA_VERSION}" | cut -d '.' -f 1) if ! apt-cache show "$cuda_pkg"; then echo "The requested version of CUDA is not available: CUDA $CUDA_VERSION" exit 1 @@ -68,11 +66,23 @@ fi echo "Installing CUDA libraries..." apt-get install -yq "$cuda_pkg" +apt-get update -yq --fix-missing + +# auto find recent cudnn version +major_cuda_version=$(echo "${CUDA_VERSION}" | cut -d '.' -f 1) +if [ "$CUDNN_VERSION" = "automatic" ]; then + if [[ "$CUDA_VERSION" < "12.3" ]]; then + CUDNN_VERSION=$(apt-cache policy libcudnn8 | grep "$CUDA_VERSION" | grep -Eo '^[^-1+]*' | sort -V | tail -n1 | xargs) + else + CUDNN_VERSION=$(apt-cache policy libcudnn9-cuda-$major_cuda_version | grep "Candidate" | awk '{print $2}' | grep -Eo '^[^-1+]*') + fi +fi +major_cudnn_version=$(echo "${CUDNN_VERSION}" | cut -d '.' -f 1) if [ "$INSTALL_CUDNN" = "true" ]; then # Ensure that the requested version of cuDNN is available AND compatible - #if major cudnn version is 9, then we need to install libcudnn9-cuda- package - #else we need to install libcudnn8-cuda- package + #if major cudnn version is 9, then we need to install libcudnn9-cuda-_-1 package + #else we need to install libcudnn8_-1+cuda" package if [[ $major_cudnn_version -ge "9" ]] then cudnn_pkg_version="libcudnn9-cuda-${major_cuda_version}=${CUDNN_VERSION}-1" @@ -91,13 +101,14 @@ fi if [ "$INSTALL_CUDNNDEV" = "true" ]; then # Ensure that the requested version of cuDNN development package is available AND compatible + #if major cudnn version is 9, then we need to install libcudnn9-dev-cuda-_-1 package + #else we need to install libcudnn8-dev_-1+cuda" package if [[ $major_cudnn_version -ge "9" ]] then cudnn_dev_pkg_version="libcudnn9-dev-cuda-${major_cuda_version}=${CUDNN_VERSION}-1" else cudnn_dev_pkg_version="libcudnn8-dev=${CUDNN_VERSION}-1+cuda${CUDA_VERSION}" fi - if ! apt-cache show "$cudnn_dev_pkg_version"; then echo "The requested version of cuDNN development package is not available: cuDNN $CUDNN_VERSION for CUDA $CUDA_VERSION" exit 1 diff --git a/test/nvidia-cuda/install_cuda_12_3_version.sh b/test/nvidia-cuda/install_cuda_12_3_version.sh new file mode 100644 index 000000000..95d4e8bdc --- /dev/null +++ b/test/nvidia-cuda/install_cuda_12_3_version.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# # Check installation of libcudnn9-cuda-12 (9.4.0) +check "libcudnn.so.9.5.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.5.0' | wc -l)" + +# Check installation of cuda-nvtx-12-3 (12.3) +check "cuda-12-3+nvtx" test -e '/usr/local/cuda-12.3/targets/x86_64-linux/include/nvtx3/' + +# Report result +reportResults diff --git a/test/nvidia-cuda/install_cuda_12_4_version.sh b/test/nvidia-cuda/install_cuda_12_4_version.sh new file mode 100644 index 000000000..77ecbf190 --- /dev/null +++ b/test/nvidia-cuda/install_cuda_12_4_version.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# # Check installation of libcudnn9-cuda-12 (9.4.0) +check "libcudnn.so.9.5.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.5.0' | wc -l)" + +# Check installation of cuda-nvtx-12-4 (12.4) +check "cuda-12-4+nvtx" test -e '/usr/local/cuda-12.4/targets/x86_64-linux/include/nvtx3/' + +# Report result +reportResults diff --git a/test/nvidia-cuda/install_cuda_12_5_version.sh b/test/nvidia-cuda/install_cuda_12_5_version.sh new file mode 100644 index 000000000..05cd20c88 --- /dev/null +++ b/test/nvidia-cuda/install_cuda_12_5_version.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# # Check installation of libcudnn9-cuda-12 (9.4.0) +check "libcudnn.so.9.5.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.5.0' | wc -l)" + +# Check installation of cuda-nvtx-12-5 (12.5) +check "cuda-12-5+nvtx" test -e '/usr/local/cuda-12.5/targets/x86_64-linux/include/nvtx3/' + +# Report result +reportResults diff --git a/test/nvidia-cuda/install_cudnn_123_version.sh b/test/nvidia-cuda/install_cudnn_123_version.sh deleted file mode 100644 index f331a591f..000000000 --- a/test/nvidia-cuda/install_cudnn_123_version.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -e - -# Optional: Import test library -source dev-container-features-test-lib - -# Check installation of libcudnn9-cuda-12 (9.4.0) -check "libcudnn.so.9.4.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.4.0' | wc -l)" - -# Check installation of cuda-nvtx-11-7 (11.7) -# check "cuda-12-4+nvtx" test -e '/usr/local/cuda-12.4/targets/x86_64-linux/include/nvtx3' - -# Report result -reportResults - \ No newline at end of file diff --git a/test/nvidia-cuda/install_cudnn_124_version.sh b/test/nvidia-cuda/install_cudnn_124_version.sh deleted file mode 100644 index f331a591f..000000000 --- a/test/nvidia-cuda/install_cudnn_124_version.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -e - -# Optional: Import test library -source dev-container-features-test-lib - -# Check installation of libcudnn9-cuda-12 (9.4.0) -check "libcudnn.so.9.4.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.4.0' | wc -l)" - -# Check installation of cuda-nvtx-11-7 (11.7) -# check "cuda-12-4+nvtx" test -e '/usr/local/cuda-12.4/targets/x86_64-linux/include/nvtx3' - -# Report result -reportResults - \ No newline at end of file diff --git a/test/nvidia-cuda/install_cudnn_latest_version.sh b/test/nvidia-cuda/install_cudnn_latest_version.sh deleted file mode 100644 index f331a591f..000000000 --- a/test/nvidia-cuda/install_cudnn_latest_version.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -e - -# Optional: Import test library -source dev-container-features-test-lib - -# Check installation of libcudnn9-cuda-12 (9.4.0) -check "libcudnn.so.9.4.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.4.0' | wc -l)" - -# Check installation of cuda-nvtx-11-7 (11.7) -# check "cuda-12-4+nvtx" test -e '/usr/local/cuda-12.4/targets/x86_64-linux/include/nvtx3' - -# Report result -reportResults - \ No newline at end of file diff --git a/test/nvidia-cuda/scenarios.json b/test/nvidia-cuda/scenarios.json index d2400503b..82c84f119 100644 --- a/test/nvidia-cuda/scenarios.json +++ b/test/nvidia-cuda/scenarios.json @@ -16,47 +16,41 @@ "nvidia-cuda": { "installCudnn": true, "installNvtx": true, - "cudaVersion": "11.7", - "cudnnVersion": "8.5.0.96" + "cudaVersion": "11.7" } } }, - "install_cudnn_123_version": { + "install_cuda_12_3_version": { "image": "debian", "features": { "nvidia-cuda": { "installCudnn": true, - "installNvtx": true, "installCudnnDev": true, - "installToolkit": true, - "cudaVersion": "12.3", - "cudnnVersion": "9.4.0.58" + "installNvtx": true, + "cudaVersion": "12.3" } } }, - "install_cudnn_124_version": { + "install_cuda_12_4_version": { "image": "debian", "features": { "nvidia-cuda": { "installCudnn": true, - "installNvtx": true, "installCudnnDev": true, - "installToolkit": true, - "cudaVersion": "12.4", - "cudnnVersion": "9.4.0.58" + "installNvtx": true, + "cudaVersion": "12.4" } } }, - "install_cudnn_latest_version": { + "install_cuda_12_5_version": { "image": "debian", "features": { "nvidia-cuda": { "installCudnn": true, - "installNvtx": true, "installCudnnDev": true, - "installToolkit": true, + "installNvtx": true, "cudaVersion": "12.5", - "cudnnVersion": "9.4.0.58" + "cudnnVersion": "9.5.0.50" } } } From 28b75a69ab132429f2c7d96849ee0cd2e51e3bba Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Tue, 28 Jan 2025 21:57:01 +0530 Subject: [PATCH 006/138] [aws-cli] - issue #1224 - installing less for paginated output and avoiding errors (#1226) Co-authored-by: Daniel Doyle --- src/aws-cli/install.sh | 2 +- test/aws-cli/less_installed.sh | 13 +++++++++++++ test/aws-cli/scenarios.json | 8 ++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test/aws-cli/less_installed.sh create mode 100644 test/aws-cli/scenarios.json diff --git a/src/aws-cli/install.sh b/src/aws-cli/install.sh index e7c03f728..feb806de5 100755 --- a/src/aws-cli/install.sh +++ b/src/aws-cli/install.sh @@ -68,7 +68,7 @@ check_packages() { export DEBIAN_FRONTEND=noninteractive -check_packages curl ca-certificates gnupg2 dirmngr unzip bash-completion +check_packages curl ca-certificates gnupg2 dirmngr unzip bash-completion less verify_aws_cli_gpg_signature() { local filePath=$1 diff --git a/test/aws-cli/less_installed.sh b/test/aws-cli/less_installed.sh new file mode 100644 index 000000000..a700a7a18 --- /dev/null +++ b/test/aws-cli/less_installed.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +check "less is installed, pagination works !" less --version +check "less binary installation path" which less +check "Testing paginated output with less" ls -R / | less + +# Report result +reportResults \ No newline at end of file diff --git a/test/aws-cli/scenarios.json b/test/aws-cli/scenarios.json new file mode 100644 index 000000000..9dd703c27 --- /dev/null +++ b/test/aws-cli/scenarios.json @@ -0,0 +1,8 @@ +{ + "less_installed": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "aws-cli": {} + } + } +} \ No newline at end of file From c31723d2df7c7d2406e796b78d57e86d6738e693 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Tue, 28 Jan 2025 22:08:01 +0530 Subject: [PATCH 007/138] [docker-in-docker] - issue #1202 solution - moby=false, holds configured docker-ce and docker-ce-cli version (#1215) * [docker-in-docker] - issue #1202 solution - moby=false, holds configured docker-ce and docker-ce-cli version * test case for scenario of issue --------- Co-authored-by: Daniel Doyle --- src/docker-in-docker/install.sh | 1 + .../pin_docker-ce_version_moby_false.sh | 10 ++++++++++ test/docker-in-docker/scenarios.json | 16 ++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 test/docker-in-docker/pin_docker-ce_version_moby_false.sh diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index c4c098ba8..906393997 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -312,6 +312,7 @@ else else apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} docker-ce${engine_version_suffix} # Install compose + apt-mark hold docker-ce docker-ce-cli apt-get -y install --no-install-recommends docker-compose-plugin || echo "(*) Package docker-compose-plugin (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." fi fi diff --git a/test/docker-in-docker/pin_docker-ce_version_moby_false.sh b/test/docker-in-docker/pin_docker-ce_version_moby_false.sh new file mode 100644 index 000000000..ec33d1504 --- /dev/null +++ b/test/docker-in-docker/pin_docker-ce_version_moby_false.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Optional: Import test library +source dev-container-features-test-lib + +check "docker-ce" bash -c "docker --version" +check "docker-ce-cli" bash -c "docker version" + +#report result +reportResults \ No newline at end of file diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index 699a1dd79..57681b799 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -142,6 +142,22 @@ } } }, + "pin_docker-ce_version_moby_false": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "docker-in-docker": { + "version": "26.1.4", + "moby": "false", + "mobyBuildxVersion": "latest", + "dockerDashComposeVersion": "none", + "azureDnsAutoDetection": "true", + "dockerDefaultAddressPool": "", + "installDockerBuildx": "true", + "installDockerComposeSwitch": "true", + "disableIp6tables": "false" + } + } + }, // DO NOT REMOVE: This scenario is used by the docker-in-docker-stress-test workflow "docker_with_on_create_command": { "image": "mcr.microsoft.com/devcontainers/base:debian", From 5c67da03b794f207e45aa34e04fddcb2fa3e5aaa Mon Sep 17 00:00:00 2001 From: jurjenoskam <39823959+jurjenoskam@users.noreply.github.com> Date: Wed, 12 Feb 2025 18:52:41 +0100 Subject: [PATCH 008/138] `[azure-cli]`: add `bicepVersion` for use with `installBicep` (#1227) Add `bicepVersion` parameter (defaulting to `latest`) to optionally specify a specific Bicep version when `installBicep` is `true`. Co-authored-by: Jurjen Oskam Co-authored-by: Daniel Doyle --- src/azure-cli/devcontainer-feature.json | 10 +++++++++- src/azure-cli/install.sh | 11 +++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/azure-cli/devcontainer-feature.json b/src/azure-cli/devcontainer-feature.json index e73d2295c..a95c33dab 100644 --- a/src/azure-cli/devcontainer-feature.json +++ b/src/azure-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "azure-cli", - "version": "1.2.5", + "version": "1.2.6", "name": "Azure CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/azure-cli", "description": "Installs the Azure CLI along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.", @@ -23,6 +23,14 @@ "description": "Optionally install Azure Bicep", "default": false }, + "bicepVersion": { + "type": "string", + "proposals": [ + "latest" + ], + "default": "latest", + "description": "Select or enter a Bicep version. ('latest' or a specic version such as 'v0.31.92')" + }, "installUsingPython": { "type": "boolean", "description": "Install Azure CLI using Python instead of pipx", diff --git a/src/azure-cli/install.sh b/src/azure-cli/install.sh index 2b52ca158..93e10ff52 100755 --- a/src/azure-cli/install.sh +++ b/src/azure-cli/install.sh @@ -15,6 +15,7 @@ rm -rf /var/lib/apt/lists/* AZ_VERSION=${VERSION:-"latest"} AZ_EXTENSIONS=${EXTENSIONS} AZ_INSTALLBICEP=${INSTALLBICEP:-false} +AZ_BICEPVERSION=${BICEPVERSION:-latest} INSTALL_USING_PYTHON=${INSTALLUSINGPYTHON:-false} MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" AZCLI_ARCHIVE_ARCHITECTURES="amd64 arm64" @@ -229,10 +230,16 @@ if [ "${AZ_INSTALLBICEP}" = "true" ]; then # The `az bicep install --target-platform` could be a solution; however, linux-arm64 is not an allowed value for this argument yet # Manually installing Bicep and moving to the appropriate directory where az expects it to be + if [ "${AZ_BICEPVERSION}" = "latest" ]; then + bicep_download_path="https://github.com/Azure/bicep/releases/latest/download" + else + bicep_download_path="https://github.com/Azure/bicep/releases/download/${AZ_BICEPVERSION}" + fi + if [ "${architecture}" = "arm64" ]; then - curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-arm64 + curl -Lo bicep ${bicep_download_path}/bicep-linux-arm64 else - curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64 + curl -Lo bicep ${bicep_download_path}/bicep-linux-x64 fi chmod +x ./bicep From 13521bc5efd79a1cea7da58df59a523243b3cea6 Mon Sep 17 00:00:00 2001 From: William Date: Thu, 27 Feb 2025 03:23:32 +0000 Subject: [PATCH 009/138] Remove azure terraform extension (#1267) * Remove azure terraform extension * Update README.md --- src/terraform/README.md | 3 --- src/terraform/devcontainer-feature.json | 6 ++---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/terraform/README.md b/src/terraform/README.md index 199c566d6..f6f5c9636 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -28,9 +28,6 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la ### VS Code Extensions - `HashiCorp.terraform` -- `ms-azuretools.vscode-azureterraform` - - ## Licensing diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index 3193f25af..e3e5fb9ad 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -59,15 +59,13 @@ "customizations": { "vscode": { "extensions": [ - "HashiCorp.terraform", - "ms-azuretools.vscode-azureterraform" + "HashiCorp.terraform" ], "settings": { "terraform.languageServer.enable": true, "terraform.languageServer.args": [ "serve" - ], - "azureTerraform.terminal": "integrated" + ] } } }, From a9f7f0fb49b1f7878a6e5b4e9a68abc5fc3c3eca Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Fri, 28 Feb 2025 23:34:14 +0100 Subject: [PATCH 010/138] Fix access to socket for Podman (microsoft/vscode-remote-release#10706) --- src/docker-outside-of-docker/devcontainer-feature.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index 24b5658dc..317c0289c 100644 --- a/src/docker-outside-of-docker/devcontainer-feature.json +++ b/src/docker-outside-of-docker/devcontainer-feature.json @@ -61,6 +61,9 @@ "type": "bind" } ], + "securityOpt": [ + "label=disable" + ], "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ], From 8f42e09481b87706aaab3e06dce7d225ebf73f58 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Mon, 3 Mar 2025 22:39:00 +0530 Subject: [PATCH 011/138] [nvidia-cuda] - Cudnn install script issue, unable to fetch latest version of libcudnn9 library (#1275) nvidia-cuda fix for Issue #1270 --- src/nvidia-cuda/install.sh | 2 +- test/nvidia-cuda/install_cuda_12_3_version.sh | 4 ++-- test/nvidia-cuda/install_cuda_12_4_version.sh | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nvidia-cuda/install.sh b/src/nvidia-cuda/install.sh index 1cfc7668e..a1055ac45 100644 --- a/src/nvidia-cuda/install.sh +++ b/src/nvidia-cuda/install.sh @@ -74,7 +74,7 @@ if [ "$CUDNN_VERSION" = "automatic" ]; then if [[ "$CUDA_VERSION" < "12.3" ]]; then CUDNN_VERSION=$(apt-cache policy libcudnn8 | grep "$CUDA_VERSION" | grep -Eo '^[^-1+]*' | sort -V | tail -n1 | xargs) else - CUDNN_VERSION=$(apt-cache policy libcudnn9-cuda-$major_cuda_version | grep "Candidate" | awk '{print $2}' | grep -Eo '^[^-1+]*') + CUDNN_VERSION=$(apt-cache policy libcudnn9-cuda-$major_cuda_version | grep "Candidate" | awk '{print $2}' | grep -Eo '^[^-+]*') fi fi major_cudnn_version=$(echo "${CUDNN_VERSION}" | cut -d '.' -f 1) diff --git a/test/nvidia-cuda/install_cuda_12_3_version.sh b/test/nvidia-cuda/install_cuda_12_3_version.sh index 95d4e8bdc..15c2abd7a 100644 --- a/test/nvidia-cuda/install_cuda_12_3_version.sh +++ b/test/nvidia-cuda/install_cuda_12_3_version.sh @@ -5,8 +5,8 @@ set -e # Optional: Import test library source dev-container-features-test-lib -# # Check installation of libcudnn9-cuda-12 (9.4.0) -check "libcudnn.so.9.5.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.5.0' | wc -l)" +# Check installation of libcudnn9 +check "libcudnn.so.9" test 1 -eq "$(find /usr -name 'libcudnn.so.9' | wc -l)" # Check installation of cuda-nvtx-12-3 (12.3) check "cuda-12-3+nvtx" test -e '/usr/local/cuda-12.3/targets/x86_64-linux/include/nvtx3/' diff --git a/test/nvidia-cuda/install_cuda_12_4_version.sh b/test/nvidia-cuda/install_cuda_12_4_version.sh index 77ecbf190..284920a33 100644 --- a/test/nvidia-cuda/install_cuda_12_4_version.sh +++ b/test/nvidia-cuda/install_cuda_12_4_version.sh @@ -5,8 +5,8 @@ set -e # Optional: Import test library source dev-container-features-test-lib -# # Check installation of libcudnn9-cuda-12 (9.4.0) -check "libcudnn.so.9.5.0" test 1 -eq "$(find /usr -name 'libcudnn.so.9.5.0' | wc -l)" +# Check installation of libcudnn9 +check "libcudnn.so.9" test 1 -eq "$(find /usr -name 'libcudnn.so.9' | wc -l)" # Check installation of cuda-nvtx-12-4 (12.4) check "cuda-12-4+nvtx" test -e '/usr/local/cuda-12.4/targets/x86_64-linux/include/nvtx3/' From c264b4e837f3273789fc83dae898152daae4cd90 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Mon, 3 Mar 2025 22:39:37 +0530 Subject: [PATCH 012/138] [python] - issue #1172 - provide switching versions using update-alternatives (#1260) * [python] - issue #1172 - add version switching mechanism using update-alternatives * removed commented code * [python] - update-alternatives addition for ease in switching of python versions - complete * changes for passing of other tests !! * change for better positioning of code * Added test case scenario for Update-Alternatives check * added scenario for testing * [alternatives] - added option for fedora, centos & rhel * changed file name * changes for update-alternatives test case proper functioning * arrange in asc order for default value retention after testing ends --- src/python/install.sh | 28 ++++- .../alternatives_switchable_versions.sh | 103 ++++++++++++++++++ test/python/scenarios.json | 20 ++++ ...update_alternatives_switchable_versions.sh | 102 +++++++++++++++++ 4 files changed, 250 insertions(+), 3 deletions(-) create mode 100644 test/python/alternatives_switchable_versions.sh create mode 100644 test/python/update_alternatives_switchable_versions.sh diff --git a/src/python/install.sh b/src/python/install.sh index b3311c7c6..fec8937a0 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -766,15 +766,19 @@ esac check_packages ${REQUIRED_PKGS} +# Function to get the major version from a SemVer string +get_major_version() { + local version="$1" + echo "$version" | cut -d '.' -f 1 +} + # Install Python from source if needed if [ "${PYTHON_VERSION}" != "none" ]; then if ! cat /etc/group | grep -e "^python:" > /dev/null 2>&1; then groupadd -r python fi usermod -a -G python "${USERNAME}" - CURRENT_PATH="${PYTHON_INSTALL_PATH}/current" - install_python ${PYTHON_VERSION} # Additional python versions to be installed but not be set as default. @@ -783,9 +787,27 @@ if [ "${PYTHON_VERSION}" != "none" ]; then OLDIFS=$IFS IFS="," read -a additional_versions <<< "$ADDITIONAL_VERSIONS" - for version in "${additional_versions[@]}"; do + major_version=$(get_major_version ${VERSION}) + if type apt-get > /dev/null 2>&1; then + # Debian/Ubuntu: Use update-alternatives + update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${#additional_versions[@]}+1)) + update-alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + # Fedora/RHEL/CentOS: Use alternatives + alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${#additional_versions[@]}+1)) + alternatives --set python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} + fi + for i in "${!additional_versions[@]}"; do + version=${additional_versions[$i]} OVERRIDE_DEFAULT_VERSION="false" install_python $version + if type apt-get > /dev/null 2>&1; then + # Debian/Ubuntu: Use update-alternatives + update-alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${i}+1)) + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + # Fedora/RHEL/CentOS: Use alternatives + alternatives --install ${CURRENT_PATH} python${major_version} ${PYTHON_INSTALL_PATH}/${VERSION} $((${i}+1)) + fi done INSTALL_PATH="${OLD_INSTALL_PATH}" IFS=$OLDIFS diff --git a/test/python/alternatives_switchable_versions.sh b/test/python/alternatives_switchable_versions.sh new file mode 100644 index 000000000..a29392c17 --- /dev/null +++ b/test/python/alternatives_switchable_versions.sh @@ -0,0 +1,103 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "python version 3.11 installed as default" bash -c "python --version | grep 3.11" +check "python3 version 3.11 installed as default" bash -c "python3 --version | grep 3.11" +check "python version 3.10.5 installed" bash -c "ls -l /usr/local/python | grep 3.10.5" +check "python version 3.8 installed" bash -c "ls -l /usr/local/python | grep 3.8" +check "python version 3.9.13 installed" bash -c "ls -l /usr/local/python | grep 3.9.13" + +# Check paths in settings +check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python" +check "current symlink works" /usr/local/python/current/bin/python --version + +# check alternatives command +check_version_switch() { + if type apt-get > /dev/null 2>&1; then + PYTHON_ALTERNATIVES=$(update-alternatives --query python3 | grep -E 'Alternative:|Priority:') + STYLE="debian" + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + PYTHON_ALTERNATIVES=$(alternatives --display python3 | grep " - priority") + STYLE="fedora" + else + echo "No supported package manager found." + exit 1 + fi + + AVAILABLE_VERSIONS=() + INDEX=1 + echo "Available Python versions:" + if [ "${STYLE}" = "debian" ]; then + while read -r alt && read -r pri; do + PATH=${alt#Alternative: } # Extract only the path + PRIORITY=${pri#Priority: } # Extract only the priority number + TEMP_VERSIONS+=("${PRIORITY} ${PATH}") + echo "$INDEX) $PATH (Priority: $PRIORITY)" + ((INDEX++)) + done <<< "${PYTHON_ALTERNATIVES}" + elif [ "${STYLE}" = "fedora" ]; then + export PATH="/usr/bin:$PATH" + # Fedora/RHEL output: one line per alternative in the format: + while IFS= read -r line; do + # Split using " - priority " as a delimiter. + PATH=$(/usr/bin/awk -F' - priority ' '{print $1}' <<< "$line" | /usr/bin/xargs /bin/echo) + PRIORITY=$(/usr/bin/awk -F' - priority ' '{print $2}' <<< "$line" | /usr/bin/xargs /bin/echo) + TEMP_VERSIONS+=("${PRIORITY} ${PATH}") + echo "$INDEX) $PATH (Priority: $PRIORITY_VALUE)" + ((INDEX++)) + done <<< "${PYTHON_ALTERNATIVES}" + fi + + export PATH="/usr/bin:$PATH" + # Sort by priority (numerically ascending) + IFS=$'\n' TEMP_VERSIONS=($(sort -n <<<"${TEMP_VERSIONS[*]}")) + unset IFS + + # Populate AVAILABLE_VERSIONS from sorted data + AVAILABLE_VERSIONS=() + INDEX=1 + echo -e "\nAvailable Python versions (Sorted in asc order of priority):" + for ENTRY in "${TEMP_VERSIONS[@]}"; do + PRIORITY=${ENTRY%% *} # Extract priority (first part before space) + PATH=${ENTRY#* } # Extract path (everything after first space) + AVAILABLE_VERSIONS+=("${PATH}") + echo "$INDEX) $PATH (Priority: $PRIORITY)" + ((INDEX++)) + done + + echo -e "\nAvailable Versions Count: ${#AVAILABLE_VERSIONS[@]}" + # Ensure at least 4 alternatives exist + if [ "${#AVAILABLE_VERSIONS[@]}" -lt 4 ]; then + echo "Error: Less than 4 Python versions registered in update-alternatives." + exit 1 + fi + + export PATH="/usr/bin:$PATH" + echo -e "\nSwitching to different versions using update-alternatives --set command...\n" + for CHOICE in {1..4}; do + SELECTED_VERSION="${AVAILABLE_VERSIONS[$((CHOICE - 1))]}" + echo "Switching to: ${SELECTED_VERSION}" + if command -v apt-get > /dev/null 2>&1; then + /usr/bin/update-alternatives --set python3 ${SELECTED_VERSION} + elif command -v dnf > /dev/null 2>&1 || command -v yum > /dev/null 2>&1 || command -v microdnf > /dev/null 2>&1; then + /usr/sbin/alternatives --set python3 ${SELECTED_VERSION} + fi + # Verify the switch + echo "Python version after switch:" + /usr/local/python/current/bin/python3 --version + /bin/sleep 1 + echo -e "\n" + done + echo -e "Update-Alternatives --display: \n" + if type apt-get > /dev/null 2>&1; then + /usr/bin/update-alternatives --display python3 + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + /usr/sbin/alternatives --display python3 + fi +} + +check "Version Switch With Update_Alternatives" check_version_switch \ No newline at end of file diff --git a/test/python/scenarios.json b/test/python/scenarios.json index be37869df..9dc37e16c 100644 --- a/test/python/scenarios.json +++ b/test/python/scenarios.json @@ -255,5 +255,25 @@ "enableShared": true } } + }, + "update_alternatives_switchable_versions": { + "image": "ubuntu:focal", + "features": { + "python": { + "version": "3.11", + "installTools": true, + "additionalVersions": "3.8,3.9.13,3.10.5" + } + } + }, + "alternatives_switchable_versions": { + "image": "fedora", + "features": { + "python": { + "version": "3.11", + "installTools": true, + "additionalVersions": "3.8,3.9.13,3.10.5" + } + } } } \ No newline at end of file diff --git a/test/python/update_alternatives_switchable_versions.sh b/test/python/update_alternatives_switchable_versions.sh new file mode 100644 index 000000000..07a517332 --- /dev/null +++ b/test/python/update_alternatives_switchable_versions.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "python version 3.11 installed as default" bash -c "python --version | grep 3.11" +check "python3 version 3.11 installed as default" bash -c "python3 --version | grep 3.11" +check "python version 3.10.5 installed" bash -c "ls -l /usr/local/python | grep 3.10.5" +check "python version 3.8 installed" bash -c "ls -l /usr/local/python | grep 3.8" +check "python version 3.9.13 installed" bash -c "ls -l /usr/local/python | grep 3.9.13" + +# Check paths in settings +check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python" +check "current symlink works" /usr/local/python/current/bin/python --version + +# check alternatives command +check_version_switch() { + if type apt-get > /dev/null 2>&1; then + PYTHON_ALTERNATIVES=$(update-alternatives --query python3 | grep -E 'Alternative:|Priority:') + STYLE="debian" + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + PYTHON_ALTERNATIVES=$(alternatives --display python3 | grep " - priority") + STYLE="fedora" + else + echo "No supported package manager found." + exit 1 + fi + AVAILABLE_VERSIONS=() + INDEX=1 + echo "Available Python versions:" + if [ "${STYLE}" = "debian" ]; then + while read -r alt && read -r pri; do + PATH=${alt#Alternative: } # Extract only the path + PRIORITY=${pri#Priority: } # Extract only the priority number + TEMP_VERSIONS+=("${PRIORITY} ${PATH}") + echo "$INDEX) $PATH (Priority: $PRIORITY)" + ((INDEX++)) + done <<< "${PYTHON_ALTERNATIVES}" + elif [ "${STYLE}" = "fedora" ]; then + export PATH="/usr/bin:$PATH" + # Fedora/RHEL output: one line per alternative in the format: + while IFS= read -r line; do + # Split using " - priority " as a delimiter. + PATH=$(/usr/bin/awk -F' - priority ' '{print $1}' <<< "$line" | /usr/bin/xargs /bin/echo) + PRIORITY=$(/usr/bin/awk -F' - priority ' '{print $2}' <<< "$line" | /usr/bin/xargs /bin/echo) + TEMP_VERSIONS+=("${PRIORITY} ${PATH}") + echo "$INDEX) $PATH (Priority: $PRIORITY_VALUE)" + ((INDEX++)) + done <<< "${PYTHON_ALTERNATIVES}" + fi + + export PATH="/usr/bin:$PATH" + # Sort by priority (numerically ascending) + IFS=$'\n' TEMP_VERSIONS=($(sort -n <<<"${TEMP_VERSIONS[*]}")) + unset IFS + + # Populate AVAILABLE_VERSIONS from sorted data + AVAILABLE_VERSIONS=() + INDEX=1 + echo -e "\nAvailable Python versions (Sorted in asc order of priority):" + for ENTRY in "${TEMP_VERSIONS[@]}"; do + PRIORITY=${ENTRY%% *} # Extract priority (first part before space) + PATH=${ENTRY#* } # Extract path (everything after first space) + AVAILABLE_VERSIONS+=("${PATH}") + echo "$INDEX) $PATH (Priority: $PRIORITY)" + ((INDEX++)) + done + + echo -e "\nAvailable Versions Count: ${#AVAILABLE_VERSIONS[@]}\n" + # Ensure at least 4 alternatives exist + if [ "${#AVAILABLE_VERSIONS[@]}" -lt 4 ]; then + echo "Error: Less than 4 Python versions registered in update-alternatives." + exit 1 + fi + + export PATH="/usr/bin:$PATH" + echo -e "\nSwitching to different versions using update-alternatives --set command...\n" + for CHOICE in {1..4}; do + SELECTED_VERSION="${AVAILABLE_VERSIONS[$((CHOICE - 1))]}" + echo "Switching to: ${SELECTED_VERSION}" + if command -v apt-get > /dev/null 2>&1; then + /usr/bin/update-alternatives --set python3 ${SELECTED_VERSION} + elif command -v dnf > /dev/null 2>&1 || command -v yum > /dev/null 2>&1 || command -v microdnf > /dev/null 2>&1; then + /usr/sbin/alternatives --set python3 ${SELECTED_VERSION} + fi + # Verify the switch + echo "Python version after switch:" + /usr/local/python/current/bin/python3 --version + /bin/sleep 1 + echo -e "\n" + done + echo -e "Update-Alternatives --display: \n" + if type apt-get > /dev/null 2>&1; then + /usr/bin/update-alternatives --display python3 + elif type dnf > /dev/null 2>&1 || type yum > /dev/null 2>&1 || type microdnf > /dev/null 2>&1; then + /usr/sbin/alternatives --display python3 + fi +} + +check "Version Switch With Update_Alternatives" check_version_switch \ No newline at end of file From 7eec5e6ad247ada5dd130ed7972b83d53c1af8ee Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Wed, 26 Mar 2025 19:55:56 +0530 Subject: [PATCH 013/138] [docker-outside-of-docker] - Correction in fetching previous version from github api url (#1252) * [docker-outside-of-docker] - Correction in fetching previous version from github api url * need full array of objects instead was pulling only the object pertaining to latest release * Correcting the scenario when result of json can be an object or an array, so to tackle both the scenarios in the function of fallbacking * version output for docker-compose-switch in test scenario run for testing fallback * correction in getting version for docker compose outputted in test case * correction * correction * correction * run the pipeline again * Update version devcontainer-feature.json * remove DOCKER_DASH_COMPOSE_VERSION * typo error * remove if condition --------- Co-authored-by: sireeshajonnalagadda Co-authored-by: Mathiyarasy <157102811+Mathiyarasy@users.noreply.github.com> --- .../devcontainer-feature.json | 2 +- src/docker-outside-of-docker/install.sh | 31 ++++++++--------- .../docker_build_compose_fallback.sh | 33 +++++++++---------- 3 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index 317c0289c..a58f63ee2 100644 --- a/src/docker-outside-of-docker/devcontainer-feature.json +++ b/src/docker-outside-of-docker/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "docker-outside-of-docker", - "version": "1.6.0", + "version": "1.6.1", "name": "Docker (docker-outside-of-docker)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker", "description": "Re-use the host docker socket, adding the Docker CLI to a container. Feature invokes a script to enable using a forwarded Docker socket within a container to run Docker commands.", diff --git a/src/docker-outside-of-docker/install.sh b/src/docker-outside-of-docker/install.sh index 5854fc340..97222b177 100755 --- a/src/docker-outside-of-docker/install.sh +++ b/src/docker-outside-of-docker/install.sh @@ -156,25 +156,26 @@ get_previous_version() { output=$(curl -s "$repo_url"); check_packages jq - - message=$(echo "$output" | jq -r '.message') - if [[ $message == "API rate limit exceeded"* ]]; then - echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}" - echo -e "\nAttempting to find latest version using GitHub tags." - find_prev_version_from_git_tags prev_version "$url" "tags/v" - declare -g ${variable_name}="${prev_version}" - else - echo -e "\nAttempting to find latest version using GitHub Api." - version=$(echo "$output" | jq -r '.tag_name') + if echo "$output" | jq -e 'type == "object"' > /dev/null; then + message=$(echo "$output" | jq -r '.message') + if [[ $message == "API rate limit exceeded"* ]]; then + echo -e "\nAn attempt to find previous to latest version using GitHub Api Failed... \nReason: ${message}" + echo -e "\nAttempting to find previous to latest version using GitHub tags." + find_prev_version_from_git_tags prev_version "$url" "tags/v" + declare -g ${variable_name}="${prev_version}" + fi + elif echo "$output" | jq -e 'type == "array"' > /dev/null; then + echo -e "\nAttempting to find previous version using GitHub Api." + version=$(echo "$output" | jq -r '.[1].tag_name') declare -g ${variable_name}="${version#v}" fi - echo "${variable_name}=${!variable_name}" + echo "${variable_name}=${!variable_name}" } get_github_api_repo_url() { local url=$1 - echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases/latest" + echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases" } install_compose_switch_fallback() { @@ -361,11 +362,7 @@ if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then find_version_from_git_tags compose_version "$docker_compose_url" "tags/v" echo "(*) Installing docker-compose ${compose_version}..." curl -fsSL "https://github.com/docker/compose/releases/download/v${compose_version}/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || { - if [[ $DOCKER_DASH_COMPOSE_VERSION == "latest" ]]; then - install_compose_fallback "$docker_compose_url" "$compose_version" "$target_compose_arch" "$docker_compose_path" - else - echo -e "Error: Failed to install docker-compose v${compose_version}" - fi + install_compose_fallback "$docker_compose_url" "$compose_version" "$target_compose_arch" "$docker_compose_path" } chmod +x ${docker_compose_path} diff --git a/test/docker-outside-of-docker/docker_build_compose_fallback.sh b/test/docker-outside-of-docker/docker_build_compose_fallback.sh index 7f3a6f1dd..c1bdeb544 100644 --- a/test/docker-outside-of-docker/docker_build_compose_fallback.sh +++ b/test/docker-outside-of-docker/docker_build_compose_fallback.sh @@ -112,29 +112,26 @@ get_previous_version() { local variable_name=$3 local mode=$4 prev_version=${!variable_name} - output=$(curl -s "$repo_url"); - check_packages jq - - message=$(echo "$output" | jq -r '.message') - - if [[ $message == "API rate limit exceeded"* ]] || [[ $mode == 'mode1' ]]; then - echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}" - echo -e "\nAttempting to find latest version using GitHub tags." - find_prev_version_from_git_tags prev_version "$url" "tags/v" - declare -g ${variable_name}="${prev_version}" - else - echo -e "\nAttempting to find latest version using GitHub Api." - version=$(echo "$output" | jq -r '.tag_name') + if echo "$output" | jq -e 'type == "object"' > /dev/null; then + message=$(echo "$output" | jq -r '.message') + if [[ $message == "API rate limit exceeded"* ]] || [[ $mode == 'mode1' ]]; then + echo -e "\nAn attempt to find previous to latest version using GitHub Api Failed... \nReason: ${message}" + echo -e "\nAttempting to find previous to latest version using GitHub tags." + find_prev_version_from_git_tags prev_version "$url" "tags/v" + declare -g ${variable_name}="${prev_version}" + fi + elif echo "$output" | jq -e 'type == "array"' > /dev/null; then + echo -e "\nAttempting to find previous version using GitHub Api." + version=$(echo "$output" | jq -r '.[1].tag_name') declare -g ${variable_name}="${version#v}" - fi - echo "${variable_name}=${!variable_name}" + fi } get_github_api_repo_url() { local url=$1 - echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases/latest" + echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases" } install_compose_switch_fallback() { @@ -159,7 +156,9 @@ install_compose-switch_as_docker-compose() { echo -e "\n👉 Trying to install compose-switch as docker-compose using mode 1 ( find_prev_version_from_git_tags method )"; install_compose-switch_as_docker-compose "mode1" check "installs compose-switch as docker-compose mode 1" bash -c "[[ -f /usr/local/bin/docker-compose ]]" +check "docker-compose version" bash -c "docker-compose version" echo -e "\n👉 Trying to install compose-switch as docker-compose using mode 2 ( GitHub Api )"; install_compose-switch_as_docker-compose "mode2" -check "installs compose-switch as docker-compose mode 2" bash -c "[[ -f /usr/local/bin/docker-compose ]]" \ No newline at end of file +check "installs compose-switch as docker-compose mode 2" bash -c "[[ -f /usr/local/bin/docker-compose ]]" +check "docker-compose version" bash -c "docker-compose version" \ No newline at end of file From 87fd9a35c50496f889ce309c284b9cffd3061920 Mon Sep 17 00:00:00 2001 From: Mathiyarasy <157102811+Mathiyarasy@users.noreply.github.com> Date: Wed, 26 Mar 2025 19:56:07 +0530 Subject: [PATCH 014/138] [docker-in-docker] - Correction in fetching previous version from github api url (#1302) * Update dockercompose previous version logic * Update v2 as v2 is latest * Update default to v2 * Update test for fetching previous version * default to latest to test * fix the failure scenario * previous tag * remove latest condition check --- .../devcontainer-feature.json | 8 ++--- src/docker-in-docker/install.sh | 33 +++++++++---------- .../docker_build_fallback_compose.sh | 31 ++++++++--------- 3 files changed, 34 insertions(+), 38 deletions(-) diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index f13b62d2d..94b010c1f 100644 --- a/src/docker-in-docker/devcontainer-feature.json +++ b/src/docker-in-docker/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "docker-in-docker", - "version": "2.12.0", + "version": "2.12.1", "name": "Docker (Docker-in-Docker)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-in-docker", "description": "Create child containers *inside* a container, independent from the host's docker instance. Installs Docker extension in the container along with needed CLIs.", @@ -29,11 +29,11 @@ "type": "string", "enum": [ "none", - "latest", + "v1", "v2" ], - "default": "latest", - "description": "Default version of Docker Compose (latest, v2 or none)" + "default": "v2", + "description": "Default version of Docker Compose (v1, v2 or none)" }, "azureDnsAutoDetection": { "type": "boolean", diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 906393997..b43a12918 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -11,7 +11,7 @@ DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version USE_MOBY="${MOBY:-"true"}" MOBY_BUILDX_VERSION="${MOBYBUILDXVERSION:-"latest"}" -DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"latest"}" #latest, v2 or none +DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v2"}" #v1, v2 or none AZURE_DNS_AUTO_DETECTION="${AZUREDNSAUTODETECTION:-"true"}" DOCKER_DEFAULT_ADDRESS_POOL="${DOCKERDEFAULTADDRESSPOOL:-""}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" @@ -157,18 +157,20 @@ get_previous_version() { local repo_url=$2 local variable_name=$3 prev_version=${!variable_name} - + output=$(curl -s "$repo_url"); - message=$(echo "$output" | jq -r '.message') - - if [[ $message == "API rate limit exceeded"* ]]; then - echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}" - echo -e "\nAttempting to find latest version using GitHub tags." - find_prev_version_from_git_tags prev_version "$url" "tags/v" - declare -g ${variable_name}="${prev_version}" - else + if echo "$output" | jq -e 'type == "object"' > /dev/null; then + message=$(echo "$output" | jq -r '.message') + + if [[ $message == "API rate limit exceeded"* ]]; then + echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}" + echo -e "\nAttempting to find latest version using GitHub tags." + find_prev_version_from_git_tags prev_version "$url" "tags/v" + declare -g ${variable_name}="${prev_version}" + fi + elif echo "$output" | jq -e 'type == "array"' > /dev/null; then echo -e "\nAttempting to find latest version using GitHub Api." - version=$(echo "$output" | jq -r '.tag_name') + version=$(echo "$output" | jq -r '.[1].tag_name') declare -g ${variable_name}="${version#v}" fi echo "${variable_name}=${!variable_name}" @@ -176,7 +178,7 @@ get_previous_version() { get_github_api_repo_url() { local url=$1 - echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases/latest" + echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases" } ########################################### @@ -372,11 +374,8 @@ if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then find_version_from_git_tags compose_version "$docker_compose_url" "tags/v" echo "(*) Installing docker-compose ${compose_version}..." curl -fsSL "https://github.com/docker/compose/releases/download/v${compose_version}/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} || { - if [[ $DOCKER_DASH_COMPOSE_VERSION == "latest" ]]; then - fallback_compose "$docker_compose_url" - else - echo -e "Error: Failed to install docker-compose v${compose_version}" - fi + echo -e "\n(!) Failed to fetch the latest artifacts for docker-compose v${compose_version}..." + fallback_compose "$docker_compose_url" } chmod +x ${docker_compose_path} diff --git a/test/docker-in-docker/docker_build_fallback_compose.sh b/test/docker-in-docker/docker_build_fallback_compose.sh index 4a18640f0..ed1dab3f4 100644 --- a/test/docker-in-docker/docker_build_fallback_compose.sh +++ b/test/docker-in-docker/docker_build_fallback_compose.sh @@ -108,31 +108,28 @@ get_previous_version() { local mode=$4 prev_version=${!variable_name} - echo -e "\nAttempting to find latest version using Github Api." - output=$(curl -s "$repo_url"); - message=$(echo "$output" | jq -r '.message') - if [[ $mode != "install_from_github_api_valid" ]]; then - message="API rate limit exceeded" - fi - - if [[ $message == "API rate limit exceeded"* ]]; then - echo -e "\nAttempting to find latest version using Github Api Failed. Exceeded API Rate Limit." - echo -e "\nAttempting to find latest version using Github Tags." - find_prev_version_from_git_tags prev_version "$url" "tags/v" - declare -g ${variable_name}="${prev_version}" - else - echo -e "\nAttempting to find latest version using Github Api Succeeded." - version=$(echo "$output" | jq -r '.tag_name') + if echo "$output" | jq -e 'type == "object"' > /dev/null; then + message=$(echo "$output" | jq -r '.message') + + if [[ $message == "API rate limit exceeded"* ]]; then + echo -e "\nAn attempt to find latest version using GitHub Api Failed... \nReason: ${message}" + echo -e "\nAttempting to find latest version using GitHub tags." + find_prev_version_from_git_tags prev_version "$url" "tags/v" + declare -g ${variable_name}="${prev_version}" + fi + elif echo "$output" | jq -e 'type == "array"' > /dev/null; then + echo -e "\nAttempting to find latest version using GitHub Api." + version=$(echo "$output" | jq -r '.[1].tag_name') declare -g ${variable_name}="${version#v}" - fi + fi echo "${variable_name}=${!variable_name}" } get_github_api_repo_url() { local url=$1 - echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases/latest" + echo "${url/https:\/\/github.com/https:\/\/api.github.com\/repos}/releases" } install_using_get_previous_version() { From 87befbc765cd90ab9bd952dd2eb485cf91fccbc7 Mon Sep 17 00:00:00 2001 From: William Date: Wed, 26 Mar 2025 14:34:05 +0000 Subject: [PATCH 015/138] Bump Terraform version to 1.3.9 in devcontainer feature (#1290) --- src/terraform/devcontainer-feature.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index e3e5fb9ad..ef6db8dec 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.3.8", + "version": "1.3.9", "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.", From fdbd9b4731d596562cd99e6f0239b4771cb34953 Mon Sep 17 00:00:00 2001 From: sireeshajonnalagadda Date: Wed, 26 Mar 2025 20:08:16 +0530 Subject: [PATCH 016/138] common-utils Azure linux 3 support (#1310) * added tdnf package manager and some checks for Azure linux * added tdnf package manager and some checks for Azure linux * modified install_cmd * modified install_cmd --------- Co-authored-by: Daniel Doyle --- src/common-utils/install.sh | 4 +++- src/common-utils/main.sh | 20 +++++++++++++------- test/common-utils/Azure-linux-CU.sh | 22 ++++++++++++++++++++++ test/common-utils/scenarios.json | 6 ++++++ 4 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 test/common-utils/Azure-linux-CU.sh diff --git a/src/common-utils/install.sh b/src/common-utils/install.sh index 8f1ece4d7..a89490347 100755 --- a/src/common-utils/install.sh +++ b/src/common-utils/install.sh @@ -31,6 +31,8 @@ fi if [ "${ID}" = "alpine" ]; then apk add --no-cache bash fi - +if [ "${ID}" = "azurelinux" ]; then + tdnf install -y curl git +fi exec /bin/bash "$(dirname $0)/main.sh" "$@" exit $? diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index b5fe11f57..abef18430 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -161,12 +161,18 @@ install_redhat_packages() { local package_list="" local remove_epel="false" local install_cmd=microdnf - if ! type microdnf > /dev/null 2>&1; then - install_cmd=dnf - if ! type dnf > /dev/null 2>&1; then - install_cmd=yum - fi - fi + if type microdnf > /dev/null 2>&1; then + install_cmd=microdnf + elif type tdnf > /dev/null 2>&1; then + install_cmd=tdnf + elif type dnf > /dev/null 2>&1; then + install_cmd=dnf + elif type yum > /dev/null 2>&1; then + install_cmd=yum + else + echo "Unable to find 'tdnf', 'dnf', or 'yum' package manager. Exiting." + exit 1 +fi if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then package_list="${package_list} \ @@ -344,7 +350,7 @@ chmod +x /etc/profile.d/00-restore-env.sh # Get an adjusted ID independent of distro variants if [ "${ID}" = "debian" ] || [ "${ID_LIKE}" = "debian" ]; then ADJUSTED_ID="debian" -elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then +elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "azurelinux" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then ADJUSTED_ID="rhel" VERSION_CODENAME="${ID}${VERSION_ID}" elif [ "${ID}" = "alpine" ]; then diff --git a/test/common-utils/Azure-linux-CU.sh b/test/common-utils/Azure-linux-CU.sh new file mode 100644 index 000000000..eeba25d10 --- /dev/null +++ b/test/common-utils/Azure-linux-CU.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Load Linux distribution info +. /etc/os-release + +# Check if the current user is root +check "root user" test "$(whoami)" = "root" + +# Check if the Linux distro is Azure Linux +check "azurelinux distro" test "$ID" = "azurelinux" + +# Definition specific tests +check "curl" curl --version +check "jq" jq --version + +# Report result +reportResults diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index a929f534a..4ffbde1ac 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -292,5 +292,11 @@ "features": { "common-utils": {} } + }, + "Azure-linux-CU": { + "image": "mcr.microsoft.com/dotnet/sdk:8.0-azurelinux3.0", + "features": { + "common-utils": {} + } } } \ No newline at end of file From 091886b3568dad70f835cc428dad1fdf7bc6a9b3 Mon Sep 17 00:00:00 2001 From: Kaniska Date: Thu, 27 Mar 2025 21:42:31 +0530 Subject: [PATCH 017/138] Bump up the common-utils version for azurelinux support change (#1311) --- src/common-utils/devcontainer-feature.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 3fa6487df..82ddde046 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.5.2", + "version": "2.5.3", "name": "Common Utilities", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/common-utils", "description": "Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-root user.", From 12f1b2f5d5419714040a7552eb9f5acb8572ee59 Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 1 Apr 2025 20:11:48 +0200 Subject: [PATCH 018/138] Custom instructions for features (#1314) * Custom instructions for github-cli, node, python * Custom instructions for docker-in-docker, docker-outside-of-docker --- src/docker-in-docker/devcontainer-feature.json | 9 ++++++++- .../devcontainer-feature.json | 9 ++++++++- src/github-cli/devcontainer-feature.json | 11 +++++++++++ src/node/devcontainer-feature.json | 9 ++++++++- src/python/devcontainer-feature.json | 5 +++++ 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 94b010c1f..be9368f39 100644 --- a/src/docker-in-docker/devcontainer-feature.json +++ b/src/docker-in-docker/devcontainer-feature.json @@ -71,7 +71,14 @@ "vscode": { "extensions": [ "ms-azuretools.vscode-docker" - ] + ], + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the Docker CLI (`docker`) pre-installed and available on the `PATH` for running and managing containers using a dedicated Docker daemon running inside the dev container." + } + ] + } } }, "mounts": [ diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index a58f63ee2..9ded8a5de 100644 --- a/src/docker-outside-of-docker/devcontainer-feature.json +++ b/src/docker-outside-of-docker/devcontainer-feature.json @@ -51,7 +51,14 @@ "vscode": { "extensions": [ "ms-azuretools.vscode-docker" - ] + ], + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the Docker CLI (`docker`) pre-installed and available on the `PATH` for running and managing containers using the Docker daemon on the host machine." + } + ] + } } }, "mounts": [ diff --git a/src/github-cli/devcontainer-feature.json b/src/github-cli/devcontainer-feature.json index 9b1558ec0..26f9989d7 100644 --- a/src/github-cli/devcontainer-feature.json +++ b/src/github-cli/devcontainer-feature.json @@ -19,6 +19,17 @@ "default": true } }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the GitHub CLI (`gh`), which is pre-installed and available on the `PATH`. IMPORTANT: `gh api -f` does not support object values, use multiple `-f` flags with hierarchical keys and string values instead. When using GitHub actions `actions/upload-artifact` or `actions/download-artifact` use v4 or later." + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils", "ghcr.io/devcontainers/features/git" diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index d8d49e538..9bbeb2ecd 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -61,7 +61,14 @@ "vscode": { "extensions": [ "dbaeumer.vscode-eslint" - ] + ], + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes `node`, `npm` and `eslint` pre-installed and available on the `PATH` for Node.js and JavaScript development." + } + ] + } } }, "containerEnv": { diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index 64976fc63..bd5b71887 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -77,6 +77,11 @@ "ms-python.autopep8" ], "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes `python3` and `pip3` pre-installed and available on the `PATH`, along with the Python language extensions for Python development." + } + ], "python.defaultInterpreterPath": "/usr/local/python/current/bin/python", "[python]": { "editor.defaultFormatter": "ms-python.autopep8" From 2eb4b5ce7ad97b3ea82a84606e69139a867f078d Mon Sep 17 00:00:00 2001 From: Christof Marti Date: Tue, 1 Apr 2025 21:43:46 +0200 Subject: [PATCH 019/138] Increment versions (#1315) --- src/docker-in-docker/devcontainer-feature.json | 2 +- src/docker-outside-of-docker/devcontainer-feature.json | 2 +- src/github-cli/devcontainer-feature.json | 2 +- src/node/devcontainer-feature.json | 2 +- src/python/devcontainer-feature.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index be9368f39..fe705db37 100644 --- a/src/docker-in-docker/devcontainer-feature.json +++ b/src/docker-in-docker/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "docker-in-docker", - "version": "2.12.1", + "version": "2.12.2", "name": "Docker (Docker-in-Docker)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-in-docker", "description": "Create child containers *inside* a container, independent from the host's docker instance. Installs Docker extension in the container along with needed CLIs.", diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index 9ded8a5de..85f598974 100644 --- a/src/docker-outside-of-docker/devcontainer-feature.json +++ b/src/docker-outside-of-docker/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "docker-outside-of-docker", - "version": "1.6.1", + "version": "1.6.2", "name": "Docker (docker-outside-of-docker)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-outside-of-docker", "description": "Re-use the host docker socket, adding the Docker CLI to a container. Feature invokes a script to enable using a forwarded Docker socket within a container to run Docker commands.", diff --git a/src/github-cli/devcontainer-feature.json b/src/github-cli/devcontainer-feature.json index 26f9989d7..04e373dfd 100644 --- a/src/github-cli/devcontainer-feature.json +++ b/src/github-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "github-cli", - "version": "1.0.13", + "version": "1.0.14", "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.", diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index 9bbeb2ecd..b8d699def 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.6.1", + "version": "1.6.2", "name": "Node.js (via nvm), yarn and pnpm", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/node", "description": "Installs Node.js, nvm, yarn, pnpm, and needed dependencies.", diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index bd5b71887..635b233cf 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.7.0", + "version": "1.7.1", "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.", From efd88326ddc3f226885e4bc91669901facfd664f Mon Sep 17 00:00:00 2001 From: Kaniska Date: Fri, 4 Apr 2025 20:09:35 +0530 Subject: [PATCH 020/138] [Ruby] - 3.1 EOL and 3.4 addition (#1312) Ruby 3.1 EOL and 3.4 addition --- src/ruby/devcontainer-feature.json | 7 +++---- test/ruby/install_additional_ruby.sh | 6 +++--- test/ruby/ruby_fallback_test.sh | 2 +- test/ruby/scenarios.json | 4 ++-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/ruby/devcontainer-feature.json b/src/ruby/devcontainer-feature.json index 0618d4296..3d7a081e8 100644 --- a/src/ruby/devcontainer-feature.json +++ b/src/ruby/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby", - "version": "1.2.3", + "version": "1.3.0", "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.", @@ -10,9 +10,8 @@ "proposals": [ "latest", "none", - "3.1", - "3.0", - "2.7" + "3.4", + "3.2" ], "default": "latest", "description": "Select or enter a Ruby version to install" diff --git a/test/ruby/install_additional_ruby.sh b/test/ruby/install_additional_ruby.sh index 4fa844475..12b77def3 100644 --- a/test/ruby/install_additional_ruby.sh +++ b/test/ruby/install_additional_ruby.sh @@ -5,9 +5,9 @@ set -e # Optional: Import test library source dev-container-features-test-lib -check "ruby version 3.1.2 installed as default" ruby -v | grep 3.1.2 -check "ruby version 2.5.9 installed" rvm list | grep 2.5.9 -check "ruby version 3.0.4 installed" rvm list | grep 3.0.4 +check "ruby version 3.4.2 installed as default" ruby -v | grep 3.4.2 +check "ruby version 3.2.8 installed" rvm list | grep 3.2.8 +check "ruby version 3.3.2 installed" rvm list | grep 3.3.2 check "rbenv" bash -c 'eval "$(rbenv init -)" && rbenv --version' check "rake" bash -c "gem list | grep rake" diff --git a/test/ruby/ruby_fallback_test.sh b/test/ruby/ruby_fallback_test.sh index 1c2179fc3..a4ec9a6b5 100644 --- a/test/ruby/ruby_fallback_test.sh +++ b/test/ruby/ruby_fallback_test.sh @@ -248,7 +248,7 @@ get_github_api_repo_url() { # Figure out correct version of a three part version number is not passed ruby_url="https://github.com/ruby/ruby" -RUBY_VERSION="3.1.xyz" +RUBY_VERSION="3.4.xyz" set_rvm_install_args() { RUBY_VERSION=$1 diff --git a/test/ruby/scenarios.json b/test/ruby/scenarios.json index cfa2d8554..dd59d30fb 100644 --- a/test/ruby/scenarios.json +++ b/test/ruby/scenarios.json @@ -3,8 +3,8 @@ "image": "ubuntu:focal", "features": { "ruby": { - "version": "3.1.2", - "additionalVersions": "2.5,3.0.4" + "version": "3.4.2", + "additionalVersions": "3.2,3.3.2" } } }, From 66385f3d5cf87ca1e1c23c1468a63e218b344f53 Mon Sep 17 00:00:00 2001 From: Mathiyarasy <157102811+Mathiyarasy@users.noreply.github.com> Date: Mon, 7 Apr 2025 12:50:53 +0530 Subject: [PATCH 021/138] Remove hardcoded fallback to tem from ms JDK (#1316) * REmove hardcoded fallback to tem from ms JDK * Update latest version * address review comments --- src/java/devcontainer-feature.json | 3 ++- src/java/install.sh | 11 ++++++++++- test/java/install_latest_version.sh | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/java/devcontainer-feature.json b/src/java/devcontainer-feature.json index 4e4b6c5d3..c1a96abff 100644 --- a/src/java/devcontainer-feature.json +++ b/src/java/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "java", - "version": "1.6.2", + "version": "1.6.3", "name": "Java (via SDKMAN!)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/java", "description": "Installs Java, SDKMAN! (if not installed), and needed dependencies.", @@ -10,6 +10,7 @@ "proposals": [ "latest", "none", + "21", "17", "11", "8" diff --git a/src/java/install.sh b/src/java/install.sh index ef3d1913a..62fd39462 100644 --- a/src/java/install.sh +++ b/src/java/install.sh @@ -213,11 +213,20 @@ find_version_list() { major_version=$(echo "$java_ver" | cut -d '.' -f 1) fi + # Remove the hardcoded fallback as this fails for new jdk latest version released ex: 24 + # Related Issue: https://github.com/devcontainers/features/issues/1308 if [ "${JDK_DISTRO}" = "ms" ]; then - if [ "${major_version}" = "8" ] || [ "${major_version}" = "18" ] || [ "${major_version}" = "22" ] || [ "${major_version}" = "23" ]; then + # Check if the requested version is available in the 'ms' distribution + echo "Check if OpenJDK is available for version ${major_version} for ${JDK_DISTRO} Distro" + available_versions=$(su ${USERNAME} -c ". ${SDKMAN_DIR}/bin/sdkman-init.sh && sdk list ${install_type} | grep ${JDK_DISTRO} | grep -oE '[0-9]+(\.[0-9]+(\.[0-9]+)?)?' | sort -u") + if echo "${available_versions}" | grep -q "^${major_version}"; then + echo "JDK version ${major_version} is available in ${JDK_DISTRO}..." + else + echo "JDK version ${major_version} not available in ${JDK_DISTRO}.... Switching to (tem)." JDK_DISTRO="tem" fi fi + echo "JDK_DISTRO: ${JDK_DISTRO}" if [ "${install_type}" != "java" ]; then regex="${prefix}\\K[0-9]+\\.?[0-9]*\\.?[0-9]*${suffix}" else diff --git a/test/java/install_latest_version.sh b/test/java/install_latest_version.sh index af8a621ce..007699b59 100644 --- a/test/java/install_latest_version.sh +++ b/test/java/install_latest_version.sh @@ -9,7 +9,7 @@ echo 'public class HelloWorld { public static void main(String[] args) { System. javac HelloWorld.java check "hello world" /bin/bash -c "java HelloWorld | grep "Hello, World!"" -check "java version latest installed" grep "23" <(java --version) +check "java version latest installed" grep "24" <(java --version) # Report result reportResults From b89a41f6ccda3adbbb6f270d85f653ec09c31cf6 Mon Sep 17 00:00:00 2001 From: Brigit Murtaugh Date: Mon, 7 Apr 2025 12:53:09 -0700 Subject: [PATCH 022/138] Add custom instructions and bump versions (#1317) --- src/anaconda/devcontainer-feature.json | 13 ++++++++++++- src/aws-cli/devcontainer-feature.json | 11 +++++++++-- src/azure-cli/devcontainer-feature.json | 11 +++++++++-- src/conda/devcontainer-feature.json | 13 ++++++++++++- src/desktop-lite/devcontainer-feature.json | 13 ++++++++++++- src/dotnet/devcontainer-feature.json | 11 +++++++++-- src/git-lfs/devcontainer-feature.json | 13 ++++++++++++- src/git/devcontainer-feature.json | 13 ++++++++++++- src/go/devcontainer-feature.json | 11 +++++++++-- src/hugo/devcontainer-feature.json | 13 ++++++++++++- src/java/devcontainer-feature.json | 7 ++++++- src/kubectl-helm-minikube/devcontainer-feature.json | 13 ++++++++++++- src/nix/devcontainer-feature.json | 13 ++++++++++++- src/nvidia-cuda/devcontainer-feature.json | 13 ++++++++++++- src/oryx/devcontainer-feature.json | 13 ++++++++++++- src/php/devcontainer-feature.json | 11 +++++++++-- src/powershell/devcontainer-feature.json | 11 +++++++++-- src/ruby/devcontainer-feature.json | 11 +++++++++-- src/rust/devcontainer-feature.json | 9 +++++++-- src/sshd/devcontainer-feature.json | 13 ++++++++++++- src/terraform/devcontainer-feature.json | 7 ++++++- 21 files changed, 214 insertions(+), 29 deletions(-) diff --git a/src/anaconda/devcontainer-feature.json b/src/anaconda/devcontainer-feature.json index 6b92b9147..e4779279b 100644 --- a/src/anaconda/devcontainer-feature.json +++ b/src/anaconda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "anaconda", - "version": "1.0.12", + "version": "1.0.13", "name": "Anaconda", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/anaconda", "options": { @@ -17,6 +17,17 @@ "CONDA_DIR": "/usr/local/conda", "PATH": "/usr/local/conda/bin:${PATH}" }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes Anaconda and the conda package manager pre-installed and available on the `PATH` for data science and Python development. Additional packages installed using Conda will be downloaded from Anaconda or another repository configured by the user. A user can install different versions of Python than the one in this dev container by running a command like: conda install python=3.7" + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] diff --git a/src/aws-cli/devcontainer-feature.json b/src/aws-cli/devcontainer-feature.json index 3c3128ac3..3de7a92a3 100644 --- a/src/aws-cli/devcontainer-feature.json +++ b/src/aws-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "aws-cli", - "version": "1.1.0", + "version": "1.1.1", "name": "AWS CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/aws-cli", "description": "Installs the AWS CLI along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.", @@ -18,7 +18,14 @@ "vscode": { "extensions": [ "AmazonWebServices.aws-toolkit-vscode" - ] + ], + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the AWS CLI along with needed dependencies pre-installed and available on the `PATH`, along with the AWS Toolkit extensions for AWS development." + } + ] + } } }, "installsAfter": [ diff --git a/src/azure-cli/devcontainer-feature.json b/src/azure-cli/devcontainer-feature.json index a95c33dab..3b731a6b3 100644 --- a/src/azure-cli/devcontainer-feature.json +++ b/src/azure-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "azure-cli", - "version": "1.2.6", + "version": "1.2.7", "name": "Azure CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/azure-cli", "description": "Installs the Azure CLI along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.", @@ -41,7 +41,14 @@ "vscode": { "extensions": [ "ms-vscode.azurecli" - ] + ], + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the Azure CLI along with needed dependencies pre-installed and available on the `PATH`, along with the Azure CLI extension for Azure development." + } + ] + } } }, "installsAfter": [ diff --git a/src/conda/devcontainer-feature.json b/src/conda/devcontainer-feature.json index 9a2365253..163696a20 100644 --- a/src/conda/devcontainer-feature.json +++ b/src/conda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "conda", - "version": "1.0.9", + "version": "1.0.10", "name": "Conda", "description": "A cross-platform, language-agnostic binary package manager", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/conda", @@ -26,6 +26,17 @@ "CONDA_SCRIPT":"/opt/conda/etc/profile.d/conda.sh", "PATH": "/opt/conda/bin:${PATH}" }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the conda package manager pre-installed and available on the `PATH` for data science and Python development. Additional packages installed using Conda will be downloaded from Anaconda or another repository configured by the user. A user can install different versions of Python than the one in this dev container by running a command like: conda install python=3.7" + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] diff --git a/src/desktop-lite/devcontainer-feature.json b/src/desktop-lite/devcontainer-feature.json index 135c812b7..72adc7c81 100644 --- a/src/desktop-lite/devcontainer-feature.json +++ b/src/desktop-lite/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "desktop-lite", - "version": "1.2.5", + "version": "1.2.6", "name": "Light-weight Desktop", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/desktop-lite", "description": "Adds a lightweight Fluxbox based desktop to the container that can be accessed using a VNC viewer or the web. GUI-based commands executed from the built-in VS code terminal will open on the desktop automatically.", @@ -54,6 +54,17 @@ "containerEnv": { "DISPLAY": ":1" }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes a lightweight Fluxbox based desktop that can be accessed using a VNC viewer or the web. GUI-based commands executed from the built-in VS Code terminal will open on the desktop automatically." + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index 600997dde..5d553bcd0 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "2.2.0", + "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.", @@ -49,7 +49,14 @@ "vscode": { "extensions": [ "ms-dotnettools.csharp" - ] + ], + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the .NET SDK, which includes the .NET CLI and the shared runtime, pre-installed and available on the `PATH`, along with the C# language extension for .NET development." + } + ] + } } }, "installsAfter": [ diff --git a/src/git-lfs/devcontainer-feature.json b/src/git-lfs/devcontainer-feature.json index 69f83dd86..03acfcbbf 100644 --- a/src/git-lfs/devcontainer-feature.json +++ b/src/git-lfs/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git-lfs", - "version": "1.2.3", + "version": "1.2.4", "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.", @@ -25,6 +25,17 @@ "description": "Installs 'git-lfs' from GitHub releases instead of package manager feeds" } }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes Git Large File Support (Git LFS) along with needed dependencies pre-installed and available on the `PATH`." + } + ] + } + } + }, "postCreateCommand": "/usr/local/share/pull-git-lfs-artifacts.sh", "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" diff --git a/src/git/devcontainer-feature.json b/src/git/devcontainer-feature.json index 87fb2ab3f..dc79008a5 100644 --- a/src/git/devcontainer-feature.json +++ b/src/git/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git", - "version": "1.3.2", + "version": "1.3.3", "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.", @@ -21,6 +21,17 @@ "description": "Install from PPA if available (only supported for Ubuntu distributions)" } }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes an up-to-date version of Git, built from source as needed, pre-installed and available on the `PATH`." + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] diff --git a/src/go/devcontainer-feature.json b/src/go/devcontainer-feature.json index afb1f9128..4b0adb192 100644 --- a/src/go/devcontainer-feature.json +++ b/src/go/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "go", - "version": "1.3.1", + "version": "1.3.2", "name": "Go", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/go", "description": "Installs Go and common Go utilities. Auto-detects latest version and installs needed dependencies.", @@ -27,7 +27,14 @@ "vscode": { "extensions": [ "golang.Go" - ] + ], + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes Go and common Go utilities pre-installed and available on the `PATH`, along with the Go language extension for Go development." + } + ] + } } }, "containerEnv": { diff --git a/src/hugo/devcontainer-feature.json b/src/hugo/devcontainer-feature.json index d6358d703..376826509 100644 --- a/src/hugo/devcontainer-feature.json +++ b/src/hugo/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "hugo", - "version": "1.1.2", + "version": "1.1.3", "name": "Hugo", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/hugo", "options": { @@ -22,6 +22,17 @@ "HUGO_DIR": "/usr/local/hugo", "PATH": "/usr/local/hugo/bin:${PATH}" }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes Hugo, a popular open-source static site generator written in Go, pre-installed and available on the `PATH`." + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] diff --git a/src/java/devcontainer-feature.json b/src/java/devcontainer-feature.json index c1a96abff..4198af326 100644 --- a/src/java/devcontainer-feature.json +++ b/src/java/devcontainer-feature.json @@ -105,7 +105,12 @@ "vscjava.vscode-java-pack" ], "settings": { - "java.import.gradle.java.home": "/usr/local/sdkman/candidates/java/current" + "java.import.gradle.java.home": "/usr/local/sdkman/candidates/java/current", + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes Java, SDKMAN! and needed dependencies pre-installed and available on the `PATH`, along with the Java language extension pack for Java development." + } + ] } } }, diff --git a/src/kubectl-helm-minikube/devcontainer-feature.json b/src/kubectl-helm-minikube/devcontainer-feature.json index 23596516c..30c621f28 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.0", + "version": "1.2.1", "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.", @@ -44,6 +44,17 @@ "type": "volume" } ], + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes kubectl, Helm, optionally minikube, and needed dependencies pre-installed and available on the `PATH`. When configuring Ingress for your Kubernetes cluster, note that by default Kubernetes will bind to a specific interface's IP rather than localhost or all interfaces. This is why you need to use the Kubernetes Node's IP when connecting - even if there's only one Node as in the case of Minikube." + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] diff --git a/src/nix/devcontainer-feature.json b/src/nix/devcontainer-feature.json index 7fadd63fa..63723e591 100644 --- a/src/nix/devcontainer-feature.json +++ b/src/nix/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nix", - "version": "1.3.0", + "version": "1.3.1", "name": "Nix Package Manager", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/nix", "description": "Installs the Nix package manager and optionally a set of packages.", @@ -40,6 +40,17 @@ "description": "Optional comma separated list of extra lines to add to /etc/nix/nix.conf." } }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the Nix package manager pre-installed and available on the `PATH`. Currently `flakeUri` works best with a remote URI (e.g., `github:nixos/nixpkgs/nixpkgs-unstable#hello`) as local files need to be in the image. The dev container supports two installation models for Nix: multi-user and single user. Multi-user is the default." + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ], diff --git a/src/nvidia-cuda/devcontainer-feature.json b/src/nvidia-cuda/devcontainer-feature.json index d29074fd9..7ed66478f 100644 --- a/src/nvidia-cuda/devcontainer-feature.json +++ b/src/nvidia-cuda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nvidia-cuda", - "version": "1.2.0", + "version": "1.2.1", "name": "NVIDIA CUDA", "description": "Installs shared libraries for NVIDIA CUDA.", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/nvidia-cuda", @@ -84,6 +84,17 @@ "description": "Version of cuDNN to install" } }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes shared libraries for NVIDIA CUDA pre-installed and available on the `PATH`. It's only useful for dev containers that run on a host machine with an NVIDIA GPU. Within your dev container, use the `nvidia-smi` command to ensure that your GPU is available for CUDA. If the `nvidia-smi` command is not available, you may need to follow NVIDIA's instructions to install the NVIDIA Container Toolkit on your host machine." + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json index ab9a8e782..860a39003 100644 --- a/src/oryx/devcontainer-feature.json +++ b/src/oryx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oryx", - "version": "1.4.0", + "version": "1.4.1", "name": "Oryx", "description": "Installs the oryx CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/oryx", @@ -13,6 +13,17 @@ "DEBIAN_FLAVOR": "focal-scm", "PATH": "/usr/local/oryx:${PATH}" }, + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the oryx CLI pre-installed and available on the `PATH`." + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils", "ghcr.io/devcontainers/features/dotnet" diff --git a/src/php/devcontainer-feature.json b/src/php/devcontainer-feature.json index a4edcca95..4db478230 100644 --- a/src/php/devcontainer-feature.json +++ b/src/php/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "php", - "version": "1.1.3", + "version": "1.1.4", "name": "PHP", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/php", "options": { @@ -29,7 +29,14 @@ "bmewburn.vscode-intelephense-client", "xdebug.php-pack", "devsense.phptools-vscode" - ] + ], + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes PHP pre-installed and available on the `PATH`, along with PHP language extensions for PHP development." + } + ] + } } }, "containerEnv": { diff --git a/src/powershell/devcontainer-feature.json b/src/powershell/devcontainer-feature.json index 585e34630..f4867cc9e 100644 --- a/src/powershell/devcontainer-feature.json +++ b/src/powershell/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "powershell", - "version": "1.5.0", + "version": "1.5.1", "name": "PowerShell", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/powershell", "description": "Installs PowerShell along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.", @@ -33,7 +33,14 @@ "extensions": [ "ms-vscode.powershell" ] - } + }, + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes PowerShell along with needed dependencies pre-installed and available on the `PATH`, along with the PowerShell extension." + } + ] + } }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" diff --git a/src/ruby/devcontainer-feature.json b/src/ruby/devcontainer-feature.json index 3d7a081e8..82ae50a10 100644 --- a/src/ruby/devcontainer-feature.json +++ b/src/ruby/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby", - "version": "1.3.0", + "version": "1.3.1", "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.", @@ -21,7 +21,14 @@ "vscode": { "extensions": [ "shopify.ruby-lsp" - ] + ], + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies pre-installed and available on the `PATH`, along with the Ruby language extension for Ruby development." + } + ] + } } }, "containerEnv": { diff --git a/src/rust/devcontainer-feature.json b/src/rust/devcontainer-feature.json index 9fc540c7d..8ee423050 100644 --- a/src/rust/devcontainer-feature.json +++ b/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "1.3.1", + "version": "1.3.2", "name": "Rust", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust", "description": "Installs Rust, common Rust utilities, and their required dependencies", @@ -64,7 +64,12 @@ "settings": { "files.watcherExclude": { "**/target/**": true - } + }, + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes Rust, common Rust utilities, and needed dependencies pre-installed and available on the `PATH`, along with the Rust language extension for Rust development." + } + ] } } }, diff --git a/src/sshd/devcontainer-feature.json b/src/sshd/devcontainer-feature.json index a5d464f69..e400b0601 100644 --- a/src/sshd/devcontainer-feature.json +++ b/src/sshd/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sshd", - "version": "1.0.9", + "version": "1.0.10", "name": "SSH server", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/sshd", "description": "Adds a SSH server into a container so that you can use an external terminal, sftp, or SSHFS to interact with it.", @@ -15,6 +15,17 @@ } }, "entrypoint": "/usr/local/share/ssh-init.sh", + "customizations": { + "vscode": { + "settings": { + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes an SSH server so that you can use an external terminal, sftp, or SSHFS to interact with it. The first time you've started the container, you will want to set a password for your user. With each connection to the container, you'll want to forward the SSH port to your local machine and use a local terminal or other tool to connect using the password you set." + } + ] + } + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index ef6db8dec..d022f83c1 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.3.9", + "version": "1.3.10", "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.", @@ -65,6 +65,11 @@ "terraform.languageServer.enable": true, "terraform.languageServer.args": [ "serve" + ], + "github.copilot.chat.codeGeneration.instructions": [ + { + "text": "This dev container includes the Terraform CLI and optionally TFLint and Terragrunt pre-installed and available on the `PATH`, along with the Terraform extension for Terraform development." + } ] } } From 8895eb3d161d28ada3a8de761a83135e811cae3d Mon Sep 17 00:00:00 2001 From: Kaniska Date: Thu, 17 Apr 2025 19:41:09 +0530 Subject: [PATCH 023/138] [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 024/138] 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 025/138] 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 026/138] [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 027/138] 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 028/138] [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 029/138] 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 030/138] 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 031/138] 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 032/138] 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