From 62f7f7f448bf08701462ebcd15839888f7828329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=B6chenberger?= Date: Thu, 20 Jun 2024 23:07:17 +0200 Subject: [PATCH 001/189] Allow installing `yarn` via `corepack` on Debian-based systems, too (#1009) * Allow installing `yarn` via `corepack` on Debian-based systems, too The default behavior remains unchanged, but users can now opt-out from the APT-based installation to get the latest `yarn` via `corepack`. Closes #1004 * Update src/node/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * Update src/node/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * Rename variable * Expand comment * Add test scenario * Improve tests * Update test/node/debian_yarn_from_corepack.sh * Betetr comments * Update src/node/devcontainer-feature.json --------- Co-authored-by: Samruddhi Khandale --- src/node/devcontainer-feature.json | 7 ++++++- src/node/install.sh | 8 +++++--- test/node/debian_yarn_from_corepack.sh | 20 ++++++++++++++++++++ test/node/scenarios.json | 8 ++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100755 test/node/debian_yarn_from_corepack.sh diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index f15ae4a4d..4e67aa6de 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.4.1", + "version": "1.5.0", "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.", @@ -36,6 +36,11 @@ ], "default": "latest", "description": "Version of NVM to install." + }, + "installYarnUsingApt": { + "type": "boolean", + "default": true, + "description": "On Debian and Ubuntu systems, you have the option to install Yarn globally via APT. If you choose not to use this option, Yarn will be set up using Corepack instead. This choice is specific to Debian and Ubuntu; for other Linux distributions, Yarn is always installed using Corepack, with a fallback to installation via NPM if an error occurs." } }, "customizations": { diff --git a/src/node/install.sh b/src/node/install.sh index 11a123534..5e833c6fe 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -11,6 +11,7 @@ export NODE_VERSION="${VERSION:-"lts"}" export NVM_VERSION="${NVMVERSION:-"latest"}" export NVM_DIR="${NVMINSTALLPATH:-"/usr/local/share/nvm"}" INSTALL_TOOLS_FOR_NODE_GYP="${NODEGYPDEPENDENCIES:-true}" +export INSTALL_YARN_USING_APT="${INSTALLYARNUSINGAPT:-true}" # only concerns Debian-based systems # Comma-separated list of node versions to be installed (with nvm) # alongside NODE_VERSION, but not set as default. @@ -188,7 +189,7 @@ find_version_from_git_tags() { } install_yarn() { - if [ "${ADJUSTED_ID}" = "debian" ]; then + if [ "${ADJUSTED_ID}" = "debian" ] && [ "${INSTALL_YARN_USING_APT}" = "true" ]; then # for backward compatiblity with existing devcontainer features, install yarn # via apt-get on Debian systems if ! type yarn >/dev/null 2>&1; then @@ -202,8 +203,9 @@ install_yarn() { fi else local _ver=${1:-node} - # on non-debian systems, prefer corepack, fallback to npm based installation of yarn... - # Try to leverage corepack if possible + # on non-debian systems or if user opted not to use APT, prefer corepack + # Fallback to npm based installation of yarn. + # But try to leverage corepack if possible # From https://yarnpkg.com: # The preferred way to manage Yarn is by-project and through Corepack, a tool # shipped by default with Node.js. Modern releases of Yarn aren't meant to be diff --git a/test/node/debian_yarn_from_corepack.sh b/test/node/debian_yarn_from_corepack.sh new file mode 100755 index 000000000..97d21ca56 --- /dev/null +++ b/test/node/debian_yarn_from_corepack.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +YARN_VERSION="4.3.0" + +# Corepack provides shims for package managers like yarn. The first time yarn is invoked via the "yarn" +# command, corepack will interactively request permission to download the yarn binary. To +# avoid this interactive mode and download the binary automatically, we explicitly call "corepack use yarn" +# instead (doesn't require user input). Once that command completes, "yarn" can be used in a non-interactive mode. +check "yarn shim location" bash -c ". /usr/local/share/nvm/nvm.sh && type yarn &> /dev/null" +check "download yarn" bash -c ". /usr/local/share/nvm/nvm.sh && corepack use yarn@${YARN_VERSION}" +check "yarn version" bash -c ". /usr/local/share/nvm/nvm.sh && yarn --version | grep ${YARN_VERSION}" + +# Report result +reportResults diff --git a/test/node/scenarios.json b/test/node/scenarios.json index 954c2c2e9..4f07e5ac3 100644 --- a/test/node/scenarios.json +++ b/test/node/scenarios.json @@ -185,5 +185,13 @@ "version": "lts" } } + }, + "debian_yarn_from_corepack": { + "image": "debian:11", + "features": { + "node": { + "installYarnUsingApt": false + } + } } } \ No newline at end of file From 414d3450434b9072f01afe80cab226c60088224a Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:09:43 -0700 Subject: [PATCH 002/189] Automated documentation update (#1013) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/node/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/node/README.md b/src/node/README.md index 6ac1b0ff0..dff3f8bfe 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -19,6 +19,7 @@ Installs Node.js, nvm, yarn, pnpm, and needed dependencies. | nodeGypDependencies | Install dependencies to compile native node modules (node-gyp)? | boolean | true | | nvmInstallPath | The path where NVM will be installed. | string | /usr/local/share/nvm | | nvmVersion | Version of NVM to install. | string | latest | +| installYarnUsingApt | On Debian and Ubuntu systems, you have the option to install Yarn globally via APT. If you choose not to use this option, Yarn will be set up using Corepack instead. This choice is specific to Debian and Ubuntu; for other Linux distributions, Yarn is always installed using Corepack, with a fallback to installation via NPM if an error occurs. | boolean | true | ## Customizations From 694906e3c18ddf66b8b6c691fe07489476b2ffc6 Mon Sep 17 00:00:00 2001 From: Jonathan Backhaus Date: Thu, 27 Jun 2024 14:59:08 -0400 Subject: [PATCH 003/189] Add support for Alpine to `git` feature (#1008) * feat: add basic scaffolding for alpine, based on debian implementation * feat: add baseline packages from * fix: add `curl` package (needed for version lookup) * feat: use `jq`-based version matching implementation for alpine the alpine version of `grep` doesn't support PCRE * fix: forgot to strip the leading "v" from the version number * fix: need `make` package to build from source * feat: parameterize make options to easily inject Alpine-specific option * fix: wip: latest baseline (still breaking due to musl) * feat: add basic scaffolding for alpine, based on debian implementation note: this won't install from source (due to build issues with musl) but will install using the `apk` package manager * chore: chmod +x * chore: bump semver (proposed) * docs: add Alpine/apk to notes * test: add test for `alpine:3` to install system package note: feature does not currently implement building from source on Alpine * fix: working build from source! still need to tweak the package dependencies and make config * perf: remove OBE `gettext-dev` package from dependencies no longer required with "NO_GETTEXT=YesPlease" make config * perf: remove OBE `libintl` package from dependencies no longer required with "NO_GETTEXT=YesPlease" make config (?) * feat: add remaining make options from apk package source reference * docs: add refs. for alpine build from source * test(git): add test case for building git from src on alpine:3 * fix: lint: SC2068: Double quote array expansions to avoid re-splitting elements * fix: use Devcontainer Alpine image as base (because it has `bash` installed); refactor test script names to remove major version suffix (since it isn't specified in the associated image tag) * perf: consolidate to a single, jq-based implementation using `jq` avoids the need for PCRE `grep` expression (not supported in Alpine) * fix: set `sysconfdir` option for alpine build as well see [#395](https://github.com/devcontainers/features/pull/395) * test: fix: alpine doesn't include perl support; leverage test cases from `install_git_from_src.sh` script * style: remove unused options * fix: set `prefix` option for alpine build to be consistent with other builds see [#395](https://github.com/devcontainers/features/pull/395) * refactor: move common arguments out of distro-specific logic * perf: minimum set of make options for building git from source in Alpine * chore: remove OBE code (unused make options for Git) * style: whitespace * test: fix: remove `gettext` check (since this package isn't installed in Alpine) * feat: update implementation based on local Git feature in `base-alpine` image * feat: remove `libsecret-dev` package not present in local Git feature in `base-alpine` image `install.sh` script * feat: switch `glib-dev` to `g++` and `gcc` packages, based on local Git feature in `base-alpine` image * chore: remove `alpine-sdk` package, based on local Git feature in `base-alpine` image no longer needed, based on initial testing * revert: switch back to `grep`-based PCRE implementation, based on local Git feature in `base-alpine` image `jq` package no longer needed * test: revert: remove test cases (covered by generic `install_git_from_src.sh`) * test: fix: remove perl check for system package in Alpine (because the system package is not built with PCRE support) --------- Co-authored-by: Samruddhi Khandale --- src/git/NOTES.md | 2 +- src/git/devcontainer-feature.json | 2 +- src/git/install.sh | 40 +++++++++++++++++++++- test/git/install_git_from_src_alpine.sh | 16 +++++++++ test/git/install_git_from_system_alpine.sh | 15 ++++++++ test/git/scenarios.json | 18 ++++++++++ 6 files changed, 90 insertions(+), 3 deletions(-) mode change 100644 => 100755 src/git/install.sh create mode 100644 test/git/install_git_from_src_alpine.sh create mode 100644 test/git/install_git_from_system_alpine.sh diff --git a/src/git/NOTES.md b/src/git/NOTES.md index e809f2099..507ba8e8b 100644 --- a/src/git/NOTES.md +++ b/src/git/NOTES.md @@ -2,6 +2,6 @@ ## OS Support -This Feature should work on recent versions of Debian/Ubuntu, RedHat Enterprise Linux, Fedora, Alma, and RockyLinux distributions with the `apt`, `yum`, `dnf`, or `microdnf` package manager installed. +This Feature should work on recent versions of Alpine, Debian/Ubuntu, RedHat Enterprise Linux, Fedora, Alma, and RockyLinux distributions with the `apk`, `apt`, `yum`, `dnf`, or `microdnf` package manager installed. `bash` is required to execute the `install.sh` script. diff --git a/src/git/devcontainer-feature.json b/src/git/devcontainer-feature.json index 02c155cef..4eef35df0 100644 --- a/src/git/devcontainer-feature.json +++ b/src/git/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git", - "version": "1.2.1", + "version": "1.3.0", "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.", diff --git a/src/git/install.sh b/src/git/install.sh old mode 100644 new mode 100755 index 706beb4f2..133bff8b1 --- a/src/git/install.sh +++ b/src/git/install.sh @@ -26,6 +26,8 @@ fi # Get an adjusted ID independent of distro variants if [ "${ID}" = "debian" ] || [ "${ID_LIKE}" = "debian" ]; then ADJUSTED_ID="debian" +elif [ "${ID}" = "alpine" ]; then + ADJUSTED_ID="alpine" elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then ADJUSTED_ID="rhel" VERSION_CODENAME="${ID}{$VERSION_ID}" @@ -36,6 +38,8 @@ fi if type apt-get > /dev/null 2>&1; then INSTALL_CMD=apt-get +elif type apk > /dev/null 2>&1; then + INSTALL_CMD=apk elif type microdnf > /dev/null 2>&1; then INSTALL_CMD=microdnf elif type dnf > /dev/null 2>&1; then @@ -53,6 +57,9 @@ clean_up() { debian) rm -rf /var/lib/apt/lists/* ;; + alpine) + rm -rf /var/cache/apk/* + ;; rhel) rm -rf /var/cache/dnf/* rm -rf /var/cache/yum/* @@ -102,6 +109,11 @@ pkg_mgr_update() { echo "Running apt-get update..." ${INSTALL_CMD} update -y fi + elif [ ${INSTALL_CMD} = "apk" ]; then + if [ "$(find /var/cache/apk/* | wc -l)" = "0" ]; then + echo "Running apk update..." + ${INSTALL_CMD} update + fi elif [ ${INSTALL_CMD} = "dnf" ] || [ ${INSTALL_CMD} = "yum" ]; then if [ "$(find /var/cache/${INSTALL_CMD}/* | wc -l)" = "0" ]; then echo "Running ${INSTALL_CMD} check-update ..." @@ -118,6 +130,10 @@ check_packages() { pkg_mgr_update ${INSTALL_CMD} -y install --no-install-recommends "$@" fi + elif [ ${INSTALL_CMD} = "apk" ]; then + ${INSTALL_CMD} add \ + --no-cache \ + "$@" elif [ ${INSTALL_CMD} = "dnf" ] || [ ${INSTALL_CMD} = "yum" ]; then _num_pkgs=$(echo "$@" | tr ' ' \\012 | wc -l) _num_installed=$(${INSTALL_CMD} -C list installed "$@" | sed '1,/^Installed/d' | wc -l) @@ -154,6 +170,8 @@ if [ ${GIT_VERSION} = "os-provided" ] || [ ${GIT_VERSION} = "system" ]; then if [ "$INSTALL_CMD" = "apt-get" ]; then echo "Installing git from OS apt repository" + elif [ "$INSTALL_CMD" = "apk" ]; then + echo "Installing git from OS apk repository" else echo "Installing git from OS yum/dnf repository" fi @@ -194,6 +212,14 @@ if [ "${ADJUSTED_ID}" = "debian" ]; then check_packages libpcre2-posix3 fi +elif [ "${ADJUSTED_ID}" = "alpine" ]; then + + # update build dependencies + ${INSTALL_CMD} add --no-cache --update curl grep make zlib-dev + + # ref. + check_packages asciidoc curl-dev expat-dev g++ gcc openssl-dev pcre2-dev perl-dev perl-error python3-dev tcl tk xmlto + elif [ "${ADJUSTED_ID}" = "rhel" ]; then if [ $VERSION_CODENAME = "centos7" ]; then @@ -212,6 +238,10 @@ elif [ "${ADJUSTED_ID}" = "rhel" ]; then if [ $ID = "mariner" ]; then check_packages glibc-devel kernel-headers binutils fi + +else + echo "Linux distro ${ID} not supported." + exit 1 fi # Partial version matching @@ -235,7 +265,15 @@ echo "Downloading source for ${GIT_VERSION}..." curl -sL https://github.com/git/git/archive/v${GIT_VERSION}.tar.gz | tar -xzC /tmp 2>&1 echo "Building..." cd /tmp/git-${GIT_VERSION} -make -s USE_LIBPCRE=YesPlease prefix=/usr/local sysconfdir=/etc all && make -s USE_LIBPCRE=YesPlease prefix=/usr/local sysconfdir=/etc install 2>&1 +git_options=("prefix=/usr/local") +git_options+=("sysconfdir=/etc") +git_options+=("USE_LIBPCRE=YesPlease") +if [ "${ADJUSTED_ID}" = "alpine" ]; then + # ref. + git_options+=("NO_REGEX=YesPlease") + git_options+=("NO_GETTEXT=YesPlease") +fi +make -s "${git_options[@]}" all && make -s "${git_options[@]}" install 2>&1 rm -rf /tmp/git-${GIT_VERSION} clean_up echo "Done!" diff --git a/test/git/install_git_from_src_alpine.sh b/test/git/install_git_from_src_alpine.sh new file mode 100644 index 000000000..2a26beec5 --- /dev/null +++ b/test/git/install_git_from_src_alpine.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/test/git/install_git_from_system_alpine.sh b/test/git/install_git_from_system_alpine.sh new file mode 100644 index 000000000..972976a4c --- /dev/null +++ b/test/git/install_git_from_system_alpine.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter + +# Report result +reportResults diff --git a/test/git/scenarios.json b/test/git/scenarios.json index 583c1adbe..4d606c365 100644 --- a/test/git/scenarios.json +++ b/test/git/scenarios.json @@ -8,6 +8,15 @@ } } }, + "install_git_from_src_alpine": { + "image": "mcr.microsoft.com/devcontainers/base:alpine", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, "install_git_from_src_jammy": { "image": "ubuntu:jammy", "features": { @@ -107,6 +116,15 @@ } } }, + "install_git_from_system_alpine": { + "image": "mcr.microsoft.com/devcontainers/base:alpine", + "features": { + "git": { + "version": "system", + "ppa": "false" + } + } + }, "install_git_from_system_centos-7": { "image": "centos:centos7", "features": { From 0356cbb046e3bac9ecff76ac3624178681592cff Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Thu, 27 Jun 2024 12:02:04 -0700 Subject: [PATCH 004/189] Automated documentation update (#1019) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/git/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/git/README.md b/src/git/README.md index adcb04e36..e750bbed2 100644 --- a/src/git/README.md +++ b/src/git/README.md @@ -22,7 +22,7 @@ Install an up-to-date version of Git, built from source as needed. Useful for wh ## OS Support -This Feature should work on recent versions of Debian/Ubuntu, RedHat Enterprise Linux, Fedora, Alma, and RockyLinux distributions with the `apt`, `yum`, `dnf`, or `microdnf` package manager installed. +This Feature should work on recent versions of Alpine, Debian/Ubuntu, RedHat Enterprise Linux, Fedora, Alma, and RockyLinux distributions with the `apk`, `apt`, `yum`, `dnf`, or `microdnf` package manager installed. `bash` is required to execute the `install.sh` script. From 9387225ac7ada315d94511848fd490a8519ed591 Mon Sep 17 00:00:00 2001 From: Paul Taylor <178183+trxcllnt@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:28:44 -0700 Subject: [PATCH 005/189] Guard against undefined variables when PS1 is evaluated (#1020) * Guard against undefined variables when PS1 is evaluated * Update version in devcontainer-feature.json --- src/common-utils/devcontainer-feature.json | 4 ++-- src/common-utils/scripts/bash_theme_snippet.sh | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 308e256ef..dc62272ad 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.4.3", + "version": "2.4.4", "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.", @@ -66,4 +66,4 @@ "description": "Add packages from non-free Debian repository? (Debian only)" } } -} \ No newline at end of file +} diff --git a/src/common-utils/scripts/bash_theme_snippet.sh b/src/common-utils/scripts/bash_theme_snippet.sh index a028e4b63..491e4c047 100644 --- a/src/common-utils/scripts/bash_theme_snippet.sh +++ b/src/common-utils/scripts/bash_theme_snippet.sh @@ -2,13 +2,13 @@ # bash theme - partly inspired by https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/robbyrussell.zsh-theme __bash_prompt() { local userpart='`export XIT=$? \ - && [ ! -z "${GITHUB_USER}" ] && echo -n "\[\033[0;32m\]@${GITHUB_USER} " || echo -n "\[\033[0;32m\]\u " \ + && [ ! -z "${GITHUB_USER:-}" ] && echo -n "\[\033[0;32m\]@${GITHUB_USER:-} " || echo -n "\[\033[0;32m\]\u " \ && [ "$XIT" -ne "0" ] && echo -n "\[\033[1;31m\]➜" || echo -n "\[\033[0m\]➜"`' local gitbranch='`\ if [ "$(git config --get devcontainers-theme.hide-status 2>/dev/null)" != 1 ] && [ "$(git config --get codespaces-theme.hide-status 2>/dev/null)" != 1 ]; then \ - export BRANCH=$(git --no-optional-locks symbolic-ref --short HEAD 2>/dev/null || git --no-optional-locks rev-parse --short HEAD 2>/dev/null); \ - if [ "${BRANCH}" != "" ]; then \ - echo -n "\[\033[0;36m\](\[\033[1;31m\]${BRANCH}" \ + export BRANCH="$(git --no-optional-locks symbolic-ref --short HEAD 2>/dev/null || git --no-optional-locks rev-parse --short HEAD 2>/dev/null)"; \ + if [ "${BRANCH:-}" != "" ]; then \ + echo -n "\[\033[0;36m\](\[\033[1;31m\]${BRANCH:-}" \ && if [ "$(git config --get devcontainers-theme.show-dirty 2>/dev/null)" = 1 ] && \ git --no-optional-locks ls-files --error-unmatch -m --directory --no-empty-directory -o --exclude-standard ":/*" > /dev/null 2>&1; then \ echo -n " \[\033[1;33m\]✗"; \ From 09d5632279a541ba9db0834fbe451776d64ccfdd Mon Sep 17 00:00:00 2001 From: James Hodgkinson Date: Wed, 10 Jul 2024 11:56:22 -0700 Subject: [PATCH 006/189] Rust: add the option to install additional targets (#1033) * Rust: add the option to install additional targets Fixes #1032 * Apply suggestions from code review Co-authored-by: Samruddhi Khandale * Changed description --------- Co-authored-by: Samruddhi Khandale --- src/rust/devcontainer-feature.json | 14 +++++++++-- src/rust/install.sh | 37 +++++++++++++++++++----------- test/rust/rust_with_target.sh | 15 ++++++++++++ test/rust/scenarios.json | 9 ++++++++ 4 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 test/rust/rust_with_target.sh diff --git a/src/rust/devcontainer-feature.json b/src/rust/devcontainer-feature.json index 70013442f..909f315c4 100644 --- a/src/rust/devcontainer-feature.json +++ b/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "1.1.3", + "version": "1.2.0", "name": "Rust", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust", "description": "Installs Rust, common Rust utilities, and their required dependencies", @@ -39,6 +39,16 @@ ], "default": "minimal", "description": "Select a rustup install profile." + }, + "targets": { + "type": "string", + "default": "", + "description": "Optional comma separated list of additional Rust targets to install.", + "proposals": [ + "aarch64-unknown-linux-gnu", + "armv7-unknown-linux-gnueabihf", + "x86_64-unknown-redox,x86_64-unknown-uefi" + ] } }, "customizations": { @@ -70,4 +80,4 @@ "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] -} +} \ No newline at end of file diff --git a/src/rust/install.sh b/src/rust/install.sh index 4db9edc1e..1025e46bb 100755 --- a/src/rust/install.sh +++ b/src/rust/install.sh @@ -9,6 +9,7 @@ RUST_VERSION="${VERSION:-"latest"}" RUSTUP_PROFILE="${PROFILE:-"minimal"}" +RUSTUP_TARGETS="${TARGETS:-""}" export CARGO_HOME="${CARGO_HOME:-"/usr/local/cargo"}" export RUSTUP_HOME="${RUSTUP_HOME:-"/usr/local/rustup"}" @@ -19,7 +20,9 @@ UPDATE_RUST="${UPDATE_RUST:-"false"}" set -e # Clean up -rm -rf /var/lib/apt/lists/* +if [ "$(ls -1 /var/lib/apt/lists/ | wc -l)" -gt -1 ]; then + rm -rf /var/lib/apt/lists/* +fi 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.' @@ -36,7 +39,7 @@ if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then USERNAME="" POSSIBLE_USERS=("vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do - if id -u ${CURRENT_USER} > /dev/null 2>&1; then + if id -u "${CURRENT_USER}" > /dev/null 2>&1; then USERNAME=${CURRENT_USER} break fi @@ -44,7 +47,7 @@ if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then if [ "${USERNAME}" = "" ]; then USERNAME=root fi -elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then +elif [ "${USERNAME}" = "none" ] || ! id -u "${USERNAME}" > /dev/null 2>&1; then USERNAME=root fi @@ -56,7 +59,7 @@ find_version_from_git_tags() { 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 @@ -66,7 +69,7 @@ find_version_from_git_tags() { last_part="${escaped_separator}[0-9]+" fi local regex="${prefix}\\K[0-9]+${escaped_separator}[0-9]+${last_part}$" - local version_list="$(git ls-remote --tags ${repository} | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" + local version_list="$(git ls-remote --tags "${repository}" | grep -oP "${regex}" | tr -d ' ' | tr "${separator}" "." | sort -rV)" if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" else @@ -89,13 +92,13 @@ check_nightly_version_formatting() { local version_date=$(echo ${requested_version} | sed -e "s/^nightly-//") - date -d ${version_date} &>/dev/null - if [ $? != 0 ]; then + + if ! date -d "${version_date}" &>/dev/null; then echo -e "Invalid ${variable_name} value: ${requested_version}\nNightly version should be in the format nightly-YYYY-MM-DD" >&2 exit 1 fi - if [ $(date -d ${version_date} +%s) -ge $(date +%s) ]; then + if [ "$(date -d "${version_date}" +%s)" -ge "$(date +%s)" ]; then echo -e "Invalid ${variable_name} value: ${requested_version}\nNightly version should not exceed current date" >&2 exit 1 fi @@ -141,10 +144,10 @@ fi architecture="$(dpkg --print-architecture)" download_architecture="${architecture}" case ${download_architecture} in - amd64) + amd64) download_architecture="x86_64" ;; - arm64) + arm64) download_architecture="aarch64" ;; *) echo "(!) Architecture ${architecture} not supported." @@ -154,7 +157,7 @@ esac # Install Rust umask 0002 -if ! cat /etc/group | grep -e "^rustlang:" > /dev/null 2>&1; then +if ! grep -e "^rustlang:" /etc/group > /dev/null 2>&1; then groupadd -r rustlang fi usermod -a -G rustlang "${USERNAME}" @@ -172,7 +175,7 @@ else fi is_nightly=0 - echo ${RUST_VERSION} | grep -q "nightly" || is_nightly=$? + echo "${RUST_VERSION}" | grep -q "nightly" || is_nightly=$? if [ $is_nightly = 0 ]; then check_nightly_version_formatting RUST_VERSION else @@ -189,7 +192,7 @@ else cp /tmp/rustup/target/${download_architecture}-unknown-linux-gnu/release/rustup-init /tmp/rustup/rustup-init sha256sum -c rustup-init.sha256 chmod +x target/${download_architecture}-unknown-linux-gnu/release/rustup-init - target/${download_architecture}-unknown-linux-gnu/release/rustup-init -y --no-modify-path --profile ${RUSTUP_PROFILE} ${default_toolchain_arg} + target/${download_architecture}-unknown-linux-gnu/release/rustup-init -y --no-modify-path --profile "${RUSTUP_PROFILE}" ${default_toolchain_arg} cd ~ rm -rf /tmp/rustup fi @@ -202,6 +205,14 @@ fi echo "Installing common Rust dependencies..." rustup component add rls rust-analysis rust-src rustfmt clippy 2>&1 +if [ -n "${RUSTUP_TARGETS}" ]; then + IFS=',' read -ra targets <<< "${RUSTUP_TARGETS}" + for target in "${targets[@]}"; do + echo "Installing additional Rust target $target" + rustup target add "$target" 2>&1 + done +fi + # Add CARGO_HOME, RUSTUP_HOME and bin directory into bashrc/zshrc files (unless disabled) updaterc "$(cat << EOF export RUSTUP_HOME="${RUSTUP_HOME}" diff --git a/test/rust/rust_with_target.sh b/test/rust/rust_with_target.sh new file mode 100644 index 000000000..c00a21dd2 --- /dev/null +++ b/test/rust/rust_with_target.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "cargo version" cargo --version +check "rustc version" rustc --version +check "correct rust version" rustup target list | grep aarch64-unknown-linux-gnu + + +# Report result +reportResults \ No newline at end of file diff --git a/test/rust/scenarios.json b/test/rust/scenarios.json index 4a2d540ef..de037cd29 100644 --- a/test/rust/scenarios.json +++ b/test/rust/scenarios.json @@ -6,5 +6,14 @@ "version": "1.62.0" } } + }, + "rust_with_target": { + "image": "ubuntu:focal", + "features": { + "rust": { + "version": "latest", + "targets": "aarch64-unknown-linux-gnu" + } + } } } \ No newline at end of file From f45518999e598127c46ece79a607a241eb5e38d6 Mon Sep 17 00:00:00 2001 From: H3xCat <2304691+h3xcat@users.noreply.github.com> Date: Wed, 17 Jul 2024 09:36:01 -0700 Subject: [PATCH 007/189] Resolve slow key retrieval when some GPG key servers are not reachable (#1016) * Reduce timeout to GPG key servers for Python feature * Dynamically find out reachable GPG servers * Apply fix to other features * Fix build issues * Fix shellcheck SC2068 by quoting array expansion * Bump up patch version for affected features * improve readability for keyservers_curl_map --- src/git-lfs/devcontainer-feature.json | 2 +- src/git-lfs/install.sh | 43 ++++++++++++++-- src/git/devcontainer-feature.json | 2 +- src/git/install.sh | 43 ++++++++++++++-- src/github-cli/devcontainer-feature.json | 2 +- src/github-cli/install.sh | 42 +++++++++++++-- .../devcontainer-feature.json | 2 +- src/kubectl-helm-minikube/install.sh | 38 ++++++++++++-- src/python/devcontainer-feature.json | 2 +- src/python/install.sh | 51 ++++++++++++++++--- src/ruby/devcontainer-feature.json | 2 +- src/ruby/install.sh | 43 ++++++++++++++-- src/terraform/devcontainer-feature.json | 2 +- src/terraform/install.sh | 41 +++++++++++++-- ...tall_cpython_fallback_prev_version_test.sh | 46 ++++++++++++++++- test/ruby/ruby_fallback_test.sh | 43 ++++++++++++++-- 16 files changed, 354 insertions(+), 50 deletions(-) diff --git a/src/git-lfs/devcontainer-feature.json b/src/git-lfs/devcontainer-feature.json index 0c6dccad2..c9e0d9b82 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.1", + "version": "1.2.2", "name": "Git Large File Support (LFS)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/git-lfs", "description": "Installs Git Large File Support (Git LFS) along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like git and curl.", diff --git a/src/git-lfs/install.sh b/src/git-lfs/install.sh index 4d14c9918..f5c473816 100755 --- a/src/git-lfs/install.sh +++ b/src/git-lfs/install.sh @@ -15,10 +15,6 @@ GIT_LFS_ARCHIVE_GPG_KEY_URI="https://packagecloud.io/github/git-lfs/gpgkey" GIT_LFS_ARCHIVE_ARCHITECTURES="amd64 arm64" GIT_LFS_ARCHIVE_VERSION_CODENAMES="stretch buster bullseye bionic focal jammy" GIT_LFS_CHECKSUM_GPG_KEYS="0x88ace9b29196305ba9947552f1ba225c0223b187 0x86cd3297749375bcf8206715f54fe648088335a9 0xaa3b3450295830d2de6db90caba67be5a5795889" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com -keyserver hkp://keyserver.ubuntu.com:80 -keyserver hkps://keys.openpgp.org -keyserver hkp://keyserver.pgp.com" set -e @@ -64,15 +60,52 @@ find_version_from_git_tags() { echo "${variable_name}=${!variable_name}" } +# Get the list of GPG key servers that are reachable +get_gpg_key_servers() { + declare -A keyservers_curl_map=( + ["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371" + ["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com" + ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" + ["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371" + ) + + local curl_args="" + local keyserver_reachable=false # Flag to indicate if any keyserver is reachable + + if [ ! -z "${KEYSERVER_PROXY}" ]; then + curl_args="--proxy ${KEYSERVER_PROXY}" + fi + + for keyserver in "${!keyservers_curl_map[@]}"; do + local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" + if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + echo "keyserver ${keyserver}" + keyserver_reachable=true + else + echo "(*) Keyserver ${keyserver} is not reachable." >&2 + fi + done + + if ! $keyserver_reachable; then + echo "(!) No keyserver is reachable." >&2 + exit 1 + fi +} + # Import the specified key in a variable name passed in as receive_gpg_keys() { local keys=${!1} + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} - echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf + echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf # GPG key download sometimes fails for some reason and retrying fixes it. local retry_count=0 local gpg_ok="false" diff --git a/src/git/devcontainer-feature.json b/src/git/devcontainer-feature.json index 4eef35df0..2d18b8d34 100644 --- a/src/git/devcontainer-feature.json +++ b/src/git/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git", - "version": "1.3.0", + "version": "1.3.1", "name": "Git (from source)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/git", "description": "Install an up-to-date version of Git, built from source as needed. Useful for when you want the latest and greatest features. Auto-detects latest stable version and installs needed dependencies.", diff --git a/src/git/install.sh b/src/git/install.sh index 133bff8b1..974dc66c0 100755 --- a/src/git/install.sh +++ b/src/git/install.sh @@ -11,10 +11,6 @@ GIT_VERSION=${VERSION} # 'system' checks the base image first, else installs 'la USE_PPA_IF_AVAILABLE=${PPA} GIT_CORE_PPA_ARCHIVE_GPG_KEY=E1DD270288B4E6030699E45FA1715D88E1DF1F24 -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com -keyserver hkp://keyserver.ubuntu.com:80 -keyserver hkps://keys.openpgp.org -keyserver hkp://keyserver.pgp.com" if [ "$(id -u)" -ne 0 ]; then echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' @@ -68,6 +64,38 @@ clean_up() { } clean_up +# Get the list of GPG key servers that are reachable +get_gpg_key_servers() { + declare -A keyservers_curl_map=( + ["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371" + ["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com" + ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" + ["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371" + ) + + local curl_args="" + local keyserver_reachable=false # Flag to indicate if any keyserver is reachable + + if [ ! -z "${KEYSERVER_PROXY}" ]; then + curl_args="--proxy ${KEYSERVER_PROXY}" + fi + + for keyserver in "${!keyservers_curl_map[@]}"; do + local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" + if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + echo "keyserver ${keyserver}" + keyserver_reachable=true + else + echo "(*) Keyserver ${keyserver} is not reachable." >&2 + fi + done + + if ! $keyserver_reachable; then + echo "(!) No keyserver is reachable." >&2 + exit 1 + fi +} + # Import the specified key in a variable name passed in as receive_gpg_keys() { local keys=${!1} @@ -77,11 +105,16 @@ receive_gpg_keys() { keyring_args="--no-default-keyring --keyring $2" fi + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} - echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf + echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf # GPG key download sometimes fails for some reason and retrying fixes it. local retry_count=0 local gpg_ok="false" diff --git a/src/github-cli/devcontainer-feature.json b/src/github-cli/devcontainer-feature.json index 61b249fde..9b1558ec0 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.12", + "version": "1.0.13", "name": "GitHub CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/github-cli", "description": "Installs the GitHub CLI. Auto-detects latest version and installs needed dependencies.", diff --git a/src/github-cli/install.sh b/src/github-cli/install.sh index 2f196c981..18dae33ce 100755 --- a/src/github-cli/install.sh +++ b/src/github-cli/install.sh @@ -11,10 +11,6 @@ CLI_VERSION=${VERSION:-"latest"} INSTALL_DIRECTLY_FROM_GITHUB_RELEASE=${INSTALLDIRECTLYFROMGITHUBRELEASE:-"true"} GITHUB_CLI_ARCHIVE_GPG_KEY=23F3D4EA75716059 -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com -keyserver hkp://keyserver.ubuntu.com:80 -keyserver hkps://keys.openpgp.org -keyserver hkp://keyserver.pgp.com" set -e @@ -26,6 +22,37 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi +# Get the list of GPG key servers that are reachable +get_gpg_key_servers() { + declare -A keyservers_curl_map=( + ["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371" + ["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com" + ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" + ["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371" + ) + + local curl_args="" + local keyserver_reachable=false # Flag to indicate if any keyserver is reachable + + if [ ! -z "${KEYSERVER_PROXY}" ]; then + curl_args="--proxy ${KEYSERVER_PROXY}" + fi + + for keyserver in "${!keyservers_curl_map[@]}"; do + local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" + if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + echo "keyserver ${keyserver}" + keyserver_reachable=true + else + echo "(*) Keyserver ${keyserver} is not reachable." >&2 + fi + done + + if ! $keyserver_reachable; then + echo "(!) No keyserver is reachable." >&2 + exit 1 + fi +} # Import the specified key in a variable name passed in as receive_gpg_keys() { @@ -35,11 +62,16 @@ receive_gpg_keys() { keyring_args="--no-default-keyring --keyring $2" fi + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} - echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf + echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf # GPG key download sometimes fails for some reason and retrying fixes it. local retry_count=0 local gpg_ok="false" diff --git a/src/kubectl-helm-minikube/devcontainer-feature.json b/src/kubectl-helm-minikube/devcontainer-feature.json index 8c5dfddc0..dabee64a5 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.1.9", + "version": "1.1.10", "name": "Kubectl, Helm, and Minikube", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/kubectl-helm-minikube", "description": "Installs latest version of kubectl, Helm, and optionally minikube. Auto-detects latest versions and installs needed dependencies.", diff --git a/src/kubectl-helm-minikube/install.sh b/src/kubectl-helm-minikube/install.sh index 871a77ca1..c2f9ba0c9 100755 --- a/src/kubectl-helm-minikube/install.sh +++ b/src/kubectl-helm-minikube/install.sh @@ -22,10 +22,6 @@ MINIKUBE_SHA256="${MINIKUBE_SHA256:-"automatic"}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" HELM_GPG_KEYS_URI="https://raw.githubusercontent.com/helm/helm/main/KEYS" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com -keyserver hkp://keyserver.ubuntu.com:80 -keyserver hkps://keys.openpgp.org -keyserver hkp://keyserver.pgp.com" if [ "$(id -u)" -ne 0 ]; then echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' @@ -234,6 +230,38 @@ get_helm() { curl -sSL "https://github.com/helm/helm/releases/download/${HELM_VERSION}/${helm_filename}.asc" -o "${tmp_helm_filename}.asc" } +# Get the list of GPG key servers that are reachable +get_gpg_key_servers() { + declare -A keyservers_curl_map=( + ["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371" + ["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com" + ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" + ["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371" + ) + + local curl_args="" + local keyserver_reachable=false # Flag to indicate if any keyserver is reachable + + if [ ! -z "${KEYSERVER_PROXY}" ]; then + curl_args="--proxy ${KEYSERVER_PROXY}" + fi + + for keyserver in "${!keyservers_curl_map[@]}"; do + local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" + if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + echo "keyserver ${keyserver}" + keyserver_reachable=true + else + echo "(*) Keyserver ${keyserver} is not reachable." >&2 + fi + done + + if ! $keyserver_reachable; then + echo "(!) No keyserver is reachable." >&2 + exit 1 + fi +} + if [ ${HELM_VERSION} != "none" ]; then # Install Helm, verify signature and checksum echo "Downloading Helm..." @@ -255,7 +283,7 @@ if [ ${HELM_VERSION} != "none" ]; then mkdir -p "${GNUPGHOME}" chmod 700 ${GNUPGHOME} curl -sSL "${HELM_GPG_KEYS_URI}" -o /tmp/helm/KEYS - echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf + echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf gpg -q --import "/tmp/helm/KEYS" if ! gpg --verify "${tmp_helm_filename}.asc" > ${GNUPGHOME}/verify.log 2>&1; then echo "Verification failed!" diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index 27417c63e..2cb4cc87b 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.6.2", + "version": "1.6.3", "name": "Python", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/python", "description": "Installs the provided version of Python, as well as PIPX, and other common Python utilities. JupyterLab is conditionally installed with the python feature. Note: May require source code compilation.", diff --git a/src/python/install.sh b/src/python/install.sh index 7da236e0e..e6702add9 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -31,12 +31,7 @@ ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" # Comma-separated list of additional tools to be installed via pipx. IFS="," read -r -a DEFAULT_UTILS <<< "${TOOLSTOINSTALL:-flake8,autopep8,black,yapf,mypy,pydocstyle,pycodestyle,bandit,pipenv,virtualenv,pytest}" - PYTHON_SOURCE_GPG_KEYS="64E628F8D684696D B26995E310250568 2D347EA6AA65421D FB9921286F5E1540 3A5CA953F73C700D 04C367C218ADD4FF 0EDDC5F26A45C816 6AF053F07D9DC8D2 C9BE28DEE6DF025C 126EB563A74B06BF D9866941EA5BBD71 ED9D77D5 A821E680E5FA6305" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com -keyserver hkp://keyserver.ubuntu.com:80 -keyserver hkps://keys.openpgp.org -keyserver hkp://keyserver.pgp.com" KEYSERVER_PROXY="${HTTPPROXY:-"${HTTP_PROXY:-""}"}" @@ -130,6 +125,38 @@ updaterc() { fi } +# Get the list of GPG key servers that are reachable +get_gpg_key_servers() { + declare -A keyservers_curl_map=( + ["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371" + ["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com" + ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" + ["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371" + ) + + local curl_args="" + local keyserver_reachable=false # Flag to indicate if any keyserver is reachable + + if [ ! -z "${KEYSERVER_PROXY}" ]; then + curl_args="--proxy ${KEYSERVER_PROXY}" + fi + + for keyserver in "${!keyservers_curl_map[@]}"; do + local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" + if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + echo "keyserver ${keyserver}" + keyserver_reachable=true + else + echo "(*) Keyserver ${keyserver} is not reachable." >&2 + fi + done + + if ! $keyserver_reachable; then + echo "(!) No keyserver is reachable." >&2 + exit 1 + fi +} + # Import the specified key in a variable name passed in as receive_gpg_keys() { local keys=${!1} @@ -143,11 +170,16 @@ receive_gpg_keys() { keyring_args="${keyring_args} --keyserver-options http-proxy=${KEYSERVER_PROXY}" fi + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} - echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf + echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf # GPG key download sometimes fails for some reason and retrying fixes it. local retry_count=0 local gpg_ok="false" @@ -182,6 +214,11 @@ receive_gpg_keys_centos7() { keyring_args="${keyring_args} --keyserver-options http-proxy=${KEYSERVER_PROXY}" fi + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} @@ -193,7 +230,7 @@ receive_gpg_keys_centos7() { set +e echo "(*) Downloading GPG keys..." until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; do - for keyserver in $(echo "${GPG_KEY_SERVERS}" | sed 's/keyserver //'); do + for keyserver in $(echo "$(get_gpg_key_servers)" | sed 's/keyserver //'); do ( echo "${keys}" | xargs -n 1 gpg -q ${keyring_args} --recv-keys --keyserver=${keyserver} ) 2>&1 downloaded_keys=$(gpg --list-keys | grep ^pub | wc -l) if [[ ${num_keys} = ${downloaded_keys} ]]; then diff --git a/src/ruby/devcontainer-feature.json b/src/ruby/devcontainer-feature.json index 2a95fef8b..0618d4296 100644 --- a/src/ruby/devcontainer-feature.json +++ b/src/ruby/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby", - "version": "1.2.2", + "version": "1.2.3", "name": "Ruby (via rvm)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/ruby", "description": "Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies.", diff --git a/src/ruby/install.sh b/src/ruby/install.sh index a0a97f0b1..befeee4af 100755 --- a/src/ruby/install.sh +++ b/src/ruby/install.sh @@ -23,10 +23,6 @@ ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" DEFAULT_GEMS="rake" RVM_GPG_KEYS="409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com -keyserver hkp://keyserver.ubuntu.com:80 -keyserver hkps://keys.openpgp.org -keyserver hkp://keyserver.pgp.com" set -e @@ -72,6 +68,38 @@ updaterc() { fi } +# Get the list of GPG key servers that are reachable +get_gpg_key_servers() { + declare -A keyservers_curl_map=( + ["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371" + ["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com" + ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" + ["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371" + ) + + local curl_args="" + local keyserver_reachable=false # Flag to indicate if any keyserver is reachable + + if [ ! -z "${KEYSERVER_PROXY}" ]; then + curl_args="--proxy ${KEYSERVER_PROXY}" + fi + + for keyserver in "${!keyservers_curl_map[@]}"; do + local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" + if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + echo "keyserver ${keyserver}" + keyserver_reachable=true + else + echo "(*) Keyserver ${keyserver} is not reachable." >&2 + fi + done + + if ! $keyserver_reachable; then + echo "(!) No keyserver is reachable." >&2 + exit 1 + fi +} + # Import the specified key in a variable name passed in as receive_gpg_keys() { local keys=${!1} @@ -80,11 +108,16 @@ receive_gpg_keys() { keyring_args="--no-default-keyring --keyring \"$2\"" fi + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} - echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf + echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf # GPG key download sometimes fails for some reason and retrying fixes it. local retry_count=0 local gpg_ok="false" diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index c4294efd4..3193f25af 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.3.7", + "version": "1.3.8", "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.", diff --git a/src/terraform/install.sh b/src/terraform/install.sh index 93d27ac7a..a2aace9b4 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -28,9 +28,6 @@ TERRAFORM_DOCS_SHA256="${TERRAFORM_DOCS_SHA256:-"automatic"}" TERRAFORM_GPG_KEY="72D7468F" TFLINT_GPG_KEY_URI="https://raw.githubusercontent.com/terraform-linters/tflint/v0.46.1/8CE69160EB3F2FE9.key" -GPG_KEY_SERVERS="keyserver hkps://keyserver.ubuntu.com -keyserver hkps://keys.openpgp.org -keyserver hkps://keyserver.pgp.com" KEYSERVER_PROXY="${HTTPPROXY:-"${HTTP_PROXY:-""}"}" architecture="$(uname -m)" @@ -47,6 +44,37 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi +# Get the list of GPG key servers that are reachable +get_gpg_key_servers() { + declare -A keyservers_curl_map=( + ["hkps://keyserver.ubuntu.com"]="https://keyserver.ubuntu.com" + ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" + ["hkps://keyserver.pgp.com"]="https://keyserver.pgp.com" + ) + + local curl_args="" + local keyserver_reachable=false # Flag to indicate if any keyserver is reachable + + if [ ! -z "${KEYSERVER_PROXY}" ]; then + curl_args="--proxy ${KEYSERVER_PROXY}" + fi + + for keyserver in "${!keyservers_curl_map[@]}"; do + local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" + if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + echo "keyserver ${keyserver}" + keyserver_reachable=true + else + echo "(*) Keyserver ${keyserver} is not reachable." >&2 + fi + done + + if ! $keyserver_reachable; then + echo "(!) No keyserver is reachable." >&2 + exit 1 + fi +} + # Import the specified key in a variable name passed in as receive_gpg_keys() { local keys=${!1} @@ -58,11 +86,16 @@ receive_gpg_keys() { keyring_args="${keyring_args} --keyserver-options http-proxy=${KEYSERVER_PROXY}" fi + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} - echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf + echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf # GPG key download sometimes fails for some reason and retrying fixes it. local retry_count=0 local gpg_ok="false" diff --git a/test/python/install_cpython_fallback_prev_version_test.sh b/test/python/install_cpython_fallback_prev_version_test.sh index 85275c73b..c1beba455 100644 --- a/test/python/install_cpython_fallback_prev_version_test.sh +++ b/test/python/install_cpython_fallback_prev_version_test.sh @@ -93,6 +93,38 @@ check_packages() { esac } +# Get the list of GPG key servers that are reachable +get_gpg_key_servers() { + declare -A keyservers_curl_map=( + ["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371" + ["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com" + ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" + ["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371" + ) + + local curl_args="" + local keyserver_reachable=false # Flag to indicate if any keyserver is reachable + + if [ ! -z "${KEYSERVER_PROXY}" ]; then + curl_args="--proxy ${KEYSERVER_PROXY}" + fi + + for keyserver in "${!keyservers_curl_map[@]}"; do + local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" + if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + echo "keyserver ${keyserver}" + keyserver_reachable=true + else + echo "(*) Keyserver ${keyserver} is not reachable." >&2 + fi + done + + if ! $keyserver_reachable; then + echo "(!) No keyserver is reachable." >&2 + exit 1 + fi +} + # Import the specified key in a variable name passed in as receive_gpg_keys() { local keys=${!1} @@ -106,11 +138,16 @@ receive_gpg_keys() { keyring_args="${keyring_args} --keyserver-options http-proxy=${KEYSERVER_PROXY}" fi + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} - echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf + echo -e "disable-ipv6\n$(get_gpg_key_servers)" > ${GNUPGHOME}/dirmngr.conf # GPG key download sometimes fails for some reason and retrying fixes it. local retry_count=0 local gpg_ok="false" @@ -145,6 +182,11 @@ receive_gpg_keys_centos7() { keyring_args="${keyring_args} --keyserver-options http-proxy=${KEYSERVER_PROXY}" fi + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} @@ -156,7 +198,7 @@ receive_gpg_keys_centos7() { set +e echo "(*) Downloading GPG keys..." until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; do - for keyserver in $(echo "${GPG_KEY_SERVERS}" | sed 's/keyserver //'); do + for keyserver in $(echo "$(get_gpg_key_servers)" | sed 's/keyserver //'); do ( echo "${keys}" | xargs -n 1 gpg -q ${keyring_args} --recv-keys --keyserver=${keyserver} ) 2>&1 downloaded_keys=$(gpg --list-keys | grep ^pub | wc -l) if [[ ${num_keys} = ${downloaded_keys} ]]; then diff --git a/test/ruby/ruby_fallback_test.sh b/test/ruby/ruby_fallback_test.sh index 1e65e28e5..1c2179fc3 100644 --- a/test/ruby/ruby_fallback_test.sh +++ b/test/ruby/ruby_fallback_test.sh @@ -13,10 +13,6 @@ check "ruby" ruby -v trap 'echo "Last executed command failed at line ${LINENO}"' ERR RVM_GPG_KEYS="409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com -keyserver hkp://keyserver.ubuntu.com:80 -keyserver hkps://keys.openpgp.org -keyserver hkp://keyserver.pgp.com" # Clean up rm -rf /var/lib/apt/lists/* @@ -63,6 +59,38 @@ check_packages() { fi } +# Get the list of GPG key servers that are reachable +get_gpg_key_servers() { + declare -A keyservers_curl_map=( + ["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371" + ["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com" + ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" + ["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371" + ) + + local curl_args="" + local keyserver_reachable=false # Flag to indicate if any keyserver is reachable + + if [ ! -z "${KEYSERVER_PROXY}" ]; then + curl_args="--proxy ${KEYSERVER_PROXY}" + fi + + for keyserver in "${!keyservers_curl_map[@]}"; do + local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" + if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + echo "keyserver ${keyserver}" + keyserver_reachable=true + else + echo "(*) Keyserver ${keyserver} is not reachable." >&2 + fi + done + + if ! $keyserver_reachable; then + echo "(!) No keyserver is reachable." >&2 + exit 1 + fi +} + # Import the specified key in a variable name passed in as receive_gpg_keys() { local keys=${!1} @@ -71,11 +99,16 @@ receive_gpg_keys() { keyring_args="--no-default-keyring --keyring \"$2\"" fi + # Install curl + if ! type curl > /dev/null 2>&1; then + check_packages curl + fi + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} - echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" | tee ${GNUPGHOME}/dirmngr.conf > /dev/null + echo -e "disable-ipv6\n$(get_gpg_key_servers)" | tee ${GNUPGHOME}/dirmngr.conf > /dev/null # GPG key download sometimes fails for some reason and retrying fixes it. local retry_count=0 local gpg_ok="false" From 47e1764cfe6255ba3682c39b7675c59360a5a056 Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Wed, 17 Jul 2024 09:47:59 -0700 Subject: [PATCH 008/189] Automated documentation update (#1042) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/rust/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rust/README.md b/src/rust/README.md index 974d78516..e72b932f0 100644 --- a/src/rust/README.md +++ b/src/rust/README.md @@ -17,6 +17,7 @@ Installs Rust, common Rust utilities, and their required dependencies |-----|-----|-----|-----| | version | Select or enter a version of Rust to install. | string | latest | | profile | Select a rustup install profile. | string | minimal | +| targets | Optional comma separated list of additional Rust targets to install. | string | - | ## Customizations From 4bb0335b0e6b31a7d9b4f5bbf58061396951fa55 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Fri, 19 Jul 2024 09:52:50 +0530 Subject: [PATCH 009/189] [rust] - remove crates deprecated ext. - install dependi ext. instead (#1045) * [rust] - remove crates deprecated ext. - install dependi ext. instead * Update devcontainer-feature.json * [rust] - bump minor version as removed extension * Update src/rust/devcontainer-feature.json --------- Co-authored-by: Samruddhi Khandale --- src/rust/devcontainer-feature.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/rust/devcontainer-feature.json b/src/rust/devcontainer-feature.json index 909f315c4..929b27eef 100644 --- a/src/rust/devcontainer-feature.json +++ b/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "1.2.0", + "version": "1.3.0", "name": "Rust", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust", "description": "Installs Rust, common Rust utilities, and their required dependencies", @@ -56,8 +56,7 @@ "extensions": [ "vadimcn.vscode-lldb", "rust-lang.rust-analyzer", - "tamasfe.even-better-toml", - "serayuzgur.crates" + "tamasfe.even-better-toml" ], "settings": { "files.watcherExclude": { @@ -80,4 +79,4 @@ "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] -} \ No newline at end of file +} From d2bee515543a424b58c6951b1ec8a458227aa5b2 Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Thu, 18 Jul 2024 21:24:19 -0700 Subject: [PATCH 010/189] Automated documentation update (#1047) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/rust/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rust/README.md b/src/rust/README.md index e72b932f0..c19855aac 100644 --- a/src/rust/README.md +++ b/src/rust/README.md @@ -26,7 +26,6 @@ Installs Rust, common Rust utilities, and their required dependencies - `vadimcn.vscode-lldb` - `rust-lang.rust-analyzer` - `tamasfe.even-better-toml` -- `serayuzgur.crates` From 779283ad4e27b08051952de0c81566e0c41204e3 Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Mon, 22 Jul 2024 09:53:32 -0700 Subject: [PATCH 011/189] [Updates] Automated vendor dotnet-install script (#1051) * Automated dotnet-install script update * Bump version --------- Co-authored-by: github-actions --- src/dotnet/devcontainer-feature.json | 2 +- src/dotnet/scripts/vendor/dotnet-install.sh | 4 ++++ src/oryx/devcontainer-feature.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index a9fa62901..eb09f1d54 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "2.1.1", + "version": "2.1.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/src/dotnet/scripts/vendor/dotnet-install.sh b/src/dotnet/scripts/vendor/dotnet-install.sh index 42c201af4..caa3ea450 100755 --- a/src/dotnet/scripts/vendor/dotnet-install.sh +++ b/src/dotnet/scripts/vendor/dotnet-install.sh @@ -327,6 +327,10 @@ get_machine_architecture() { echo "loongarch64" return 0 ;; + riscv64) + echo "riscv64" + return 0 + ;; esac fi diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json index 9e6e698a1..e0813fbb9 100644 --- a/src/oryx/devcontainer-feature.json +++ b/src/oryx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oryx", - "version": "1.3.3", + "version": "1.3.4", "name": "Oryx", "description": "Installs the oryx CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/oryx", From 648c8d56b9ec4f90cb9d754cd532a9d2e08c0674 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 23 Jul 2024 12:05:01 -0700 Subject: [PATCH 012/189] Update update-dotnet-install-script.yml which updates vendor dotnet script for oryx (#938) Update update-dotnet-install-script.yml --- .github/workflows/update-dotnet-install-script.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/update-dotnet-install-script.yml b/.github/workflows/update-dotnet-install-script.yml index 85a9ea4d8..3394e8798 100644 --- a/.github/workflows/update-dotnet-install-script.yml +++ b/.github/workflows/update-dotnet-install-script.yml @@ -39,7 +39,7 @@ jobs: # Add / update and commit git add src/dotnet/scripts/vendor/dotnet-install.sh - git add src/dotnet/scripts/vendor/dotnet-install.sh + git add src/oryx/scripts/vendor/dotnet-install.sh git commit -m 'Automated dotnet-install script update' || export NO_UPDATES=true From 788017f6860f75080b6917bdc225f2f815c6be74 Mon Sep 17 00:00:00 2001 From: Paul Taylor <178183+trxcllnt@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:26:19 -0700 Subject: [PATCH 013/189] Fix installing latest git from PPA in bionic (#1056) * add failing bionic test * Enforce keyserver test order (fixes #1055) * bump feature version * remove check for gettext * update centos7 .repo files to reference vault.centos.org instead of mirrorlist.centos.org * fix centos7 build from source --- src/git/devcontainer-feature.json | 5 ++- src/git/install.sh | 56 +++++++++++++------------ test/git/install_git_from_ppa_bionic.sh | 16 +++++++ test/git/scenarios.json | 11 ++++- 4 files changed, 58 insertions(+), 30 deletions(-) create mode 100644 test/git/install_git_from_ppa_bionic.sh diff --git a/src/git/devcontainer-feature.json b/src/git/devcontainer-feature.json index 2d18b8d34..87fb2ab3f 100644 --- a/src/git/devcontainer-feature.json +++ b/src/git/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git", - "version": "1.3.1", + "version": "1.3.2", "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.", @@ -9,6 +9,7 @@ "type": "string", "proposals": [ "latest", + "system", "os-provided" ], "default": "os-provided", @@ -23,4 +24,4 @@ "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] -} \ No newline at end of file +} diff --git a/src/git/install.sh b/src/git/install.sh index 974dc66c0..976eb348d 100755 --- a/src/git/install.sh +++ b/src/git/install.sh @@ -26,12 +26,20 @@ elif [ "${ID}" = "alpine" ]; then ADJUSTED_ID="alpine" elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then ADJUSTED_ID="rhel" - VERSION_CODENAME="${ID}{$VERSION_ID}" + VERSION_CODENAME="${ID}${VERSION_ID}" else echo "Linux distro ${ID} not supported." exit 1 fi +if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then + # As of 1 July 2024, mirrorlist.centos.org no longer exists. + # Update the repo files to reference vault.centos.org. + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo +fi + if type apt-get > /dev/null 2>&1; then INSTALL_CMD=apt-get elif type apk > /dev/null 2>&1; then @@ -66,13 +74,6 @@ clean_up # Get the list of GPG key servers that are reachable get_gpg_key_servers() { - declare -A keyservers_curl_map=( - ["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371" - ["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com" - ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" - ["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371" - ) - local curl_args="" local keyserver_reachable=false # Flag to indicate if any keyserver is reachable @@ -80,15 +81,26 @@ get_gpg_key_servers() { curl_args="--proxy ${KEYSERVER_PROXY}" fi - for keyserver in "${!keyservers_curl_map[@]}"; do - local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" - if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + test_keyserver() { + local keyserver="$1" + local keyserver_curl_url="$2" + if curl -s ${curl_args} --max-time 5 "${keyserver_curl_url}" > /dev/null; then echo "keyserver ${keyserver}" keyserver_reachable=true else echo "(*) Keyserver ${keyserver} is not reachable." >&2 fi - done + } + + # Explicitly test these in order because Bash v4.4.20 (Ubuntu Bionic) + # enumerates associative array keys in a different order than Bash v5 + test_keyserver "hkp://keyserver.ubuntu.com" "http://keyserver.ubuntu.com:11371" + test_keyserver "hkp://keyserver.ubuntu.com:80" "http://keyserver.ubuntu.com" + test_keyserver "hkp://keyserver.pgp.com" "http://keyserver.pgp.com:11371" + # Test this server last because keys.openpgp.org strips user IDs from keys unless + # the owner gives permission, which causes gpg in Ubuntu Bionic to reject the key + # (https://github.com/devcontainers/features/issues/1055) + test_keyserver "hkps://keys.openpgp.org" "https://keys.openpgp.org" if ! $keyserver_reachable; then echo "(!) No keyserver is reachable." >&2 @@ -96,7 +108,7 @@ get_gpg_key_servers() { fi } -# Import the specified key in a variable name passed in as +# Import the specified key in a variable name passed in as receive_gpg_keys() { local keys=${!1} local keyring_args="" @@ -109,7 +121,7 @@ receive_gpg_keys() { if ! type curl > /dev/null 2>&1; then check_packages curl fi - + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} @@ -119,7 +131,7 @@ receive_gpg_keys() { local retry_count=0 local gpg_ok="false" set +e - until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; + until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; do echo "(*) Downloading GPG key..." ( echo "${keys}" | xargs -n 1 gpg -q ${keyring_args} --recv-keys) 2>&1 && gpg_ok="true" @@ -224,7 +236,7 @@ if ([ "${GIT_VERSION}" = "latest" ] || [ "${GIT_VERSION}" = "lts" ] || [ "${GIT_ receive_gpg_keys GIT_CORE_PPA_ARCHIVE_GPG_KEY /usr/share/keyrings/gitcoreppa-archive-keyring.gpg echo -e "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gitcoreppa-archive-keyring.gpg] http://ppa.launchpad.net/git-core/ppa/ubuntu ${VERSION_CODENAME} main\ndeb-src [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gitcoreppa-archive-keyring.gpg] http://ppa.launchpad.net/git-core/ppa/ubuntu ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/git-core-ppa.list ${INSTALL_CMD} update - ${INSTALL_CMD} -y install --no-install-recommends git + ${INSTALL_CMD} -y install --no-install-recommends git rm -rf "/tmp/tmp-gnupg" rm -rf /var/lib/apt/lists/* exit 0 @@ -254,17 +266,7 @@ elif [ "${ADJUSTED_ID}" = "alpine" ]; then check_packages asciidoc curl-dev expat-dev g++ gcc openssl-dev pcre2-dev perl-dev perl-error python3-dev tcl tk xmlto elif [ "${ADJUSTED_ID}" = "rhel" ]; then - - if [ $VERSION_CODENAME = "centos7" ]; then - check_packages centos-release-scl - check_packages devtoolset-11 - source /opt/rh/devtoolset-11/enable - else - check_packages gcc - fi - - - check_packages libcurl-devel expat-devel gettext-devel openssl-devel perl-devel zlib-devel cmake pcre2-devel tar gzip ca-certificates + check_packages gcc libcurl-devel expat-devel gettext-devel openssl-devel perl-devel zlib-devel cmake pcre2-devel tar gzip ca-certificates if ! type curl > /dev/null 2>&1; then check_packages curl fi diff --git a/test/git/install_git_from_ppa_bionic.sh b/test/git/install_git_from_ppa_bionic.sh new file mode 100644 index 000000000..84800b543 --- /dev/null +++ b/test/git/install_git_from_ppa_bionic.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" git --version + +cd /tmp && git clone https://github.com/devcontainers/feature-starter.git +cd feature-starter +check "perl" bash -c "git -c grep.patternType=perl grep -q 'a.+b'" + +# Report result +reportResults diff --git a/test/git/scenarios.json b/test/git/scenarios.json index 4d606c365..0f5d522b3 100644 --- a/test/git/scenarios.json +++ b/test/git/scenarios.json @@ -26,6 +26,15 @@ } } }, + "install_git_from_ppa_bionic": { + "image": "ubuntu:bionic", + "features": { + "git": { + "version": "latest", + "ppa": "true" + } + } + }, "install_git_from_src_bionic": { "image": "ubuntu:bionic", "features": { @@ -188,4 +197,4 @@ } } } -} \ No newline at end of file +} From 51940aa423dfa5928c40f897a78e88b88b24197f Mon Sep 17 00:00:00 2001 From: Anoop Nayak <665703+anoopknayak@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:02:46 -0700 Subject: [PATCH 014/189] [Rust] Update devcontainer-feature.json to include rust versions until 1.79 (#1040) * Update devcontainer-feature.json to include rust versions until 1.79 Update devcontainer.json to enable pinning rustc version upto 1.79 * Bump patch version for devcontainer.json --- src/rust/devcontainer-feature.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/rust/devcontainer-feature.json b/src/rust/devcontainer-feature.json index 929b27eef..9fc540c7d 100644 --- a/src/rust/devcontainer-feature.json +++ b/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "1.3.0", + "version": "1.3.1", "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,9 @@ "proposals": [ "latest", "none", + "1.79", + "1.78", + "1.77", "1.76", "1.75", "1.74", From 5f4d20101820e52c0a6c877637088c8981af3dc0 Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Mon, 29 Jul 2024 10:05:53 -0700 Subject: [PATCH 015/189] [Updates] Automated vendor dotnet-install script (#1064) * Automated dotnet-install script update * Bump version * Update src/dotnet/devcontainer-feature.json --------- Co-authored-by: github-actions Co-authored-by: Samruddhi Khandale --- src/oryx/devcontainer-feature.json | 2 +- src/oryx/scripts/vendor/dotnet-install.sh | 30 +++++++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json index e0813fbb9..68391cde9 100644 --- a/src/oryx/devcontainer-feature.json +++ b/src/oryx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oryx", - "version": "1.3.4", + "version": "1.3.5", "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 f6b08d1f8..caa3ea450 100755 --- a/src/oryx/scripts/vendor/dotnet-install.sh +++ b/src/oryx/scripts/vendor/dotnet-install.sh @@ -298,6 +298,10 @@ get_machine_architecture() { if command -v uname > /dev/null; then CPUName=$(uname -m) case $CPUName in + armv1*|armv2*|armv3*|armv4*|armv5*|armv6*) + echo "armv6-or-below" + return 0 + ;; armv*l) echo "arm" return 0 @@ -323,6 +327,10 @@ get_machine_architecture() { echo "loongarch64" return 0 ;; + riscv64) + echo "riscv64" + return 0 + ;; esac fi @@ -339,7 +347,13 @@ get_normalized_architecture_from_architecture() { local architecture="$(to_lowercase "$1")" if [[ $architecture == \ ]]; then - echo "$(get_machine_architecture)" + machine_architecture="$(get_machine_architecture)" + if [[ "$machine_architecture" == "armv6-or-below" ]]; then + say_err "Architecture \`$machine_architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues" + return 1 + fi + + echo $machine_architecture return 0 fi @@ -1013,7 +1027,7 @@ extract_dotnet_package() { rm -rf "$temp_out_path" if [ -z ${keep_zip+x} ]; then - rm -f "$zip_path" && say_verbose "Temporary zip file $zip_path was removed" + rm -f "$zip_path" && say_verbose "Temporary archive file $zip_path was removed" fi if [ "$failed" = true ]; then @@ -1261,6 +1275,12 @@ get_download_link_from_aka_ms() { http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' ) # They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404). broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' ) + # The response may end without final code 2xx/4xx/5xx somehow, e.g. network restrictions on www.bing.com causes redirecting to bing.com fails with connection refused. + # In this case it should not exclude the last. + last_http_code=$( echo "$http_codes" | tail -n 1 ) + if ! [[ $last_http_code =~ ^(2|4|5)[0-9][0-9]$ ]]; then + broken_redirects=$( echo "$http_codes" | grep -v '301' ) + fi # All HTTP codes are 301 (Moved Permanently), the redirect link exists. if [[ -z "$broken_redirects" ]]; then @@ -1512,7 +1532,7 @@ install_dotnet() { mkdir -p "$install_root" zip_path="${zip_path:-$(mktemp "$temporary_file_template")}" - say_verbose "Zip path: $zip_path" + say_verbose "Archive path: $zip_path" for link_index in "${!download_links[@]}" do @@ -1536,7 +1556,7 @@ install_dotnet() { say "Failed to download $link_type link '$download_link': $download_error_msg" ;; esac - rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed" + rm -f "$zip_path" 2>&1 && say_verbose "Temporary archive file $zip_path was removed" else download_completed=true break @@ -1551,7 +1571,7 @@ install_dotnet() { remote_file_size="$(get_remote_file_size "$download_link")" - say "Extracting zip from $download_link" + say "Extracting archive from $download_link" extract_dotnet_package "$zip_path" "$install_root" "$remote_file_size" || return 1 # Check if the SDK version is installed; if not, fail the installation. From 175185811e716c1f3b92caea7ae2b3389aba9134 Mon Sep 17 00:00:00 2001 From: Dmytro Kyrychuk Date: Mon, 29 Jul 2024 20:54:13 +0300 Subject: [PATCH 016/189] common-utils: add bash-completion (#1048) * common-utils: add bash-completion Resolve #1043 * update centos7 .repo files to reference vault.centos.org instead of mirrorlist.centos.org Copied from src/git/install.sh --------- Co-authored-by: Samruddhi Khandale --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index dc62272ad..a253bfb05 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.4.4", + "version": "2.4.5", "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.", diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index 5d7592cfc..8f82dcdf9 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -32,6 +32,7 @@ install_debian_packages() { if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then package_list="${package_list} \ apt-utils \ + bash-completion \ openssh-client \ gnupg2 \ dirmngr \ @@ -170,6 +171,7 @@ install_redhat_packages() { if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then package_list="${package_list} \ gawk \ + bash-completion \ openssh-clients \ gnupg2 \ iproute \ @@ -254,6 +256,7 @@ install_alpine_packages() { if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then apk add --no-cache \ openssh-client \ + bash-completion \ gnupg \ procps \ lsof \ @@ -343,6 +346,7 @@ 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 ADJUSTED_ID="rhel" + VERSION_CODENAME="${ID}${VERSION_ID}" elif [ "${ID}" = "alpine" ]; then ADJUSTED_ID="alpine" else @@ -350,6 +354,14 @@ else exit 1 fi +if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then + # As of 1 July 2024, mirrorlist.centos.org no longer exists. + # Update the repo files to reference vault.centos.org. + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo +fi + # Install packages for appropriate OS case "${ADJUSTED_ID}" in "debian") From f5f489f66e6f6ae777dcff4a555a15945a4ce2ae Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Wed, 7 Aug 2024 00:03:59 +0530 Subject: [PATCH 017/189] [Desktop-lite] - VNC_RESOLUTION unreadable fix - issue #945 fix (#1024) * [Desktop-lite] - VNC_RESOLUTION unreadable fix - issue #945 * bump to patch version done * changes as suggested * changes - removing escaped variables for init to go smoothly * misc change * few more escaped vars - making them unescaped * misc changes * changes for sudo - command not found error in few test cases --- src/desktop-lite/devcontainer-feature.json | 2 +- src/desktop-lite/install.sh | 73 +++++++++++++--------- 2 files changed, 46 insertions(+), 29 deletions(-) diff --git a/src/desktop-lite/devcontainer-feature.json b/src/desktop-lite/devcontainer-feature.json index 417787c51..2dee08bde 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.0", + "version": "1.2.1", "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.", diff --git a/src/desktop-lite/install.sh b/src/desktop-lite/install.sh index ef8b603c6..777be8f1a 100755 --- a/src/desktop-lite/install.sh +++ b/src/desktop-lite/install.sh @@ -293,7 +293,7 @@ echo -e "\nSuccess!\n" EOF # Container ENTRYPOINT script -cat << EOF > /usr/local/share/desktop-init.sh +cat << 'EOF' > /usr/local/share/desktop-init.sh #!/bin/bash user_name="${USERNAME}" @@ -309,50 +309,67 @@ export LANGUAGE="${LANGUAGE:-"en_US.UTF-8"}" # Execute the command it not already running startInBackgroundIfNotRunning() { - log "Starting \$1." - echo -e "\n** \$(date) **" | sudoIf tee -a /tmp/\$1.log > /dev/null - if ! pgrep -x \$1 > /dev/null; then - keepRunningInBackground "\$@" - while ! pgrep -x \$1 > /dev/null; do + log "Starting $1." + echo -e "\n** $(date) **" | sudoIf tee -a /tmp/\$1.log > /dev/null + if ! pgrep -x $1 > /dev/null; then + keepRunningInBackground "$@" + while ! pgrep -x $1 > /dev/null; do sleep 1 done - log "\$1 started." + log "$1 started." else - echo "\$1 is already running." | sudoIf tee -a /tmp/\$1.log > /dev/null - log "\$1 is already running." + echo "$1 is already running." | sudoIf tee -a /tmp/\$1.log > /dev/null + log "$1 is already running." fi } # Keep command running in background keepRunningInBackground() { - (\$2 bash -c "while :; do echo [\\\$(date)] Process started.; \$3; echo [\\\$(date)] Process exited!; sleep 5; done 2>&1" | sudoIf tee -a /tmp/\$1.log > /dev/null & echo "\$!" | sudoIf tee /tmp/\$1.pid > /dev/null) + ($2 bash -c "while :; do echo [\\$(date)] Process started.; $3; echo [\\$(date)] Process exited!; sleep 5; done 2>&1" | sudoIf tee -a /tmp/\$1.log > /dev/null & echo "\$!" | sudoIf tee /tmp/\$1.pid > /dev/null) +} + +apt_get_update() +{ + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi +} + +check_packages() { + if ! dpkg -s "$@" > /dev/null 2>&1; then + apt_get_update + apt-get -y install --no-install-recommends "$@" + fi } # Use sudo to run as root when required sudoIf() { - if [ "\$(id -u)" -ne 0 ]; then - sudo "\$@" + if [ "$(id -u)" -ne 0 ]; then + check_packages sudo + sudo "$@" else - "\$@" + "$@" fi } # Use sudo to run as non-root user if not already running sudoUserIf() { - if [ "\$(id -u)" -eq 0 ] && [ "\${user_name}" != "root" ]; then - sudo -u \${user_name} "\$@" + if [ "$(id -u)" -eq 0 ] && [ "${user_name}" != "root" ]; then + check_packages sudo + sudo -u "${user_name}" "$@" else - "\$@" + "$@" fi } # Log messages log() { - echo -e "[\$(date)] \$@" | sudoIf tee -a \$LOG > /dev/null + echo -e "[$(date)] $@" | sudoIf tee -a $LOG > /dev/null } log "** SCRIPT START **" @@ -371,22 +388,22 @@ done sudoIf rm -rf /tmp/.X11-unix /tmp/.X*-lock mkdir -p /tmp/.X11-unix sudoIf chmod 1777 /tmp/.X11-unix -sudoIf chown root:\${group_name} /tmp/.X11-unix -if [ "\$(echo "\${VNC_RESOLUTION}" | tr -cd 'x' | wc -c)" = "1" ]; then VNC_RESOLUTION=\${VNC_RESOLUTION}x16; fi -screen_geometry="\${VNC_RESOLUTION%*x*}" -screen_depth="\${VNC_RESOLUTION##*x}" +sudoIf chown root:${group_name} /tmp/.X11-unix +if [ "$(echo "${VNC_RESOLUTION}" | tr -cd 'x' | wc -c)" = "1" ]; then VNC_RESOLUTION=${VNC_RESOLUTION}x16; fi +screen_geometry="${VNC_RESOLUTION%*x*}" +screen_depth="${VNC_RESOLUTION##*x}" # Check if VNC_PASSWORD is set and use the appropriate command -common_options="tigervncserver \${DISPLAY} -geometry \${screen_geometry} -depth \${screen_depth} -rfbport ${VNC_PORT} -dpi \${VNC_DPI:-96} -localhost -desktop fluxbox -fg" +common_options="tigervncserver ${DISPLAY} -geometry ${screen_geometry} -depth ${screen_depth} -rfbport ${VNC_PORT} -dpi ${VNC_DPI:-96} -localhost -desktop fluxbox -fg" -if [ -n "\${VNC_PASSWORD+x}" ]; then - startInBackgroundIfNotRunning "Xtigervnc" sudoUserIf "\${common_options} -passwd /usr/local/etc/vscode-dev-containers/vnc-passwd" +if [ -n "${VNC_PASSWORD+x}" ]; then + startInBackgroundIfNotRunning "Xtigervnc" sudoUserIf "${common_options} -passwd /usr/local/etc/vscode-dev-containers/vnc-passwd" else - startInBackgroundIfNotRunning "Xtigervnc" sudoUserIf "\${common_options} -SecurityTypes None" + startInBackgroundIfNotRunning "Xtigervnc" sudoUserIf "${common_options} -SecurityTypes None" fi # Spin up noVNC if installed and not running. -if [ -d "/usr/local/novnc" ] && [ "\$(ps -ef | grep /usr/local/novnc/noVNC*/utils/launch.sh | grep -v grep)" = "" ]; then +if [ -d "/usr/local/novnc" ] && [ "$(ps -ef | grep /usr/local/novnc/noVNC*/utils/launch.sh | grep -v grep)" = "" ]; then keepRunningInBackground "noVNC" sudoIf "/usr/local/novnc/noVNC*/utils/launch.sh --listen ${NOVNC_PORT} --vnc localhost:${VNC_PORT}" log "noVNC started." else @@ -394,8 +411,8 @@ else fi # Run whatever was passed in -log "Executing \"\$@\"." -exec "\$@" +log "Executing "\$@\"." +exec "$@" log "** SCRIPT EXIT **" EOF From dd0266fe7161dfb097c3d92315822bb248fc9047 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Wed, 7 Aug 2024 22:57:55 +0530 Subject: [PATCH 018/189] [Java] - features issue #1101 - installs -tem instead -ms for lts installation (#1021) * [Java] - features issue #1101 - installs -tem instead -ms for lts installation * misc change * misc change, by mistake needs correction * leave a line change * remove spaces * bump patch version.. * changes for pr reviewed * changes * Update src/java/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * [java] - corrected lts version finding logic in install.sh * small change * changes as requested.. * changes as requested * changes as suggested - centos-7, mirrorlist no longer exists - changed to vault * corrected condition for specific version installations.. * misc change * corrected condition * small change * corrections * change * changes in test cases - removing /tmp before test specific test runs.. * few changes to test cases again.. * small change * addition of --overwrite option to gradle init command * changes as suggested on pr comments * misc. change for correcting logic --------- Co-authored-by: Samruddhi Khandale --- src/java/devcontainer-feature.json | 2 +- src/java/install.sh | 44 ++++++++++++++++--- ...all_ant_and_gradle_and_maven_and_groovy.sh | 2 +- ...nd_gradle_and_maven_and_groovy_for_user.sh | 3 +- ...d_maven_and_groovy_for_user_rhel_family.sh | 2 +- ...gradle_and_maven_and_groovy_rhel_family.sh | 2 +- test/java/install_lts_version.sh | 11 +++++ test/java/scenarios.json | 8 ++++ 8 files changed, 62 insertions(+), 12 deletions(-) create mode 100644 test/java/install_lts_version.sh diff --git a/src/java/devcontainer-feature.json b/src/java/devcontainer-feature.json index c43862610..51e214a25 100644 --- a/src/java/devcontainer-feature.json +++ b/src/java/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "java", - "version": "1.5.0", + "version": "1.6.0", "name": "Java (via SDKMAN!)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/java", "description": "Installs Java, SDKMAN! (if not installed), and needed dependencies.", diff --git a/src/java/install.sh b/src/java/install.sh index 30b6cb10c..277681fec 100644 --- a/src/java/install.sh +++ b/src/java/install.sh @@ -9,7 +9,7 @@ # # Syntax: ./java-debian.sh [JDK version] [SDKMAN_DIR] [non-root user] [Add to rc files flag] -JAVA_VERSION="${VERSION:-"lts"}" +JAVA_VERSION="${VERSION:-"latest"}" INSTALL_GRADLE="${INSTALLGRADLE:-"false"}" GRADLE_VERSION="${GRADLEVERSION:-"latest"}" INSTALL_MAVEN="${INSTALLMAVEN:-"false"}" @@ -53,6 +53,14 @@ else exit 1 fi +if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then + # As of 1 July 2024, mirrorlist.centos.org no longer exists. + # Update the repo files to reference vault.centos.org. + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo +fi + # Setup INSTALL_CMD & PKG_MGR_CMD if type apt-get > /dev/null 2>&1; then PKG_MGR_CMD=apt-get @@ -197,6 +205,22 @@ get_jdk_distro() { fi } +find_version_list() { + prefix="$1" + suffix="$2" + install_type=$3 + ifLts="$4" + version_list=$5 + if [ "${ifLts}" = "true" ]; then + all_lts_versions=$(curl -s https://api.adoptium.net/v3/info/available_releases) + major_version=$(echo "$all_lts_versions" | jq -r '.most_recent_lts') + regex="${prefix}\\K${major_version}\\.?[0-9]*\\.?[0-9]*${suffix}" + else + regex="${prefix}\\K[0-9]+\\.?[0-9]*\\.?[0-9]*${suffix}" + fi + declare -g ${version_list}="$(su ${USERNAME} -c ". \${SDKMAN_DIR}/bin/sdkman-init.sh && sdk list ${install_type} 2>&1 | grep -oP \"${regex}\" | tr -d ' ' | sort -rV")" +} + # Use SDKMAN to install something using a partial version match sdk_install() { local install_type=$1 @@ -205,15 +229,21 @@ sdk_install() { local suffix="${4:-"\\s*"}" local full_version_check=${5:-".*-[a-z]+"} local set_as_default=${6:-"true"} + pkgs=("maven" "gradle" "ant" "groovy") + pkg_vals="${pkgs[@]}" if [ "${requested_version}" = "none" ]; then return; fi - # Blank will install latest stable version SDKMAN has - if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "lts" ] || [ "${requested_version}" = "default" ]; then - requested_version="" + if [ "${requested_version}" = "default" ]; then + requested_version="" + elif [[ "${pkg_vals}" =~ "${install_type}" ]] && [ "${requested_version}" = "latest" ]; then + requested_version="" + elif [ "${requested_version}" = "lts" ]; then + check_packages jq + find_version_list "$prefix" "$suffix" "$install_type" "true" version_list + requested_version="$(echo "${version_list}" | head -n 1)" elif echo "${requested_version}" | grep -oE "${full_version_check}" > /dev/null 2>&1; then echo "${requested_version}" - else - local regex="${prefix}\\K[0-9]+\\.?[0-9]*\\.?[0-9]*${suffix}" - local version_list=$(su ${USERNAME} -c ". \${SDKMAN_DIR}/bin/sdkman-init.sh && sdk list ${install_type} 2>&1 | grep -oP \"${regex}\" | tr -d ' ' | sort -rV") + else + find_version_list "$prefix" "$suffix" "$install_type" "false" version_list if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ]; then requested_version="$(echo "${version_list}" | head -n 1)" else diff --git a/test/java/install_ant_and_gradle_and_maven_and_groovy.sh b/test/java/install_ant_and_gradle_and_maven_and_groovy.sh index e171f5be5..a9ab99dfd 100644 --- a/test/java/install_ant_and_gradle_and_maven_and_groovy.sh +++ b/test/java/install_ant_and_gradle_and_maven_and_groovy.sh @@ -17,7 +17,7 @@ cd /tmp && ant init check "ant-src exists" grep "ant-src" <(ls -la /tmp) check "gradle" gradle --version -cd /tmp && gradle init --type basic --dsl groovy --incubating --project-name test +cd /tmp && gradle init --type basic --dsl groovy --overwrite --incubating --project-name test check "GRADLE_USER_HOME exists" grep ".gradle" <(ls -la /root) check "maven" mvn --version diff --git a/test/java/install_ant_and_gradle_and_maven_and_groovy_for_user.sh b/test/java/install_ant_and_gradle_and_maven_and_groovy_for_user.sh index 8d9f293e9..54f7ee9ea 100644 --- a/test/java/install_ant_and_gradle_and_maven_and_groovy_for_user.sh +++ b/test/java/install_ant_and_gradle_and_maven_and_groovy_for_user.sh @@ -10,6 +10,7 @@ check "user is vscode" grep vscode <(whoami) check "java" java --version check "ant" ant -version + cat << EOF > /tmp/build.xml EOF @@ -17,7 +18,7 @@ cd /tmp && ant init check "ant-src exists" grep "ant-src" <(ls -la /tmp) check "gradle" gradle --version -cd /tmp && gradle init --type basic --dsl groovy --incubating --project-name test +cd /tmp && gradle init --type basic --dsl groovy --overwrite --incubating --project-name test check "GRADLE_USER_HOME exists" grep ".gradle" <(ls -la /home/vscode) check "maven" mvn --version diff --git a/test/java/install_ant_and_gradle_and_maven_and_groovy_for_user_rhel_family.sh b/test/java/install_ant_and_gradle_and_maven_and_groovy_for_user_rhel_family.sh index 8d9f293e9..6ff97f5b1 100644 --- a/test/java/install_ant_and_gradle_and_maven_and_groovy_for_user_rhel_family.sh +++ b/test/java/install_ant_and_gradle_and_maven_and_groovy_for_user_rhel_family.sh @@ -17,7 +17,7 @@ cd /tmp && ant init check "ant-src exists" grep "ant-src" <(ls -la /tmp) check "gradle" gradle --version -cd /tmp && gradle init --type basic --dsl groovy --incubating --project-name test +cd /tmp && gradle init --type basic --dsl groovy --overwrite --incubating --project-name test check "GRADLE_USER_HOME exists" grep ".gradle" <(ls -la /home/vscode) check "maven" mvn --version diff --git a/test/java/install_ant_and_gradle_and_maven_and_groovy_rhel_family.sh b/test/java/install_ant_and_gradle_and_maven_and_groovy_rhel_family.sh index e171f5be5..a9ab99dfd 100644 --- a/test/java/install_ant_and_gradle_and_maven_and_groovy_rhel_family.sh +++ b/test/java/install_ant_and_gradle_and_maven_and_groovy_rhel_family.sh @@ -17,7 +17,7 @@ cd /tmp && ant init check "ant-src exists" grep "ant-src" <(ls -la /tmp) check "gradle" gradle --version -cd /tmp && gradle init --type basic --dsl groovy --incubating --project-name test +cd /tmp && gradle init --type basic --dsl groovy --overwrite --incubating --project-name test check "GRADLE_USER_HOME exists" grep ".gradle" <(ls -la /root) check "maven" mvn --version diff --git a/test/java/install_lts_version.sh b/test/java/install_lts_version.sh new file mode 100644 index 000000000..c3518897f --- /dev/null +++ b/test/java/install_lts_version.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "java version LTS installed as default" grep "LTS" <(java --version) + +# Report result +reportResults diff --git a/test/java/scenarios.json b/test/java/scenarios.json index 6e6426969..538d77972 100644 --- a/test/java/scenarios.json +++ b/test/java/scenarios.json @@ -8,6 +8,14 @@ } } }, + "install_lts_version": { + "image": "ubuntu:focal", + "features": { + "java": { + "version": "lts" + } + } + }, "install_additional_java": { "image": "ubuntu:focal", "features": { From 6d2b646ad118454674d7c72df4f2e0f85d8cf18c Mon Sep 17 00:00:00 2001 From: Daniel Meilak <32960789+daniel-meilak@users.noreply.github.com> Date: Mon, 12 Aug 2024 19:27:26 +0200 Subject: [PATCH 019/189] [desktop-lite] Suggested usage of appPort instead of forwardPorts for devconatiner-cli (#1086) [desktop-lite] Suggested usage of appPort instead of forwardPorts for devcontainer-cli --- src/desktop-lite/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/desktop-lite/README.md b/src/desktop-lite/README.md index 6f2d67ce2..f8b692471 100644 --- a/src/desktop-lite/README.md +++ b/src/desktop-lite/README.md @@ -25,7 +25,7 @@ Adds a lightweight Fluxbox based desktop to the container that can be accessed u This feature provides two ways of connecting to the desktop environment it adds. The first is to connect using a web browser. To do so: -1. Forward the noVNC port (`6080` by default) to your local machine using either the `forwardPorts` property in `devcontainer.json` or the user interface in your tool (e.g., you can press F1 or Ctrl/Cmd+Shift+P and select **Ports: Focus on Ports View** in VS Code to bring it into focus). +1. Forward the noVNC port (`6080` by default) to your local machine using either the `forwardPorts` property in `devcontainer.json` or the user interface in your tool (e.g., you can press F1 or Ctrl/Cmd+Shift+P and select **Ports: Focus on Ports View** in VS Code to bring it into focus). If using the [Dev Conatiner Cli](https://github.com/devcontainers/cli), you should use the `appPort` property in `devcontainer.json` instead. 1. Open the ports view in your tool, select the noVNC port, and click the Globe icon. 1. In the browser that appears, click the **Connect** button and enter the desktop password (`vscode` by default). From 46f7cea75d820562617297ea0421dc7bf103e6ae Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Mon, 12 Aug 2024 10:37:46 -0700 Subject: [PATCH 020/189] Automated documentation update (#1087) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/desktop-lite/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/desktop-lite/README.md b/src/desktop-lite/README.md index f8b692471..6f2d67ce2 100644 --- a/src/desktop-lite/README.md +++ b/src/desktop-lite/README.md @@ -25,7 +25,7 @@ Adds a lightweight Fluxbox based desktop to the container that can be accessed u This feature provides two ways of connecting to the desktop environment it adds. The first is to connect using a web browser. To do so: -1. Forward the noVNC port (`6080` by default) to your local machine using either the `forwardPorts` property in `devcontainer.json` or the user interface in your tool (e.g., you can press F1 or Ctrl/Cmd+Shift+P and select **Ports: Focus on Ports View** in VS Code to bring it into focus). If using the [Dev Conatiner Cli](https://github.com/devcontainers/cli), you should use the `appPort` property in `devcontainer.json` instead. +1. Forward the noVNC port (`6080` by default) to your local machine using either the `forwardPorts` property in `devcontainer.json` or the user interface in your tool (e.g., you can press F1 or Ctrl/Cmd+Shift+P and select **Ports: Focus on Ports View** in VS Code to bring it into focus). 1. Open the ports view in your tool, select the noVNC port, and click the Globe icon. 1. In the browser that appears, click the **Connect** button and enter the desktop password (`vscode` by default). From 8f3115afe337554b1077ab51659b2f7334ca67d2 Mon Sep 17 00:00:00 2001 From: Mostafa Dahshan <12108158+mdahshan@users.noreply.github.com> Date: Tue, 13 Aug 2024 09:49:50 +1000 Subject: [PATCH 021/189] Desktop lite: Fix quote error (#1082) * Update install.sh Corrected a syntax error in line 414 log "Executing "\$@\"." was corrected to log "Executing \"$@\"." * Update devcontainer-feature.json --------- Co-authored-by: Samruddhi Khandale --- src/desktop-lite/devcontainer-feature.json | 2 +- src/desktop-lite/install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/desktop-lite/devcontainer-feature.json b/src/desktop-lite/devcontainer-feature.json index 2dee08bde..86eabbdad 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.1", + "version": "1.2.2", "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.", diff --git a/src/desktop-lite/install.sh b/src/desktop-lite/install.sh index 777be8f1a..83f9635b4 100755 --- a/src/desktop-lite/install.sh +++ b/src/desktop-lite/install.sh @@ -411,7 +411,7 @@ else fi # Run whatever was passed in -log "Executing "\$@\"." +log "Executing \"$@\"." exec "$@" log "** SCRIPT EXIT **" EOF From 9b189037cd883cd817321720d5916e086ad982be Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 13 Aug 2024 08:58:28 -0700 Subject: [PATCH 022/189] Revert "[Desktop-lite] - VNC_RESOLUTION unreadable fix - issue #945 fix (#1024) (#1088) Revert "[Desktop-lite] - VNC_RESOLUTION unreadable fix - issue #945 fix (#1024)" This reverts commit f5f489f66e6f6ae777dcff4a555a15945a4ce2ae. --- src/desktop-lite/devcontainer-feature.json | 2 +- src/desktop-lite/install.sh | 71 ++++++++-------------- 2 files changed, 28 insertions(+), 45 deletions(-) diff --git a/src/desktop-lite/devcontainer-feature.json b/src/desktop-lite/devcontainer-feature.json index 86eabbdad..ebc04ebad 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.2", + "version": "1.2.3", "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.", diff --git a/src/desktop-lite/install.sh b/src/desktop-lite/install.sh index 83f9635b4..5230425f0 100755 --- a/src/desktop-lite/install.sh +++ b/src/desktop-lite/install.sh @@ -293,7 +293,7 @@ echo -e "\nSuccess!\n" EOF # Container ENTRYPOINT script -cat << 'EOF' > /usr/local/share/desktop-init.sh +cat << EOF > /usr/local/share/desktop-init.sh #!/bin/bash user_name="${USERNAME}" @@ -309,67 +309,50 @@ export LANGUAGE="${LANGUAGE:-"en_US.UTF-8"}" # Execute the command it not already running startInBackgroundIfNotRunning() { - log "Starting $1." - echo -e "\n** $(date) **" | sudoIf tee -a /tmp/\$1.log > /dev/null - if ! pgrep -x $1 > /dev/null; then - keepRunningInBackground "$@" - while ! pgrep -x $1 > /dev/null; do + log "Starting \$1." + echo -e "\n** \$(date) **" | sudoIf tee -a /tmp/\$1.log > /dev/null + if ! pgrep -x \$1 > /dev/null; then + keepRunningInBackground "\$@" + while ! pgrep -x \$1 > /dev/null; do sleep 1 done - log "$1 started." + log "\$1 started." else - echo "$1 is already running." | sudoIf tee -a /tmp/\$1.log > /dev/null - log "$1 is already running." + echo "\$1 is already running." | sudoIf tee -a /tmp/\$1.log > /dev/null + log "\$1 is already running." fi } # Keep command running in background keepRunningInBackground() { - ($2 bash -c "while :; do echo [\\$(date)] Process started.; $3; echo [\\$(date)] Process exited!; sleep 5; done 2>&1" | sudoIf tee -a /tmp/\$1.log > /dev/null & echo "\$!" | sudoIf tee /tmp/\$1.pid > /dev/null) -} - -apt_get_update() -{ - if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then - echo "Running apt-get update..." - apt-get update -y - fi -} - -check_packages() { - if ! dpkg -s "$@" > /dev/null 2>&1; then - apt_get_update - apt-get -y install --no-install-recommends "$@" - fi + (\$2 bash -c "while :; do echo [\\\$(date)] Process started.; \$3; echo [\\\$(date)] Process exited!; sleep 5; done 2>&1" | sudoIf tee -a /tmp/\$1.log > /dev/null & echo "\$!" | sudoIf tee /tmp/\$1.pid > /dev/null) } # Use sudo to run as root when required sudoIf() { - if [ "$(id -u)" -ne 0 ]; then - check_packages sudo - sudo "$@" + if [ "\$(id -u)" -ne 0 ]; then + sudo "\$@" else - "$@" + "\$@" fi } # Use sudo to run as non-root user if not already running sudoUserIf() { - if [ "$(id -u)" -eq 0 ] && [ "${user_name}" != "root" ]; then - check_packages sudo - sudo -u "${user_name}" "$@" + if [ "\$(id -u)" -eq 0 ] && [ "\${user_name}" != "root" ]; then + sudo -u \${user_name} "\$@" else - "$@" + "\$@" fi } # Log messages log() { - echo -e "[$(date)] $@" | sudoIf tee -a $LOG > /dev/null + echo -e "[\$(date)] \$@" | sudoIf tee -a \$LOG > /dev/null } log "** SCRIPT START **" @@ -388,22 +371,22 @@ done sudoIf rm -rf /tmp/.X11-unix /tmp/.X*-lock mkdir -p /tmp/.X11-unix sudoIf chmod 1777 /tmp/.X11-unix -sudoIf chown root:${group_name} /tmp/.X11-unix -if [ "$(echo "${VNC_RESOLUTION}" | tr -cd 'x' | wc -c)" = "1" ]; then VNC_RESOLUTION=${VNC_RESOLUTION}x16; fi -screen_geometry="${VNC_RESOLUTION%*x*}" -screen_depth="${VNC_RESOLUTION##*x}" +sudoIf chown root:\${group_name} /tmp/.X11-unix +if [ "\$(echo "\${VNC_RESOLUTION}" | tr -cd 'x' | wc -c)" = "1" ]; then VNC_RESOLUTION=\${VNC_RESOLUTION}x16; fi +screen_geometry="\${VNC_RESOLUTION%*x*}" +screen_depth="\${VNC_RESOLUTION##*x}" # Check if VNC_PASSWORD is set and use the appropriate command -common_options="tigervncserver ${DISPLAY} -geometry ${screen_geometry} -depth ${screen_depth} -rfbport ${VNC_PORT} -dpi ${VNC_DPI:-96} -localhost -desktop fluxbox -fg" +common_options="tigervncserver \${DISPLAY} -geometry \${screen_geometry} -depth \${screen_depth} -rfbport ${VNC_PORT} -dpi \${VNC_DPI:-96} -localhost -desktop fluxbox -fg" -if [ -n "${VNC_PASSWORD+x}" ]; then - startInBackgroundIfNotRunning "Xtigervnc" sudoUserIf "${common_options} -passwd /usr/local/etc/vscode-dev-containers/vnc-passwd" +if [ -n "\${VNC_PASSWORD+x}" ]; then + startInBackgroundIfNotRunning "Xtigervnc" sudoUserIf "\${common_options} -passwd /usr/local/etc/vscode-dev-containers/vnc-passwd" else - startInBackgroundIfNotRunning "Xtigervnc" sudoUserIf "${common_options} -SecurityTypes None" + startInBackgroundIfNotRunning "Xtigervnc" sudoUserIf "\${common_options} -SecurityTypes None" fi # Spin up noVNC if installed and not running. -if [ -d "/usr/local/novnc" ] && [ "$(ps -ef | grep /usr/local/novnc/noVNC*/utils/launch.sh | grep -v grep)" = "" ]; then +if [ -d "/usr/local/novnc" ] && [ "\$(ps -ef | grep /usr/local/novnc/noVNC*/utils/launch.sh | grep -v grep)" = "" ]; then keepRunningInBackground "noVNC" sudoIf "/usr/local/novnc/noVNC*/utils/launch.sh --listen ${NOVNC_PORT} --vnc localhost:${VNC_PORT}" log "noVNC started." else @@ -411,7 +394,7 @@ else fi # Run whatever was passed in -log "Executing \"$@\"." +log "Executing \"\$@\"." exec "$@" log "** SCRIPT EXIT **" EOF From 56233fda3b8dfad16dfc1bf1bcc11350eaf772d0 Mon Sep 17 00:00:00 2001 From: Prathamesh Zarkar <159782310+prathameshzarkar9@users.noreply.github.com> Date: Wed, 14 Aug 2024 01:52:24 +0530 Subject: [PATCH 023/189] common-utils overwrites .zshrc coming from image built (#1069) * common-utils overwrites .zshrc coming from image built with common-utils already * version bumped and added scenario to test the user issue * cp command failing fix test * bump version reverted * fixed the pipeline failures * discarded diff logic and introduced new one * Update src/common-utils/main.sh * instead of overwritting, template file will be appended to existing .zshrc file if INSTALL_OH_MY_ZSH_CONFIG is true * removed if statement to check .zshrc file exists * if condition added to check user_rc_file exist * linter error fixed * optimize duplication for template_path and user_rc_file logic --------- Co-authored-by: Samruddhi Khandale --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 4 ++-- test/common-utils/devcontainer-ruby-zshrc.sh | 12 ++++++++++++ .../devcontainer-ruby-zshrc/Dockerfile | 4 ++++ .../devcontainer-ruby-zshrc/meta.env | 8 ++++++++ test/common-utils/scenarios.json | 18 ++++++++++++++++++ 6 files changed, 45 insertions(+), 3 deletions(-) create mode 100755 test/common-utils/devcontainer-ruby-zshrc.sh create mode 100644 test/common-utils/devcontainer-ruby-zshrc/Dockerfile create mode 100644 test/common-utils/devcontainer-ruby-zshrc/meta.env diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index a253bfb05..3ae86cd3e 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.4.5", + "version": "2.4.6", "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.", diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index 8f82dcdf9..91cfc4d3b 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -491,7 +491,6 @@ if [ "${INSTALL_ZSH}" = "true" ]; then echo 'source $HOME/.profile' >> "${user_home}/.zprofile" # TODO: Reconsider adding '.profile' to '.zprofile' chown ${USERNAME}:${group_name} "${user_home}/.zprofile" fi - if [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then if [ "${ADJUSTED_ID}" = "rhel" ]; then global_rc_path="/etc/zshrc" @@ -543,7 +542,8 @@ if [ "${INSTALL_ZSH}" = "true" ]; then # Add devcontainer .zshrc template if [ "$INSTALL_OH_MY_ZSH_CONFIG" = "true" ]; then - echo -e "$(cat "${template_path}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" > ${user_rc_file} + template_code="$(cat "${template_path}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" + echo -e "$([ -f "${user_rc_file}" ] && cat "${user_rc_file}")\n${template_code}" > "${user_rc_file}" sed -i -e 's/ZSH_THEME=.*/ZSH_THEME="devcontainers"/g' ${user_rc_file} fi diff --git a/test/common-utils/devcontainer-ruby-zshrc.sh b/test/common-utils/devcontainer-ruby-zshrc.sh new file mode 100755 index 000000000..9e7b26e4c --- /dev/null +++ b/test/common-utils/devcontainer-ruby-zshrc.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "configure-zshrc-without-overwrite" bash -c "grep 'rbenv init -' ~/.zshrc" + +# Report result +reportResults diff --git a/test/common-utils/devcontainer-ruby-zshrc/Dockerfile b/test/common-utils/devcontainer-ruby-zshrc/Dockerfile new file mode 100644 index 000000000..67cabf907 --- /dev/null +++ b/test/common-utils/devcontainer-ruby-zshrc/Dockerfile @@ -0,0 +1,4 @@ +FROM mcr.microsoft.com/devcontainers/ruby:3.2 + +RUN echo 'eval "$(rbenv init -)"' >> /home/vscode/.zshrc + diff --git a/test/common-utils/devcontainer-ruby-zshrc/meta.env b/test/common-utils/devcontainer-ruby-zshrc/meta.env new file mode 100644 index 000000000..dfc61d31c --- /dev/null +++ b/test/common-utils/devcontainer-ruby-zshrc/meta.env @@ -0,0 +1,8 @@ +VERSION='test-version' +DEFINITION_ID='test-id' +VARIANT='test-variant' +GIT_REPOSITORY='test-repository' +GIT_REPOSITORY_RELEASE='test-release' +GIT_REPOSITORY_REVISION='test-revision' +BUILD_TIMESTAMP='test-time' +CONTENTS_URL='test-url' diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index 744f16dc1..0151d9d1f 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -235,6 +235,24 @@ } } }, + "devcontainer-ruby-zshrc": { + "build": { + "dockerfile": "Dockerfile" + }, + "remoteUser": "vscode", + "features": { + "common-utils": { + "installZsh": true, + "username": "vscode", + "userUid": "1000", + "userGid": "1000", + "upgradePackages": true, + "installOhMyZsh": true, + "installOhMyZshConfig": true, + "configureZshAsDefaultShell": true + } + } + }, "alpine-base-zsh-default": { "image": "mcr.microsoft.com/devcontainers/base:alpine", "remoteUser": "vscode", From b2c7d17f0a8320895c3b52df8485c645398854e1 Mon Sep 17 00:00:00 2001 From: Ruben Suarez Alvarez Date: Tue, 13 Aug 2024 22:30:03 +0200 Subject: [PATCH 024/189] =?UTF-8?q?feat(kubectl-helm-minikube):=20?= =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20add=20helm=20completion=20(?= =?UTF-8?q?#1080)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(kubectl-helm-minikube): 🧑‍💻 add helm completion Like **kubectl**, **helm** supports **bash** and **zsh** command completion. * test(kubectl-helm-minikube): ✅ test helm bash completion * chore(kubectl-helm-minikube): 🔧 update feature version --- .../devcontainer-feature.json | 2 +- src/kubectl-helm-minikube/install.sh | 10 +++++++ .../checkBashCompletion.sh | 27 +++++++++++++++++++ test/kubectl-helm-minikube/test.sh | 10 +++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100755 test/kubectl-helm-minikube/checkBashCompletion.sh diff --git a/src/kubectl-helm-minikube/devcontainer-feature.json b/src/kubectl-helm-minikube/devcontainer-feature.json index dabee64a5..23596516c 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.1.10", + "version": "1.2.0", "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 c2f9ba0c9..bf6c8f535 100755 --- a/src/kubectl-helm-minikube/install.sh +++ b/src/kubectl-helm-minikube/install.sh @@ -311,6 +311,16 @@ if [ ${HELM_VERSION} != "none" ]; then echo '(!) Helm installation failed!' exit 1 fi + + # helm bash completion + helm completion bash > /etc/bash_completion.d/helm + + # helm zsh completion + if [ -e "${USERHOME}/.oh-my-zsh" ]; then + mkdir -p "${USERHOME}/.oh-my-zsh/completions" + helm completion zsh > "${USERHOME}/.oh-my-zsh/completions/_helm" + chown -R "${USERNAME}" "${USERHOME}/.oh-my-zsh" + fi fi # Install Minikube, verify checksum diff --git a/test/kubectl-helm-minikube/checkBashCompletion.sh b/test/kubectl-helm-minikube/checkBashCompletion.sh new file mode 100755 index 000000000..376461b52 --- /dev/null +++ b/test/kubectl-helm-minikube/checkBashCompletion.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +command=$1 +expected=$2 + +echo -e "Checking completion for command '$command'..." + +# Send command as a character stream, followed by two tab characters, into an interactive bash shell. +# Also note the 'y' which responds to the possible Bash question "Display all xxx possibilities? (y or n)". +# Bash produces the autocompletion output on stderr, so redirect that to stdout. +# The sed bit captures the lines between Header and Footer (used as output delimiters). +# The first grep removes the "Display all" message (that is atomatically answered to "y" by the script). +# The last grep filters the output to lines containing the expected result. +COMPLETE_OUTPUT=$(echo if false\; then "Header"\; $command$'\t'$'\t'y\; "Footer" fi | bash -i 2>&1 | sed -n '/Header/{:a;n;/Footer/q;p;ba}' | grep -v ^'Display all ') +echo -e "\nCompletion output:\n" +echo -e "$COMPLETE_OUTPUT" +echo -e "\n" + +FILTERED_COMPLETE_OUTPUT=$(echo "$COMPLETE_OUTPUT" | grep "$expected") + +if [ -z "$FILTERED_COMPLETE_OUTPUT" ]; then + echo -e "Completion output does not contains '$expected'." + exit 1 +else + echo -e "Completion output contains '$expected'." + exit 0 +fi diff --git a/test/kubectl-helm-minikube/test.sh b/test/kubectl-helm-minikube/test.sh index 9dc41417a..703ba58d7 100755 --- a/test/kubectl-helm-minikube/test.sh +++ b/test/kubectl-helm-minikube/test.sh @@ -10,5 +10,15 @@ check "kube" kubectl check "helm" helm version check "minikune" minikube version +# By default bash complete is disabled for the root user +# Enable it by replacing current ~/.bashrc with the /etc/skel/.bashrc file +mv ~/.bashrc ~/.bashrc.bak +cp /etc/skel/.bashrc ~/ + +check "helm-bash-completion-contains-version-command" ./checkBashCompletion.sh "helm " "version" + +# Restore original ~/.bashrc +mv ~/.bashrc.bak ~/.bashrc + # Report result reportResults \ No newline at end of file From 28ca71a147402fb0189c688bf0abb9843da4b435 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Thu, 15 Aug 2024 09:29:12 -0700 Subject: [PATCH 025/189] Revert "common-utils overwrites .zshrc coming from image built" (#1094) * Revert "common-utils overwrites .zshrc coming from image built (#1069)" This reverts commit 56233fda3b8dfad16dfc1bf1bcc11350eaf772d0. * Update devcontainer-feature.json --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 4 ++-- test/common-utils/devcontainer-ruby-zshrc.sh | 12 ------------ .../devcontainer-ruby-zshrc/Dockerfile | 4 ---- .../devcontainer-ruby-zshrc/meta.env | 8 -------- test/common-utils/scenarios.json | 18 ------------------ 6 files changed, 3 insertions(+), 45 deletions(-) delete mode 100755 test/common-utils/devcontainer-ruby-zshrc.sh delete mode 100644 test/common-utils/devcontainer-ruby-zshrc/Dockerfile delete mode 100644 test/common-utils/devcontainer-ruby-zshrc/meta.env diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 3ae86cd3e..c403c2644 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.4.6", + "version": "2.4.7", "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.", diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index 91cfc4d3b..8f82dcdf9 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -491,6 +491,7 @@ if [ "${INSTALL_ZSH}" = "true" ]; then echo 'source $HOME/.profile' >> "${user_home}/.zprofile" # TODO: Reconsider adding '.profile' to '.zprofile' chown ${USERNAME}:${group_name} "${user_home}/.zprofile" fi + if [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then if [ "${ADJUSTED_ID}" = "rhel" ]; then global_rc_path="/etc/zshrc" @@ -542,8 +543,7 @@ if [ "${INSTALL_ZSH}" = "true" ]; then # Add devcontainer .zshrc template if [ "$INSTALL_OH_MY_ZSH_CONFIG" = "true" ]; then - template_code="$(cat "${template_path}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" - echo -e "$([ -f "${user_rc_file}" ] && cat "${user_rc_file}")\n${template_code}" > "${user_rc_file}" + echo -e "$(cat "${template_path}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" > ${user_rc_file} sed -i -e 's/ZSH_THEME=.*/ZSH_THEME="devcontainers"/g' ${user_rc_file} fi diff --git a/test/common-utils/devcontainer-ruby-zshrc.sh b/test/common-utils/devcontainer-ruby-zshrc.sh deleted file mode 100755 index 9e7b26e4c..000000000 --- a/test/common-utils/devcontainer-ruby-zshrc.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -set -e - -# Optional: Import test library -source dev-container-features-test-lib - -# Definition specific tests -check "configure-zshrc-without-overwrite" bash -c "grep 'rbenv init -' ~/.zshrc" - -# Report result -reportResults diff --git a/test/common-utils/devcontainer-ruby-zshrc/Dockerfile b/test/common-utils/devcontainer-ruby-zshrc/Dockerfile deleted file mode 100644 index 67cabf907..000000000 --- a/test/common-utils/devcontainer-ruby-zshrc/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM mcr.microsoft.com/devcontainers/ruby:3.2 - -RUN echo 'eval "$(rbenv init -)"' >> /home/vscode/.zshrc - diff --git a/test/common-utils/devcontainer-ruby-zshrc/meta.env b/test/common-utils/devcontainer-ruby-zshrc/meta.env deleted file mode 100644 index dfc61d31c..000000000 --- a/test/common-utils/devcontainer-ruby-zshrc/meta.env +++ /dev/null @@ -1,8 +0,0 @@ -VERSION='test-version' -DEFINITION_ID='test-id' -VARIANT='test-variant' -GIT_REPOSITORY='test-repository' -GIT_REPOSITORY_RELEASE='test-release' -GIT_REPOSITORY_REVISION='test-revision' -BUILD_TIMESTAMP='test-time' -CONTENTS_URL='test-url' diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index 0151d9d1f..744f16dc1 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -235,24 +235,6 @@ } } }, - "devcontainer-ruby-zshrc": { - "build": { - "dockerfile": "Dockerfile" - }, - "remoteUser": "vscode", - "features": { - "common-utils": { - "installZsh": true, - "username": "vscode", - "userUid": "1000", - "userGid": "1000", - "upgradePackages": true, - "installOhMyZsh": true, - "installOhMyZshConfig": true, - "configureZshAsDefaultShell": true - } - } - }, "alpine-base-zsh-default": { "image": "mcr.microsoft.com/devcontainers/base:alpine", "remoteUser": "vscode", From 5cb0d2da02402aa0d3cbb93c1fc58c33f53022e7 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Fri, 16 Aug 2024 04:59:51 +0530 Subject: [PATCH 026/189] [desktop-lite] - add tests for running xtigervnc and novnc (#1090) * [desktop-lite] - add tests for running xtigervnc and novnc * change for error while running test scenario * changed test * Update devcontainer-feature.json --------- Co-authored-by: Samruddhi Khandale --- src/desktop-lite/devcontainer-feature.json | 2 +- src/desktop-lite/install.sh | 8 +++-- test/desktop-lite/scenarios.json | 8 +++++ .../test_xtigervnc_novnc_started.sh | 31 +++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 test/desktop-lite/scenarios.json create mode 100644 test/desktop-lite/test_xtigervnc_novnc_started.sh diff --git a/src/desktop-lite/devcontainer-feature.json b/src/desktop-lite/devcontainer-feature.json index ebc04ebad..7c2549a0d 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.3", + "version": "1.2.4", "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.", diff --git a/src/desktop-lite/install.sh b/src/desktop-lite/install.sh index 5230425f0..5060f9210 100755 --- a/src/desktop-lite/install.sh +++ b/src/desktop-lite/install.sh @@ -394,8 +394,12 @@ else fi # Run whatever was passed in -log "Executing \"\$@\"." -exec "$@" +if [ -n "$1" ]; then + log "Executing \"\$@\"." + exec "$@" +else + log "No command provided to execute." +fi log "** SCRIPT EXIT **" EOF diff --git a/test/desktop-lite/scenarios.json b/test/desktop-lite/scenarios.json new file mode 100644 index 000000000..d86b321fd --- /dev/null +++ b/test/desktop-lite/scenarios.json @@ -0,0 +1,8 @@ +{ + "test_xtigervnc_novnc_started": { + "image": "ubuntu:noble", + "features": { + "desktop-lite": {} + } + } +} \ No newline at end of file diff --git a/test/desktop-lite/test_xtigervnc_novnc_started.sh b/test/desktop-lite/test_xtigervnc_novnc_started.sh new file mode 100644 index 000000000..671032229 --- /dev/null +++ b/test/desktop-lite/test_xtigervnc_novnc_started.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Check if xtigervnc & noVnc processes are running after successful installation and initialization +check_process_running() { + port=$1 + # Get process id of process running on specific port + PID=$(lsof -i :$port | awk 'NR==2 {print $2}') + if [ -n "$PID" ]; then + CMD=$(ps -p $PID -o cmd --no-headers) + GREEN='\033[0;32m'; NC='\033[0m'; RED='\033[0;31m'; YELLOW='\033[0;33m'; + echo -e "${GREEN}Command running on port $port: ${YELLOW}$CMD${NC}" + else + echo -e "${RED}No process found listening on port $port.${NC}" + fi +} + +check "Whether xtigervnc is Running" check_process_running 5901 +sleep 1 +check "Whether no_vnc is Running" check_process_running 6080 + +check "desktop-init-exists" bash -c "ls /usr/local/share/desktop-init.sh" +check "log-exists" bash -c "ls /tmp/container-init.log" +check "log file contents" bash -c "cat /tmp/container-init.log" + +# Report result +reportResults \ No newline at end of file From 808ee3846c7ccec8d3e550e50d6479a4cb9c3c17 Mon Sep 17 00:00:00 2001 From: Daniel Meilak <32960789+daniel-meilak@users.noreply.github.com> Date: Fri, 16 Aug 2024 22:56:46 +0200 Subject: [PATCH 027/189] [desktop-lite] Suggested usage of appPort instead of forwardPorts for devcontainer-cli (#1096) * [desktop-lite] Suggested usage of appPort instead of forwardPorts for devcontainer-cli * Update src/desktop-lite/NOTES.md Co-authored-by: Samruddhi Khandale --------- Co-authored-by: Samruddhi Khandale --- src/desktop-lite/NOTES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/desktop-lite/NOTES.md b/src/desktop-lite/NOTES.md index 924ce9b6e..ec9ec71d4 100644 --- a/src/desktop-lite/NOTES.md +++ b/src/desktop-lite/NOTES.md @@ -19,7 +19,7 @@ To set up the `6080` port from your `devcontainer.json` file, include the follow You can also connect to the desktop using a [VNC viewer](https://www.realvnc.com/en/connect/download/viewer/). To do so: 1. Connect to the environment from a desktop tool that supports the dev container spec (e.g., VS Code client). -1. Forward the VNC server port (`5901` by default) to your local machine using either the `forwardPorts` property in `devcontainer.json` or the user interface in your tool (e.g., you can press F1 or Ctrl/Cmd+Shift+P and select **Ports: Focus on Ports View** in VS Code to bring it into focus). +1. Forward the VNC server port (`5901` by default) to your local machine using either the `forwardPorts` property in `devcontainer.json` or the user interface in your tool (e.g., you can press F1 or Ctrl/Cmd+Shift+P and select **Ports: Focus on Ports View** in VS Code to bring it into focus). If you are using the [Dev Container CLI](https://github.com/devcontainers/cli), you should instead use the `appPort` property in `devcontainer.json`. 1. Start your VNC Viewer and connect to localhost:5901. Note that you may need to bump up the color depth to 24 bits to see full color. 1. Enter the desktop password (`vscode` by default). From 5150fb9a06aae0d9aff30e03789c2a31b7df38fb Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Fri, 16 Aug 2024 14:33:48 -0700 Subject: [PATCH 028/189] Automated documentation update (#1097) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/desktop-lite/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/desktop-lite/README.md b/src/desktop-lite/README.md index 6f2d67ce2..a70997405 100644 --- a/src/desktop-lite/README.md +++ b/src/desktop-lite/README.md @@ -42,7 +42,7 @@ To set up the `6080` port from your `devcontainer.json` file, include the follow You can also connect to the desktop using a [VNC viewer](https://www.realvnc.com/en/connect/download/viewer/). To do so: 1. Connect to the environment from a desktop tool that supports the dev container spec (e.g., VS Code client). -1. Forward the VNC server port (`5901` by default) to your local machine using either the `forwardPorts` property in `devcontainer.json` or the user interface in your tool (e.g., you can press F1 or Ctrl/Cmd+Shift+P and select **Ports: Focus on Ports View** in VS Code to bring it into focus). +1. Forward the VNC server port (`5901` by default) to your local machine using either the `forwardPorts` property in `devcontainer.json` or the user interface in your tool (e.g., you can press F1 or Ctrl/Cmd+Shift+P and select **Ports: Focus on Ports View** in VS Code to bring it into focus). If you are using the [Dev Container CLI](https://github.com/devcontainers/cli), you should instead use the `appPort` property in `devcontainer.json`. 1. Start your VNC Viewer and connect to localhost:5901. Note that you may need to bump up the color depth to 24 bits to see full color. 1. Enter the desktop password (`vscode` by default). From b45b19975b636d082daa45c6832f9f915e020071 Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Mon, 19 Aug 2024 09:51:08 -0700 Subject: [PATCH 029/189] [Updates] Automated vendor dotnet-install script (#1098) * Automated dotnet-install script update * Bump version --------- Co-authored-by: github-actions --- src/dotnet/devcontainer-feature.json | 2 +- src/dotnet/scripts/vendor/dotnet-install.sh | 4 ++++ src/oryx/devcontainer-feature.json | 2 +- src/oryx/scripts/vendor/dotnet-install.sh | 4 ++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index eb09f1d54..f6e0c39ab 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "2.1.2", + "version": "2.1.3", "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/vendor/dotnet-install.sh b/src/dotnet/scripts/vendor/dotnet-install.sh index caa3ea450..38a160cf1 100755 --- a/src/dotnet/scripts/vendor/dotnet-install.sh +++ b/src/dotnet/scripts/vendor/dotnet-install.sh @@ -331,6 +331,10 @@ get_machine_architecture() { echo "riscv64" return 0 ;; + powerpc|ppc) + echo "ppc" + return 0 + ;; esac fi diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json index 68391cde9..39b9a7103 100644 --- a/src/oryx/devcontainer-feature.json +++ b/src/oryx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oryx", - "version": "1.3.5", + "version": "1.3.6", "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 caa3ea450..38a160cf1 100755 --- a/src/oryx/scripts/vendor/dotnet-install.sh +++ b/src/oryx/scripts/vendor/dotnet-install.sh @@ -331,6 +331,10 @@ get_machine_architecture() { echo "riscv64" return 0 ;; + powerpc|ppc) + echo "ppc" + return 0 + ;; esac fi From 34c3a51114451043f3608d803c99bbbcc9aaa60b Mon Sep 17 00:00:00 2001 From: Osvaldo Ortega <48293249+osortega@users.noreply.github.com> Date: Mon, 19 Aug 2024 12:05:32 -0700 Subject: [PATCH 030/189] Modify scripts to stream terminal title changes (#1095) * Modify scripts to stream terminal title changes Adding the capabilities to signal terminal title changes based on the command that is being executed * Fixes * Review comments * Update src/common-utils/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * Update src/common-utils/scripts/bash_theme_snippet.sh Co-authored-by: Samruddhi Khandale * Update src/common-utils/scripts/rc_snippet.sh Co-authored-by: Samruddhi Khandale * Remove RC * Adding tests * Update test/common-utils/scenarios.json * Update src/common-utils/scripts/bash_theme_snippet.sh * Test fixes --------- Co-authored-by: Samruddhi Khandale Co-authored-by: Samruddhi Khandale --- src/common-utils/devcontainer-feature.json | 2 +- .../scripts/bash_theme_snippet.sh | 21 ++++++++++++++++++- .../scripts/devcontainers.zsh-theme | 19 +++++++++++++++++ src/common-utils/scripts/rc_snippet.sh | 1 - .../no-terminal-title-by-default.sh | 18 ++++++++++++++++ test/common-utils/scenarios.json | 15 +++++++++++++ test/common-utils/terminal-title-on-xterm.sh | 18 ++++++++++++++++ 7 files changed, 91 insertions(+), 3 deletions(-) create mode 100755 test/common-utils/no-terminal-title-by-default.sh create mode 100755 test/common-utils/terminal-title-on-xterm.sh diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index c403c2644..153e2503d 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.4.7", + "version": "2.5.0", "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.", diff --git a/src/common-utils/scripts/bash_theme_snippet.sh b/src/common-utils/scripts/bash_theme_snippet.sh index 491e4c047..6e80952a4 100644 --- a/src/common-utils/scripts/bash_theme_snippet.sh +++ b/src/common-utils/scripts/bash_theme_snippet.sh @@ -1,4 +1,3 @@ - # bash theme - partly inspired by https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/robbyrussell.zsh-theme __bash_prompt() { local userpart='`export XIT=$? \ @@ -23,3 +22,23 @@ __bash_prompt() { } __bash_prompt export PROMPT_DIRTRIM=4 + +# Check if the terminal is xterm +if [[ "$TERM" == "xterm" ]]; then + # Function to set the terminal title to the current command + preexec() { + local cmd="${BASH_COMMAND}" + echo -ne "\033]0;${USER}@${HOSTNAME}: ${cmd}\007" + } + + # Function to reset the terminal title to the shell type after the command is executed + precmd() { + echo -ne "\033]0;${USER}@${HOSTNAME}: ${SHELL}\007" + } + + # Trap DEBUG signal to call preexec before each command + trap 'preexec' DEBUG + + # Append to PROMPT_COMMAND to call precmd before displaying the prompt + PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND; }precmd" +fi \ No newline at end of file diff --git a/src/common-utils/scripts/devcontainers.zsh-theme b/src/common-utils/scripts/devcontainers.zsh-theme index ff11c917e..d12993a67 100644 --- a/src/common-utils/scripts/devcontainers.zsh-theme +++ b/src/common-utils/scripts/devcontainers.zsh-theme @@ -24,3 +24,22 @@ __zsh_prompt() { unset -f __zsh_prompt } __zsh_prompt + +# Check if the terminal is xterm +if [[ "$TERM" == "xterm" ]]; then + # Function to set the terminal title to the current command + preexec() { + local cmd=${1} + echo -ne "\033]0;${USER}@${HOSTNAME}: ${cmd}\007" + } + + # Function to reset the terminal title to the shell type after the command is executed + precmd() { + echo -ne "\033]0;${USER}@${HOSTNAME}: ${SHELL}\007" + } + + # Add the preexec and precmd functions to the corresponding hooks + autoload -Uz add-zsh-hook + add-zsh-hook preexec preexec + add-zsh-hook precmd precmd +fi \ No newline at end of file diff --git a/src/common-utils/scripts/rc_snippet.sh b/src/common-utils/scripts/rc_snippet.sh index 4810cd993..42249ecbd 100644 --- a/src/common-utils/scripts/rc_snippet.sh +++ b/src/common-utils/scripts/rc_snippet.sh @@ -1,4 +1,3 @@ - if [ -z "${USER}" ]; then export USER=$(whoami); fi if [[ "${PATH}" != *"$HOME/.local/bin"* ]]; then export PATH="${PATH}:$HOME/.local/bin"; fi diff --git a/test/common-utils/no-terminal-title-by-default.sh b/test/common-utils/no-terminal-title-by-default.sh new file mode 100755 index 000000000..83fe7d221 --- /dev/null +++ b/test/common-utils/no-terminal-title-by-default.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release + +# Make sure bashrc is applied +source /root/.bashrc + +check "check_term_is_not_set" test !"$TERM" +check "check_prompt_command_not_set" test !"$PROMPT_COMMAND" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index 744f16dc1..e5529ea04 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -259,5 +259,20 @@ "features": { "common-utils": {} } + }, + "terminal-title-on-xterm": { + "image": "node", + "features": { + "common-utils": {} + }, + "containerEnv": { + "TERM": "xterm" + } + }, + "no-terminal-title-by-default": { + "image": "node", + "features": { + "common-utils": {} + } } } \ No newline at end of file diff --git a/test/common-utils/terminal-title-on-xterm.sh b/test/common-utils/terminal-title-on-xterm.sh new file mode 100755 index 000000000..9b483651f --- /dev/null +++ b/test/common-utils/terminal-title-on-xterm.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release + +# Make sure bashrc is applied +source /root/.bashrc + +check "check_term_is_set" test "$TERM" = "xterm" +check "check_term_is_set" test "$PROMPT_COMMAND" = "precmd" + +# Report result +reportResults \ No newline at end of file From f0e6ba6b8c4c719c57c93b6bf845c344e14d9f58 Mon Sep 17 00:00:00 2001 From: Paul Taylor <178183+trxcllnt@users.noreply.github.com> Date: Tue, 20 Aug 2024 09:58:50 -0700 Subject: [PATCH 031/189] Ensure `common-utils` rc snippets end with newlines (#1100) ensure common-utils rc snippets have line endings --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/scripts/bash_theme_snippet.sh | 2 +- src/common-utils/scripts/devcontainers.zsh-theme | 4 ++-- src/common-utils/scripts/rc_snippet.sh | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 153e2503d..968cbfb77 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.0", + "version": "2.5.1", "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.", diff --git a/src/common-utils/scripts/bash_theme_snippet.sh b/src/common-utils/scripts/bash_theme_snippet.sh index 6e80952a4..ab76ada33 100644 --- a/src/common-utils/scripts/bash_theme_snippet.sh +++ b/src/common-utils/scripts/bash_theme_snippet.sh @@ -41,4 +41,4 @@ if [[ "$TERM" == "xterm" ]]; then # Append to PROMPT_COMMAND to call precmd before displaying the prompt PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND; }precmd" -fi \ No newline at end of file +fi diff --git a/src/common-utils/scripts/devcontainers.zsh-theme b/src/common-utils/scripts/devcontainers.zsh-theme index d12993a67..0cfd70e65 100644 --- a/src/common-utils/scripts/devcontainers.zsh-theme +++ b/src/common-utils/scripts/devcontainers.zsh-theme @@ -1,7 +1,7 @@ # Oh My Zsh! theme - partly inspired by https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/robbyrussell.zsh-theme __zsh_prompt() { local prompt_username - if [ ! -z "${GITHUB_USER}" ]; then + if [ ! -z "${GITHUB_USER}" ]; then prompt_username="@${GITHUB_USER}" else prompt_username="%n" @@ -42,4 +42,4 @@ if [[ "$TERM" == "xterm" ]]; then autoload -Uz add-zsh-hook add-zsh-hook preexec preexec add-zsh-hook precmd precmd -fi \ No newline at end of file +fi diff --git a/src/common-utils/scripts/rc_snippet.sh b/src/common-utils/scripts/rc_snippet.sh index 42249ecbd..f3f36a4b8 100644 --- a/src/common-utils/scripts/rc_snippet.sh +++ b/src/common-utils/scripts/rc_snippet.sh @@ -16,9 +16,9 @@ fi # Set the default git editor if not already set if [ -z "$(git config --get core.editor)" ] && [ -z "${GIT_EDITOR}" ]; then if [ "${TERM_PROGRAM}" = "vscode" ]; then - if [[ -n $(command -v code-insiders) && -z $(command -v code) ]]; then + if [[ -n $(command -v code-insiders) && -z $(command -v code) ]]; then export GIT_EDITOR="code-insiders --wait" - else + else export GIT_EDITOR="code --wait" fi fi From 07dc0288d4b98f0ef76ea307d262ddc3d08b81c2 Mon Sep 17 00:00:00 2001 From: Shoki Hata Date: Thu, 22 Aug 2024 02:23:24 +0900 Subject: [PATCH 032/189] [Go] Update proposals for the "version" option (#1104) Update Go version to 1.3.1 and proposals to 1.23 and 1.22 --- src/go/devcontainer-feature.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/go/devcontainer-feature.json b/src/go/devcontainer-feature.json index 58415ce6b..afb1f9128 100644 --- a/src/go/devcontainer-feature.json +++ b/src/go/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "go", - "version": "1.3.0", + "version": "1.3.1", "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.", @@ -10,8 +10,8 @@ "proposals": [ "latest", "none", - "1.21", - "1.20" + "1.23", + "1.22" ], "default": "latest", "description": "Select or enter a Go version to install" @@ -44,4 +44,4 @@ "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] -} \ No newline at end of file +} From 52c79b4963879dd941c67b583199ec7966e41ab4 Mon Sep 17 00:00:00 2001 From: Prathamesh Zarkar <159782310+prathameshzarkar9@users.noreply.github.com> Date: Wed, 28 Aug 2024 04:54:29 +0530 Subject: [PATCH 033/189] Features update logic for PPA in bionic (#1079) * Features update logic for PPA in bionic * node failing fixed after pnpm install from npm package manager * for node version 16 pnpm version 7 is installed * uninstalled pnpm package first and then reinstalled as per node version * force installing pnpm package * optimized logic to install compatible pnpm for node 16 * pnpm install specific version compatible for node * new variable added pnpmVersion in node feature * test case failure fixed * fixed test cases * fixing test cases * pnpm version fixed for test cases * default version for pnpm updated * review comments addressed * Update src/node/devcontainer-feature.json --------- Co-authored-by: Samruddhi Khandale --- src/common-utils/main.sh | 8 ++++++++ src/go/install.sh | 8 ++++++++ src/node/devcontainer-feature.json | 16 +++++++++++++++- src/node/install.sh | 15 ++++++++++++--- src/python/devcontainer-feature.json | 2 +- src/python/install.sh | 8 ++++++++ test/node/centos-7.sh | 2 +- test/node/install_additional_node.sh | 2 +- .../install_additional_node_on_rhel_family.sh | 2 +- test/node/install_node_16_on_bionic.sh | 2 +- test/node/install_nvm_0.39.sh | 2 +- test/node/non_root_user.sh | 2 +- test/node/scenarios.json | 18 ++++++++++++------ 13 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index 8f82dcdf9..7658c4850 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -362,6 +362,14 @@ if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo fi +if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then + # As of 1 July 2024, mirrorlist.centos.org no longer exists. + # Update the repo files to reference vault.centos.org. + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo +fi + # Install packages for appropriate OS case "${ADJUSTED_ID}" in "debian") diff --git a/src/go/install.sh b/src/go/install.sh index ca01d34f5..85fea5dc4 100755 --- a/src/go/install.sh +++ b/src/go/install.sh @@ -43,6 +43,14 @@ else exit 1 fi +if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then + # As of 1 July 2024, mirrorlist.centos.org no longer exists. + # Update the repo files to reference vault.centos.org. + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo +fi + # Setup INSTALL_CMD & PKG_MGR_CMD if type apt-get > /dev/null 2>&1; then PKG_MGR_CMD=apt-get diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index 4e67aa6de..a9b0d46b8 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.5.0", + "version": "1.6.0", "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.", @@ -28,6 +28,20 @@ "default": "/usr/local/share/nvm", "description": "The path where NVM will be installed." }, + "pnpmVersion": { + "type": "string", + "proposals": [ + "latest", + "8.8.0", + "8.0.0", + "7.30.0", + "6.14.8", + "5.18.10", + "none" + ], + "default": "latest", + "description": "Select or enter the PNPM version to install" + }, "nvmVersion": { "type": "string", "proposals": [ diff --git a/src/node/install.sh b/src/node/install.sh index 5e833c6fe..3b74f885b 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -8,6 +8,7 @@ # Maintainer: The Dev Container spec maintainers export NODE_VERSION="${VERSION:-"lts"}" +export PNPM_VERSION="${PNPMVERSION:-"latest"}" export NVM_VERSION="${NVMVERSION:-"latest"}" export NVM_DIR="${NVMINSTALLPATH:-"/usr/local/share/nvm"}" INSTALL_TOOLS_FOR_NODE_GYP="${NODEGYPDEPENDENCIES:-true}" @@ -45,6 +46,14 @@ else exit 1 fi +if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then + # As of 1 July 2024, mirrorlist.centos.org no longer exists. + # Update the repo files to reference vault.centos.org. + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo +fi + # Setup INSTALL_CMD & PKG_MGR_CMD if type apt-get > /dev/null 2>&1; then PKG_MGR_CMD=apt-get @@ -370,8 +379,8 @@ if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then fi # Install pnpm -if bash -c ". '${NVM_DIR}/nvm.sh' && type pnpm >/dev/null 2>&1"; then - echo "pnpm already installed." +if [ ! -z "${PNPM_VERSION}" ] && [ "${PNPM_VERSION}" = "none" ]; then + echo "Ignoring installation of PNPM" else if bash -c ". '${NVM_DIR}/nvm.sh' && type npm >/dev/null 2>&1"; then ( @@ -379,7 +388,7 @@ else [ ! -z "$http_proxy" ] && npm set proxy="$http_proxy" [ ! -z "$https_proxy" ] && npm set https-proxy="$https_proxy" [ ! -z "$no_proxy" ] && npm set noproxy="$no_proxy" - npm install -g pnpm + npm install -g pnpm@$PNPM_VERSION --force ) else echo "Skip installing pnpm because npm is missing" diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index 2cb4cc87b..768cb4388 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.6.3", + "version": "1.6.4", "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.", diff --git a/src/python/install.sh b/src/python/install.sh index e6702add9..7e30ea041 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -60,6 +60,14 @@ else exit 1 fi +if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then + # As of 1 July 2024, mirrorlist.centos.org no longer exists. + # Update the repo files to reference vault.centos.org. + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo +fi + # To find some devel packages, some rhel need to enable specific extra repos, but not on RedHat ubi images... INSTALL_CMD_ADDL_REPO="" if [ ${ADJUSTED_ID} = "rhel" ] && [ ${ID} != "rhel" ]; then diff --git a/test/node/centos-7.sh b/test/node/centos-7.sh index c5980129b..7c064131f 100755 --- a/test/node/centos-7.sh +++ b/test/node/centos-7.sh @@ -7,7 +7,7 @@ source dev-container-features-test-lib # Definition specific tests check "version" node --version -check "pnpm" pnpm -v +check "pnpm" bash -c "pnpm -v | grep 8.8.0" check "nvm" bash -c ". /usr/local/share/nvm/nvm.sh && nvm install 10" check "yarn" yarn --version diff --git a/test/node/install_additional_node.sh b/test/node/install_additional_node.sh index d8f27317f..57d615a0a 100644 --- a/test/node/install_additional_node.sh +++ b/test/node/install_additional_node.sh @@ -7,7 +7,7 @@ source dev-container-features-test-lib # 'lts' is now some version of node 20... check "version_on_path" node -v | grep 20 -check "pnpm" pnpm -v +check "pnpm" bash -c "pnpm -v | grep 8.8.0" check "v20_installed" ls -1 /usr/local/share/nvm/versions/node | grep 20 check "v14_installed" ls -1 /usr/local/share/nvm/versions/node | grep 14.19.3 diff --git a/test/node/install_additional_node_on_rhel_family.sh b/test/node/install_additional_node_on_rhel_family.sh index d8f27317f..3300f7f1a 100644 --- a/test/node/install_additional_node_on_rhel_family.sh +++ b/test/node/install_additional_node_on_rhel_family.sh @@ -7,7 +7,7 @@ source dev-container-features-test-lib # 'lts' is now some version of node 20... check "version_on_path" node -v | grep 20 -check "pnpm" pnpm -v +check "pnpm" bash -c "pnpm -v | grep 6.16.0" check "v20_installed" ls -1 /usr/local/share/nvm/versions/node | grep 20 check "v14_installed" ls -1 /usr/local/share/nvm/versions/node | grep 14.19.3 diff --git a/test/node/install_node_16_on_bionic.sh b/test/node/install_node_16_on_bionic.sh index 500e0070e..aefa0b490 100755 --- a/test/node/install_node_16_on_bionic.sh +++ b/test/node/install_node_16_on_bionic.sh @@ -7,7 +7,7 @@ source dev-container-features-test-lib # Definition specific tests check "version" bash -c "node --version | grep 16" -check "pnpm" pnpm -v +check "pnpm" bash -c "pnpm -v | grep 8.8.0" check "nvm" bash -c ". /usr/local/share/nvm/nvm.sh && nvm install 10" # Report result diff --git a/test/node/install_nvm_0.39.sh b/test/node/install_nvm_0.39.sh index 6b96381b5..1f34f7ce4 100755 --- a/test/node/install_nvm_0.39.sh +++ b/test/node/install_nvm_0.39.sh @@ -7,7 +7,7 @@ source dev-container-features-test-lib # Definition specific tests check "version" bash -c "node --version" -check "pnpm" pnpm -v +check "pnpm" bash -c "pnpm -v | grep 6.16.0" check "nvm version" bash -c ". /usr/local/share/nvm/nvm.sh && nvm --version | grep 0.39" # Report result diff --git a/test/node/non_root_user.sh b/test/node/non_root_user.sh index 499dbe68a..2826adcbf 100755 --- a/test/node/non_root_user.sh +++ b/test/node/non_root_user.sh @@ -7,7 +7,7 @@ source dev-container-features-test-lib # Definition specific tests check "version" node --version -check "pnpm" pnpm -v +check "pnpm" bash -c "pnpm -v | grep 8.8.0" check "nvm" bash -c ". /usr/local/share/nvm/nvm.sh && nvm install 10" # Report result diff --git a/test/node/scenarios.json b/test/node/scenarios.json index 4f07e5ac3..df03128d6 100644 --- a/test/node/scenarios.json +++ b/test/node/scenarios.json @@ -12,7 +12,8 @@ "features": { "node": { "version": "lts", - "additionalVersions": "v17.9.1,v14.19.3" + "additionalVersions": "v17.9.1,v14.19.3", + "pnpmVersion": "8.8.0" } } }, @@ -21,7 +22,8 @@ "features": { "node": { "version": "lts", - "additionalVersions": "v17.9.1,v14.19.3" + "additionalVersions": "v17.9.1,v14.19.3", + "pnpmVersion": "6.16.0" } } }, @@ -30,7 +32,8 @@ "remoteUser": "vscode", "features": { "node": { - "version": "latest" + "version": "latest", + "pnpmVersion": "8.8.0" } } }, @@ -78,7 +81,8 @@ "image": "mcr.microsoft.com/devcontainers/base:ubuntu-18.04", "features": { "node": { - "version": "16" + "version": "16", + "pnpmVersion":"8.8.0" } } }, @@ -86,7 +90,8 @@ "image": "mcr.microsoft.com/devcontainers/base", "features": { "node": { - "nvmVersion": "0.39" + "nvmVersion": "0.39", + "pnpmVersion": "6.16.0" } } }, @@ -102,7 +107,8 @@ "image": "centos:centos7", "features": { "node": { - "version": "16" + "version": "16", + "pnpmVersion": "8.8.0" } } }, From 3bf4e20e5fb560b7df0fc821ceca64569a61d1da Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Tue, 27 Aug 2024 16:28:38 -0700 Subject: [PATCH 034/189] Automated documentation update (#1109) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/node/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/node/README.md b/src/node/README.md index dff3f8bfe..328af529f 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -18,6 +18,7 @@ Installs Node.js, nvm, yarn, pnpm, and needed dependencies. | version | Select or enter a Node.js version to install | string | lts | | nodeGypDependencies | Install dependencies to compile native node modules (node-gyp)? | boolean | true | | nvmInstallPath | The path where NVM will be installed. | string | /usr/local/share/nvm | +| pnpmVersion | Select or enter the PNPM version to install | string | latest | | nvmVersion | Version of NVM to install. | string | latest | | installYarnUsingApt | On Debian and Ubuntu systems, you have the option to install Yarn globally via APT. If you choose not to use this option, Yarn will be set up using Corepack instead. This choice is specific to Debian and Ubuntu; for other Linux distributions, Yarn is always installed using Corepack, with a fallback to installation via NPM if an error occurs. | boolean | true | From 878a900d55e60add9c7a76b433c7d4a4adf299bc Mon Sep 17 00:00:00 2001 From: Julian Pawlowski <75446+jpawlowski@users.noreply.github.com> Date: Wed, 28 Aug 2024 01:56:57 +0200 Subject: [PATCH 035/189] `[powershell]`: Fix manual PowerShell installation binary execution permissions (#1050) * Align manual pwsh install with DEB package - ensure execution permissions for pwsh - correct path from /usr/local/bin/pwsh to /usr/bin/pwsh - register as shell in /etc/shells * Update versions * Update repositories * Check for existing pwsh installation This will avoid build failures when multiple features depend on this PowerShell package * test: Fix PS profile test * Test: Fix install_using_github * Test: Fix getcwd warning * fix: Move out of directory before deleting it * test: Add validate_powershell_installation * test: Change Ubuntu test base image to upcoming new LTS version --- src/powershell/devcontainer-feature.json | 6 ++- src/powershell/install.sh | 37 +++++++++++-------- .../install_powershell_fallback_test.sh | 10 +++-- test/powershell/scenarios.json | 12 ++++-- .../validate_powershell_installation.sh | 19 ++++++++++ 5 files changed, 60 insertions(+), 24 deletions(-) create mode 100644 test/powershell/validate_powershell_installation.sh diff --git a/src/powershell/devcontainer-feature.json b/src/powershell/devcontainer-feature.json index d51b5c03f..585e34630 100644 --- a/src/powershell/devcontainer-feature.json +++ b/src/powershell/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "powershell", - "version": "1.4.0", + "version": "1.5.0", "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.", @@ -10,7 +10,9 @@ "proposals": [ "latest", "none", - "7.1" + "7.4", + "7.3", + "7.2" ], "default": "latest", "description": "Select or enter a version of PowerShell." diff --git a/src/powershell/install.sh b/src/powershell/install.sh index 43773b3f6..4953a49d8 100755 --- a/src/powershell/install.sh +++ b/src/powershell/install.sh @@ -18,7 +18,7 @@ POWERSHELL_PROFILE_URL="${POWERSHELLPROFILEURL}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" POWERSHELL_ARCHIVE_ARCHITECTURES="amd64" -POWERSHELL_ARCHIVE_VERSION_CODENAMES="stretch buster bionic focal bullseye jammy" +POWERSHELL_ARCHIVE_VERSION_CODENAMES="stretch buster bionic focal bullseye jammy bookworm noble" GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkp://keyserver.ubuntu.com:80 keyserver hkps://keys.openpgp.org @@ -221,25 +221,32 @@ install_using_github() { echo "${powershell_archive_sha256} *${powershell_filename}" | sha256sum -c - fi tar xf "${powershell_filename}" -C "${powershell_target_path}" - ln -s "${powershell_target_path}/pwsh" /usr/local/bin/pwsh + chmod 755 "${powershell_target_path}/pwsh" + ln -sf "${powershell_target_path}/pwsh" /usr/bin/pwsh + add-shell "/usr/bin/pwsh" + cd /tmp rm -rf /tmp/pwsh } -export DEBIAN_FRONTEND=noninteractive - -# Source /etc/os-release to get OS info -. /etc/os-release -architecture="$(dpkg --print-architecture)" +if ! type pwsh >/dev/null 2>&1; then + export DEBIAN_FRONTEND=noninteractive + + # Source /etc/os-release to get OS info + . /etc/os-release + architecture="$(dpkg --print-architecture)" -if [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${architecture}"* ]] && [[ "${POWERSHELL_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]]; then - install_using_apt || use_github="true" + if [[ "${POWERSHELL_ARCHIVE_ARCHITECTURES}" = *"${architecture}"* ]] && [[ "${POWERSHELL_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]]; then + install_using_apt || use_github="true" + else + use_github="true" + fi + + if [ "${use_github}" = "true" ]; then + echo "Attempting install from GitHub release..." + install_using_github + fi else - use_github="true" -fi - -if [ "${use_github}" = "true" ]; then - echo "Attempting install from GitHub release..." - install_using_github + echo "PowerShell is already installed." fi # If PowerShell modules are requested, loop through and install diff --git a/test/powershell/install_powershell_fallback_test.sh b/test/powershell/install_powershell_fallback_test.sh index 39c8bc49e..169863c7b 100644 --- a/test/powershell/install_powershell_fallback_test.sh +++ b/test/powershell/install_powershell_fallback_test.sh @@ -8,7 +8,7 @@ source dev-container-features-test-lib # Extension-specific tests check "az.resources" pwsh -Command "(Get-Module -ListAvailable -Name Az.Resources).Version.ToString()" check "az.storage" pwsh -Command "(Get-Module -ListAvailable -Name Az.Storage).Version.ToString()" -check "profile" pwsh -Command "(Get-Variable $env:ProfileLoaded).Value" +check "profile" pwsh -Command "if (\$null -eq \$env:ProfileLoaded) { echo 'Not set!'; exit 1 } else { if ( [bool]\$env:ProfileLoaded ) { echo 'Profile loaded.'; exit 0 } else { echo 'False value!'; exit 1 } }" check "Powershell version as installed by feature" bash -c "pwsh --version" @@ -168,9 +168,11 @@ install_using_github() { echo "${powershell_archive_sha256} *${powershell_filename}" | sha256sum -c - fi sudo tar xf "${powershell_filename}" -C "${powershell_target_path}" - sudo ln -s "${powershell_target_path}/pwsh" /usr/local/bin/pwsh - sudo rm -rf /tmp/pwsh /usr/local/bin/pwsh - + sudo chmod 755 "${powershell_target_path}/pwsh" + sudo ln -sf "${powershell_target_path}/pwsh" /usr/bin/pwsh + sudo add-shell "/usr/bin/pwsh" + cd /tmp + sudo rm -rf /tmp/pwsh } echo -e "\nInstalling Powershell with find_prev_version_from_git_tags() fn 👈🏻" diff --git a/test/powershell/scenarios.json b/test/powershell/scenarios.json index 757a8cc97..87a5b9d16 100644 --- a/test/powershell/scenarios.json +++ b/test/powershell/scenarios.json @@ -1,6 +1,6 @@ { "install_modules": { - "image": "mcr.microsoft.com/devcontainers/base:jammy", + "image": "mcr.microsoft.com/devcontainers/base:noble", "features": { "powershell": { "modules": "az.resources, az.storage", @@ -9,7 +9,7 @@ } }, "install_powershell_fallback_test": { - "image": "mcr.microsoft.com/devcontainers/base:jammy", + "image": "mcr.microsoft.com/devcontainers/base:noble", "features": { "powershell": { "modules": "az.resources, az.storage", @@ -18,11 +18,17 @@ } }, "install_modules_version": { - "image": "mcr.microsoft.com/devcontainers/base:jammy", + "image": "mcr.microsoft.com/devcontainers/base:noble", "features": { "powershell": { "modules": "az.resources==2.5.0, az.storage==4.3.0" } } + }, + "validate_powershell_installation": { + "image": "mcr.microsoft.com/devcontainers/base:noble", + "features": { + "powershell": {} + } } } diff --git a/test/powershell/validate_powershell_installation.sh b/test/powershell/validate_powershell_installation.sh new file mode 100644 index 000000000..88544f28b --- /dev/null +++ b/test/powershell/validate_powershell_installation.sh @@ -0,0 +1,19 @@ +#!/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) -eq 1 ]" +check "pwsh target is correct" bash -c "[ $(readlink /usr/bin/pwsh) = /opt/microsoft/powershell/7/pwsh ]" +check "pwsh target is registered as shell" bash -c "[ $(grep -c '/opt/microsoft/powershell/7/pwsh' /etc/shells) -eq 1 ]" +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 From 6123e41230425fc830c5e190005f91e88309efc2 Mon Sep 17 00:00:00 2001 From: Ruben Suarez Alvarez Date: Wed, 28 Aug 2024 02:00:05 +0200 Subject: [PATCH 036/189] =?UTF-8?q?feat(aws-cli):=20=F0=9F=A7=91=E2=80=8D?= =?UTF-8?q?=F0=9F=92=BB=20add=20aws-cli=20completion=20(#1083)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(aws-cli): 🧑‍💻 add aws completion aws supports bash and zsh command completion. * test(aws-cli): ✅ test aws bash completion * chore(aws-cli): 🔧 update feature version * fix(aws-cli): cp command fix * refactor(aws-cli): move vendor scripts to specific folder * docs(aws-cli): add README to vendor scripts * build(aws-cli): automate aws-cli vendor completer scripts updates * chore(aws-cli): update vendor completer scripts * build(aws-cli): update message * chore(aws-cli): remove some code remainders --- .../update-aws-cli-completer-scripts.yml | 58 ++++++++++++++++++ src/aws-cli/devcontainer-feature.json | 2 +- src/aws-cli/install.sh | 24 +++++--- .../scripts/fetch-latest-completer-scripts.sh | 20 +++++++ src/aws-cli/scripts/vendor/README.md | 12 ++++ src/aws-cli/scripts/vendor/aws_bash_completer | 6 ++ .../scripts/vendor/aws_zsh_completer.sh | 60 +++++++++++++++++++ test/aws-cli/checkBashCompletion.sh | 27 +++++++++ test/aws-cli/test.sh | 10 ++++ 9 files changed, 211 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/update-aws-cli-completer-scripts.yml create mode 100755 src/aws-cli/scripts/fetch-latest-completer-scripts.sh create mode 100644 src/aws-cli/scripts/vendor/README.md create mode 100755 src/aws-cli/scripts/vendor/aws_bash_completer create mode 100755 src/aws-cli/scripts/vendor/aws_zsh_completer.sh create mode 100755 test/aws-cli/checkBashCompletion.sh diff --git a/.github/workflows/update-aws-cli-completer-scripts.yml b/.github/workflows/update-aws-cli-completer-scripts.yml new file mode 100644 index 000000000..b46d43f39 --- /dev/null +++ b/.github/workflows/update-aws-cli-completer-scripts.yml @@ -0,0 +1,58 @@ +name: "Updates vendor 'aws_bash_completer' and 'aws_zsh_completer.sh' scripts" +on: + workflow_dispatch: + schedule: + - cron: '0 0 * * 0' # Runs every Sunday at midnight UTC (adjust as needed) + +jobs: + fetch-latest-aws-completer-scripts: + runs-on: ubuntu-latest + environment: documentation # grants access to secrets.PAT, for creating pull requests + permissions: + contents: write + pull-requests: write + steps: + - uses: actions/checkout@v3 + + - name: Run fetch-latest-completer-scripts.sh + run: src/aws-cli/scripts/fetch-latest-completer-scripts.sh + + - name: Create a PR for completer scripts + id: push_image_info + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + run: | + set -e + echo "Start." + + # Configure git and Push updates + git config --global user.email github-actions@github.com + git config --global user.name github-actions + git config pull.rebase false + + branch=automated-script-update-$GITHUB_RUN_ID + git checkout -b $branch + message='[Updates] Automated vendor 'aws-cli' completer scripts' + + # Add / update and commit + git add src/aws-cli/scripts/vendor/aws_bash_completer + git add src/aws-cli/scripts/vendor/aws_zsh_completer.sh + + git commit -m 'Automated completer scripts update' || export NO_UPDATES=true + + # Bump version and push + if [ "$NO_UPDATES" != "true" ] ; then + echo "$(jq --indent 4 '.version = (.version | split(".") | map(tonumber) | .[2] += 1 | join("."))' src/aws-cli/devcontainer-feature.json)" > src/aws-cli/devcontainer-feature.json + git add src/aws-cli/devcontainer-feature.json + + git commit -m 'Bump version' + git push origin "$branch" + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + /repos/${GITHUB_REPOSITORY}/pulls \ + -f title="$message" \ + -f body="$message" \ + -f head="$branch" \ + -f base="$GITHUB_REF_NAME" + fi diff --git a/src/aws-cli/devcontainer-feature.json b/src/aws-cli/devcontainer-feature.json index 35a035917..3c3128ac3 100644 --- a/src/aws-cli/devcontainer-feature.json +++ b/src/aws-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "aws-cli", - "version": "1.0.7", + "version": "1.1.0", "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.", diff --git a/src/aws-cli/install.sh b/src/aws-cli/install.sh index d802400ef..e7c03f728 100755 --- a/src/aws-cli/install.sh +++ b/src/aws-cli/install.sh @@ -52,24 +52,23 @@ fi apt_get_update() { - echo "Running apt-get update..." - apt-get update -y + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + apt-get update -y + fi } # Checks if packages are installed and installs them if not check_packages() { if ! dpkg -s "$@" > /dev/null 2>&1; then - if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then - echo "Running apt-get update..." - apt-get update -y - fi + apt_get_update apt-get -y install --no-install-recommends "$@" fi } export DEBIAN_FRONTEND=noninteractive -check_packages curl ca-certificates gnupg2 dirmngr unzip +check_packages curl ca-certificates gnupg2 dirmngr unzip bash-completion verify_aws_cli_gpg_signature() { local filePath=$1 @@ -114,6 +113,17 @@ install() { unzip "${scriptZipFile}" ./aws/install + # kubectl bash completion + mkdir -p /etc/bash_completion.d + cp ./scripts/vendor/aws_bash_completer /etc/bash_completion.d/aws + + # kubectl zsh completion + if [ -e "${USERHOME}/.oh-my-zsh" ]; then + mkdir -p "${USERHOME}/.oh-my-zsh/completions" + cp ./scripts/vendor/aws_zsh_completer.sh "${USERHOME}/.oh-my-zsh/completions/_aws" + chown -R "${USERNAME}" "${USERHOME}/.oh-my-zsh" + fi + rm -rf ./aws } diff --git a/src/aws-cli/scripts/fetch-latest-completer-scripts.sh b/src/aws-cli/scripts/fetch-latest-completer-scripts.sh new file mode 100755 index 000000000..47dc6ee1d --- /dev/null +++ b/src/aws-cli/scripts/fetch-latest-completer-scripts.sh @@ -0,0 +1,20 @@ +#!/bin/bash +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- +# +# Docs: https://github.com/devcontainers/features/tree/main/src/aws-cli +# Maintainer: The Dev Container spec maintainers +# +# Run this script to replace aws_bash_completer and aws_zsh_completer.sh with the latest and greatest available version +# +COMPLETER_SCRIPTS=$(dirname "${BASH_SOURCE[0]}") +BASH_COMPLETER_SCRIPT="$COMPLETER_SCRIPTS/vendor/aws_bash_completer" +ZSH_COMPLETER_SCRIPT="$COMPLETER_SCRIPTS/vendor/aws_zsh_completer.sh" + +wget https://raw.githubusercontent.com/aws/aws-cli/v2/bin/aws_bash_completer -O "$BASH_COMPLETER_SCRIPT" +chmod +x "$BASH_COMPLETER_SCRIPT" + +wget https://raw.githubusercontent.com/aws/aws-cli/v2/bin/aws_zsh_completer.sh -O "$ZSH_COMPLETER_SCRIPT" +chmod +x "$ZSH_COMPLETER_SCRIPT" diff --git a/src/aws-cli/scripts/vendor/README.md b/src/aws-cli/scripts/vendor/README.md new file mode 100644 index 000000000..1f3838d46 --- /dev/null +++ b/src/aws-cli/scripts/vendor/README.md @@ -0,0 +1,12 @@ +### **IMPORTANT NOTE** + +Scripts in this directory are sourced externally and not maintained by the Dev Container spec maintainers. Do not make changes directly as they might be overwritten at any moment. + +## aws_bash_completer + +`aws_bash_completer` is a copy of . + +## aws_zsh_completer.sh + +`aws_zsh_completer.sh` is a copy of . + diff --git a/src/aws-cli/scripts/vendor/aws_bash_completer b/src/aws-cli/scripts/vendor/aws_bash_completer new file mode 100755 index 000000000..32cd1dd8f --- /dev/null +++ b/src/aws-cli/scripts/vendor/aws_bash_completer @@ -0,0 +1,6 @@ +# Typically that would be added under one of the following paths: +# - /etc/bash_completion.d +# - /usr/local/etc/bash_completion.d +# - /usr/share/bash-completion/completions + +complete -C aws_completer aws diff --git a/src/aws-cli/scripts/vendor/aws_zsh_completer.sh b/src/aws-cli/scripts/vendor/aws_zsh_completer.sh new file mode 100755 index 000000000..c1b2c1244 --- /dev/null +++ b/src/aws-cli/scripts/vendor/aws_zsh_completer.sh @@ -0,0 +1,60 @@ +# Source this file to activate auto completion for zsh using the bash +# compatibility helper. Make sure to run `compinit` before, which should be +# given usually. +# +# % source /path/to/zsh_complete.sh +# +# Typically that would be called somewhere in your .zshrc. +# +# Note, the overwrite of _bash_complete() is to export COMP_LINE and COMP_POINT +# That is only required for zsh <= edab1d3dbe61da7efe5f1ac0e40444b2ec9b9570 +# +# https://github.com/zsh-users/zsh/commit/edab1d3dbe61da7efe5f1ac0e40444b2ec9b9570 +# +# zsh releases prior to that version do not export the required env variables! + +autoload -Uz bashcompinit +bashcompinit -i + +_bash_complete() { + local ret=1 + local -a suf matches + local -x COMP_POINT COMP_CWORD + local -a COMP_WORDS COMPREPLY BASH_VERSINFO + local -x COMP_LINE="$words" + local -A savejobstates savejobtexts + + (( COMP_POINT = 1 + ${#${(j. .)words[1,CURRENT]}} + $#QIPREFIX + $#IPREFIX + $#PREFIX )) + (( COMP_CWORD = CURRENT - 1)) + COMP_WORDS=( $words ) + BASH_VERSINFO=( 2 05b 0 1 release ) + + savejobstates=( ${(kv)jobstates} ) + savejobtexts=( ${(kv)jobtexts} ) + + [[ ${argv[${argv[(I)nospace]:-0}-1]} = -o ]] && suf=( -S '' ) + + matches=( ${(f)"$(compgen $@ -- ${words[CURRENT]})"} ) + + if [[ -n $matches ]]; then + if [[ ${argv[${argv[(I)filenames]:-0}-1]} = -o ]]; then + compset -P '*/' && matches=( ${matches##*/} ) + compset -S '/*' && matches=( ${matches%%/*} ) + compadd -Q -f "${suf[@]}" -a matches && ret=0 + else + compadd -Q "${suf[@]}" -a matches && ret=0 + fi + fi + + if (( ret )); then + if [[ ${argv[${argv[(I)default]:-0}-1]} = -o ]]; then + _default "${suf[@]}" && ret=0 + elif [[ ${argv[${argv[(I)dirnames]:-0}-1]} = -o ]]; then + _directories "${suf[@]}" && ret=0 + fi + fi + + return ret +} + +complete -C aws_completer aws diff --git a/test/aws-cli/checkBashCompletion.sh b/test/aws-cli/checkBashCompletion.sh new file mode 100755 index 000000000..376461b52 --- /dev/null +++ b/test/aws-cli/checkBashCompletion.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +command=$1 +expected=$2 + +echo -e "Checking completion for command '$command'..." + +# Send command as a character stream, followed by two tab characters, into an interactive bash shell. +# Also note the 'y' which responds to the possible Bash question "Display all xxx possibilities? (y or n)". +# Bash produces the autocompletion output on stderr, so redirect that to stdout. +# The sed bit captures the lines between Header and Footer (used as output delimiters). +# The first grep removes the "Display all" message (that is atomatically answered to "y" by the script). +# The last grep filters the output to lines containing the expected result. +COMPLETE_OUTPUT=$(echo if false\; then "Header"\; $command$'\t'$'\t'y\; "Footer" fi | bash -i 2>&1 | sed -n '/Header/{:a;n;/Footer/q;p;ba}' | grep -v ^'Display all ') +echo -e "\nCompletion output:\n" +echo -e "$COMPLETE_OUTPUT" +echo -e "\n" + +FILTERED_COMPLETE_OUTPUT=$(echo "$COMPLETE_OUTPUT" | grep "$expected") + +if [ -z "$FILTERED_COMPLETE_OUTPUT" ]; then + echo -e "Completion output does not contains '$expected'." + exit 1 +else + echo -e "Completion output contains '$expected'." + exit 0 +fi diff --git a/test/aws-cli/test.sh b/test/aws-cli/test.sh index d213eac38..45ef63db1 100755 --- a/test/aws-cli/test.sh +++ b/test/aws-cli/test.sh @@ -8,5 +8,15 @@ source dev-container-features-test-lib # Definition specific tests check "version" aws --version +# By default bash complete is disabled for the root user +# Enable it by replacing current ~/.bashrc with the /etc/skel/.bashrc file +mv ~/.bashrc ~/.bashrc.bak +cp /etc/skel/.bashrc ~/ + +check "aws-bash-completion-contains-version-option" ./checkBashCompletion.sh "aws --" "version" + +# Restore original ~/.bashrc +mv ~/.bashrc.bak ~/.bashrc + # Report result reportResults \ No newline at end of file From 28846e52809dfd65c0569fb58eae55afcb5f366a Mon Sep 17 00:00:00 2001 From: Vatsal Gupta <40350810+gvatsal60@users.noreply.github.com> Date: Wed, 4 Sep 2024 00:40:16 +0530 Subject: [PATCH 037/189] Updated actions version i.e checkout@4 and paths-filter@v3 (#1110) * Updated from checkout@3 to checkout@4 * Updated action paths-filter from @v2 to @v3 --- .github/workflows/docker-in-docker-stress-test.yaml | 4 ++-- .github/workflows/linter-automated.yaml | 4 ++-- .github/workflows/linter-manual.yaml | 2 +- .github/workflows/release.yaml | 4 ++-- .github/workflows/test-all.yaml | 6 +++--- .github/workflows/test-manual.yaml | 2 +- .github/workflows/test-pr.yaml | 8 ++++---- .github/workflows/update-aws-cli-completer-scripts.yml | 4 ++-- .github/workflows/update-documentation.yml | 2 +- .github/workflows/update-dotnet-install-script.yml | 4 ++-- .github/workflows/validate-metadata-files.yml | 4 ++-- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.github/workflows/docker-in-docker-stress-test.yaml b/.github/workflows/docker-in-docker-stress-test.yaml index 569f94699..1c9410a88 100644 --- a/.github/workflows/docker-in-docker-stress-test.yaml +++ b/.github/workflows/docker-in-docker-stress-test.yaml @@ -13,7 +13,7 @@ jobs: fail-fast: false runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli @@ -28,7 +28,7 @@ jobs: fail-fast: false runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli diff --git a/.github/workflows/linter-automated.yaml b/.github/workflows/linter-automated.yaml index 98921bf68..46cbd085a 100644 --- a/.github/workflows/linter-automated.yaml +++ b/.github/workflows/linter-automated.yaml @@ -1,5 +1,5 @@ name: "CI - Shell Script Linter" -on: +on: push: branches: - main @@ -9,7 +9,7 @@ jobs: shellchecker: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Shell Linter uses: azohra/shell-linter@v0.6.0 diff --git a/.github/workflows/linter-manual.yaml b/.github/workflows/linter-manual.yaml index ec2e5f0a7..019724d35 100644 --- a/.github/workflows/linter-manual.yaml +++ b/.github/workflows/linter-manual.yaml @@ -15,7 +15,7 @@ jobs: shellchecker: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Shell Linter uses: azohra/shell-linter@v0.6.0 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a1ec773b9..22297641a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -12,8 +12,8 @@ jobs: permissions: packages: write steps: - - uses: actions/checkout@v3 - + - uses: actions/checkout@v4 + - name: "Publish" uses: devcontainers/action@v1 with: diff --git a/.github/workflows/test-all.yaml b/.github/workflows/test-all.yaml index 7a9554314..7e4c343bd 100644 --- a/.github/workflows/test-all.yaml +++ b/.github/workflows/test-all.yaml @@ -51,7 +51,7 @@ jobs: "mcr.microsoft.com/devcontainers/base:noble" ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli @@ -94,7 +94,7 @@ jobs: "nix", ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli @@ -106,7 +106,7 @@ jobs: runs-on: ubuntu-latest continue-on-error: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli diff --git a/.github/workflows/test-manual.yaml b/.github/workflows/test-manual.yaml index f163eb8ea..10d099b25 100644 --- a/.github/workflows/test-manual.yaml +++ b/.github/workflows/test-manual.yaml @@ -19,7 +19,7 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index 776a9731f..79a34fb66 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -8,7 +8,7 @@ jobs: outputs: features: ${{ steps.filter.outputs.changes }} steps: - - uses: dorny/paths-filter@v2 + - uses: dorny/paths-filter@v3 id: filter with: filters: | @@ -17,7 +17,7 @@ jobs: azure-cli: ./**/azure-cli/** common-utils: ./**/common-utils/** conda: ./**/conda/** - desktop-lite: ./**/desktop-lite/** + desktop-lite: ./**/desktop-lite/** docker-outside-of-docker: ./**/docker-outside-of-docker/** docker-in-docker: ./**/docker-in-docker/** dotnet: ./**/dotnet/** @@ -58,7 +58,7 @@ jobs: "mcr.microsoft.com/devcontainers/base:noble" ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli @@ -74,7 +74,7 @@ jobs: matrix: features: ${{ fromJSON(needs.detect-changes.outputs.features) }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli diff --git a/.github/workflows/update-aws-cli-completer-scripts.yml b/.github/workflows/update-aws-cli-completer-scripts.yml index b46d43f39..41d67189f 100644 --- a/.github/workflows/update-aws-cli-completer-scripts.yml +++ b/.github/workflows/update-aws-cli-completer-scripts.yml @@ -12,7 +12,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Run fetch-latest-completer-scripts.sh run: src/aws-cli/scripts/fetch-latest-completer-scripts.sh @@ -42,7 +42,7 @@ jobs: # Bump version and push if [ "$NO_UPDATES" != "true" ] ; then - echo "$(jq --indent 4 '.version = (.version | split(".") | map(tonumber) | .[2] += 1 | join("."))' src/aws-cli/devcontainer-feature.json)" > src/aws-cli/devcontainer-feature.json + echo "$(jq --indent 4 '.version = (.version | split(".") | map(tonumber) | .[2] += 1 | join("."))' src/aws-cli/devcontainer-feature.json)" > src/aws-cli/devcontainer-feature.json git add src/aws-cli/devcontainer-feature.json git commit -m 'Bump version' diff --git a/.github/workflows/update-documentation.yml b/.github/workflows/update-documentation.yml index 2452e0d71..d74d970d5 100644 --- a/.github/workflows/update-documentation.yml +++ b/.github/workflows/update-documentation.yml @@ -14,7 +14,7 @@ jobs: pull-requests: write if: "github.ref == 'refs/heads/main'" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Generate Documentation uses: devcontainers/action@v1 diff --git a/.github/workflows/update-dotnet-install-script.yml b/.github/workflows/update-dotnet-install-script.yml index 3394e8798..604f6880b 100644 --- a/.github/workflows/update-dotnet-install-script.yml +++ b/.github/workflows/update-dotnet-install-script.yml @@ -12,7 +12,7 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Run fetch-latest-dotnet-install.sh run: src/dotnet/scripts/fetch-latest-dotnet-install.sh @@ -45,7 +45,7 @@ jobs: # Bump version and push if [ "$NO_UPDATES" != "true" ] ; then - echo "$(jq --indent 4 '.version = (.version | split(".") | map(tonumber) | .[2] += 1 | join("."))' src/dotnet/devcontainer-feature.json)" > src/dotnet/devcontainer-feature.json + echo "$(jq --indent 4 '.version = (.version | split(".") | map(tonumber) | .[2] += 1 | join("."))' src/dotnet/devcontainer-feature.json)" > src/dotnet/devcontainer-feature.json git add src/dotnet/devcontainer-feature.json echo "$(jq --indent 4 '.version = (.version | split(".") | map(tonumber) | .[2] += 1 | join("."))' src/oryx/devcontainer-feature.json)" > src/oryx/devcontainer-feature.json diff --git a/.github/workflows/validate-metadata-files.yml b/.github/workflows/validate-metadata-files.yml index dbba8e2b4..863418e93 100644 --- a/.github/workflows/validate-metadata-files.yml +++ b/.github/workflows/validate-metadata-files.yml @@ -7,8 +7,8 @@ jobs: validate: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - + - uses: actions/checkout@v4 + - name: "Validate devcontainer-feature.json files" uses: devcontainers/action@v1 with: From b0667c5589bfe1b382c49392c58fe4c9433f1fde Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Tue, 10 Sep 2024 05:27:54 +0530 Subject: [PATCH 038/189] [desktop-lite] - vnc_resolution - set thru env var (#1112) * [desktop-lite] - vnc_resolution - set thru env var * mistake in scenarios.json corrected * small change of function addition in desktop-init.sh file * changes as requested (review pr) * changes as suggested --- src/desktop-lite/devcontainer-feature.json | 2 +- src/desktop-lite/install.sh | 10 ++-- test/desktop-lite/scenarios.json | 27 +++++++++++ ...est_vnc_resolution_as_container_env_var.sh | 47 +++++++++++++++++++ .../test_vnc_resolution_as_remote_env_var.sh | 33 +++++++++++++ 5 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 test/desktop-lite/test_vnc_resolution_as_container_env_var.sh create mode 100644 test/desktop-lite/test_vnc_resolution_as_remote_env_var.sh diff --git a/src/desktop-lite/devcontainer-feature.json b/src/desktop-lite/devcontainer-feature.json index 7c2549a0d..135c812b7 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.4", + "version": "1.2.5", "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.", diff --git a/src/desktop-lite/install.sh b/src/desktop-lite/install.sh index 5060f9210..6e6fff265 100755 --- a/src/desktop-lite/install.sh +++ b/src/desktop-lite/install.sh @@ -300,11 +300,11 @@ user_name="${USERNAME}" group_name="$(id -gn ${USERNAME})" LOG=/tmp/container-init.log -export DBUS_SESSION_BUS_ADDRESS="${DBUS_SESSION_BUS_ADDRESS:-"autolaunch:"}" -export DISPLAY="${DISPLAY:-:1}" -export VNC_RESOLUTION="${VNC_RESOLUTION:-1440x768x16}" -export LANG="${LANG:-"en_US.UTF-8"}" -export LANGUAGE="${LANGUAGE:-"en_US.UTF-8"}" +export DBUS_SESSION_BUS_ADDRESS="\${DBUS_SESSION_BUS_ADDRESS:-"autolaunch:"}" +export DISPLAY="\${DISPLAY:-:1}" +export VNC_RESOLUTION="\${VNC_RESOLUTION:-1440x768x16}" +export LANG="\${LANG:-"en_US.UTF-8"}" +export LANGUAGE="\${LANGUAGE:-"en_US.UTF-8"}" # Execute the command it not already running startInBackgroundIfNotRunning() diff --git a/test/desktop-lite/scenarios.json b/test/desktop-lite/scenarios.json index d86b321fd..ab920ddb9 100644 --- a/test/desktop-lite/scenarios.json +++ b/test/desktop-lite/scenarios.json @@ -4,5 +4,32 @@ "features": { "desktop-lite": {} } + }, + "test_vnc_resolution_as_container_env_var": { + "image": "ubuntu:noble", + "features": { + "desktop-lite": {} + } + , + "containerEnv": { + "VNC_RESOLUTION": "1920x1080x32" + }, + "forwardPorts": [ + 5901, + 6080 + ] + }, + "test_vnc_resolution_as_remote_env_var": { + "image": "ubuntu:noble", + "features": { + "desktop-lite": {} + }, + "remoteEnv": { + "VNC_RESOLUTION": "1920x1080x32" + }, + "forwardPorts": [ + 5901, + 6080 + ] } } \ No newline at end of file diff --git a/test/desktop-lite/test_vnc_resolution_as_container_env_var.sh b/test/desktop-lite/test_vnc_resolution_as_container_env_var.sh new file mode 100644 index 000000000..cc3dd3261 --- /dev/null +++ b/test/desktop-lite/test_vnc_resolution_as_container_env_var.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +GREEN='\033[0;32m'; NC='\033[0m'; RED='\033[0;31m'; YELLOW='\033[0;33m'; + +# Check if xtigervnc & noVnc processes are running after successful installation and initialization +check_process_running() { + port=$1 + # Get process id of process running on specific port + PID=$(lsof -i :$port | awk 'NR==2 {print $2}') + if [ -n "$PID" ]; then + CMD=$(ps -p $PID -o cmd --no-headers) + echo -e "${GREEN}Command running on port $port: ${YELLOW}$CMD${NC}" + else + echo -e "${RED}No process found listening on port $port.${NC}" + exit 1 + fi +} + +check_w_config_resolution() { + configResolution=$1 + actualResolution=$2 + + if echo "$1" | grep -q "$2"; then + echo -e "\n👍👍 ${GREEN}Configured resolution i.e. ${YELLOW}$configResolution${GREEN} has been set as vnc resolution i.e. ${YELLOW}$actualResolution${GREEN} in container.${NC}" + else + echo -e "\n❌❌ ${GREEN}Configured resolution i.e. ${YELLOW}$configResolution${GREEN} couldn't be set as vnc resolution i.e. ${YELLOW}$actualResolution${GREEN} in container.${NC}" + fi +} + +check "Whether xtigervnc is Running" check_process_running 5901 +resolution=$(ps -x -ww | grep Xtigervnc | awk "{for(i=1;i<=NF;i++) if (\$i ~ /-geometry/) {print \$(i+1); exit}}") +check "xtigervnc resolution" bash -c '$resolution' +check_w_config_resolution $VNC_RESOLUTION $resolution +sleep 2 +check "Whether no_vnc is Running" check_process_running 6080 + +check "desktop-init-exists" bash -c "ls /usr/local/share/desktop-init.sh" +check "log-exists" bash -c "ls /tmp/container-init.log" +check "log file contents" bash -c "cat /tmp/container-init.log" + +# Report result +reportResults \ No newline at end of file diff --git a/test/desktop-lite/test_vnc_resolution_as_remote_env_var.sh b/test/desktop-lite/test_vnc_resolution_as_remote_env_var.sh new file mode 100644 index 000000000..18409505c --- /dev/null +++ b/test/desktop-lite/test_vnc_resolution_as_remote_env_var.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Check if xtigervnc & noVnc processes are running after successful installation and initialization +check_process_running() { + port=$1 + # Get process id of process running on specific port + PID=$(lsof -i :$port | awk 'NR==2 {print $2}') + GREEN='\033[0;32m'; NC='\033[0m'; RED='\033[0;31m'; YELLOW='\033[0;33m'; + if [ -n "$PID" ]; then + CMD=$(ps -p $PID -o cmd --no-headers) + echo -e "${GREEN}Command running on port $port: ${YELLOW}$CMD${NC}" + else + echo -e "${RED}No process found listening on port $port.${NC}" + exit 1 + fi +} + +check "Whether xtigervnc is Running" check_process_running 5901 +check "xtigervnc resolution" bash -c 'ps -x -ww | grep Xtigervnc | awk "{for(i=1;i<=NF;i++) if (\$i ~ /-geometry/) {print \$(i+1); exit}}"' +sleep 2 +check "Whether no_vnc is Running" check_process_running 6080 + +check "desktop-init-exists" bash -c "ls /usr/local/share/desktop-init.sh" +check "log-exists" bash -c "ls /tmp/container-init.log" +check "log file contents" bash -c "cat /tmp/container-init.log" + +# Report result +reportResults \ No newline at end of file From d926879cf044a7d2149eee0df4667e264a15454b Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Tue, 17 Sep 2024 02:03:34 +0530 Subject: [PATCH 039/189] [docker-in-docker] - toggle ip6tables settings value as option (#1068) * [docker-in-docker] - toggle ip6tables settings value as option * Update src/docker-in-docker/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * Update src/docker-in-docker/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * ip6tables - can be toggled * changes as requested * change to add test file.. * changes for docker_build_older test passing * misc change * CHANGE * chg * minor change to make tests pass * for sh compatibility * change for version * small change * few imp. changes * few changes * for test passing * minor commit * version added to a test scenario * changes * LOGIC was moved outside the init file for faster initialization times * changes * logic updated ! * chg * default value to be null * changes as suggested in review comments.. * by mistake * another small change * requested changes in comments (review pr) * change as requested * changes as suggested in review comments * Update src/docker-in-docker/install.sh Co-authored-by: Samruddhi Khandale --------- Co-authored-by: Samruddhi Khandale --- .../devcontainer-feature.json | 7 +++++- src/docker-in-docker/install.sh | 23 ++++++++++++++++-- .../dockerIp6tablesDisabledTest.sh | 24 +++++++++++++++++++ test/docker-in-docker/scenarios.json | 9 +++++++ 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 test/docker-in-docker/dockerIp6tablesDisabledTest.sh diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 4897ebf3e..f13b62d2d 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.11.0", + "version": "2.12.0", "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.", @@ -55,6 +55,11 @@ "type": "boolean", "default": true, "description": "Install Compose Switch (provided docker compose is available) which is a replacement to the Compose V1 docker-compose (python) executable. It translates the command line into Compose V2 docker compose then runs the latter." + }, + "disableIp6tables": { + "type": "boolean", + "default": false, + "description": "Disable ip6tables (this option is only applicable for Docker versions 27 and greater)" } }, "entrypoint": "/usr/local/share/docker-init.sh", diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index ee9cb6ee6..c4c098ba8 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -20,6 +20,7 @@ INSTALL_DOCKER_COMPOSE_SWITCH="${INSTALLDOCKERCOMPOSESWITCH:-"true"}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal jammy noble" DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal hirsute impish jammy noble" +DISABLE_IP6_TABLES="${DISABLEIP6TABLES:-false}" # Default: Exit on any failure. set -e @@ -468,6 +469,23 @@ if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then find "${docker_home}" -type d -print0 | xargs -n 1 -0 chmod g+s fi +DOCKER_DEFAULT_IP6_TABLES="" +if [ "$DISABLE_IP6_TABLES" == true ]; then + requested_version="" + # checking whether the version requested either is in semver format or just a number denoting the major version + # and, extracting the major version number out of the two scenarios + semver_regex="^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?(\+([0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*))?$" + if echo "$DOCKER_VERSION" | grep -Eq $semver_regex; then + requested_version=$(echo $DOCKER_VERSION | cut -d. -f1) + elif echo "$DOCKER_VERSION" | grep -Eq "^[1-9][0-9]*$"; then + requested_version=$DOCKER_VERSION + fi + if [ "$DOCKER_VERSION" = "latest" ] || [[ -n "$requested_version" && "$requested_version" -ge 27 ]] ; then + DOCKER_DEFAULT_IP6_TABLES="--ip6tables=false" + echo "(!) As requested, passing '${DOCKER_DEFAULT_IP6_TABLES}'" + fi +fi + tee /usr/local/share/docker-init.sh > /dev/null \ << EOF #!/bin/sh @@ -480,11 +498,12 @@ set -e AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} +DOCKER_DEFAULT_IP6_TABLES=${DOCKER_DEFAULT_IP6_TABLES} EOF tee -a /usr/local/share/docker-init.sh > /dev/null \ << 'EOF' -dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} $(cat << 'INNEREOF' +dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} DOCKER_DEFAULT_IP6_TABLES=${DOCKER_DEFAULT_IP6_TABLES} $(cat << 'INNEREOF' # explicitly remove dockerd and containerd PID file to ensure that it can start properly if it was stopped uncleanly find /run /var/run -iname 'docker*.pid' -delete || : find /run /var/run -iname 'container*.pid' -delete || : @@ -562,7 +581,7 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU fi # Start docker/moby engine - ( dockerd $CUSTOMDNS $DEFAULT_ADDRESS_POOL > /tmp/dockerd.log 2>&1 ) & + ( dockerd $CUSTOMDNS $DEFAULT_ADDRESS_POOL $DOCKER_DEFAULT_IP6_TABLES > /tmp/dockerd.log 2>&1 ) & INNEREOF )" diff --git a/test/docker-in-docker/dockerIp6tablesDisabledTest.sh b/test/docker-in-docker/dockerIp6tablesDisabledTest.sh new file mode 100644 index 000000000..977054ffc --- /dev/null +++ b/test/docker-in-docker/dockerIp6tablesDisabledTest.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +ip6tablesCheck() { + if command -v ip6tables > /dev/null 2>&1; then + if ip6tables -L > /dev/null 2>&1; then + echo "✔️ ip6tables is enabled." + else + echo "❌ ip6tables is disabled." + fi + else + echo "❕ip6tables command not found. ❕" + fi +} + +check "ip6tables" ip6tablesCheck +check "ip6tables check" bash -c "docker network inspect bridge" +check "docker-build" docker build ./ + +reportResults \ No newline at end of file diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index 33333583d..699a1dd79 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -8,6 +8,15 @@ } } }, + "dockerIp6tablesDisabledTest": { + "image": "ubuntu:focal", + "features": { + "docker-in-docker": { + "version": "27.0.3", + "disableIp6tables": true + } + } + }, "dockerDefaultAddressPool": { "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:0-18", "remoteUser": "node", From d1c0cc2476690cb9479cf1b6a3e27211b14cbe88 Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Mon, 16 Sep 2024 21:36:25 +0100 Subject: [PATCH 040/189] Automated documentation update (#1123) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/docker-in-docker/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/docker-in-docker/README.md b/src/docker-in-docker/README.md index b913fa45f..336e458e4 100644 --- a/src/docker-in-docker/README.md +++ b/src/docker-in-docker/README.md @@ -23,6 +23,7 @@ Create child containers *inside* a container, independent from the host's docker | dockerDefaultAddressPool | Define default address pools for Docker networks. e.g. base=192.168.0.0/16,size=24 | string | - | | installDockerBuildx | Install Docker Buildx | boolean | true | | installDockerComposeSwitch | Install Compose Switch (provided docker compose is available) which is a replacement to the Compose V1 docker-compose (python) executable. It translates the command line into Compose V2 docker compose then runs the latter. | boolean | true | +| disableIp6tables | Disable ip6tables (this option is only applicable for Docker versions 27 and greater) | boolean | false | ## Customizations From d849e12748a2e7e44b17ecad9fb386f1e9aa30d3 Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Tue, 24 Sep 2024 05:00:18 +0530 Subject: [PATCH 041/189] [Git-Lfs] - Solution to #1072 issue - Can't download public key (#1124) * [Git-Lfs] - Solution to #1072 issue * bumped patch version for ths feature --- src/git-lfs/devcontainer-feature.json | 2 +- src/git-lfs/install.sh | 26 +++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/git-lfs/devcontainer-feature.json b/src/git-lfs/devcontainer-feature.json index c9e0d9b82..69f83dd86 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.2", + "version": "1.2.3", "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.", diff --git a/src/git-lfs/install.sh b/src/git-lfs/install.sh index f5c473816..554f42bbe 100755 --- a/src/git-lfs/install.sh +++ b/src/git-lfs/install.sh @@ -62,13 +62,6 @@ find_version_from_git_tags() { # Get the list of GPG key servers that are reachable get_gpg_key_servers() { - declare -A keyservers_curl_map=( - ["hkp://keyserver.ubuntu.com"]="http://keyserver.ubuntu.com:11371" - ["hkp://keyserver.ubuntu.com:80"]="http://keyserver.ubuntu.com" - ["hkps://keys.openpgp.org"]="https://keys.openpgp.org" - ["hkp://keyserver.pgp.com"]="http://keyserver.pgp.com:11371" - ) - local curl_args="" local keyserver_reachable=false # Flag to indicate if any keyserver is reachable @@ -76,15 +69,26 @@ get_gpg_key_servers() { curl_args="--proxy ${KEYSERVER_PROXY}" fi - for keyserver in "${!keyservers_curl_map[@]}"; do - local keyserver_curl_url="${keyservers_curl_map[${keyserver}]}" - if curl -s ${curl_args} --max-time 5 ${keyserver_curl_url} > /dev/null; then + test_keyserver() { + local keyserver="$1" + local keyserver_curl_url="$2" + if curl -s ${curl_args} --max-time 5 "${keyserver_curl_url}" > /dev/null; then echo "keyserver ${keyserver}" keyserver_reachable=true else echo "(*) Keyserver ${keyserver} is not reachable." >&2 fi - done + } + + # Explicitly test these in order because Bash v4.4.20 (Ubuntu Bionic) + # enumerates associative array keys in a different order than Bash v5 + test_keyserver "hkp://keyserver.ubuntu.com" "http://keyserver.ubuntu.com:11371" + test_keyserver "hkp://keyserver.ubuntu.com:80" "http://keyserver.ubuntu.com" + test_keyserver "hkp://keyserver.pgp.com" "http://keyserver.pgp.com:11371" + # Test this server last because keys.openpgp.org strips user IDs from keys unless + # the owner gives permission, which causes gpg in Ubuntu Bionic to reject the key + # (https://github.com/devcontainers/features/issues/1055) + test_keyserver "hkps://keys.openpgp.org" "https://keys.openpgp.org" if ! $keyserver_reachable; then echo "(!) No keyserver is reachable." >&2 From 1a6b7152026edf77a5ef39b975fcf2072e3f040a Mon Sep 17 00:00:00 2001 From: Prathamesh Zarkar <159782310+prathameshzarkar9@users.noreply.github.com> Date: Tue, 24 Sep 2024 05:17:20 +0530 Subject: [PATCH 042/189] cuda support for 12.3 .. 12.5 (#1119) * cuda support for 12.3 .. 12.5 * cuda 12.3 to 12.5 support * patch version update * review comments addressed --- src/nvidia-cuda/devcontainer-feature.json | 32 +++++++++------ src/nvidia-cuda/install.sh | 20 +++++++++- 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 | 39 +++++++++++++++++++ 6 files changed, 126 insertions(+), 13 deletions(-) create mode 100644 test/nvidia-cuda/install_cudnn_123_version.sh create mode 100644 test/nvidia-cuda/install_cudnn_124_version.sh create 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 4a0fb0834..b46d7c433 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.2", + "version": "1.1.3", "name": "NVIDIA CUDA", "description": "Installs shared libraries for NVIDIA CUDA.", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/nvidia-cuda", @@ -28,6 +28,9 @@ "cudaVersion": { "type": "string", "proposals": [ + "12.5", + "12.4", + "12.3", "12.2", "12.1", "12.0", @@ -45,15 +48,15 @@ "cudnnVersion": { "type": "string", "proposals": [ - "8.9.5.29", - "8.9.4.25", - "8.9.3.28", - "8.9.2.26", - "8.9.1.23", - "8.9.0.131", - "8.8.1.3", - "8.8.0.121", - "8.7.0.84", + "8.9.5.29", + "8.9.4.25", + "8.9.3.28", + "8.9.2.26", + "8.9.1.23", + "8.9.0.131", + "8.8.1.3", + "8.8.0.121", + "8.7.0.84", "8.6.0.163", "8.5.0.96", "8.4.1.50", @@ -67,7 +70,14 @@ "8.2.1.32", "8.2.0.53", "8.1.1.33", - "8.1.0.77" + "8.1.0.77", + "9.0.0.312", + "9.1.0.70", + "9.1.1.17", + "9.2.0.82", + "9.2.1.18", + "9.3.0.75", + "9.4.0.58" ], "default": "8.6.0.163", "description": "Version of cuDNN to install" diff --git a/src/nvidia-cuda/install.sh b/src/nvidia-cuda/install.sh index 79a7a9a20..37ba7f0f4 100644 --- a/src/nvidia-cuda/install.sh +++ b/src/nvidia-cuda/install.sh @@ -59,6 +59,8 @@ 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 @@ -69,7 +71,15 @@ apt-get install -yq "$cuda_pkg" if [ "$INSTALL_CUDNN" = "true" ]; then # Ensure that the requested version of cuDNN is available AND compatible - cudnn_pkg_version="libcudnn8=${CUDNN_VERSION}-1+cuda${CUDA_VERSION}" + #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 -ge "9" ]] + then + cudnn_pkg_version="libcudnn9-cuda-${major_cuda_version}=${CUDNN_VERSION}-1" + else + cudnn_pkg_version="libcudnn8=${CUDNN_VERSION}-1+cuda${CUDA_VERSION}" + fi + if ! apt-cache show "$cudnn_pkg_version"; then echo "The requested version of cuDNN is not available: cuDNN $CUDNN_VERSION for CUDA $CUDA_VERSION" exit 1 @@ -81,7 +91,13 @@ fi if [ "$INSTALL_CUDNNDEV" = "true" ]; then # Ensure that the requested version of cuDNN development package is available AND compatible - cudnn_dev_pkg_version="libcudnn8-dev=${CUDNN_VERSION}-1+cuda${CUDA_VERSION}" + 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_cudnn_123_version.sh b/test/nvidia-cuda/install_cudnn_123_version.sh new file mode 100644 index 000000000..f331a591f --- /dev/null +++ b/test/nvidia-cuda/install_cudnn_123_version.sh @@ -0,0 +1,16 @@ +#!/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 new file mode 100644 index 000000000..f331a591f --- /dev/null +++ b/test/nvidia-cuda/install_cudnn_124_version.sh @@ -0,0 +1,16 @@ +#!/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 new file mode 100644 index 000000000..f331a591f --- /dev/null +++ b/test/nvidia-cuda/install_cudnn_latest_version.sh @@ -0,0 +1,16 @@ +#!/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 bd73263b3..d2400503b 100644 --- a/test/nvidia-cuda/scenarios.json +++ b/test/nvidia-cuda/scenarios.json @@ -20,5 +20,44 @@ "cudnnVersion": "8.5.0.96" } } + }, + "install_cudnn_123_version": { + "image": "debian", + "features": { + "nvidia-cuda": { + "installCudnn": true, + "installNvtx": true, + "installCudnnDev": true, + "installToolkit": true, + "cudaVersion": "12.3", + "cudnnVersion": "9.4.0.58" + } + } + }, + "install_cudnn_124_version": { + "image": "debian", + "features": { + "nvidia-cuda": { + "installCudnn": true, + "installNvtx": true, + "installCudnnDev": true, + "installToolkit": true, + "cudaVersion": "12.4", + "cudnnVersion": "9.4.0.58" + } + } + }, + "install_cudnn_latest_version": { + "image": "debian", + "features": { + "nvidia-cuda": { + "installCudnn": true, + "installNvtx": true, + "installCudnnDev": true, + "installToolkit": true, + "cudaVersion": "12.5", + "cudnnVersion": "9.4.0.58" + } + } } } From f02df17a38df650a130405bf06a35db49e8a9eff Mon Sep 17 00:00:00 2001 From: Gaurav Saini <147703805+gauravsaini04@users.noreply.github.com> Date: Wed, 25 Sep 2024 00:53:44 +0530 Subject: [PATCH 043/189] [docker-outside-of-docker] - Fix externally-managed-environment python error for "bookworm" - solution to issue #1120 (#1121) * [docker-outside-of-docker] - solution to issue #1120 * minor changes * err fn addition * changes as required * Update src/docker-outside-of-docker/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * remove debugging code * missed this change * reverting changes * keeping docker_compose_install to be false for v1 installs * changes as requested * changes as required --------- Co-authored-by: Samruddhi Khandale --- .../devcontainer-feature.json | 7 +- src/docker-outside-of-docker/install.sh | 111 +++++++++++++----- .../docker_build_compose_fallback.sh | 10 +- .../docker_install_compose_switch.sh | 29 +++++ .../docker_not_install_compose_switch.sh | 29 +++++ .../docker_python_bookworm.sh | 22 ++++ test/docker-outside-of-docker/scenarios.json | 30 +++++ 7 files changed, 202 insertions(+), 36 deletions(-) create mode 100644 test/docker-outside-of-docker/docker_install_compose_switch.sh create mode 100644 test/docker-outside-of-docker/docker_not_install_compose_switch.sh create mode 100644 test/docker-outside-of-docker/docker_python_bookworm.sh diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index 19018ea8e..24b5658dc 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.5.0", + "version": "1.6.0", "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.", @@ -39,6 +39,11 @@ "type": "boolean", "default": true, "description": "Install Docker Buildx" + }, + "installDockerComposeSwitch": { + "type": "boolean", + "default": true, + "description": "Install Compose Switch (provided docker compose is available) which is a replacement to the Compose V1 docker-compose (python) executable. It translates the command line into Compose V2 docker compose then runs the latter." } }, "entrypoint": "/usr/local/share/docker-init.sh", diff --git a/src/docker-outside-of-docker/install.sh b/src/docker-outside-of-docker/install.sh index de5212fe6..5854fc340 100755 --- a/src/docker-outside-of-docker/install.sh +++ b/src/docker-outside-of-docker/install.sh @@ -17,6 +17,7 @@ SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}" TARGET_SOCKET="${TARGET_SOCKET:-"/var/run/docker.sock"}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" INSTALL_DOCKER_BUILDX="${INSTALLDOCKERBUILDX:-"true"}" +INSTALL_DOCKER_COMPOSE_SWITCH="${INSTALLDOCKERCOMPOSESWITCH:-"true"}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal jammy noble" @@ -27,6 +28,11 @@ set -e # Clean up rm -rf /var/lib/apt/lists/* +# Setup STDERR. +err() { + echo "(!) $*" >&2 +} + 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 @@ -177,7 +183,7 @@ install_compose_switch_fallback() { echo -e "\n(!) Failed to fetch the latest artifacts for compose-switch v${compose_switch_version}..." get_previous_version "${compose_switch_url}" "${repo_url}" compose_switch_version echo -e "\nAttempting to install v${compose_switch_version}" - curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/docker-compose + curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch } # Ensure apt is in non-interactive to avoid prompts @@ -273,6 +279,19 @@ if [ "${USE_MOBY}" = "true" ]; then fi fi + +docker_home="/usr/libexec/docker" +cli_plugins_dir="${docker_home}/cli-plugins" + +install_compose_fallback(){ + local url=$1 + local repo_url=$(get_github_api_repo_url "$url") + echo -e "\n(!) Failed to fetch the latest artifacts for docker-compose v${compose_version}..." + get_previous_version "${url}" "${repo_url}" compose_version + echo -e "\nAttempting to install v${compose_version}" + curl -fsSL "https://github.com/docker/compose/releases/download/v${compose_version}/docker-compose-linux-${target_compose_arch}" -o ${docker_compose_path} +} + # Install Docker / Moby CLI if not already installed if type docker > /dev/null 2>&1; then echo "Docker / Moby CLI already installed." @@ -302,44 +321,82 @@ fi # If 'docker-compose' command is to be included if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then + case "${architecture}" in + amd64) target_compose_arch=x86_64 ;; + arm64) target_compose_arch=aarch64 ;; + *) + echo "(!) Docker outside of docker does not support machine architecture '$architecture'. Please use an x86-64 or ARM64 machine." + exit 1 + esac + docker_compose_path="/usr/local/bin/docker-compose" # Install Docker Compose if not already installed and is on a supported architecture if type docker-compose > /dev/null 2>&1; then echo "Docker Compose already installed." elif [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then - TARGET_COMPOSE_ARCH="$(uname -m)" - if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then - TARGET_COMPOSE_ARCH="x86_64" - fi - if [ "${TARGET_COMPOSE_ARCH}" != "x86_64" ]; then + err "The final Compose V1 release, version 1.29.2, was May 10, 2021. These packages haven't received any security updates since then. Use at your own risk." + INSTALL_DOCKER_COMPOSE_SWITCH="false" + + if [ "${target_compose_arch}" = "x86_64" ]; then + echo "(*) Installing docker compose v1..." + curl -fsSL "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64" -o ${docker_compose_path} + chmod +x ${docker_compose_path} + + # Download the SHA256 checksum + DOCKER_COMPOSE_SHA256="$(curl -sSL "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-Linux-x86_64.sha256" | awk '{print $1}')" + echo "${DOCKER_COMPOSE_SHA256} ${docker_compose_path}" > docker-compose.sha256sum + sha256sum -c docker-compose.sha256sum --ignore-missing + elif [ "${VERSION_CODENAME}" = "bookworm" ]; then + err "Docker compose v1 is unavailable for 'bookworm' on Arm64. Kindly switch to use v2" + exit 1 + else # Use pip to get a version that runs on this architecture check_packages python3-minimal python3-pip libffi-dev python3-venv - export PIPX_HOME=/usr/local/pipx - mkdir -p ${PIPX_HOME} - export PIPX_BIN_DIR=/usr/local/bin - export PYTHONUSERBASE=/tmp/pip-tmp - export PIP_CACHE_DIR=/tmp/pip-tmp/cache - pipx_bin=pipx - if ! type pipx > /dev/null 2>&1; then - pip3 install --disable-pip-version-check --no-cache-dir --user pipx - pipx_bin=/tmp/pip-tmp/bin/pipx - fi - ${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' docker-compose - rm -rf /tmp/pip-tmp - else - compose_v1_version="1" - find_version_from_git_tags compose_v1_version "https://github.com/docker/compose" "tags/" - echo "(*) Installing docker-compose ${compose_v1_version}..." - curl -fsSL "https://github.com/docker/compose/releases/download/${compose_v1_version}/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose - chmod +x /usr/local/bin/docker-compose + echo "(*) Installing docker compose v1 via pip..." + export PYTHONUSERBASE=/usr/local + pip3 install --disable-pip-version-check --no-cache-dir --user "Cython<3.0" pyyaml wheel docker-compose --no-build-isolation fi else - echo "(*) Installing compose-switch as docker-compose..." + compose_version=${DOCKER_DASH_COMPOSE_VERSION#v} + docker_compose_url="https://github.com/docker/compose" + 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 + } + chmod +x ${docker_compose_path} + + # Download the SHA256 checksum + DOCKER_COMPOSE_SHA256="$(curl -sSL "https://github.com/docker/compose/releases/download/v${compose_version}/docker-compose-linux-${target_compose_arch}.sha256" | awk '{print $1}')" + echo "${DOCKER_COMPOSE_SHA256} ${docker_compose_path}" > docker-compose.sha256sum + sha256sum -c docker-compose.sha256sum --ignore-missing + + mkdir -p ${cli_plugins_dir} + cp ${docker_compose_path} ${cli_plugins_dir} + fi +fi + +# Install docker-compose switch if not already installed - https://github.com/docker/compose-switch#manual-installation +if [ "${INSTALL_DOCKER_COMPOSE_SWITCH}" = "true" ] && ! type compose-switch > /dev/null 2>&1; then + if type docker-compose > /dev/null 2>&1; then + echo "(*) Installing compose-switch..." + current_compose_path="$(which docker-compose)" + target_compose_path="$(dirname "${current_compose_path}")/docker-compose-v1" compose_switch_version="latest" compose_switch_url="https://github.com/docker/compose-switch" find_version_from_git_tags compose_switch_version "${compose_switch_url}" - curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/docker-compose || install_compose_switch_fallback "${compose_switch_url}" - chmod +x /usr/local/bin/docker-compose + curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch || install_compose_switch_fallback "${compose_switch_url}" + chmod +x /usr/local/bin/compose-switch # TODO: Verify checksum once available: https://github.com/docker/compose-switch/issues/11 + # Setup v1 CLI as alternative in addition to compose-switch (which maps to v2) + mv "${current_compose_path}" "${target_compose_path}" + update-alternatives --install ${docker_compose_path} docker-compose /usr/local/bin/compose-switch 99 + update-alternatives --install ${docker_compose_path} docker-compose "${target_compose_path}" 1 + else + err "Skipping installation of compose-switch as docker compose is unavailable..." fi fi 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 193d79d28..7f3a6f1dd 100644 --- a/test/docker-outside-of-docker/docker_build_compose_fallback.sh +++ b/test/docker-outside-of-docker/docker_build_compose_fallback.sh @@ -112,20 +112,14 @@ 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 [[ $mode == 'mode1' ]]; then - message="API rate limit exceeded" - else - message="" - fi - if [[ $message == "API rate limit exceeded"* ]]; then + 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" diff --git a/test/docker-outside-of-docker/docker_install_compose_switch.sh b/test/docker-outside-of-docker/docker_install_compose_switch.sh new file mode 100644 index 000000000..77f7bbef6 --- /dev/null +++ b/test/docker-outside-of-docker/docker_install_compose_switch.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Check if compose-switch is installed +check_compose_switch_installation() { + COMPOSE_SWITCH_BINARY="/usr/local/bin/compose-switch" + # Check if the binary exists + if [ ! -x "$COMPOSE_SWITCH_BINARY" ]; then + echo "compose-switch binary not found at $COMPOSE_SWITCH_BINARY" + exit 1 + else + compose_switch_version=$("$COMPOSE_SWITCH_BINARY" --version | awk '{print $4}') + if [ -z "$compose_switch_version" ]; then + echo "Unable to determine compose-switch version" + else + echo "compose-switch version: $compose_switch_version" + echo -e "\n✅ compose-switch is installed" + fi + fi +} + +check "Check whether compose-switch is installed" check_compose_switch_installation + +reportResults + \ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_not_install_compose_switch.sh b/test/docker-outside-of-docker/docker_not_install_compose_switch.sh new file mode 100644 index 000000000..7160ef7ce --- /dev/null +++ b/test/docker-outside-of-docker/docker_not_install_compose_switch.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Check if compose-switch is installed +check_compose_switch_installation() { + COMPOSE_SWITCH_BINARY="/usr/local/bin/compose-switch" + # Check if the binary exists + if [ ! -x "$COMPOSE_SWITCH_BINARY" ]; then + echo "compose-switch binary not found at $COMPOSE_SWITCH_BINARY" + echo -e "\n❎ compose-switch is not installed" + else + compose_switch_version=$("$COMPOSE_SWITCH_BINARY" --version | awk '{print $4}') + if [ -z "$compose_switch_version" ]; then + echo "Unable to determine compose-switch version" + else + echo "compose-switch version: $compose_switch_version" + fi + exit 1 + fi +} + +check "Check whether compose-switch is installed" check_compose_switch_installation + +reportResults + \ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_python_bookworm.sh b/test/docker-outside-of-docker/docker_python_bookworm.sh new file mode 100644 index 000000000..21ad3b7a4 --- /dev/null +++ b/test/docker-outside-of-docker/docker_python_bookworm.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker-buildx" bash -c "docker buildx version" +check "docker-buildx-path" bash -c "ls -la /usr/libexec/docker/cli-plugins/docker-buildx" + +check "docker-buildx" docker buildx version +check "docker-build" docker build ./ + +check "installs docker-compose v2 install" bash -c "type docker-compose" +check "docker compose" bash -c "docker compose version | grep -E '2.[0-9]+.[0-9]+'" +check "docker-compose" bash -c "docker-compose --version | grep -E '2.[0-9]+.[0-9]+'" + +check "installs compose-switch as docker-compose" bash -c "[[ -f /usr/local/bin/docker-compose ]]" + +# Report result +reportResults \ No newline at end of file diff --git a/test/docker-outside-of-docker/scenarios.json b/test/docker-outside-of-docker/scenarios.json index 6239a1ada..7d3301f12 100644 --- a/test/docker-outside-of-docker/scenarios.json +++ b/test/docker-outside-of-docker/scenarios.json @@ -142,5 +142,35 @@ "mobyBuildxVersion": "0.12.0" } } + }, + "docker_python_bookworm": { + "image": "mcr.microsoft.com/devcontainers/base:bookworm", + "features": { + "docker-outside-of-docker": { + "moby": true, + "installDockerBuildx": true, + "dockerDashComposeVersion": "v2" + } + } + }, + "docker_not_install_compose_switch": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "dockerDashComposeVersion": "latest", + "installDockerComposeSwitch": false + } + }, + "containerUser": "vscode" + }, + "docker_install_compose_switch": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "dockerDashComposeVersion": "latest", + "installDockerComposeSwitch": true + } + }, + "containerUser": "vscode" } } From 0be79410981d50c2b5fa35e97f4af8a1a4f4727d Mon Sep 17 00:00:00 2001 From: Dev containers Bot <126614555+devcontainers-bot@users.noreply.github.com> Date: Tue, 24 Sep 2024 21:36:19 +0100 Subject: [PATCH 044/189] Automated documentation update (#1129) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/docker-outside-of-docker/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/docker-outside-of-docker/README.md b/src/docker-outside-of-docker/README.md index 18fe79573..04e7260f6 100644 --- a/src/docker-outside-of-docker/README.md +++ b/src/docker-outside-of-docker/README.md @@ -22,6 +22,7 @@ Re-use the host docker socket, adding the Docker CLI to a container. Feature inv | mobyBuildxVersion | Install a specific version of moby-buildx when using Moby | string | latest | | dockerDashComposeVersion | Compose version to use for docker-compose (v1 or v2 or none) | string | v2 | | installDockerBuildx | Install Docker Buildx | boolean | true | +| installDockerComposeSwitch | Install Compose Switch (provided docker compose is available) which is a replacement to the Compose V1 docker-compose (python) executable. It translates the command line into Compose V2 docker compose then runs the latter. | boolean | true | ## Customizations From 5077a2cb2c9ab9e2eb82b569c3ec27a9eedc4e5e Mon Sep 17 00:00:00 2001 From: Prathamesh Zarkar <159782310+prathameshzarkar9@users.noreply.github.com> Date: Thu, 26 Sep 2024 03:38:25 +0530 Subject: [PATCH 045/189] [Java] Add JDK 22 support (#1102) * Add JDK 22 support * bump patch version * removed exit added for debugging * added one condition before changing the JDK_DISTRO * version set to 21 and jdk_distro open fixed * failed test cases fixed * fixing install_type issue if not java * yum update with epel-release install * explicit test case writen to validate jdk 22 works fine * moved check_packages to the start * INSTALL_CMD moved to start * variable changed --- src/java/devcontainer-feature.json | 2 +- src/java/install.sh | 166 ++++++++++++++-------------- test/java/install_latest_version.sh | 15 +++ test/java/scenarios.json | 8 ++ 4 files changed, 108 insertions(+), 83 deletions(-) create mode 100644 test/java/install_latest_version.sh diff --git a/src/java/devcontainer-feature.json b/src/java/devcontainer-feature.json index 51e214a25..7a9caa924 100644 --- a/src/java/devcontainer-feature.json +++ b/src/java/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "java", - "version": "1.6.0", + "version": "1.6.1", "name": "Java (via SDKMAN!)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/java", "description": "Installs Java, SDKMAN! (if not installed), and needed dependencies.", diff --git a/src/java/install.sh b/src/java/install.sh index 277681fec..47f0e8559 100644 --- a/src/java/install.sh +++ b/src/java/install.sh @@ -53,14 +53,6 @@ else exit 1 fi -if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then - # As of 1 July 2024, mirrorlist.centos.org no longer exists. - # Update the repo files to reference vault.centos.org. - sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo - sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo - sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo -fi - # Setup INSTALL_CMD & PKG_MGR_CMD if type apt-get > /dev/null 2>&1; then PKG_MGR_CMD=apt-get @@ -79,6 +71,67 @@ else exit 1 fi +pkg_manager_update() { + case $ADJUSTED_ID in + debian) + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + echo "Running apt-get update..." + ${PKG_MGR_CMD} update -y + fi + ;; + rhel) + if [ ${PKG_MGR_CMD} = "microdnf" ]; then + if [ "$(ls /var/cache/yum/* 2>/dev/null | wc -l)" = 0 ]; then + echo "Running ${PKG_MGR_CMD} makecache ..." + ${PKG_MGR_CMD} makecache + fi + else + if [ "$(ls /var/cache/${PKG_MGR_CMD}/* 2>/dev/null | wc -l)" = 0 ]; then + echo "Running ${PKG_MGR_CMD} check-update ..." + set +e + stderr_messages=$(${PKG_MGR_CMD} -q check-update 2>&1) + rc=$? + # centos 7 sometimes returns a status of 100 when it apears to work. + if [ $rc != 0 ] && [ $rc != 100 ]; then + echo "(Error) ${PKG_MGR_CMD} check-update produced the following error message(s):" + echo "${stderr_messages}" + exit 1 + fi + set -e + fi + fi + ;; + esac +} + +# Checks if packages are installed and installs them if not +check_packages() { + case ${ADJUSTED_ID} in + debian) + if ! dpkg -s "$@" > /dev/null 2>&1; then + pkg_manager_update + ${INSTALL_CMD} "$@" + fi + ;; + rhel) + if ! rpm -q "$@" > /dev/null 2>&1; then + pkg_manager_update + ${INSTALL_CMD} "$@" + fi + ;; + esac +} + +if [ "${ADJUSTED_ID}" = "rhel" ] && [ "${VERSION_CODENAME-}" = "centos7" ]; then + # As of 1 July 2024, mirrorlist.centos.org no longer exists. + # Update the repo files to reference vault.centos.org. + sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo + sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo + sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo + yum update -y + check_packages epel-release +fi + # Clean up clean_up() { local pkg @@ -95,7 +148,6 @@ clean_up() { ;; esac } -clean_up # Ensure that login shells get the correct path if the user updated the PATH using ENV. rm -f /etc/profile.d/00-restore-env.sh @@ -143,80 +195,33 @@ updaterc() { fi } - -pkg_manager_update() { - case $ADJUSTED_ID in - debian) - if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then - echo "Running apt-get update..." - ${PKG_MGR_CMD} update -y - fi - ;; - rhel) - if [ ${PKG_MGR_CMD} = "microdnf" ]; then - if [ "$(ls /var/cache/yum/* 2>/dev/null | wc -l)" = 0 ]; then - echo "Running ${PKG_MGR_CMD} makecache ..." - ${PKG_MGR_CMD} makecache - fi - else - if [ "$(ls /var/cache/${PKG_MGR_CMD}/* 2>/dev/null | wc -l)" = 0 ]; then - echo "Running ${PKG_MGR_CMD} check-update ..." - set +e - stderr_messages=$(${PKG_MGR_CMD} -q check-update 2>&1) - rc=$? - # centos 7 sometimes returns a status of 100 when it apears to work. - if [ $rc != 0 ] && [ $rc != 100 ]; then - echo "(Error) ${PKG_MGR_CMD} check-update produced the following error message(s):" - echo "${stderr_messages}" - exit 1 - fi - set -e - fi - fi - ;; - esac -} - -# Checks if packages are installed and installs them if not -check_packages() { - case ${ADJUSTED_ID} in - debian) - if ! dpkg -s "$@" > /dev/null 2>&1; then - pkg_manager_update - ${INSTALL_CMD} "$@" - fi - ;; - rhel) - if ! rpm -q "$@" > /dev/null 2>&1; then - pkg_manager_update - ${INSTALL_CMD} "$@" - fi - ;; - esac -} - -# Use Microsoft JDK for everything but JDK 8 and 18 (unless specified differently with jdkDistro option) -get_jdk_distro() { - VERSION="$1" - if [ "${JDK_DISTRO}" = "ms" ]; then - if echo "${VERSION}" | grep -E '^8([\s\.]|$)' > /dev/null 2>&1 || echo "${VERSION}" | grep -E '^18([\s\.]|$)' > /dev/null 2>&1; then - JDK_DISTRO="tem" - fi - fi -} - find_version_list() { prefix="$1" suffix="$2" install_type=$3 ifLts="$4" version_list=$5 + java_ver=$6 + + check_packages jq + all_versions=$(curl -s https://api.adoptium.net/v3/info/available_releases) if [ "${ifLts}" = "true" ]; then - all_lts_versions=$(curl -s https://api.adoptium.net/v3/info/available_releases) - major_version=$(echo "$all_lts_versions" | jq -r '.most_recent_lts') - regex="${prefix}\\K${major_version}\\.?[0-9]*\\.?[0-9]*${suffix}" - else + major_version=$(echo "$all_versions" | jq -r '.most_recent_lts') + elif [ "${java_ver}" = "latest" ]; then + major_version=$(echo "$all_versions" | jq -r '.most_recent_feature_release') + else + major_version=$(echo "$java_ver" | cut -d '.' -f 1) + fi + + if [ "${JDK_DISTRO}" = "ms" ]; then + if [ "${major_version}" = "8" ] || [ "${major_version}" = "18" ] || [ "${major_version}" = "22" ]; then + JDK_DISTRO="tem" + fi + fi + if [ "${install_type}" != "java" ]; then regex="${prefix}\\K[0-9]+\\.?[0-9]*\\.?[0-9]*${suffix}" + else + regex="${prefix}\\K${major_version}\\.?[0-9]*\\.?[0-9]*${suffix}${JDK_DISTRO}\\s*" fi declare -g ${version_list}="$(su ${USERNAME} -c ". \${SDKMAN_DIR}/bin/sdkman-init.sh && sdk list ${install_type} 2>&1 | grep -oP \"${regex}\" | tr -d ' ' | sort -rV")" } @@ -237,13 +242,12 @@ sdk_install() { elif [[ "${pkg_vals}" =~ "${install_type}" ]] && [ "${requested_version}" = "latest" ]; then requested_version="" elif [ "${requested_version}" = "lts" ]; then - check_packages jq - find_version_list "$prefix" "$suffix" "$install_type" "true" version_list + find_version_list "$prefix" "$suffix" "$install_type" "true" version_list "${requested_version}" requested_version="$(echo "${version_list}" | head -n 1)" elif echo "${requested_version}" | grep -oE "${full_version_check}" > /dev/null 2>&1; then echo "${requested_version}" else - find_version_list "$prefix" "$suffix" "$install_type" "false" version_list + find_version_list "$prefix" "$suffix" "$install_type" "false" version_list "${requested_version}" if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ]; then requested_version="$(echo "${version_list}" | head -n 1)" else @@ -301,8 +305,7 @@ if [ ! -d "${SDKMAN_DIR}" ]; then updaterc "export SDKMAN_DIR=${SDKMAN_DIR}\n. \${SDKMAN_DIR}/bin/sdkman-init.sh" fi -get_jdk_distro ${JAVA_VERSION} -sdk_install java ${JAVA_VERSION} "\\s*" "(\\.[a-z0-9]+)*-${JDK_DISTRO}\\s*" ".*-[a-z]+$" "true" +sdk_install java ${JAVA_VERSION} "\\s*" "(\\.[a-z0-9]+)*-" ".*-[a-z]+$" "true" # Additional java versions to be installed but not be set as default. if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then @@ -310,8 +313,7 @@ if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then IFS="," read -a additional_versions <<< "$ADDITIONAL_VERSIONS" for version in "${additional_versions[@]}"; do - get_jdk_distro ${version} - sdk_install java ${version} "\\s*" "(\\.[a-z0-9]+)*-${JDK_DISTRO}\\s*" ".*-[a-z]+$" "false" + sdk_install java ${version} "\\s*" "(\\.[a-z0-9]+)*-" ".*-[a-z]+$" "false" done IFS=$OLDIFS su ${USERNAME} -c ". ${SDKMAN_DIR}/bin/sdkman-init.sh && sdk default java ${JAVA_VERSION}" diff --git a/test/java/install_latest_version.sh b/test/java/install_latest_version.sh new file mode 100644 index 000000000..a45d5e0b0 --- /dev/null +++ b/test/java/install_latest_version.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +echo 'public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }' > HelloWorld.java +javac HelloWorld.java + +check "hello world" /bin/bash -c "java HelloWorld | grep "Hello, World!"" +check "java version latest installed" grep "22.0.2" <(java --version) + +# Report result +reportResults diff --git a/test/java/scenarios.json b/test/java/scenarios.json index 538d77972..f28fceb41 100644 --- a/test/java/scenarios.json +++ b/test/java/scenarios.json @@ -8,6 +8,14 @@ } } }, + "install_latest_version": { + "image": "ubuntu:focal", + "features": { + "java": { + "version": "latest" + } + } + }, "install_lts_version": { "image": "ubuntu:focal", "features": { From 302fecab063c63a4f3b6de1bbba408f4b896f7cd Mon Sep 17 00:00:00 2001 From: Flo Date: Thu, 26 Sep 2024 01:35:41 +0200 Subject: [PATCH 046/189] feat(nix): Enable persistent volume for shared nix-store (#1127) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(nix): Enable persistent volume for shared nix-store * fix: Wrong mount * fix: Switch to persistent volumes per devcontainer, fixes renamed nix package used in test * Update src/nix/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * fix: Bump version --------- Co-authored-by: Flo Müller Co-authored-by: Samruddhi Khandale --- src/nix/devcontainer-feature.json | 14 +++- src/nix/install.sh | 104 ++++++++++++++---------------- test/nix/scenarios.json | 1 - 3 files changed, 62 insertions(+), 57 deletions(-) diff --git a/src/nix/devcontainer-feature.json b/src/nix/devcontainer-feature.json index 0e37efed2..7fadd63fa 100644 --- a/src/nix/devcontainer-feature.json +++ b/src/nix/devcontainer-feature.json @@ -1,13 +1,16 @@ { "id": "nix", - "version": "1.2.0", + "version": "1.3.0", "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.", "options": { "version": { "type": "string", - "proposals": ["latest", "2.11"], + "proposals": [ + "latest", + "2.11" + ], "default": "latest", "description": "Version of Nix to install." }, @@ -43,5 +46,12 @@ "containerEnv": { "PATH": "/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:${PATH}" }, + "mounts": [ + { + "source": "nix-store-${devcontainerId}", + "target": "/nix", + "type": "volume" + } + ], "entrypoint": "/usr/local/share/nix-entrypoint.sh" } diff --git a/src/nix/install.sh b/src/nix/install.sh index 5b8fe8f28..0030c2b18 100755 --- a/src/nix/install.sh +++ b/src/nix/install.sh @@ -23,67 +23,63 @@ fi detect_user USERNAME -if [ -e "/nix" ]; then - echo "(!) Nix is already installed! Skipping installation." -else - if [ "${USERNAME}" = "root" ] && [ "${MULTIUSER}" != "true" ]; then - echo "(!) A single user install is not allowed for root. Add a non-root user to your image or set multiUser to true in your feature configuration." - exit 1 - fi +if [ "${USERNAME}" = "root" ] && [ "${MULTIUSER}" != "true" ]; then + echo "(!) A single user install is not allowed for root. Add a non-root user to your image or set multiUser to true in your feature configuration." + exit 1 +fi - # Verify dependencies - apt_get_update_if_exists - check_command curl "curl ca-certificates" "curl ca-certificates" "curl ca-certificates" - check_command gpg2 gnupg2 gnupg gnupg2 - check_command dirmngr dirmngr dirmngr dirmngr - check_command xz xz-utils xz xz - check_command git git git git - check_command xargs findutils findutils findutils +# Verify dependencies +apt_get_update_if_exists +check_command curl "curl ca-certificates" "curl ca-certificates" "curl ca-certificates" +check_command gpg2 gnupg2 gnupg gnupg2 +check_command dirmngr dirmngr dirmngr dirmngr +check_command xz xz-utils xz xz +check_command git git git git +check_command xargs findutils findutils findutils - # Determine version - find_version_from_git_tags VERSION https://github.com/NixOS/nix "tags/" +# Determine version +find_version_from_git_tags VERSION https://github.com/NixOS/nix "tags/" - # Download and verify install per https://nixos.org/download.html#nix-verify-installation - tmpdir="$(mktemp -d)" - echo "(*) Downloading Nix installer..." - set +e +# Download and verify install per https://nixos.org/download.html#nix-verify-installation +tmpdir="$(mktemp -d)" +echo "(*) Downloading Nix installer..." +set +e +curl -sSLf -o "${tmpdir}/install-nix" https://releases.nixos.org/nix/nix-${VERSION}/install +exit_code=$? +set -e +if [ "$exit_code" != "0" ]; then + # Handle situation where git tags are ahead of what was is available to actually download + echo "(!) Nix version ${VERSION} failed to download. Attempting to fall back one version to retry..." + find_prev_version_from_git_tags VERSION https://github.com/NixOS/nix "tags/" curl -sSLf -o "${tmpdir}/install-nix" https://releases.nixos.org/nix/nix-${VERSION}/install - exit_code=$? - set -e - if [ "$exit_code" != "0" ]; then - # Handle situation where git tags are ahead of what was is available to actually download - echo "(!) Nix version ${VERSION} failed to download. Attempting to fall back one version to retry..." - find_prev_version_from_git_tags VERSION https://github.com/NixOS/nix "tags/" - curl -sSLf -o "${tmpdir}/install-nix" https://releases.nixos.org/nix/nix-${VERSION}/install - fi - cd "${FEATURE_DIR}" +fi +cd "${FEATURE_DIR}" - # Do a multi or single-user setup based on feature config - if [ "${MULTIUSER}" = "true" ]; then - echo "(*) Performing multi-user install..." - sh "${tmpdir}/install-nix" --daemon - else - home_dir="$(eval echo ~${USERNAME})" - if [ ! -e "${home_dir}" ]; then - echo "(!) Home directory ${home_dir} does not exist for ${USERNAME}. Nix install will fail." - exit 1 - fi - echo "(*) Performing single-user install..." - echo -e "\n**NOTE: Nix will only work for user ${USERNAME} on Linux if the host machine user's UID is $(id -u ${USERNAME}). You will need to chown /nix otherwise.**\n" - # Install per https://nixos.org/manual/nix/stable/installation/installing-binary.html#single-user-installation - mkdir -p /nix - chown ${USERNAME} /nix ${tmpdir} - su ${USERNAME} -c "sh \"${tmpdir}/install-nix\" --no-daemon --no-modify-profile" - # nix installer does not update ~/.bashrc, and USER may or may not be defined, so update rc/profile files directly to handle that - snippet=' - if [ "${PATH#*$HOME/.nix-profile/bin}" = "${PATH}" ]; then if [ -z "$USER" ]; then USER=$(whoami); fi; . $HOME/.nix-profile/etc/profile.d/nix.sh; fi - ' - update_rc_file "$home_dir/.bashrc" "${snippet}" - update_rc_file "$home_dir/.zshenv" "${snippet}" - update_rc_file "$home_dir/.profile" "${snippet}" +# Do a multi or single-user setup based on feature config +if [ "${MULTIUSER}" = "true" ]; then + echo "(*) Performing multi-user install..." + sh "${tmpdir}/install-nix" --daemon +else + home_dir="$(eval echo ~${USERNAME})" + if [ ! -e "${home_dir}" ]; then + echo "(!) Home directory ${home_dir} does not exist for ${USERNAME}. Nix install will fail." + exit 1 fi - rm -rf "${tmpdir}" "/tmp/tmp-gnupg" + echo "(*) Performing single-user install..." + echo -e "\n**NOTE: Nix will only work for user ${USERNAME} on Linux if the host machine user's UID is $(id -u ${USERNAME}). You will need to chown /nix otherwise.**\n" + # Install per https://nixos.org/manual/nix/stable/installation/installing-binary.html#single-user-installation + mkdir -p /nix + chown ${USERNAME} /nix ${tmpdir} + su ${USERNAME} -c "sh \"${tmpdir}/install-nix\" --no-daemon --no-modify-profile" + # nix installer does not update ~/.bashrc, and USER may or may not be defined, so update rc/profile files directly to handle that + snippet=' + if [ "${PATH#*$HOME/.nix-profile/bin}" = "${PATH}" ]; then if [ -z "$USER" ]; then USER=$(whoami); fi; . $HOME/.nix-profile/etc/profile.d/nix.sh; fi + ' + update_rc_file "$home_dir/.bashrc" "${snippet}" + update_rc_file "$home_dir/.zshenv" "${snippet}" + update_rc_file "$home_dir/.profile" "${snippet}" fi +rm -rf "${tmpdir}" "/tmp/tmp-gnupg" # Set nix config mkdir -p /etc/nix diff --git a/test/nix/scenarios.json b/test/nix/scenarios.json index 80ead7ff6..dac5624f1 100644 --- a/test/nix/scenarios.json +++ b/test/nix/scenarios.json @@ -91,7 +91,6 @@ } } }, - "flake": { "image": "mcr.microsoft.com/devcontainers/base:ubuntu", "remoteUser": "vscode", From 68871f5cd6a1f22fd66caca00f82e5c7eb0ea9c3 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Mon, 7 Oct 2024 08:54:19 -0700 Subject: [PATCH 047/189] Add 'contents: write' permission to release workflow (#1142) I suspect this will fix the git tagging issue reported in https://github.com/devcontainers/features/issues/1122 --- .github/workflows/release.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 22297641a..6890f5ae5 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,6 +11,7 @@ jobs: runs-on: ubuntu-latest permissions: packages: write + contents: write steps: - uses: actions/checkout@v4 @@ -20,4 +21,4 @@ jobs: publish-features: "true" base-path-to-features: "./src" env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From d23166286d8123410be6c41144669dcd8e4c8eea Mon Sep 17 00:00:00 2001 From: Vatsal Gupta <40350810+gvatsal60@users.noreply.github.com> Date: Wed, 9 Oct 2024 00:32:21 +0530 Subject: [PATCH 048/189] Fix: Handle case where Python version is already installed (#222) (#1115) * Fix: Handle case where Python version is already installed in dev container (#617) * Incorporated Review Comment: Version exist handling --- src/python/install.sh | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/python/install.sh b/src/python/install.sh index 7e30ea041..ead55cc8a 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -465,16 +465,18 @@ install_prev_vers_cpython() { install_cpython() { VERSION=$1 INSTALL_PATH="${PYTHON_INSTALL_PATH}/${VERSION}" + + # Check if the specified Python version is already installed if [ -d "${INSTALL_PATH}" ]; then echo "(!) Python version ${VERSION} already exists." - exit 1 + else + mkdir -p /tmp/python-src ${INSTALL_PATH} + cd /tmp/python-src + cpython_tgz_filename="Python-${VERSION}.tgz" + cpython_tgz_url="https://www.python.org/ftp/python/${VERSION}/${cpython_tgz_filename}" + echo "Downloading ${cpython_tgz_filename}..." + curl -sSL -o "/tmp/python-src/${cpython_tgz_filename}" "${cpython_tgz_url}" fi - mkdir -p /tmp/python-src ${INSTALL_PATH} - cd /tmp/python-src - cpython_tgz_filename="Python-${VERSION}.tgz" - cpython_tgz_url="https://www.python.org/ftp/python/${VERSION}/${cpython_tgz_filename}" - echo "Downloading ${cpython_tgz_filename}..." - curl -sSL -o "/tmp/python-src/${cpython_tgz_filename}" "${cpython_tgz_url}" } install_from_source() { @@ -560,20 +562,20 @@ install_using_oryx() { VERSION=$1 INSTALL_PATH="${PYTHON_INSTALL_PATH}/${VERSION}" + # Check if the specified Python version is already installed if [ -d "${INSTALL_PATH}" ]; then echo "(!) Python version ${VERSION} already exists." - exit 1 - fi - - # The python install root path may not exist, so create it - mkdir -p "${PYTHON_INSTALL_PATH}" - oryx_install "python" "${VERSION}" "${INSTALL_PATH}" "lib" || return 1 + else + # The python install root path may not exist, so create it + mkdir -p "${PYTHON_INSTALL_PATH}" + oryx_install "python" "${VERSION}" "${INSTALL_PATH}" "lib" || return 1 - ln -s "${INSTALL_PATH}/bin/idle3" "${INSTALL_PATH}/bin/idle" - ln -s "${INSTALL_PATH}/bin/pydoc3" "${INSTALL_PATH}/bin/pydoc" - ln -s "${INSTALL_PATH}/bin/python3-config" "${INSTALL_PATH}/bin/python-config" + ln -s "${INSTALL_PATH}/bin/idle3" "${INSTALL_PATH}/bin/idle" + ln -s "${INSTALL_PATH}/bin/pydoc3" "${INSTALL_PATH}/bin/pydoc" + ln -s "${INSTALL_PATH}/bin/python3-config" "${INSTALL_PATH}/bin/python-config" - add_symlink + add_symlink + fi } sudo_if() { From 88253ef4ce3827c381ff1a1e6c37d47396bc3232 Mon Sep 17 00:00:00 2001 From: Prathamesh Zarkar <159782310+prathameshzarkar9@users.noreply.github.com> Date: Fri, 18 Oct 2024 03:32:07 +0530 Subject: [PATCH 049/189] common-utils zshrc issue fix (#1111) * common-utils zshrc issue fix * bump feature patch version * test added to validate the changes of zshrc fix * user vscode added * User env added --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 4 +++- test/common-utils/devcontainer-ruby-zshrc.sh | 12 ++++++++++++ .../devcontainer-ruby-zshrc/Dockerfile | 6 ++++++ test/common-utils/scenarios.json | 18 ++++++++++++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 test/common-utils/devcontainer-ruby-zshrc.sh create mode 100644 test/common-utils/devcontainer-ruby-zshrc/Dockerfile diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 968cbfb77..3fa6487df 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.1", + "version": "2.5.2", "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.", diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index 7658c4850..b5fe11f57 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -551,7 +551,9 @@ if [ "${INSTALL_ZSH}" = "true" ]; then # Add devcontainer .zshrc template if [ "$INSTALL_OH_MY_ZSH_CONFIG" = "true" ]; then - echo -e "$(cat "${template_path}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" > ${user_rc_file} + if ! [ -f "${template_path}" ] || ! grep -qF "$(head -n 1 "${template_path}")" "${user_rc_file}"; then + echo -e "$(cat "${template_path}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" > ${user_rc_file} + fi sed -i -e 's/ZSH_THEME=.*/ZSH_THEME="devcontainers"/g' ${user_rc_file} fi diff --git a/test/common-utils/devcontainer-ruby-zshrc.sh b/test/common-utils/devcontainer-ruby-zshrc.sh new file mode 100644 index 000000000..9e7b26e4c --- /dev/null +++ b/test/common-utils/devcontainer-ruby-zshrc.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "configure-zshrc-without-overwrite" bash -c "grep 'rbenv init -' ~/.zshrc" + +# Report result +reportResults diff --git a/test/common-utils/devcontainer-ruby-zshrc/Dockerfile b/test/common-utils/devcontainer-ruby-zshrc/Dockerfile new file mode 100644 index 000000000..c5e7c69c4 --- /dev/null +++ b/test/common-utils/devcontainer-ruby-zshrc/Dockerfile @@ -0,0 +1,6 @@ +FROM mcr.microsoft.com/devcontainers/ruby:3.2 + +USER vscode +ENV USER=vscode +RUN echo 'eval "$(rbenv init -)"' >> /home/$USER/.zshrc + diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index e5529ea04..a929f534a 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -235,6 +235,24 @@ } } }, + "devcontainer-ruby-zshrc": { + "build": { + "dockerfile": "Dockerfile" + }, + "remoteUser": "vscode", + "features": { + "common-utils": { + "installZsh": true, + "username": "vscode", + "userUid": "1000", + "userGid": "1000", + "upgradePackages": true, + "installOhMyZsh": true, + "installOhMyZshConfig": true, + "configureZshAsDefaultShell": true + } + } + }, "alpine-base-zsh-default": { "image": "mcr.microsoft.com/devcontainers/base:alpine", "remoteUser": "vscode", From 125f6b0071597a59f3ccbefaf9145b5867528ae3 Mon Sep 17 00:00:00 2001 From: Prathamesh Zarkar <159782310+prathameshzarkar9@users.noreply.github.com> Date: Fri, 18 Oct 2024 03:34:12 +0530 Subject: [PATCH 050/189] latest jdk 23 is introduced accordingly changed the source code (#1152) * latest jdk 23 is introduced accordingly changed the source code * java version bumped --- src/java/devcontainer-feature.json | 2 +- src/java/install.sh | 2 +- test/java/install_latest_version.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/devcontainer-feature.json b/src/java/devcontainer-feature.json index 7a9caa924..4e4b6c5d3 100644 --- a/src/java/devcontainer-feature.json +++ b/src/java/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "java", - "version": "1.6.1", + "version": "1.6.2", "name": "Java (via SDKMAN!)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/java", "description": "Installs Java, SDKMAN! (if not installed), and needed dependencies.", diff --git a/src/java/install.sh b/src/java/install.sh index 47f0e8559..ef3d1913a 100644 --- a/src/java/install.sh +++ b/src/java/install.sh @@ -214,7 +214,7 @@ find_version_list() { fi if [ "${JDK_DISTRO}" = "ms" ]; then - if [ "${major_version}" = "8" ] || [ "${major_version}" = "18" ] || [ "${major_version}" = "22" ]; then + if [ "${major_version}" = "8" ] || [ "${major_version}" = "18" ] || [ "${major_version}" = "22" ] || [ "${major_version}" = "23" ]; then JDK_DISTRO="tem" fi fi diff --git a/test/java/install_latest_version.sh b/test/java/install_latest_version.sh index a45d5e0b0..af8a621ce 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 "22.0.2" <(java --version) +check "java version latest installed" grep "23" <(java --version) # Report result reportResults From 90824ffb3694aa328deaa2c4b96486a953d738b4 Mon Sep 17 00:00:00 2001 From: Vatsal Gupta <40350810+gvatsal60@users.noreply.github.com> Date: Tue, 22 Oct 2024 22:23:56 +0530 Subject: [PATCH 051/189] Python Feature Version Update (#222) (#1148) * Fix: Handle case where Python version is already installed in dev container (#617) * Incorporated Review Comment: Version exist handling * Update: Python Feature Version --- src/python/devcontainer-feature.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index 768cb4388..64b02fd34 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.6.4", + "version": "1.6.5", "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 2951f0481a488ea43a6f2ea6f18a47f0a0bf744d Mon Sep 17 00:00:00 2001 From: Vatsal Gupta <40350810+gvatsal60@users.noreply.github.com> Date: Tue, 22 Oct 2024 23:51:35 +0530 Subject: [PATCH 052/189] Fixed Nvm Source Issue(#1078) (#1114) * Fixed Nvm Source Issue * Fix: Test Scenario Failure * Updated node feature version * Incorporated Review Comment --- src/node/devcontainer-feature.json | 2 +- src/node/install.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index a9b0d46b8..d8d49e538 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.6.0", + "version": "1.6.1", "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/node/install.sh b/src/node/install.sh index 3b74f885b..46d448440 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -227,7 +227,7 @@ install_yarn() { # Yum/DNF want to install nodejs dependencies, we'll use NPM to install yarn su ${USERNAME} -c "umask 0002 && . '${NVM_DIR}/nvm.sh' && nvm use ${_ver} && npm install --global yarn" fi - else + else echo "Yarn already installed." fi fi @@ -309,7 +309,7 @@ curl -so- "https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install. curl -so- "https://raw.githubusercontent.com/nvm-sh/nvm/\${PREV_NVM_VERSION}/install.sh" | bash NVM_VERSION="\${PREV_NVM_VERSION}" } -source "${NVM_DIR}/nvm.sh" +[ -s "${NVM_DIR}/nvm.sh" ] && source "${NVM_DIR}/nvm.sh" if [ "${NODE_VERSION}" != "" ]; then nvm alias default "${NODE_VERSION}" fi 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 053/189] 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 054/189] 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 055/189] 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 056/189] 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 057/189] 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 058/189] [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 059/189] [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 060/189] `[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 061/189] 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 062/189] 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 063/189] [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 064/189] [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 065/189] [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 066/189] [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 067/189] 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 068/189] 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 069/189] 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 070/189] 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 071/189] 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 072/189] [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 073/189] 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 074/189] 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 075/189] [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 076/189] 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 077/189] 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 078/189] [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 079/189] 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 080/189] [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 081/189] 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 082/189] 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 083/189] 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 084/189] 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