From a2b1c19a51b2528af4a7e75e3e1546da56b4c96c Mon Sep 17 00:00:00 2001 From: Nick Hu Date: Sat, 12 Nov 2022 18:33:16 +0000 Subject: [PATCH 001/478] Nix feature: allow extra configuration of /etc/nix/nix.conf (#277) --- src/nix/devcontainer-feature.json | 5 +++++ src/nix/install.sh | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/nix/devcontainer-feature.json b/src/nix/devcontainer-feature.json index ffd3dc9a0..9ab519b4d 100644 --- a/src/nix/devcontainer-feature.json +++ b/src/nix/devcontainer-feature.json @@ -25,6 +25,11 @@ "type": "string", "default": "", "description": "Optional URI to a Nix Flake to install in profile." + }, + "extraNixConfig": { + "type": "string", + "default": "", + "description": "Optional comma separated list of extra lines to add to /etc/nix/nix.conf." } }, "installsAfter": [ diff --git a/src/nix/install.sh b/src/nix/install.sh index 2fc436743..6141d7e0b 100755 --- a/src/nix/install.sh +++ b/src/nix/install.sh @@ -9,6 +9,7 @@ VERSION="${VERSION:-"latest"}" MULTIUSER="${MULTIUSER:-"true"}" PACKAGES="${PACKAGES//,/ }" FLAKEURI="${FLAKEURI:-""}" +EXTRANIXCONFIG="${EXTRANIXCONFIG:-""}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" # Nix keys for securly verifying installer download signature per https://nixos.org/download.html#nix-verify-installation @@ -99,6 +100,16 @@ create_or_update_file /etc/nix/nix.conf 'sandbox = false' if [ ! -z "${FLAKEURI}" ] && [ "${FLAKEURI}" != "none" ]; then create_or_update_file /etc/nix/nix.conf 'experimental-features = nix-command flakes' fi +# Extra nix config +if [ ! -z "${EXTRANIXCONFIG}" ]; then + OLDIFS=$IFS + IFS="," + read -a extra_nix_config <<< "$EXTRANIXCONFIG" + for line in "${extra_nix_config[@]}"; do + create_or_update_file /etc/nix/nix.conf "$line" + done + IFS=$OLDIFS +fi # Create entrypoint if needed if [ ! -e "/usr/local/share/nix-entrypoint.sh" ]; then From 1c61d1a0390ad52355e59df898f80a10f683bd12 Mon Sep 17 00:00:00 2001 From: Chuck Lantz Date: Sat, 12 Nov 2022 11:12:21 -0800 Subject: [PATCH 002/478] Add test, bump version for extraNixConfig (#280) --- src/nix/devcontainer-feature.json | 2 +- test/nix/extra-config.sh | 35 +++++++++++++++++++++++++++++++ test/nix/scenarios.json | 9 ++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/nix/extra-config.sh diff --git a/src/nix/devcontainer-feature.json b/src/nix/devcontainer-feature.json index 9ab519b4d..68ccdf78e 100644 --- a/src/nix/devcontainer-feature.json +++ b/src/nix/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nix", - "version": "1.0.0", + "version": "1.1.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.", diff --git a/test/nix/extra-config.sh b/test/nix/extra-config.sh new file mode 100644 index 000000000..724213b24 --- /dev/null +++ b/test/nix/extra-config.sh @@ -0,0 +1,35 @@ +#!/bin/bash +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +uid="$(id -u)" +echo "Current user UID is ${uid}." +if [ "${uid}" != "1000" ]; then + echo "Current user UID was adjusted." +fi +set +e +vscode_uid="$(id -u vscode)" +set -e +if [ "${vscode_uid}" != "" ]; then + echo "User vscode UID is ${vscode_uid}." + if [ "${vscode_uid}" != "1000" ]; then + echo "User vscode UID was adjusted." + fi +fi +nix_uid="$(stat /nix -c "%u")" +echo "/nix UID is ${nix_uid}." + +cat /etc/os-release +cat /etc/nix/nix.conf + +# Feature-specific tests +# The 'check' command comes from the dev-container-features-test-lib. +check "nix-env" type nix-env +check "First added line" grep -E '^extra-substituters = https://foo\.cachix\.org$' /etc/nix/nix.conf +check "Second added line" grep -E '^extra-trusted-public-keys = foo\.cachix\.org-1:bar=$' /etc/nix/nix.conf + +# Report result +# If any of the checks above exited with a non-zero exit code, the test will fail. +reportResults &2>1 \ No newline at end of file diff --git a/test/nix/scenarios.json b/test/nix/scenarios.json index 72ad99314..c287f58c7 100644 --- a/test/nix/scenarios.json +++ b/test/nix/scenarios.json @@ -89,5 +89,14 @@ "flakeUri": "github:nixos/nixpkgs/nixpkgs-unstable#hello" } } + }, + "extra-config": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "remoteUser": "vscode", + "features": { + "nix": { + "extraNixConfig": "extra-substituters = https://foo.cachix.org,extra-trusted-public-keys = foo.cachix.org-1:bar=" + } + } } } \ No newline at end of file From 00a51775eb76c143c96ca12079c780fef7954955 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 12 Nov 2022 11:14:29 -0800 Subject: [PATCH 003/478] Automated documentation update (#279) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/nix/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nix/README.md b/src/nix/README.md index 0ad107790..dcbc9a1df 100644 --- a/src/nix/README.md +++ b/src/nix/README.md @@ -21,6 +21,7 @@ Installs the Nix package manager and optionally a set of packages. | multiUser | Perform a multi-user install (instead of single user) | boolean | true | | packages | Optional comma separated list of Nix packages to install in profile. | string | - | | flakeUri | Optional URI to a Nix Flake to install in profile. | string | - | +| extraNixConfig | Optional comma separated list of extra lines to add to /etc/nix/nix.conf. | string | - | ## OS Support From 71726415140a08153c9e24336fce7ecaac397880 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 12 Nov 2022 11:14:58 -0800 Subject: [PATCH 004/478] Automated documentation update (#281) Automated documentation update [skip ci] Co-authored-by: github-actions From e9c4f9f8c5404d50a6120ff2228f0c34c5d70148 Mon Sep 17 00:00:00 2001 From: Chuck Lantz Date: Sat, 12 Nov 2022 11:22:41 -0800 Subject: [PATCH 005/478] Fix property name --- src/nix/NOTES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nix/NOTES.md b/src/nix/NOTES.md index f26196455..fc76a44a3 100644 --- a/src/nix/NOTES.md +++ b/src/nix/NOTES.md @@ -15,7 +15,7 @@ This Dev Container Feature supports two installation models for Nix: multi-user | Installation Model | Pros | Cons | | --- | --- | --- | | *Multi-User* | Nix can be used with any user including root.

Also still works if the UID or GID of any user is updated. | Only works with Nix 2.11 and up due to a Nix installer limitation.

Container must run either: run as root (but `remoteUser` in devcontainer.json can be non-root), or includes `sudo` with the `remoteUser` being configured to use it.

Note that automated start of the `nix-daemon` requires passwordless `sudo` if the container itself (e.g., `containerUser`) is not running as root. Manual startup using `sudo` can require a password, however (more next). | -| *Single-User* | Does not require the container to run as root or `sudo` to be included in the image. | Only works with the user specified in the `userName` property or an auto-detected user. If this user's UID/GID is updated, that user will no longer be able to work with Nix. This is primarily a consideration when running on Linux where the UID/GID is sync'd to the local user. | +| *Single-User* | Does not require the container to run as root or `sudo` to be included in the image. | Only works with the user specified in the `remoteUser` property or an auto-detected user. If this user's UID/GID is updated, that user will no longer be able to work with Nix. This is primarily a consideration when running on Linux where the UID/GID is sync'd to the local user. | ### Manually starting the Nix daemon @@ -25,4 +25,4 @@ If you have `sudo` in your base image, but have a password set so automatic star sudo /usr/local/share/nix-entrypoint.sh ``` -This same command can be used to restart the daemon if it has stopped for some reason. Logs are available at `/tmp/nix-daemon.log`. \ No newline at end of file +This same command can be used to restart the daemon if it has stopped for some reason. Logs are available at `/tmp/nix-daemon.log`. From 0e258004862f3c4e33da3138e65bc82036cf768f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 12 Nov 2022 11:24:57 -0800 Subject: [PATCH 006/478] Automated documentation update (#282) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/nix/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nix/README.md b/src/nix/README.md index dcbc9a1df..4d0e1ad2b 100644 --- a/src/nix/README.md +++ b/src/nix/README.md @@ -40,7 +40,7 @@ This Dev Container Feature supports two installation models for Nix: multi-user | Installation Model | Pros | Cons | | --- | --- | --- | | *Multi-User* | Nix can be used with any user including root.

Also still works if the UID or GID of any user is updated. | Only works with Nix 2.11 and up due to a Nix installer limitation.

Container must run either: run as root (but `remoteUser` in devcontainer.json can be non-root), or includes `sudo` with the `remoteUser` being configured to use it.

Note that automated start of the `nix-daemon` requires passwordless `sudo` if the container itself (e.g., `containerUser`) is not running as root. Manual startup using `sudo` can require a password, however (more next). | -| *Single-User* | Does not require the container to run as root or `sudo` to be included in the image. | Only works with the user specified in the `userName` property or an auto-detected user. If this user's UID/GID is updated, that user will no longer be able to work with Nix. This is primarily a consideration when running on Linux where the UID/GID is sync'd to the local user. | +| *Single-User* | Does not require the container to run as root or `sudo` to be included in the image. | Only works with the user specified in the `remoteUser` property or an auto-detected user. If this user's UID/GID is updated, that user will no longer be able to work with Nix. This is primarily a consideration when running on Linux where the UID/GID is sync'd to the local user. | ### Manually starting the Nix daemon @@ -52,6 +52,7 @@ sudo /usr/local/share/nix-entrypoint.sh This same command can be used to restart the daemon if it has stopped for some reason. Logs are available at `/tmp/nix-daemon.log`. + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/nix/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ From 258b107b39db9f28703bf6bfeed3102d54e1cafe Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 11:40:25 -0800 Subject: [PATCH 007/478] Automated documentation update (#287) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/anaconda/README.md | 4 +--- src/aws-cli/README.md | 4 +--- src/azure-cli/README.md | 4 +--- src/common-utils/README.md | 4 +--- src/conda/README.md | 4 +--- src/desktop-lite/README.md | 4 +--- src/docker-from-docker/README.md | 4 +--- src/docker-in-docker/README.md | 4 +--- src/dotnet/README.md | 4 +--- src/git-lfs/README.md | 4 +--- src/git/README.md | 4 +--- src/github-cli/README.md | 4 +--- src/go/README.md | 4 +--- src/hugo/README.md | 4 +--- src/java/README.md | 4 +--- src/kubectl-helm-minikube/README.md | 4 +--- src/nix/README.md | 4 +--- src/node/README.md | 4 +--- src/nvidia-cuda/README.md | 4 +--- src/oryx/README.md | 4 +--- src/php/README.md | 4 +--- src/powershell/README.md | 4 +--- src/python/README.md | 4 +--- src/ruby/README.md | 4 +--- src/rust/README.md | 4 +--- src/sshd/README.md | 4 +--- src/terraform/README.md | 4 +--- 27 files changed, 27 insertions(+), 81 deletions(-) diff --git a/src/anaconda/README.md b/src/anaconda/README.md index 8f1130279..b230b50df 100644 --- a/src/anaconda/README.md +++ b/src/anaconda/README.md @@ -7,9 +7,7 @@ ```json "features": { - "ghcr.io/devcontainers/features/anaconda:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/anaconda:1": {} } ``` diff --git a/src/aws-cli/README.md b/src/aws-cli/README.md index 3fb4688f8..00b8cd583 100644 --- a/src/aws-cli/README.md +++ b/src/aws-cli/README.md @@ -7,9 +7,7 @@ Installs the AWS CLI along with needed dependencies. Useful for base Dockerfiles ```json "features": { - "ghcr.io/devcontainers/features/aws-cli:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/aws-cli:1": {} } ``` diff --git a/src/azure-cli/README.md b/src/azure-cli/README.md index 8b6193ea7..e32467487 100644 --- a/src/azure-cli/README.md +++ b/src/azure-cli/README.md @@ -7,9 +7,7 @@ Installs the Azure CLI along with needed dependencies. Useful for base Dockerfil ```json "features": { - "ghcr.io/devcontainers/features/azure-cli:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/azure-cli:1": {} } ``` diff --git a/src/common-utils/README.md b/src/common-utils/README.md index 0150af31f..06af48460 100644 --- a/src/common-utils/README.md +++ b/src/common-utils/README.md @@ -7,9 +7,7 @@ Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-r ```json "features": { - "ghcr.io/devcontainers/features/common-utils:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/common-utils:1": {} } ``` diff --git a/src/conda/README.md b/src/conda/README.md index 5472af72c..4fb75dd1f 100644 --- a/src/conda/README.md +++ b/src/conda/README.md @@ -7,9 +7,7 @@ A cross-platform, language-agnostic binary package manager ```json "features": { - "ghcr.io/devcontainers/features/conda:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/conda:1": {} } ``` diff --git a/src/desktop-lite/README.md b/src/desktop-lite/README.md index 36d8693a1..9ee8227cc 100644 --- a/src/desktop-lite/README.md +++ b/src/desktop-lite/README.md @@ -7,9 +7,7 @@ Adds a lightweight Fluxbox based desktop to the container that can be accessed u ```json "features": { - "ghcr.io/devcontainers/features/desktop-lite:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/desktop-lite:1": {} } ``` diff --git a/src/docker-from-docker/README.md b/src/docker-from-docker/README.md index 07acb87b8..41d984686 100644 --- a/src/docker-from-docker/README.md +++ b/src/docker-from-docker/README.md @@ -7,9 +7,7 @@ ```json "features": { - "ghcr.io/devcontainers/features/docker-from-docker:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/docker-from-docker:1": {} } ``` diff --git a/src/docker-in-docker/README.md b/src/docker-in-docker/README.md index 0a529c42e..8ee91ef2b 100644 --- a/src/docker-in-docker/README.md +++ b/src/docker-in-docker/README.md @@ -7,9 +7,7 @@ Create child containers *inside* a container, independent from the host's docker ```json "features": { - "ghcr.io/devcontainers/features/docker-in-docker:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/docker-in-docker:1": {} } ``` diff --git a/src/dotnet/README.md b/src/dotnet/README.md index d40eb4ad1..784c7362e 100644 --- a/src/dotnet/README.md +++ b/src/dotnet/README.md @@ -7,9 +7,7 @@ Installs the .NET CLI. Provides option of installing sdk or runtime, and option ```json "features": { - "ghcr.io/devcontainers/features/dotnet:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/dotnet:1": {} } ``` diff --git a/src/git-lfs/README.md b/src/git-lfs/README.md index 1f7e6c3a2..a23a639a0 100644 --- a/src/git-lfs/README.md +++ b/src/git-lfs/README.md @@ -7,9 +7,7 @@ Installs Git Large File Support (Git LFS) along with needed dependencies. Useful ```json "features": { - "ghcr.io/devcontainers/features/git-lfs:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/git-lfs:1": {} } ``` diff --git a/src/git/README.md b/src/git/README.md index 54e1fa608..287af4995 100644 --- a/src/git/README.md +++ b/src/git/README.md @@ -7,9 +7,7 @@ Install an up-to-date version of Git, built from source as needed. Useful for wh ```json "features": { - "ghcr.io/devcontainers/features/git:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/git:1": {} } ``` diff --git a/src/github-cli/README.md b/src/github-cli/README.md index 5e95dec13..3670399da 100644 --- a/src/github-cli/README.md +++ b/src/github-cli/README.md @@ -7,9 +7,7 @@ Installs the GitHub CLI. Auto-detects latest version and installs needed depende ```json "features": { - "ghcr.io/devcontainers/features/github-cli:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/github-cli:1": {} } ``` diff --git a/src/go/README.md b/src/go/README.md index 3282b245b..5ea30c1fd 100644 --- a/src/go/README.md +++ b/src/go/README.md @@ -7,9 +7,7 @@ Installs Go and common Go utilities. Auto-detects latest version and installs ne ```json "features": { - "ghcr.io/devcontainers/features/go:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/go:1": {} } ``` diff --git a/src/hugo/README.md b/src/hugo/README.md index afd7aee86..f66f3c7fc 100644 --- a/src/hugo/README.md +++ b/src/hugo/README.md @@ -7,9 +7,7 @@ ```json "features": { - "ghcr.io/devcontainers/features/hugo:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/hugo:1": {} } ``` diff --git a/src/java/README.md b/src/java/README.md index 343cc6057..c409b3488 100644 --- a/src/java/README.md +++ b/src/java/README.md @@ -7,9 +7,7 @@ Installs Java, SDKMAN! (if not installed), and needed dependencies. ```json "features": { - "ghcr.io/devcontainers/features/java:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/java:1": {} } ``` diff --git a/src/kubectl-helm-minikube/README.md b/src/kubectl-helm-minikube/README.md index 11a139de2..bbb02028f 100644 --- a/src/kubectl-helm-minikube/README.md +++ b/src/kubectl-helm-minikube/README.md @@ -7,9 +7,7 @@ Installs latest version of kubectl, Helm, and optionally minikube. Auto-detects ```json "features": { - "ghcr.io/devcontainers/features/kubectl-helm-minikube:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {} } ``` diff --git a/src/nix/README.md b/src/nix/README.md index 4d0e1ad2b..d331f8923 100644 --- a/src/nix/README.md +++ b/src/nix/README.md @@ -7,9 +7,7 @@ Installs the Nix package manager and optionally a set of packages. ```json "features": { - "ghcr.io/devcontainers/features/nix:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/nix:1": {} } ``` diff --git a/src/node/README.md b/src/node/README.md index 5a5f64a3f..0bd837af3 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -7,9 +7,7 @@ Installs Node.js, nvm, yarn, and needed dependencies. ```json "features": { - "ghcr.io/devcontainers/features/node:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/node:1": {} } ``` diff --git a/src/nvidia-cuda/README.md b/src/nvidia-cuda/README.md index 735e72563..d756a414f 100644 --- a/src/nvidia-cuda/README.md +++ b/src/nvidia-cuda/README.md @@ -7,9 +7,7 @@ Installs shared libraries for NVIDIA CUDA. ```json "features": { - "ghcr.io/devcontainers/features/nvidia-cuda:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/nvidia-cuda:1": {} } ``` diff --git a/src/oryx/README.md b/src/oryx/README.md index 67fd70a88..670a6d1a0 100644 --- a/src/oryx/README.md +++ b/src/oryx/README.md @@ -7,9 +7,7 @@ Installs the oryx CLI ```json "features": { - "ghcr.io/devcontainers/features/oryx:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/oryx:1": {} } ``` diff --git a/src/php/README.md b/src/php/README.md index f0c605cce..c979e39b9 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -7,9 +7,7 @@ ```json "features": { - "ghcr.io/devcontainers/features/php:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/php:1": {} } ``` diff --git a/src/powershell/README.md b/src/powershell/README.md index 24bdb0cb3..0ff0469c5 100644 --- a/src/powershell/README.md +++ b/src/powershell/README.md @@ -7,9 +7,7 @@ Installs PowerShell along with needed dependencies. Useful for base Dockerfiles ```json "features": { - "ghcr.io/devcontainers/features/powershell:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/powershell:1": {} } ``` diff --git a/src/python/README.md b/src/python/README.md index 1f6e18a7f..47abf5e31 100644 --- a/src/python/README.md +++ b/src/python/README.md @@ -7,9 +7,7 @@ Installs the provided version of Python, as well as PIPX, and other common Pytho ```json "features": { - "ghcr.io/devcontainers/features/python:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/python:1": {} } ``` diff --git a/src/ruby/README.md b/src/ruby/README.md index d8ca8555f..ffb136d47 100644 --- a/src/ruby/README.md +++ b/src/ruby/README.md @@ -7,9 +7,7 @@ Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies. ```json "features": { - "ghcr.io/devcontainers/features/ruby:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/ruby:1": {} } ``` diff --git a/src/rust/README.md b/src/rust/README.md index 4756cb711..14af4ad49 100644 --- a/src/rust/README.md +++ b/src/rust/README.md @@ -7,9 +7,7 @@ Installs Rust, common Rust utilities, and their required dependencies ```json "features": { - "ghcr.io/devcontainers/features/rust:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/rust:1": {} } ``` diff --git a/src/sshd/README.md b/src/sshd/README.md index 511659e39..5245d6805 100644 --- a/src/sshd/README.md +++ b/src/sshd/README.md @@ -7,9 +7,7 @@ Adds a SSH server into a container so that you can use an external terminal, sft ```json "features": { - "ghcr.io/devcontainers/features/sshd:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/sshd:1": {} } ``` diff --git a/src/terraform/README.md b/src/terraform/README.md index 36c5d7786..8b7a25df2 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -7,9 +7,7 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la ```json "features": { - "ghcr.io/devcontainers/features/terraform:1": { - "version": "latest" - } + "ghcr.io/devcontainers/features/terraform:1": {} } ``` From 17580ee22f38b3a16e6531a8139629fd2fd8234a Mon Sep 17 00:00:00 2001 From: Chuck Lantz Date: Mon, 14 Nov 2022 11:41:32 -0800 Subject: [PATCH 008/478] Add .NET 7, drop .NET 5 (#269) * Add .NET 7, drop .NET 5 * Add libssl3 to common-utils for jammy * Handle lts/latest hard coding * Fix, improve tests * Bump version * Fix situation where version could come from either MS repo or OS * Remove unused option * Bump common version * Remove unused function * Restore DOTNET_ROOT per feedback --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/install.sh | 7 +- src/dotnet/devcontainer-feature.json | 4 +- src/dotnet/install.sh | 138 ++++++++++----------- test/dotnet/install_additional_dotnet.sh | 10 +- test/dotnet/install_dotnet_3.sh | 8 +- test/dotnet/install_dotnet_5.sh | 14 --- test/dotnet/install_dotnet_6_bullseye.sh | 17 +++ test/dotnet/install_dotnet_6_focal.sh | 17 +++ test/dotnet/install_dotnet_7_bullseye.sh | 17 +++ test/dotnet/install_dotnet_7_jammy.sh | 17 +++ test/dotnet/install_dotnet_latest.sh | 17 +++ test/dotnet/install_dotnet_lts.sh | 17 +++ test/dotnet/install_wo_apt.sh | 17 +++ test/dotnet/scenarios.json | 53 +++++++- test/dotnet/test.sh | 6 +- 16 files changed, 262 insertions(+), 99 deletions(-) delete mode 100644 test/dotnet/install_dotnet_5.sh create mode 100644 test/dotnet/install_dotnet_6_bullseye.sh create mode 100644 test/dotnet/install_dotnet_6_focal.sh create mode 100644 test/dotnet/install_dotnet_7_bullseye.sh create mode 100644 test/dotnet/install_dotnet_7_jammy.sh create mode 100644 test/dotnet/install_dotnet_latest.sh create mode 100644 test/dotnet/install_dotnet_lts.sh create mode 100644 test/dotnet/install_wo_apt.sh diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index c5f86215b..9a135d516 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "1.1.3", + "version": "1.1.4", "name": "Common Debian 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/install.sh b/src/common-utils/install.sh index 2d51a0b21..8ac0a7c62 100755 --- a/src/common-utils/install.sh +++ b/src/common-utils/install.sh @@ -140,7 +140,12 @@ if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then package_list="${package_list} libssl1.1" fi - + + # Install libssl3 if available + if [[ ! -z $(apt-cache --names-only search ^libssl3$) ]]; then + package_list="${package_list} libssl3" + fi + # Install appropriate version of libssl1.0.x if available libssl_package=$(dpkg-query -f '${db:Status-Abbrev}\t${binary:Package}\n' -W 'libssl1\.0\.?' 2>&1 || echo '') if [ "$(echo "$LIlibssl_packageBSSL" | grep -o 'libssl1\.0\.[0-9]:' | uniq | sort | wc -l)" -eq 0 ]; then diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index ce8ef060f..42eb1c287 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "1.0.8", + "version": "1.1.0", "name": "Dotnet CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet", "description": "Installs the .NET CLI. Provides option of installing sdk or runtime, and option of versions to install. Uses latest version of .NET sdk as defaults to install.", @@ -9,8 +9,8 @@ "type": "string", "proposals": [ "latest", + "7", "6", - "5", "3.1" ], "default": "latest", diff --git a/src/dotnet/install.sh b/src/dotnet/install.sh index fe4f58dab..78cd691df 100755 --- a/src/dotnet/install.sh +++ b/src/dotnet/install.sh @@ -12,6 +12,9 @@ DOTNET_RUNTIME_ONLY=${RUNTIMEONLY:-"false"} OVERRIDE_DEFAULT_VERSION=${OVERRIDEDEFAULTVERSION:-"true"} INSTALL_USING_APT=${INSTALLUSINGAPT:-"true"} +DOTNET_LATEST="7" +DOTNET_LTS="6" + USERNAME=${USERNAME:-"automatic"} UPDATE_RC=${UPDATE_RC:-"true"} TARGET_DOTNET_ROOT=${TARGET_DOTNET_ROOT:-"/usr/local/dotnet"} @@ -84,21 +87,6 @@ cleanup() { } trap cleanup EXIT -# Get central common setting -get_common_setting() { - if [ "${common_settings_file_loaded}" != "true" ]; then - curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." - common_settings_file_loaded=true - fi - if [ -f "/tmp/vsdc-settings.env" ]; then - local multi_line="" - if [ "$2" = "true" ]; then multi_line="-z"; fi - local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" - if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi - fi - echo "$1=${!1}" -} - # Add dotnet directory to PATH in bashrc/zshrc files if OVERRIDE_DEFAULT_VERSION=true. updaterc() { if [ "${UPDATE_RC}" = "true" ]; then @@ -194,72 +182,75 @@ apt_cache_package_and_version_soft_match() { } # Install .NET CLI using apt-get package installer -install_using_apt_from_microsoft_repo() { +install_using_apt() { local sdk_or_runtime="$1" - local dotnet_major_minor_version - export DOTNET_PACKAGE="dotnet-${sdk_or_runtime}" - - # Install dependencies - check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr - - # Import key safely and import Microsoft apt repo - get_common_setting MICROSOFT_GPG_KEYS_URI - curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg - echo "deb [arch=${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 - apt-get update -y + local target_dotnet_version="$2" + local use_msft_repo="$3" + + if [ "${use_msft_repo}" = "true" ]; then + # Install dependencies + check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr + # Import key safely and import Microsoft apt repo + curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg + echo "deb [arch=${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 + apt-get update -y + fi - if [ "${DOTNET_VERSION}" = "latest" ] || [ "${DOTNET_VERSION}" = "lts" ]; then - DOTNET_VERSION="" - DOTNET_PACKAGE="${DOTNET_PACKAGE}-6.0" - else - # Sets DOTNET_VERSION and DOTNET_PACKAGE if matches found. - apt_cache_package_and_version_soft_match DOTNET_VERSION DOTNET_PACKAGE false - if [ "$?" != 0 ]; then - echo "Failed to find requested version." - return 1 - fi + # .NET 7 is not a LTS version, so handle latest and LTS versions differently + export APT_DOTNET_VERSION="$target_dotnet_version" + if [ "${APT_DOTNET_VERSION}" = "latest" ]; then + APT_DOTNET_VERSION="${DOTNET_LATEST}.0" + elif [ "${APT_DOTNET_VERSION}" = "lts" ]; then + APT_DOTNET_VERSION="${DOTNET_LTS}.0" + fi - if [[ $(dotnet --version) == *"${DOTNET_VERSION}"* ]] ; then - echo "Dotnet version ${DOTNET_VERSION} is already installed" - return 1 - fi + # Sets target_dotnet_version and dotnet_package if matches found. + local base_dotnet_package="dotnet-${sdk_or_runtime}" + export DOTNET_PACKAGE="${base_dotnet_package}" + apt_cache_package_and_version_soft_match APT_DOTNET_VERSION DOTNET_PACKAGE false + if [ "$?" != 0 ] || [ ${DOTNET_PACKAGE} == "${base_dotnet_package}" ]; then + echo "Failed to find requested version." + return 1 + fi + if type dotnet > /dev/null 2>&1 && [[ "$(dotnet --version)" == *"${APT_DOTNET_VERSION}"* ]] ; then + echo "dotnet version ${APT_DOTNET_VERSION} is already installed" + return 1 fi - echo "Installing '${DOTNET_PACKAGE}${DOTNET_VERSION}'..." - apt-get install -yq ${DOTNET_PACKAGE}${DOTNET_VERSION} + echo "Installing '${DOTNET_PACKAGE}${APT_DOTNET_VERSION}'..." + apt-get install -yq ${DOTNET_PACKAGE}${APT_DOTNET_VERSION} if [ "$?" != 0 ]; then - echo "Failed to complete apt install of ${DOTNET_PACKAGE}${DOTNET_VERSION}" + echo "Failed to complete apt install of ${DOTNET_PACKAGE}${TARGET_DOTNET_VERSION}" return 1 fi -} - -install_using_default_apt_repo() { - DOTNET_PACKAGE="dotnet6" - apt_get_update - - if [[ "${DOTNET_VERSION}" = "latest" ]] || [[ "${DOTNET_VERSION}" = "lts" ]] || [[ ${DOTNET_VERSION} = "6"* ]]; then - if ! (apt-get install -yq ${DOTNET_PACKAGE}); then - echo "Failed to install 'dotnet6' package from default apt repo." - return 1 - fi + # Add symlink for current + CURRENT_DIR="${TARGET_DOTNET_ROOT}/current" + if [[ -d "${CURRENT_DIR}" ]]; then + rm -rf "${CURRENT_DIR}" + fi + mkdir -p "${TARGET_DOTNET_ROOT}" + local dotnet_installed_version="$(dotnet --version)" + # See if its the distro version + if [[ "$(dotnet --info)" == *"Base Path: /usr/lib/dotnet/dotnet${dotnet_installed_version:0:1}-${dotnet_installed_version}"* ]]; then + ln -s "/usr/lib/dotnet/dotnet${dotnet_installed_version:0:1}" "${CURRENT_DIR}" else - echo "The provided dotnet version is not distributed in this distro's default apt repo." - return 1 + # Location used by MS repo versions + ln -s "/usr/share/dotnet" "${CURRENT_DIR}" fi } # Find and extract .NET binary download details based on user-requested version # args: # sdk_or_runtime $1 +# dotnet_version_to_download $2 # exports: # DOTNET_DOWNLOAD_URL # DOTNET_DOWNLOAD_HASH # DOTNET_DOWNLOAD_NAME get_full_version_details() { local sdk_or_runtime="$1" - local VERSION="$2" local architecture local dotnet_channel_version local dotnet_releases_url @@ -267,6 +258,7 @@ get_full_version_details() { local dotnet_latest_version local dotnet_download_details + export DOTNET_DOWNLOAD_VERSION="$2" export DOTNET_DOWNLOAD_URL export DOTNET_DOWNLOAD_HASH export DOTNET_DOWNLOAD_NAME @@ -275,11 +267,11 @@ get_full_version_details() { architecture="$(get_architecture_name_for_target_os)" # Set VERSION to empty string to ensure jq includes all .NET versions in reverse sort below - if [ "${VERSION}" = "latest" ]; then - VERSION="" + if [ "${DOTNET_DOWNLOAD_VERSION}" = "latest" ]; then + DOTNET_DOWNLOAD_VERSION="" fi - dotnet_patchless_version="$(echo "${VERSION}" | cut -d "." --field=1,2)" + dotnet_patchless_version="$(echo "${DOTNET_DOWNLOAD_VERSION}" | cut -d "." --field=1,2)" set +e dotnet_channel_version="$(curl -s "${DOTNET_CDN_FEED_URI}/dotnet/release-metadata/releases-index.json" | jq -r --arg channel_version "${dotnet_patchless_version}" '[."releases-index"[]] | sort_by(."channel-version") | reverse | map( select(."channel-version" | startswith($channel_version))) | first | ."channel-version"')" @@ -299,22 +291,22 @@ get_full_version_details() { if [ -n "${dotnet_releases_json}" ] && [[ ! "${dotnet_releases_json}" = *"Error"* ]]; then dotnet_latest_version="$(echo "${dotnet_releases_json}" | jq -r --arg sdk_or_runtime "${sdk_or_runtime}" '."latest-\($sdk_or_runtime)"')" # If user-specified version has 2 or more dots, use it as is. Otherwise use latest version. - if [ "$(echo "${VERSION}" | grep -o "\." | wc -l)" -lt "2" ]; then - VERSION="${dotnet_latest_version}" + if [ "$(echo "${DOTNET_DOWNLOAD_VERSION}" | grep -o "\." | wc -l)" -lt "2" ]; then + DOTNET_DOWNLOAD_VERSION="${dotnet_latest_version}" fi - dotnet_download_details="$(echo "${dotnet_releases_json}" | jq -r --arg sdk_or_runtime "${sdk_or_runtime}" --arg dotnet_version "${VERSION}" --arg arch "${architecture}" '.releases[]."\($sdk_or_runtime)" | select(.version==$dotnet_version) | .files[] | select(.name=="dotnet-\($sdk_or_runtime)-linux-\($arch).tar.gz")')" + dotnet_download_details="$(echo "${dotnet_releases_json}" | jq -r --arg sdk_or_runtime "${sdk_or_runtime}" --arg dotnet_version "${DOTNET_DOWNLOAD_VERSION}" --arg arch "${architecture}" '.releases[]."\($sdk_or_runtime)" | select(.version==$dotnet_version) | .files[] | select(.name=="dotnet-\($sdk_or_runtime)-linux-\($arch).tar.gz")')" if [ -n "${dotnet_download_details}" ]; then - echo "Found .NET binary version ${VERSION}" + echo "Found .NET binary version ${DOTNET_DOWNLOAD_VERSION}" DOTNET_DOWNLOAD_URL="$(echo "${dotnet_download_details}" | jq -r '.url')" DOTNET_DOWNLOAD_HASH="$(echo "${dotnet_download_details}" | jq -r '.hash')" DOTNET_DOWNLOAD_NAME="$(echo "${dotnet_download_details}" | jq -r '.name')" else - err "Unable to find .NET binary for version ${VERSION}" + err "Unable to find .NET binary for version ${DOTNET_DOWNLOAD_VERSION}" exit 1 fi else - err "Unable to find .NET release details for version ${VERSION} at ${dotnet_releases_url}" + err "Unable to find .NET release details for version ${DOTNET_DOWNLOAD_VERSION} at ${dotnet_releases_url}" exit 1 fi } @@ -322,7 +314,7 @@ get_full_version_details() { # Install .NET CLI using the .NET releases url install_using_dotnet_releases_url() { local sdk_or_runtime="$1" - local VERSION="$2" + local version="$2" # Check listed package dependecies and install them if they are not already installed. # NOTE: icu-devtools is a small package with similar dependecies to .NET. @@ -336,14 +328,14 @@ install_using_dotnet_releases_url() { if [[ "${DOTNET_VERSION_CODENAMES_REQUIRE_OLDER_LIBSSL_1}" = *"${VERSION_CODENAME}"* ]]; then check_packages libssl1.1 else - check_packages libssl3.0 + check_packages libssl3 fi - get_full_version_details "${sdk_or_runtime}" "${VERSION}" + get_full_version_details "${sdk_or_runtime}" "${version}" - DOTNET_INSTALL_PATH="${TARGET_DOTNET_ROOT}/${VERSION}" + DOTNET_INSTALL_PATH="${TARGET_DOTNET_ROOT}/${DOTNET_DOWNLOAD_VERSION}" if [ -d "${DOTNET_INSTALL_PATH}" ]; then - echo "(!) Dotnet version ${VERSION} already exists." + echo "(!) Dotnet version ${DOTNET_DOWNLOAD_VERSION} already exists." exit 1 fi # exports DOTNET_DOWNLOAD_URL, DOTNET_DOWNLOAD_HASH, DOTNET_DOWNLOAD_NAME @@ -432,7 +424,7 @@ CHANGE_OWNERSHIP="false" if [[ "${DOTNET_ARCHIVE_ARCHITECTURES}" = *"${architecture}"* ]] && [[ "${DOTNET_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]] && [[ "${INSTALL_USING_APT}" = "true" ]]; then echo "Detected ${VERSION_CODENAME} on ${architecture}. Attempting to install dotnet from apt" - install_using_default_apt_repo || install_using_apt_from_microsoft_repo "${DOTNET_SDK_OR_RUNTIME}" + install_using_apt "${DOTNET_SDK_OR_RUNTIME}" "${DOTNET_VERSION}" false || install_using_apt "${DOTNET_SDK_OR_RUNTIME}" "${DOTNET_VERSION}" true if [ "$?" != 0 ]; then echo "Could not install requested version from apt on current distribution." exit 1 diff --git a/test/dotnet/install_additional_dotnet.sh b/test/dotnet/install_additional_dotnet.sh index fdb2da765..e69c7dce1 100644 --- a/test/dotnet/install_additional_dotnet.sh +++ b/test/dotnet/install_additional_dotnet.sh @@ -5,9 +5,13 @@ set -e # Optional: Import test library source dev-container-features-test-lib -check "dotnet version 6.0.301 installed as default" dotnet --version | grep 6.0.301 -check "dotnet version 5.0 installed" ls -l /usr/local/dotnet | grep 5.0 -check "dotnet version 3.1.420 installed" ls -l /usr/local/dotnet | grep 3.1.420 +check "dotnet version 6.0.301 installed as default" bash -c "dotnet --version | grep 6.0.301" +check "dotnet version 5.0 installed" bash -c "ls -l /usr/local/dotnet | grep 5.0" +check "dotnet version 3.1.420 installed" bash -c "ls -l /usr/local/dotnet | grep 3.1.420" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk # Report result reportResults diff --git a/test/dotnet/install_dotnet_3.sh b/test/dotnet/install_dotnet_3.sh index 0d05215db..51d871bcf 100644 --- a/test/dotnet/install_dotnet_3.sh +++ b/test/dotnet/install_dotnet_3.sh @@ -6,8 +6,12 @@ set -e source dev-container-features-test-lib check "dotnet sdks" dotnet --list-sdks -check "some major version of dotnet 3 is installed" dotnet --list-sdks | grep '3\.[0-9]*\.[0-9]*' -check "dotnet version 3 installed" ls -l /usr/share/dotnet/sdk | grep '3\.[0-9]*\.[0-9]*' +check "some major version of dotnet 3 is installed" bash -c "dotnet --list-sdks | grep '3\.[0-9]*\.[0-9]*'" +check "dotnet version 3 installed" bash -c "ls -l /usr/share/dotnet/sdk | grep '3\.[0-9]*\.[0-9]*'" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk # Report result reportResults diff --git a/test/dotnet/install_dotnet_5.sh b/test/dotnet/install_dotnet_5.sh deleted file mode 100644 index 5f48eb114..000000000 --- a/test/dotnet/install_dotnet_5.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -set -e - -# Optional: Import test library -source dev-container-features-test-lib - -check "dotnet sdks" dotnet --list-sdks -check "some major version of dotnet 5 is installed" dotnet --list-sdks | grep '5\.[0-9]*\.[0-9]*' -check "dotnet version 5 installed" ls -l /usr/share/dotnet/sdk | grep '5\.[0-9]*\.[0-9]*' - - -# Report result -reportResults diff --git a/test/dotnet/install_dotnet_6_bullseye.sh b/test/dotnet/install_dotnet_6_bullseye.sh new file mode 100644 index 000000000..758f0402d --- /dev/null +++ b/test/dotnet/install_dotnet_6_bullseye.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "dotnet sdks" dotnet --list-sdks +check "some major version of dotnet 6 is installed" bash -c "dotnet --list-sdks | grep '6\.[0-9]*\.[0-9]*'" +check "dotnet version 6 installed" bash -c "ls -l /usr/share/dotnet/sdk | grep '6\.[0-9]*\.[0-9]*'" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk + +# Report result +reportResults diff --git a/test/dotnet/install_dotnet_6_focal.sh b/test/dotnet/install_dotnet_6_focal.sh new file mode 100644 index 000000000..758f0402d --- /dev/null +++ b/test/dotnet/install_dotnet_6_focal.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "dotnet sdks" dotnet --list-sdks +check "some major version of dotnet 6 is installed" bash -c "dotnet --list-sdks | grep '6\.[0-9]*\.[0-9]*'" +check "dotnet version 6 installed" bash -c "ls -l /usr/share/dotnet/sdk | grep '6\.[0-9]*\.[0-9]*'" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk + +# Report result +reportResults diff --git a/test/dotnet/install_dotnet_7_bullseye.sh b/test/dotnet/install_dotnet_7_bullseye.sh new file mode 100644 index 000000000..2c015fc0e --- /dev/null +++ b/test/dotnet/install_dotnet_7_bullseye.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "dotnet sdks" dotnet --list-sdks +check "some major version of dotnet 7 is installed" bash -c "dotnet --list-sdks | grep '7\.[0-9]*\.[0-9]*'" +check "dotnet version 7 installed" bash -c "ls -l /usr/share/dotnet/sdk | grep '7\.[0-9]*\.[0-9]*'" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk + +# Report result +reportResults diff --git a/test/dotnet/install_dotnet_7_jammy.sh b/test/dotnet/install_dotnet_7_jammy.sh new file mode 100644 index 000000000..2c015fc0e --- /dev/null +++ b/test/dotnet/install_dotnet_7_jammy.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "dotnet sdks" dotnet --list-sdks +check "some major version of dotnet 7 is installed" bash -c "dotnet --list-sdks | grep '7\.[0-9]*\.[0-9]*'" +check "dotnet version 7 installed" bash -c "ls -l /usr/share/dotnet/sdk | grep '7\.[0-9]*\.[0-9]*'" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk + +# Report result +reportResults diff --git a/test/dotnet/install_dotnet_latest.sh b/test/dotnet/install_dotnet_latest.sh new file mode 100644 index 000000000..2c015fc0e --- /dev/null +++ b/test/dotnet/install_dotnet_latest.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "dotnet sdks" dotnet --list-sdks +check "some major version of dotnet 7 is installed" bash -c "dotnet --list-sdks | grep '7\.[0-9]*\.[0-9]*'" +check "dotnet version 7 installed" bash -c "ls -l /usr/share/dotnet/sdk | grep '7\.[0-9]*\.[0-9]*'" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk + +# Report result +reportResults diff --git a/test/dotnet/install_dotnet_lts.sh b/test/dotnet/install_dotnet_lts.sh new file mode 100644 index 000000000..758f0402d --- /dev/null +++ b/test/dotnet/install_dotnet_lts.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "dotnet sdks" dotnet --list-sdks +check "some major version of dotnet 6 is installed" bash -c "dotnet --list-sdks | grep '6\.[0-9]*\.[0-9]*'" +check "dotnet version 6 installed" bash -c "ls -l /usr/share/dotnet/sdk | grep '6\.[0-9]*\.[0-9]*'" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk + +# Report result +reportResults diff --git a/test/dotnet/install_wo_apt.sh b/test/dotnet/install_wo_apt.sh new file mode 100644 index 000000000..a1745c573 --- /dev/null +++ b/test/dotnet/install_wo_apt.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "dotnet sdks" dotnet --list-sdks +check "some major version of dotnet 7 is installed" bash -c "dotnet --list-sdks | grep '7\.[0-9]*\.[0-9]*'" +check "dotnet version 7 installed" bash -c "ls -l /usr/local/dotnet | grep '7\.[0-9]*\.[0-9]*'" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk + +# Report result +reportResults diff --git a/test/dotnet/scenarios.json b/test/dotnet/scenarios.json index edf4a750f..37f83d5a9 100644 --- a/test/dotnet/scenarios.json +++ b/test/dotnet/scenarios.json @@ -16,11 +16,60 @@ } } }, - "install_dotnet_5": { + "install_dotnet_6_bullseye": { + "image": "debian:bullseye", + "features": { + "dotnet": { + "version": "6" + } + } + }, + "install_dotnet_6_focal": { "image": "ubuntu:focal", "features": { "dotnet": { - "version": "5" + "version": "6" + } + } + }, + "install_dotnet_7_bullseye": { + "image": "debian:bullseye", + "features": { + "dotnet": { + "version": "7" + } + } + }, + "install_dotnet_7_jammy": { + "image": "ubuntu:jammy", + "features": { + "dotnet": { + "version": "7" + } + } + }, + "install_dotnet_latest": { + "image": "ubuntu:jammy", + "features": { + "dotnet": { + "version": "latest" + } + } + }, + "install_dotnet_lts": { + "image": "ubuntu:focal", + "features": { + "dotnet": { + "version": "lts" + } + } + }, + "install_wo_apt": { + "image": "ubuntu:jammy", + "features": { + "dotnet": { + "version": "7", + "installUsingApt": false } } } diff --git a/test/dotnet/test.sh b/test/dotnet/test.sh index a16f91df3..7eb0cf6d5 100755 --- a/test/dotnet/test.sh +++ b/test/dotnet/test.sh @@ -11,7 +11,11 @@ check "sdks" dotnet --list-sdks check "version" dotnet --version echo "Validating expected version present..." -check "some major version of dotnet 6 is installed" dotnet --version | grep '6\.[0-9]*\.[0-9]*' +check "some major version of dotnet 7 is installed" bash -c "dotnet --version | grep '7\.[0-9]*\.[0-9]*'" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk # Report result reportResults \ No newline at end of file From e00724a0c6d4c4f8fab166e065d2b00c7357514b Mon Sep 17 00:00:00 2001 From: JP Ungaretti <19893438+jungaretti@users.noreply.github.com> Date: Mon, 14 Nov 2022 11:46:13 -0800 Subject: [PATCH 009/478] Add git extension for JupyterLab to Python feature (#286) * Add git extension * Bump version --- src/python/devcontainer-feature.json | 2 +- src/python/install.sh | 1 + test/python/install_additional_jupyterlab.sh | 3 +++ test/python/install_jupyterlab.sh | 3 +++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index d6fa9bcf3..c1bcdc633 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.0.12", + "version": "1.0.13", "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 e54387ec4..93d9cce69 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -465,6 +465,7 @@ fi # Install JupyterLab if needed if [ "${INSTALL_JUPYTERLAB}" = "true" ]; then install_user_package jupyterlab + install_user_package jupyterlab-git # Configure JupyterLab if needed if [ -n "${CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN}" ]; then diff --git a/test/python/install_additional_jupyterlab.sh b/test/python/install_additional_jupyterlab.sh index d48bb4683..a5658f0d2 100755 --- a/test/python/install_additional_jupyterlab.sh +++ b/test/python/install_additional_jupyterlab.sh @@ -16,6 +16,9 @@ check "version" jupyter lab --version packages="$(python3 -m pip list)" check "location" grep jupyter <<< "$packages" +# Check for git extension +check "jupyterlab-git" grep jupyterlab-git <<< "$packages" + # Check for correct JupyterLab configuration check "config" grep ".*.allow_origin = '*'" /home/vscode/.jupyter/jupyter_server_config.py diff --git a/test/python/install_jupyterlab.sh b/test/python/install_jupyterlab.sh index d48bb4683..a5658f0d2 100755 --- a/test/python/install_jupyterlab.sh +++ b/test/python/install_jupyterlab.sh @@ -16,6 +16,9 @@ check "version" jupyter lab --version packages="$(python3 -m pip list)" check "location" grep jupyter <<< "$packages" +# Check for git extension +check "jupyterlab-git" grep jupyterlab-git <<< "$packages" + # Check for correct JupyterLab configuration check "config" grep ".*.allow_origin = '*'" /home/vscode/.jupyter/jupyter_server_config.py From eafa28287e15b51a2aa20a227056f0af43d20275 Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Mon, 14 Nov 2022 12:22:02 -0800 Subject: [PATCH 010/478] Add new option to install azure-cli extensions (#165) * Add new option for azure-cli extensions * Update to install az extensions as $_REMOTE_USER * Skip unknown extensions * Change azure cli extension option type to string * Adding test for azure-cli extensions --- src/azure-cli/devcontainer-feature.json | 19 ++++++++++++------- src/azure-cli/install.sh | 12 ++++++++++++ test/azure-cli/install_extensions.sh | 17 +++++++++++++++++ test/azure-cli/scenarios.json | 12 ++++++++++++ 4 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 test/azure-cli/install_extensions.sh create mode 100644 test/azure-cli/scenarios.json diff --git a/src/azure-cli/devcontainer-feature.json b/src/azure-cli/devcontainer-feature.json index 12a40921f..012e28784 100644 --- a/src/azure-cli/devcontainer-feature.json +++ b/src/azure-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "azure-cli", - "version": "1.0.5", + "version": "1.0.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.", @@ -12,16 +12,21 @@ ], "default": "latest", "description": "Select or enter an Azure CLI version. (Available versions may vary by Linux distribution.)" + }, + "extensions": { + "type": "string", + "default": "", + "description": "Optional comma separated list of Azure CLI extensions to install in profile." } }, "customizations": { - "vscode": { - "extensions": [ - "ms-vscode.azurecli" - ] - } + "vscode": { + "extensions": [ + "ms-vscode.azurecli" + ] + } }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] -} +} \ No newline at end of file diff --git a/src/azure-cli/install.sh b/src/azure-cli/install.sh index de5d65dfa..99b4af57e 100755 --- a/src/azure-cli/install.sh +++ b/src/azure-cli/install.sh @@ -13,6 +13,7 @@ set -e rm -rf /var/lib/apt/lists/* AZ_VERSION=${VERSION:-"latest"} +AZ_EXTENSIONS=${EXTENSIONS} MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" AZCLI_ARCHIVE_ARCHITECTURES="amd64" @@ -185,6 +186,17 @@ if [ "${use_pip}" = "true" ]; then fi fi +# If Azure CLI extensions are requested, loop through and install +if [ ${#AZ_EXTENSIONS[@]} -gt 0 ]; then + echo "Installing Azure CLI extensions: ${AZ_EXTENSIONS}" + extensions=(`echo ${AZ_EXTENSIONS} | tr ',' ' '`) + for i in "${extensions[@]}" + do + echo "Installing ${i}" + su ${_REMOTE_USER} -c "az extension add --name ${i} -y" || continue + done +fi + # Clean up rm -rf /var/lib/apt/lists/* diff --git a/test/azure-cli/install_extensions.sh b/test/azure-cli/install_extensions.sh new file mode 100644 index 000000000..1e66e2633 --- /dev/null +++ b/test/azure-cli/install_extensions.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Check to make sure the user is vscode +check "user is vscode" whoami | grep vscode + +# Extension-specific tests +check "aks-preview" az extension show --name aks-preview +check "amg" az extension show --name amg +check "containerapp" az extension show --name containerapp + +# Report result +reportResults \ No newline at end of file diff --git a/test/azure-cli/scenarios.json b/test/azure-cli/scenarios.json new file mode 100644 index 000000000..aa21f7262 --- /dev/null +++ b/test/azure-cli/scenarios.json @@ -0,0 +1,12 @@ +{ + "install_extensions": { + "image": "ubuntu:focal", + "user": "vscode", + "features": { + "azure-cli": { + "version": "latest", + "extensions": "aks-preview,amg,containerapp" + } + } + } +} \ No newline at end of file From 58fed08dcf698f7c09cc78657689ac1581121737 Mon Sep 17 00:00:00 2001 From: JP Ungaretti <19893438+jungaretti@users.noreply.github.com> Date: Mon, 14 Nov 2022 13:42:17 -0800 Subject: [PATCH 011/478] Add support for CUDA 11.8 in nvidia-cuda (#267) * Add latest CUDA versions * Move cuDNN version check * Check CUDA version --- src/nvidia-cuda/devcontainer-feature.json | 8 +++++--- src/nvidia-cuda/install.sh | 14 +++++++------- test/nvidia-cuda/test.sh | 2 ++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/nvidia-cuda/devcontainer-feature.json b/src/nvidia-cuda/devcontainer-feature.json index 76a5ec279..7611b7ef1 100644 --- a/src/nvidia-cuda/devcontainer-feature.json +++ b/src/nvidia-cuda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nvidia-cuda", - "version": "1.0.4", + "version": "1.0.5", "name": "NVIDIA CUDA", "description": "Installs shared libraries for NVIDIA CUDA.", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/nvidia-cuda", @@ -18,6 +18,7 @@ "cudaVersion": { "type": "string", "enum": [ + "11.8", "11.7", "11.6", "11.5", @@ -25,12 +26,13 @@ "11.3", "11.2" ], - "default": "11.7", + "default": "11.8", "description": "Version of CUDA to install" }, "cudnnVersion": { "type": "string", "enum": [ + "8.6.0.163", "8.5.0.96", "8.4.1.50", "8.4.0.27", @@ -45,7 +47,7 @@ "8.1.1.33", "8.1.0.77" ], - "default": "8.5.0.96", + "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 9b417132a..f7db18e5e 100644 --- a/src/nvidia-cuda/install.sh +++ b/src/nvidia-cuda/install.sh @@ -52,17 +52,17 @@ if ! apt-cache show "$cuda_pkg"; then exit 1 fi -# Ensure that the requested version of cuDNN is available AND compatible -cudnn_pkg_version="libcudnn8=${CUDNN_VERSION}-1+cuda${CUDA_VERSION}" -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 -fi - echo "Installing CUDA libraries..." 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 ! 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 + fi + echo "Installing cuDNN libraries..." apt-get install -yq "$cudnn_pkg_version" fi diff --git a/test/nvidia-cuda/test.sh b/test/nvidia-cuda/test.sh index ef50d7bdf..5c56b178d 100644 --- a/test/nvidia-cuda/test.sh +++ b/test/nvidia-cuda/test.sh @@ -5,6 +5,8 @@ set -e # Optional: Import test library source dev-container-features-test-lib +check "cuda version" test -d /usr/local/cuda-11.8 + # Check installation of cuda-libraries-11- check "libcudart.so.11.0" test 1 -eq "$(find /usr -name 'libcudart.so.11.0' | wc -l)" check "libcublas.so.11" test 1 -eq "$(find /usr -name 'libcublas.so.11' | wc -l)" From ada30c21f5148715719bf6d6b94f3e5dce50b19d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 14 Nov 2022 13:47:51 -0800 Subject: [PATCH 012/478] Automated documentation update for Azure CLI and CUDA (#289) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/azure-cli/README.md | 1 + src/nvidia-cuda/README.md | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/azure-cli/README.md b/src/azure-cli/README.md index e32467487..bf6004b7b 100644 --- a/src/azure-cli/README.md +++ b/src/azure-cli/README.md @@ -16,6 +16,7 @@ Installs the Azure CLI along with needed dependencies. Useful for base Dockerfil | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | version | Select or enter an Azure CLI version. (Available versions may vary by Linux distribution.) | string | latest | +| extensions | Optional comma separated list of Azure CLI extensions to install in profile. | string | - | diff --git a/src/nvidia-cuda/README.md b/src/nvidia-cuda/README.md index d756a414f..5e76d7243 100644 --- a/src/nvidia-cuda/README.md +++ b/src/nvidia-cuda/README.md @@ -17,8 +17,8 @@ Installs shared libraries for NVIDIA CUDA. |-----|-----|-----|-----| | installCudnn | Additionally install CUDA Deep Neural Network (cuDNN) shared library | boolean | false | | installNvtx | Additionally install NVIDIA Tools Extension (NVTX) | boolean | false | -| cudaVersion | Version of CUDA to install | string | 11.7 | -| cudnnVersion | Version of cuDNN to install | string | 8.5.0.96 | +| cudaVersion | Version of CUDA to install | string | 11.8 | +| cudnnVersion | Version of cuDNN to install | string | 8.6.0.163 | ## Compatibility From 474444fa9f0decb2d7734828c7f9d629535dcb94 Mon Sep 17 00:00:00 2001 From: "Mikey Lombardi (He/Him)" Date: Tue, 15 Nov 2022 10:19:33 -0600 Subject: [PATCH 013/478] (GH-198) Add `extended` option to hugo feature (#240) Prior to this change, the hugo feature only supported specifying the version of Hugo to install. Hugo is available in two builds: standard, which the feature already installs, and extended, which includes functionality for post-processing CSS/SCSS/SASS and JavaScript. This change adds a new `extended` option to the hugo feature, allowing users to specify that they require the extended build of Hugo. It defaults to `false` and installs the standard build of Hugo. - Resolves #198 --- src/hugo/devcontainer-feature.json | 7 ++++++- src/hugo/install.sh | 9 ++++++++- test/hugo/install_hugo_extended.sh | 12 ++++++++++++ test/hugo/scenarios.json | 11 +++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 test/hugo/install_hugo_extended.sh create mode 100644 test/hugo/scenarios.json diff --git a/src/hugo/devcontainer-feature.json b/src/hugo/devcontainer-feature.json index 7a96d8552..37a805dce 100644 --- a/src/hugo/devcontainer-feature.json +++ b/src/hugo/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "hugo", - "version": "1.0.6", + "version": "1.1.0", "name": "Hugo", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/hugo", "options": { @@ -11,6 +11,11 @@ ], "default": "latest", "description": "Select or enter a version." + }, + "extended": { + "type": "boolean", + "default": false, + "description": "Install Hugo extended for SASS/SCSS changes" } }, "containerEnv": { diff --git a/src/hugo/install.sh b/src/hugo/install.sh index 778b552e7..c5cb628f1 100755 --- a/src/hugo/install.sh +++ b/src/hugo/install.sh @@ -106,7 +106,14 @@ if ! hugo version &> /dev/null ; then arch="64bit" fi - hugo_filename="hugo_${VERSION}_Linux-${arch}.tar.gz" + # Install extended version of hugo if desired + if [ "${EXTENDED}" = "true" ]; then + extended="extended_" + else + extended="" + fi + + hugo_filename="hugo_${extended}${VERSION}_Linux-${arch}.tar.gz" curl -fsSLO --compressed "https://github.com/gohugoio/hugo/releases/download/v${VERSION}/${hugo_filename}" tar -xzf "$hugo_filename" -C "$installation_dir" diff --git a/test/hugo/install_hugo_extended.sh b/test/hugo/install_hugo_extended.sh new file mode 100644 index 000000000..4771d848c --- /dev/null +++ b/test/hugo/install_hugo_extended.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Ensure extended version is installed +check "extended_installed" bash -c "hugo version | grep extended" + +# Report result +reportResults diff --git a/test/hugo/scenarios.json b/test/hugo/scenarios.json new file mode 100644 index 000000000..4c093df1a --- /dev/null +++ b/test/hugo/scenarios.json @@ -0,0 +1,11 @@ +{ + "install_hugo_extended": { + "image": "mcr.microsoft.com/devcontainers/base", + "features": { + "hugo": { + "version": "latest", + "extended": true + } + } + } +} \ No newline at end of file From a5655189a24b04fc43f4ae9dcae0be5acf1b9ecb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 15 Nov 2022 08:23:00 -0800 Subject: [PATCH 014/478] Automated documentation update (#292) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/hugo/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hugo/README.md b/src/hugo/README.md index f66f3c7fc..bc6b99e7f 100644 --- a/src/hugo/README.md +++ b/src/hugo/README.md @@ -16,6 +16,7 @@ | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | version | Select or enter a version. | string | latest | +| extended | Install Hugo extended for SASS/SCSS changes | boolean | false | From f9acb6aae1e520b0b61aaac9ab4ecb00dd497451 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 15 Nov 2022 13:26:26 -0800 Subject: [PATCH 015/478] Python bug fix - Add jupyterlab even if python is not installed by Feature but exists (#244) * python fix bug * fix test * address comments * address comment --- src/python/devcontainer-feature.json | 2 +- src/python/install.sh | 13 +++++++++++-- .../install_jupyterlab_from_python_image.sh | 16 ++++++++++++++++ test/python/scenarios.json | 12 ++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 test/python/install_jupyterlab_from_python_image.sh diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index c1bcdc633..fbbf62c60 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.0.13", + "version": "1.0.14", "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 93d9cce69..79ab7de1c 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -322,7 +322,7 @@ sudo_if() { install_user_package() { PACKAGE="$1" - sudo_if "$INSTALL_PATH/bin/python3" -m pip install --user --upgrade --no-cache-dir "$PACKAGE" + sudo_if "${PYTHON_SRC}" -m pip install --user --upgrade --no-cache-dir "$PACKAGE" } add_user_jupyter_config() { @@ -408,11 +408,15 @@ if [ "${PYTHON_VERSION}" != "none" ]; then updaterc "if [[ \"\${PATH}\" != *\"${CURRENT_PATH}/bin\"* ]]; then export PATH=${CURRENT_PATH}/bin:\${PATH}; fi" PATH="${INSTALL_PATH}/bin:${PATH}" fi - + # Updates the symlinks for os-provided, or the installed python version in other cases chown -R "${USERNAME}:python" "${PYTHON_INSTALL_PATH}" chmod -R g+r+w "${PYTHON_INSTALL_PATH}" find "${PYTHON_INSTALL_PATH}" -type d -print0 | xargs -0 -n 1 chmod g+s + + PYTHON_SRC="${INSTALL_PATH}/bin/python3" +else + PYTHON_SRC=$(which python) fi # Install Python tools if needed @@ -464,6 +468,11 @@ fi # Install JupyterLab if needed if [ "${INSTALL_JUPYTERLAB}" = "true" ]; then + if [ -z "${PYTHON_SRC}" ]; then + echo "(!) Could not install Jupyterlab. Python not found." + exit 1 + fi + install_user_package jupyterlab install_user_package jupyterlab-git diff --git a/test/python/install_jupyterlab_from_python_image.sh b/test/python/install_jupyterlab_from_python_image.sh new file mode 100644 index 000000000..067046b68 --- /dev/null +++ b/test/python/install_jupyterlab_from_python_image.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Always run these checks as the non-root user +user="$(whoami)" +check "user" grep vscode <<< "$user" + +# Check for an installation of JupyterLab +check "version" jupyter lab --version + +# Report result +reportResults diff --git a/test/python/scenarios.json b/test/python/scenarios.json index 920f4a270..c3c1a828b 100644 --- a/test/python/scenarios.json +++ b/test/python/scenarios.json @@ -13,6 +13,7 @@ "remoteUser": "vscode", "features": { "python": { + "version": "latest", "installJupyterlab": true, "configureJupyterlabAllowOrigin": "*" } @@ -36,6 +37,17 @@ "python": "os-provided" } }, + "install_jupyterlab_from_python_image": { + "image": "mcr.microsoft.com/devcontainers/python:3.10-bullseye", + "remoteUser": "vscode", + "features": { + "python": { + "version": "none", + "installTools": false, + "installJupyterlab": true + } + } + }, "install_via_oryx": { "image": "mcr.microsoft.com/oryx/build:full-debian-bullseye", "features": { From 1e35500bda4b00fadc1b2881865ad3cffaa69ff8 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 15 Nov 2022 14:51:00 -0800 Subject: [PATCH 016/478] Node: Fix bug - version set by Feature is not default (#294) * Node:Fix bug version set by Feature is not default * node not supported for ubuntu:bionic --- src/node/devcontainer-feature.json | 2 +- src/node/install.sh | 8 +++++++- test/node/install_node_on_universal_image.sh | 11 +++++++++++ test/node/scenarios.json | 9 +++++++++ 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 test/node/install_node_on_universal_image.sh diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index 538ecb252..49d2160fa 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.1.1", + "version": "1.1.2", "name": "Node.js (via nvm) and yarn", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/node", "description": "Installs Node.js, nvm, yarn, and needed dependencies.", diff --git a/src/node/install.sh b/src/node/install.sh index f51306ebe..2f2e7aa38 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -81,6 +81,12 @@ check_packages() { # Ensure apt is in non-interactive to avoid prompts export DEBIAN_FRONTEND=noninteractive +. /etc/os-release +if [[ "bionic" = *"${VERSION_CODENAME}"* ]]; then + echo "(!) Unsupported distribution version '${VERSION_CODENAME}'. Details: https://github.com/nodejs/node/issues/42351#issuecomment-1068424442" + exit 1 +fi + # Install dependencies check_packages apt-transport-https curl ca-certificates tar gnupg2 dirmngr @@ -152,7 +158,7 @@ if [ ! -d "${NVM_DIR}" ]; then else echo "NVM already installed." if [ "${NODE_VERSION}" != "" ]; then - su ${USERNAME} -c "umask 0002 && . $NVM_DIR/nvm.sh && nvm install ${NODE_VERSION}" + su ${USERNAME} -c "umask 0002 && . $NVM_DIR/nvm.sh && nvm install ${NODE_VERSION} && nvm alias default ${NODE_VERSION}" fi fi diff --git a/test/node/install_node_on_universal_image.sh b/test/node/install_node_on_universal_image.sh new file mode 100644 index 000000000..faca1ebef --- /dev/null +++ b/test/node/install_node_on_universal_image.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "version_on_path" bash -c "node -v | grep 'v19.1.0'" + +# Report result +reportResults diff --git a/test/node/scenarios.json b/test/node/scenarios.json index 1240e61cc..70e105146 100644 --- a/test/node/scenarios.json +++ b/test/node/scenarios.json @@ -25,5 +25,14 @@ "version": "none" } } + }, + "install_node_on_universal_image": { + "image": "mcr.microsoft.com/devcontainers/universal", + "remoteUser": "codespace", + "features": { + "node": { + "version": "19.1.0" + } + } } } \ No newline at end of file From bff31788373499fdc903bad8f1b300d579c42d39 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 16 Nov 2022 10:49:06 -0800 Subject: [PATCH 017/478] Oryx: Unpin git clone from a single commit (#296) --- src/oryx/devcontainer-feature.json | 2 +- src/oryx/install.sh | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json index 741862fe1..2596bd9f9 100644 --- a/src/oryx/devcontainer-feature.json +++ b/src/oryx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oryx", - "version": "1.0.10", + "version": "1.0.11", "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 f613cf002..054983adb 100755 --- a/src/oryx/install.sh +++ b/src/oryx/install.sh @@ -146,12 +146,7 @@ GIT_ORYX=/opt/tmp/oryx-repo mkdir -p ${BUILD_SCRIPT_GENERATOR} mkdir -p ${ORYX} -git clone https://github.com/microsoft/Oryx $GIT_ORYX -cd $GIT_ORYX - -# https://github.com/microsoft/Oryx/commit/74e4830b3636e5cfbce5b3e3358bd5bb66a87f45 is breaking the `oryx` tool -# Pinning to a previous working commit until the upstream issue is fixed. -git reset --hard 2b19efca9729673fc259e6a817be3cc0bb73b9d5 +git clone --depth=1 https://github.com/microsoft/Oryx $GIT_ORYX $GIT_ORYX/build/buildSln.sh From be4f0498e4ad7948804d4be70093c1da8722d222 Mon Sep 17 00:00:00 2001 From: etienne-chrp <66628513+etienne-chrp@users.noreply.github.com> Date: Thu, 17 Nov 2022 01:46:30 +0100 Subject: [PATCH 018/478] Add Gradle and Maven version parameters to Java (#263) * Refactor java feature tests grep syntax The grep with pipe syntax was creating problems with the check helper Change them in favour of process substitution syntax * Fix java feature tests about java version Java 18 is not available anymore in SDKMAN Some tests asserts were generating false positives * Add Gradle and Maven version parameters to Java --- src/java/README.md | 2 ++ src/java/devcontainer-feature.json | 24 ++++++++++++++++++- src/java/install.sh | 6 +++-- test/java/install_additional_java.sh | 6 ++--- test/java/install_from_non_default_distro.sh | 2 +- test/java/install_gradle_and_maven.sh | 6 ++--- .../java/install_gradle_and_maven_for_user.sh | 6 ++--- ..._gradle_and_maven_with_specific_version.sh | 21 ++++++++++++++++ test/java/scenarios.json | 18 +++++++++++--- 9 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 test/java/install_gradle_and_maven_with_specific_version.sh diff --git a/src/java/README.md b/src/java/README.md index c409b3488..a9ef433fb 100644 --- a/src/java/README.md +++ b/src/java/README.md @@ -18,7 +18,9 @@ Installs Java, SDKMAN! (if not installed), and needed dependencies. | version | Select or enter a Java version to install | string | latest | | jdkDistro | Select or enter a JDK distribution | string | ms | | installGradle | Install Gradle, a build automation tool for multi-language software development | boolean | false | +| gradleVersion | Select or enter a Gradle version | string | latest | | installMaven | Install Maven, a management tool for Java | boolean | false | +| mavenVersion | Select or enter a Maven version | string | latest | ## License diff --git a/src/java/devcontainer-feature.json b/src/java/devcontainer-feature.json index 19d6c13a6..c400fb6c7 100644 --- a/src/java/devcontainer-feature.json +++ b/src/java/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "java", - "version": "1.0.11", + "version": "1.1.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.", @@ -33,10 +33,32 @@ "default": false, "description": "Install Gradle, a build automation tool for multi-language software development" }, + "gradleVersion": { + "type": "string", + "proposals": [ + "latest", + "7.5.1", + "6.9.3", + "5.6.4" + ], + "default": "latest", + "description": "Select or enter a Gradle version" + }, "installMaven": { "type": "boolean", "default": false, "description": "Install Maven, a management tool for Java" + }, + "mavenVersion": { + "type": "string", + "proposals": [ + "latest", + "3.8.6", + "3.6.3", + "3.5.4" + ], + "default": "latest", + "description": "Select or enter a Maven version" } }, "buildArg": "_VSC_INSTALL_JAVA", diff --git a/src/java/install.sh b/src/java/install.sh index d2f735d0d..592847800 100755 --- a/src/java/install.sh +++ b/src/java/install.sh @@ -11,7 +11,9 @@ JAVA_VERSION=${VERSION:-"lts"} INSTALL_GRADLE=${INSTALLGRADLE:-"false"} +GRADLE_VERSION=${GRADLEVERSION:-"latest"} INSTALL_MAVEN=${INSTALLMAVEN:-"false"} +MAVEN_VERSION=${MAVENVERSION:-"latest"} JDK_DISTRO=${JDKDISTRO} export SDKMAN_DIR=${SDKMAN_DIR:-"/usr/local/sdkman"} @@ -173,12 +175,12 @@ fi # Install Gradle if [[ "${INSTALL_GRADLE}" = "true" ]] && ! gradle --version > /dev/null; then - sdk_install gradle latest + sdk_install gradle ${GRADLE_VERSION} fi # Install Maven if [[ "${INSTALL_MAVEN}" = "true" ]] && ! mvn --version > /dev/null; then - sdk_install maven latest + sdk_install maven ${MAVEN_VERSION} fi # Clean up diff --git a/test/java/install_additional_java.sh b/test/java/install_additional_java.sh index fcfd6bdb9..882c49d1c 100644 --- a/test/java/install_additional_java.sh +++ b/test/java/install_additional_java.sh @@ -5,9 +5,9 @@ set -e # Optional: Import test library source dev-container-features-test-lib -check "java version 18 installed as default" java --version | grep 18 -check "java version 11 installed" ls /usr/local/sdkman/candidates/java | grep 11 -check "java version 8 installed" ls /usr/local/sdkman/candidates/java | grep 8 +check "java version 11 installed as default" grep "11\." <(java --version) +check "java version 17 installed" grep "^17\." <(ls /usr/local/sdkman/candidates/java) +check "java version 8 installed" grep "^8\." <(ls /usr/local/sdkman/candidates/java) # Report result reportResults diff --git a/test/java/install_from_non_default_distro.sh b/test/java/install_from_non_default_distro.sh index e45f9dd60..d4f53818e 100644 --- a/test/java/install_from_non_default_distro.sh +++ b/test/java/install_from_non_default_distro.sh @@ -5,7 +5,7 @@ set -e # Optional: Import test library source dev-container-features-test-lib -check "java version 18 installed as default" java --version | grep 18 +check "java version openjdk 11 installed" grep "openjdk 11." <(java --version) # Report result reportResults diff --git a/test/java/install_gradle_and_maven.sh b/test/java/install_gradle_and_maven.sh index c6aa3e521..636fd92a0 100644 --- a/test/java/install_gradle_and_maven.sh +++ b/test/java/install_gradle_and_maven.sh @@ -5,17 +5,17 @@ set -e # Optional: Import test library source dev-container-features-test-lib -check "user is root" whoami | grep root +check "user is root" grep root <(whoami) check "java" java --version check "gradle" gradle --version cd /tmp && gradle init --type basic --dsl groovy --incubating --project-name test -check "GRADLE_USER_HOME exists" ls -la /root | grep ".gradle" +check "GRADLE_USER_HOME exists" grep ".gradle" <(ls -la /root) check "maven" mvn --version cd /tmp && mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false -check "m2 exists" ls -la /root | grep ".m2" +check "m2 exists" grep ".m2" <(ls -la /root) # Report result reportResults diff --git a/test/java/install_gradle_and_maven_for_user.sh b/test/java/install_gradle_and_maven_for_user.sh index c724092fc..b6ea4266b 100644 --- a/test/java/install_gradle_and_maven_for_user.sh +++ b/test/java/install_gradle_and_maven_for_user.sh @@ -5,17 +5,17 @@ set -e # Optional: Import test library source dev-container-features-test-lib -check "user is vscode" whoami | grep vscode +check "user is vscode" grep vscode <(whoami) check "java" java --version check "gradle" gradle --version cd /tmp && gradle init --type basic --dsl groovy --incubating --project-name test -check "GRADLE_USER_HOME exists" ls -la /home/vscode | grep ".gradle" +check "GRADLE_USER_HOME exists" grep ".gradle" <(ls -la /home/vscode) check "maven" mvn --version cd /tmp && mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false -check "m2 exists" ls -la /home/vscode | grep ".m2" +check "m2 exists" grep ".m2" <(ls -la /home/vscode) # Report result reportResults diff --git a/test/java/install_gradle_and_maven_with_specific_version.sh b/test/java/install_gradle_and_maven_with_specific_version.sh new file mode 100644 index 000000000..c6ae6160c --- /dev/null +++ b/test/java/install_gradle_and_maven_with_specific_version.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "user is root" grep root <(whoami) + +check "java" java --version +check "gradle version" grep "Gradle 6.8.3" <(gradle --version) + +cd /tmp && gradle init --type basic --dsl groovy --project-name test +check "GRADLE_USER_HOME exists" grep ".gradle" <(ls -la /root) + +check "maven version" grep "Apache Maven 3.6.3" <(mvn --version) +cd /tmp && mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false +check "m2 exists" grep ".m2" <(ls -la /root) + +# Report result +reportResults diff --git a/test/java/scenarios.json b/test/java/scenarios.json index eec7ba53e..c33a0a7d4 100644 --- a/test/java/scenarios.json +++ b/test/java/scenarios.json @@ -3,7 +3,7 @@ "image": "ubuntu:focal", "features": { "java": { - "version": "18", + "version": "11", "jdkDistro": "open" } } @@ -12,8 +12,8 @@ "image": "ubuntu:focal", "features": { "java": { - "version": "18", - "additionalVersions": "11,8" + "version": "11", + "additionalVersions": "17,8" } } }, @@ -40,5 +40,17 @@ "installMaven": true } } + }, + "install_gradle_and_maven_with_specific_version": { + "image": "ubuntu:focal", + "features": { + "java": { + "version": "latest", + "installGradle": "true", + "gradleVersion": "6.8.3", + "installMaven": "true", + "mavenVersion": "3.6.3" + } + } } } From 3fc9604ddadc34ec44651ce981cebc7bd77095e5 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Thu, 17 Nov 2022 11:55:43 -0800 Subject: [PATCH 019/478] Oryx: Build with .NET 6 (#298) * Oryx: Install dotnet 3.1 runtime * fix tests * build with .NET 6 + add tests * add tests * fix tests * shellcheck: nit --- src/oryx/devcontainer-feature.json | 2 +- src/oryx/install.sh | 20 +++++++++------ src/python/devcontainer-feature.json | 2 +- src/python/install.sh | 2 +- test/oryx/sample-python/requirements.txt | 2 ++ test/oryx/sample-python/src/solve.py | 12 +++++++++ test/oryx/scenarios.json | 15 +++++++++++ test/oryx/test_python_project.sh | 32 ++++++++++++++++++++++++ 8 files changed, 77 insertions(+), 10 deletions(-) create mode 100644 test/oryx/sample-python/requirements.txt create mode 100644 test/oryx/sample-python/src/solve.py create mode 100644 test/oryx/test_python_project.sh diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json index 2596bd9f9..5c643445b 100644 --- a/src/oryx/devcontainer-feature.json +++ b/src/oryx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oryx", - "version": "1.0.11", + "version": "1.0.12", "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 054983adb..aa4af2c8c 100755 --- a/src/oryx/install.sh +++ b/src/oryx/install.sh @@ -116,9 +116,8 @@ echo "Installing Oryx..." # Ensure apt is in non-interactive to avoid prompts export DEBIAN_FRONTEND=noninteractive - # Install dependencies -check_packages git sudo curl ca-certificates apt-transport-https gnupg2 dirmngr libc-bin +check_packages git sudo curl ca-certificates apt-transport-https gnupg2 dirmngr libc-bin moreutils if ! cat /etc/group | grep -e "^oryx:" > /dev/null 2>&1; then groupadd -r oryx @@ -127,16 +126,23 @@ usermod -a -G oryx "${USERNAME}" # Required to decide if we want to clean up dotnet later. DOTNET_INSTALLATION_PACKAGE="" +DOTNET_BINARY="" + +if dotnet --version > /dev/null ; then + DOTNET_BINARY=$(which dotnet) +fi -# Install dotnet unless available -if ! dotnet --version > /dev/null ; then - echo "'dotnet' was not detected. Attempting to install the latest version of the dotnet sdk to build oryx." +# Oryx needs to be built with .NET 6 +if [[ "${DOTNET_BINARY}" = "" ]] || [[ "$(dotnet --version)" != *"6"* ]] ; then + echo "'dotnet 6' was not detected. Attempting to install .NET 6 to build oryx." install_dotnet_using_apt if ! dotnet --version > /dev/null ; then echo "(!) Please install Dotnet before installing Oryx" exit 1 fi + + DOTNET_BINARY="/usr/bin/dotnet" fi BUILD_SCRIPT_GENERATOR=/usr/local/buildscriptgen @@ -150,8 +156,8 @@ git clone --depth=1 https://github.com/microsoft/Oryx $GIT_ORYX $GIT_ORYX/build/buildSln.sh -dotnet publish -property:ValidateExecutableReferencesMatchSelfContained=false -r linux-x64 -o ${BUILD_SCRIPT_GENERATOR} -c Release $GIT_ORYX/src/BuildScriptGeneratorCli/BuildScriptGeneratorCli.csproj -dotnet 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 +${DOTNET_BINARY} publish -r linux-x64 -o ${BUILD_SCRIPT_GENERATOR} -c Release $GIT_ORYX/src/BuildServer/BuildServer.csproj chmod a+x ${BUILD_SCRIPT_GENERATOR}/GenerateBuildScript diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index fbbf62c60..b96511b9f 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.0.14", + "version": "1.0.15", "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 79ab7de1c..d823cc99e 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -17,7 +17,7 @@ export PIPX_HOME=${PIPX_HOME:-"/usr/local/py-utils"} USERNAME=${USERNAME:-"automatic"} UPDATE_RC=${UPDATE_RC:-"true"} -USE_ORYX_IF_AVAILABLE=${USE_ORYX_IF_AVAILABLE:-"true"} +USE_ORYX_IF_AVAILABLE=${USEORYXIFAVAILABLE:-"true"} INSTALL_JUPYTERLAB=${INSTALLJUPYTERLAB:-"false"} CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN=${CONFIGUREJUPYTERLABALLOWORIGIN:-""} diff --git a/test/oryx/sample-python/requirements.txt b/test/oryx/sample-python/requirements.txt new file mode 100644 index 000000000..c8a04f68a --- /dev/null +++ b/test/oryx/sample-python/requirements.txt @@ -0,0 +1,2 @@ +mpmath==1.2.1 +sympy==1.11.1 diff --git a/test/oryx/sample-python/src/solve.py b/test/oryx/sample-python/src/solve.py new file mode 100644 index 000000000..141a99646 --- /dev/null +++ b/test/oryx/sample-python/src/solve.py @@ -0,0 +1,12 @@ +from sympy import Symbol, Eq, solve + +x = Symbol("x") +y = Symbol("y") + +equation_1 = Eq((x + y), 2) +equation_2 = Eq((x - y), 4) +print("Equation 1:", equation_1) +print("Equation 2:", equation_2) + +solution = solve((equation_1, equation_2), (x, y)) +print("Solution:", solution) diff --git a/test/oryx/scenarios.json b/test/oryx/scenarios.json index 4b9fa90e9..bbfc277a9 100644 --- a/test/oryx/scenarios.json +++ b/test/oryx/scenarios.json @@ -8,5 +8,20 @@ }, "oryx": {} } + }, + "test_python_project": { + "image": "ubuntu:focal", + "features": { + "python": { + "version": "3.10.4", + "additionalVersions": "3.9.7", + "useOryxIfAvailable": "false" + }, + "dotnet": { + "version": "7", + "installUsingApt": "false" + }, + "oryx": {} + } } } \ No newline at end of file diff --git a/test/oryx/test_python_project.sh b/test/oryx/test_python_project.sh new file mode 100644 index 000000000..a0d5eef08 --- /dev/null +++ b/test/oryx/test_python_project.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +cd sample-python + +# Replicates Oryx's behavior for universal image +DEBIAN_FLAVOR="focal-scm" +mkdir -p /opt/oryx && echo "vso-focal" > /opt/oryx/.imagetype +echo "DEBIAN|${DEBIAN_FLAVOR}" | tr '[a-z]' '[A-Z]' > /opt/oryx/.ostype + +ln -snf /usr/local/oryx/* /opt/oryx + +PYTHON_PATH="/home/codespace/.python/current" +mkdir -p /home/codespace/.python +ln -snf /usr/local/python/current $PYTHON_PATH +ln -snf /usr/local/python /opt/python + +export PATH="/home/codespace/.python/current/bin:${PATH}" +which python + +pythonVersion=$(python -V 2>&1 | grep -Po '(?<=Python )(.+)') +pythonSite=`python -m site --user-site` +check "oryx-build-python" oryx build --property python_version="${pythonVersion}" --property packagedir="${pythonSite}" ./ +check "oryx-build-python-installed" python3 -m pip list | grep mpmath +check "oryx-build-python-result" python3 ./src/solve.py + +# Report result +reportResults From 173c7ca3c7ad646e6b9732b5af8d45f08606182e Mon Sep 17 00:00:00 2001 From: Ilkka Poutanen Date: Fri, 18 Nov 2022 20:26:05 +0200 Subject: [PATCH 020/478] Install git before github-cli (#301) * Install git before github-cli If building a devcontainer on e.g. `debian:bullseye`, github-cli installation can fail due to git not being installed yet: ``` 0 13.38 2022-11-18 13:37:19 (6.08 MB/s) - 'gh_2.20.2_linux_amd64.deb' saved [10 176698/10176698] #0 13.38 #0 13.40 Selecting previously unselected package gh. #0 13.41 (Reading database ... 13628 files and directories currently installed.) #0 13.41 Preparing to unpack .../gh_2.20.2_linux_amd64.deb ... #0 13.41 Unpacking gh (2.20.2) ... #0 13.65 dpkg: dependency problems prevent configuration of gh: #0 13.65 gh depends on git; however: #0 13.65 Package git is not installed. #0 13.65 #0 13.65 dpkg: error processing package gh (--install): #0 13.65 dependency problems - leaving unconfigured #0 13.66 Errors were encountered while processing: #0 13.66 gh #0 13.67 ERROR: Feature "GitHub CLI" (ghcr.io/devcontainers/features/github-cli) failed to install! Look at the documentation at https://github.com/devcontainer s/features/tree/main/src/github-cli for help troubleshooting this error. ``` * bump version Co-authored-by: Josh Spicer --- src/github-cli/devcontainer-feature.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/github-cli/devcontainer-feature.json b/src/github-cli/devcontainer-feature.json index fe8b76246..65968c173 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.6", + "version": "1.0.7", "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.", @@ -20,7 +20,8 @@ } }, "installsAfter": [ - "ghcr.io/devcontainers/features/common-utils" + "ghcr.io/devcontainers/features/common-utils", + "ghcr.io/devcontainers/features/git" ] } From c4648ab98cdeeb520e7e629c5db4a471ec802954 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 23 Nov 2022 09:33:50 -0800 Subject: [PATCH 021/478] go: fix bug - Go doesn't update version if go is already installed (#303) * go: fix bug - Go doesn't update version if go is already installed * Update tests with bash -c --- src/go/devcontainer-feature.json | 2 +- src/go/install.sh | 11 +++++++---- test/go/install_go_tool_in_postCreate.sh | 6 +++--- test/go/install_go_twice.sh | 11 +++++++++++ test/go/scenarios.json | 8 ++++++++ test/go/test.sh | 2 +- 6 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 test/go/install_go_twice.sh diff --git a/src/go/devcontainer-feature.json b/src/go/devcontainer-feature.json index c83b4f076..b2aa30bc7 100644 --- a/src/go/devcontainer-feature.json +++ b/src/go/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "go", - "version": "1.1.0", + "version": "1.1.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.", diff --git a/src/go/install.sh b/src/go/install.sh index f561144e7..844411fcd 100755 --- a/src/go/install.sh +++ b/src/go/install.sh @@ -142,7 +142,8 @@ if ! cat /etc/group | grep -e "^golang:" > /dev/null 2>&1; then fi usermod -a -G golang "${USERNAME}" mkdir -p "${TARGET_GOROOT}" "${TARGET_GOPATH}" -if [ "${TARGET_GO_VERSION}" != "none" ] && ! type go > /dev/null 2>&1; then + +if [[ "${TARGET_GO_VERSION}" != "none" ]] && [[ "$(go version)" != *"${TARGET_GO_VERSION}"* ]]; then # Use a temporary locaiton for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} @@ -186,7 +187,7 @@ if [ "${TARGET_GO_VERSION}" != "none" ] && ! type go > /dev/null 2>&1; then tar -xzf /tmp/go.tar.gz -C "${TARGET_GOROOT}" --strip-components=1 rm -rf /tmp/go.tar.gz /tmp/go.tar.gz.asc /tmp/tmp-gnupg else - echo "Go already installed. Skipping." + echo "(!) Go is already installed with version ${TARGET_GO_VERSION}. Skipping." fi # Install Go tools that are isImportant && !replacedByGopls based on @@ -218,8 +219,10 @@ if [ "${INSTALL_GO_TOOLS}" = "true" ]; then (echo "${GO_TOOLS}" | xargs -n 1 go ${go_install_command} -v )2>&1 | tee -a /usr/local/etc/vscode-dev-containers/go.log # Move Go tools into path and clean up - mv /tmp/gotools/bin/* ${TARGET_GOPATH}/bin/ - rm -rf /tmp/gotools + if [ -d /tmp/gotools/bin ]; then + mv /tmp/gotools/bin/* ${TARGET_GOPATH}/bin/ + rm -rf /tmp/gotools + fi # Install golangci-lint from precompiled binares if [ "$GOLANGCILINT_VERSION" = "latest" ] || [ "$GOLANGCILINT_VERSION" = "" ]; then diff --git a/test/go/install_go_tool_in_postCreate.sh b/test/go/install_go_tool_in_postCreate.sh index dbb086cfc..54637d956 100644 --- a/test/go/install_go_tool_in_postCreate.sh +++ b/test/go/install_go_tool_in_postCreate.sh @@ -5,9 +5,9 @@ set -e # Optional: Import test library source dev-container-features-test-lib -check "mkcert version" mkcert --version | grep "v1.4.2" -check "mkcert is installed at correct path" which mkcert | grep "/go/bin/mkcert" -check "golangci-lint version" golangci-lint --version | grep "golangci-lint has version 1.50.0" +check "mkcert version" bash -c "mkcert --version | grep v1.4.2" +check "mkcert is installed at correct path" bash -c "which mkcert | grep /go/bin/mkcert" +check "golangci-lint version" bash -c "golangci-lint --version | grep 'golangci-lint has version 1.50.0'" # Report result reportResults diff --git a/test/go/install_go_twice.sh b/test/go/install_go_twice.sh new file mode 100644 index 000000000..8f6ef5431 --- /dev/null +++ b/test/go/install_go_twice.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "go-version" bash -c "go version | grep 1.19" + +# Report result +reportResults diff --git a/test/go/scenarios.json b/test/go/scenarios.json index b3fe49c0a..86e127020 100644 --- a/test/go/scenarios.json +++ b/test/go/scenarios.json @@ -8,5 +8,13 @@ } }, "postCreateCommand": "go install filippo.io/mkcert@v1.4.2" + }, + "install_go_twice": { + "image": "mcr.microsoft.com/devcontainers/go:1.18", + "features": { + "go": { + "version": "1.19" + } + } } } diff --git a/test/go/test.sh b/test/go/test.sh index ee9f171af..ccae6da84 100755 --- a/test/go/test.sh +++ b/test/go/test.sh @@ -7,7 +7,7 @@ source dev-container-features-test-lib check "version" go version check "revive version" revive --version -check "revive is installed at correct path" which revive | grep "/go/bin/revive" +check "revive is installed at correct path" bash -c "which revive | grep /go/bin/revive" # Report result reportResults \ No newline at end of file From 133b4cf23c6e4d6679940a8806f76877790c7f45 Mon Sep 17 00:00:00 2001 From: Paul Yu Date: Wed, 23 Nov 2022 12:18:22 -0800 Subject: [PATCH 022/478] Optionally install Azure Bicep as part of azure-cli feature (#305) * Adding azure-cli bicep installer to correctly install on arm64 containers * Adding a few updates following @joshspicer's review. --- src/azure-cli/devcontainer-feature.json | 7 ++++++- src/azure-cli/install.sh | 25 +++++++++++++++++++++++++ test/azure-cli/install_bicep.sh | 16 ++++++++++++++++ test/azure-cli/scenarios.json | 12 +++++++++++- 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 test/azure-cli/install_bicep.sh diff --git a/src/azure-cli/devcontainer-feature.json b/src/azure-cli/devcontainer-feature.json index 012e28784..a2ba45221 100644 --- a/src/azure-cli/devcontainer-feature.json +++ b/src/azure-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "azure-cli", - "version": "1.0.6", + "version": "1.0.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.", @@ -17,6 +17,11 @@ "type": "string", "default": "", "description": "Optional comma separated list of Azure CLI extensions to install in profile." + }, + "installBicep": { + "type": "boolean", + "description": "Optionally install Azure Bicep", + "default": false } }, "customizations": { diff --git a/src/azure-cli/install.sh b/src/azure-cli/install.sh index 99b4af57e..31bc6d864 100755 --- a/src/azure-cli/install.sh +++ b/src/azure-cli/install.sh @@ -14,6 +14,7 @@ rm -rf /var/lib/apt/lists/* AZ_VERSION=${VERSION:-"latest"} AZ_EXTENSIONS=${EXTENSIONS} +AZ_INSTALLBICEP=${INSTALLBICEP:-false} MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" AZCLI_ARCHIVE_ARCHITECTURES="amd64" @@ -197,6 +198,30 @@ if [ ${#AZ_EXTENSIONS[@]} -gt 0 ]; then done fi +if [ "${AZ_INSTALLBICEP}" = "true" ]; then + # Install dependencies + check_packages apt-transport-https curl + + # Properly install Azure Bicep based on current architecture + # The `az bicep install` command installs the linux-x64 binary even on arm64 devcontainers + # 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 [ "${architecture}" = "arm64" ]; then + curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-arm64 + else + curl -Lo bicep https://github.com/Azure/bicep/releases/latest/download/bicep-linux-x64 + fi + + chmod +x ./bicep + mv ./bicep /usr/local/bin/bicep + + # Add a symlink so bicep can be accessed as a standalone executable or as part of az + mkdir -p ${_REMOTE_USER_HOME}/.azure/bin + chown -hR ${_REMOTE_USER}:${_REMOTE_USER} ${_REMOTE_USER_HOME}/.azure + ln -s /usr/local/bin/bicep ${_REMOTE_USER_HOME}/.azure/bin/bicep +fi + # Clean up rm -rf /var/lib/apt/lists/* diff --git a/test/azure-cli/install_bicep.sh b/test/azure-cli/install_bicep.sh new file mode 100644 index 000000000..955507fda --- /dev/null +++ b/test/azure-cli/install_bicep.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Check to make sure the user is vscode +check "user is vscode" whoami | grep vscode + +# Bicep-specific tests +check "bicep" bicep --version +check "az bicep" az bicep version + +# Report result +reportResults \ No newline at end of file diff --git a/test/azure-cli/scenarios.json b/test/azure-cli/scenarios.json index aa21f7262..cc1fd7512 100644 --- a/test/azure-cli/scenarios.json +++ b/test/azure-cli/scenarios.json @@ -1,6 +1,6 @@ { "install_extensions": { - "image": "ubuntu:focal", + "image": "mcr.microsoft.com/devcontainers/base:jammy", "user": "vscode", "features": { "azure-cli": { @@ -8,5 +8,15 @@ "extensions": "aks-preview,amg,containerapp" } } + }, + "install_bicep": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "user": "vscode", + "features": { + "azure-cli": { + "version": "latest", + "installBicep": true + } + } } } \ No newline at end of file From 188f1ef26bc8fa942d552dfaa8596091a8a39126 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 23 Nov 2022 12:46:03 -0800 Subject: [PATCH 023/478] Automated documentation update (#306) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/azure-cli/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/azure-cli/README.md b/src/azure-cli/README.md index bf6004b7b..9b7735f70 100644 --- a/src/azure-cli/README.md +++ b/src/azure-cli/README.md @@ -17,6 +17,7 @@ Installs the Azure CLI along with needed dependencies. Useful for base Dockerfil |-----|-----|-----|-----| | version | Select or enter an Azure CLI version. (Available versions may vary by Linux distribution.) | string | latest | | extensions | Optional comma separated list of Azure CLI extensions to install in profile. | string | - | +| installBicep | Optionally install Azure Bicep | boolean | false | From 4b3ccf36eabcad859a13806a8dc47dfa651182a1 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 23 Nov 2022 15:03:07 -0800 Subject: [PATCH 024/478] Adds test coverage (#308) * Add test coverage * temp: debug test * Update tests --- test/desktop-lite/test.sh | 4 +++- test/docker-from-docker/docker_init.sh | 15 +++++++++++++++ test/docker-from-docker/scenarios.json | 11 +++++++++++ test/docker-from-docker/test.sh | 2 ++ .../azureDnsAutoDetectionDisabled.sh | 2 +- .../azureDnsAutoDetectionEnabled.sh | 2 +- test/docker-in-docker/dockerDefaultAddressPool.sh | 2 +- test/docker-in-docker/test.sh | 7 ++++++- test/sshd/test.sh | 6 +++++- 9 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 test/docker-from-docker/docker_init.sh create mode 100644 test/docker-from-docker/scenarios.json diff --git a/test/desktop-lite/test.sh b/test/desktop-lite/test.sh index bd0a51639..9009aa9c6 100755 --- a/test/desktop-lite/test.sh +++ b/test/desktop-lite/test.sh @@ -5,7 +5,9 @@ set -e # Optional: Import test library source dev-container-features-test-lib -echo 'NO TESTS FOR ME YET!' +check "desktop-init-exists" bash -c "ls /usr/local/share/desktop-init.sh" +check "log-exists" bash -c "ls /tmp/container-init.log" +check "fluxbox-exists" bash -c "ls -la ~/.fluxbox" # Report result reportResults \ No newline at end of file diff --git a/test/docker-from-docker/docker_init.sh b/test/docker-from-docker/docker_init.sh new file mode 100644 index 000000000..216492129 --- /dev/null +++ b/test/docker-from-docker/docker_init.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "docker-init-exists" bash -c "ls /usr/local/share/docker-init.sh" +check "log-exists" bash -c "ls /tmp/vscr-docker-from-docker.log" +check "log-contents-for-success" bash -c "cat /tmp/vscr-docker-from-docker.log | grep 'Success'" +check "log-contents" bash -c "cat /tmp/vscr-docker-from-docker.log | grep 'Proxying /var/run/docker-host.sock to /var/run/docker.sock for vscode'" +check "docker-ps" bash -c "docker ps" + +# Report result +reportResults \ No newline at end of file diff --git a/test/docker-from-docker/scenarios.json b/test/docker-from-docker/scenarios.json new file mode 100644 index 000000000..196e00bf6 --- /dev/null +++ b/test/docker-from-docker/scenarios.json @@ -0,0 +1,11 @@ +{ + "docker_init": { + "image": "mcr.microsoft.com/devcontainers/base", + "remoteUser": "vscode", + "features": { + "docker-from-docker": { + "version": "latest" + } + } + } +} diff --git a/test/docker-from-docker/test.sh b/test/docker-from-docker/test.sh index 3a802b59b..517737ada 100755 --- a/test/docker-from-docker/test.sh +++ b/test/docker-from-docker/test.sh @@ -7,6 +7,8 @@ source dev-container-features-test-lib # Definition specific tests check "version" docker --version +check "docker-init-exists" bash -c "ls /usr/local/share/docker-init.sh" +check "docker-ps" bash -c "docker ps" # Report result reportResults \ No newline at end of file diff --git a/test/docker-in-docker/azureDnsAutoDetectionDisabled.sh b/test/docker-in-docker/azureDnsAutoDetectionDisabled.sh index d3f4159d0..2415116d1 100644 --- a/test/docker-in-docker/azureDnsAutoDetectionDisabled.sh +++ b/test/docker-in-docker/azureDnsAutoDetectionDisabled.sh @@ -6,7 +6,7 @@ set -e source dev-container-features-test-lib # Definition specific tests -check "dns flag should not be present" test ! "$(ps -ax | grep -E 'dockerd.+\-\-dns')" +check "dns flag should not be present" test ! "$(ps -ax | grep -v grep | grep -E 'dockerd.+\-\-dns')" # Report result reportResults \ No newline at end of file diff --git a/test/docker-in-docker/azureDnsAutoDetectionEnabled.sh b/test/docker-in-docker/azureDnsAutoDetectionEnabled.sh index e63a1f316..87f158aac 100644 --- a/test/docker-in-docker/azureDnsAutoDetectionEnabled.sh +++ b/test/docker-in-docker/azureDnsAutoDetectionEnabled.sh @@ -6,7 +6,7 @@ set -e source dev-container-features-test-lib # Definition specific tests -check "dns flag should be present" ps -ax | grep -E "dockerd.+\-\-dns" +check "dns flag should be present" ps -ax | grep -v grep | grep -E "dockerd.+\-\-dns" # Report result reportResults \ No newline at end of file diff --git a/test/docker-in-docker/dockerDefaultAddressPool.sh b/test/docker-in-docker/dockerDefaultAddressPool.sh index 8345357a8..219ad8215 100644 --- a/test/docker-in-docker/dockerDefaultAddressPool.sh +++ b/test/docker-in-docker/dockerDefaultAddressPool.sh @@ -6,7 +6,7 @@ set -e source dev-container-features-test-lib # Definition specific tests -check "default address pool setting set" ps -ax | grep -E "dockerd.+base=192.168.0.0/16,size=24" +check "default address pool setting set" ps -ax | grep -v grep | grep -E "dockerd.+base=192.168.0.0/16,size=24" # Report result reportResults \ No newline at end of file diff --git a/test/docker-in-docker/test.sh b/test/docker-in-docker/test.sh index 3a802b59b..1eebfd243 100755 --- a/test/docker-in-docker/test.sh +++ b/test/docker-in-docker/test.sh @@ -5,8 +5,13 @@ set -e # Optional: Import test library source dev-container-features-test-lib -# Definition specific tests +# Feature specific tests check "version" docker --version +check "docker-init-exists" bash -c "ls /usr/local/share/docker-init.sh" +check "log-exists" bash -c "ls /tmp/dockerd.log" +check "log-for-completion" bash -c "cat /tmp/dockerd.log | grep 'Daemon has completed initialization'" +check "log-contents" bash -c "cat /tmp/dockerd.log | grep 'API listen on /var/run/docker.sock'" +check "docker-ps" bash -c "docker ps" # Report result reportResults \ No newline at end of file diff --git a/test/sshd/test.sh b/test/sshd/test.sh index bd0a51639..6aac9e588 100755 --- a/test/sshd/test.sh +++ b/test/sshd/test.sh @@ -5,7 +5,11 @@ set -e # Optional: Import test library source dev-container-features-test-lib -echo 'NO TESTS FOR ME YET!' +check "sshd-init-exists" bash -c "ls /usr/local/share/ssh-init.sh" +check "sshd-log-exists" bash -c "ls /tmp/sshd.log" +check "sshd-log-contents" bash -c "cat /tmp/sshd.log | grep 'Starting OpenBSD Secure Shell server'" +check "sshd-log-has-sshd" bash -c "cat /tmp/sshd.log | grep 'sshd'" +check "sshd" bash -c "ps -aux | grep -v grep | grep sshd" # Report result reportResults \ No newline at end of file From 30f287605354478d4af5d6c8736c9a414369110c Mon Sep 17 00:00:00 2001 From: Chuck Lantz Date: Mon, 28 Nov 2022 10:10:56 -0600 Subject: [PATCH 025/478] Fix bad path to systemctl (#302) --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 9a135d516..74b85081b 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "1.1.4", + "version": "1.1.5", "name": "Common Debian 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/install.sh b/src/common-utils/install.sh index 8ac0a7c62..878e9caa1 100755 --- a/src/common-utils/install.sh +++ b/src/common-utils/install.sh @@ -292,7 +292,7 @@ cat << 'EOF' > /usr/local/bin/systemctl #!/bin/sh set -e if [ -d "/run/systemd/system" ]; then - exec /bin/systemctl/systemctl "$@" + exec /bin/systemctl "$@" else echo '\n"systemd" is not running in this container due to its overhead.\nUse the "service" command to start services instead. e.g.: \n\nservice --status-all' fi From 4af4c291225a165e5a9b0e5a65c450e81e5aecf0 Mon Sep 17 00:00:00 2001 From: Claudio Bandera Date: Mon, 28 Nov 2022 20:05:21 +0100 Subject: [PATCH 026/478] Proposal for fix of #312 (#313) * Proposal for fix of #312 This change moves the directory separator into the `PIPX_DIR` variable in order to not introduce an error in the case pipx has already been installed systemwide. * Bump patch version of python feature to 1.0.16 --- src/python/devcontainer-feature.json | 2 +- src/python/install.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index b96511b9f..ca474ab4c 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.0.15", + "version": "1.0.16", "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 d823cc99e..0c3f9e0fb 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -450,11 +450,11 @@ if [[ "${INSTALL_PYTHON_TOOLS}" = "true" ]] && [[ $(python --version) != "" ]]; if ! type pipx > /dev/null 2>&1; then pip3 install --disable-pip-version-check --no-cache-dir --user pipx 2>&1 /tmp/pip-tmp/bin/pipx install --pip-args=--no-cache-dir pipx - PIPX_DIR="/tmp/pip-tmp/bin" + PIPX_DIR="/tmp/pip-tmp/bin/" fi for util in "${DEFAULT_UTILS[@]}"; do if ! type ${util} > /dev/null 2>&1; then - "${PIPX_DIR}/pipx" install --system-site-packages --pip-args '--no-cache-dir --force-reinstall' ${util} + "${PIPX_DIR}pipx" install --system-site-packages --pip-args '--no-cache-dir --force-reinstall' ${util} else echo "${util} already installed. Skipping." fi From d1972b4d8d2dc75370c236c9dafe505ea42590f2 Mon Sep 17 00:00:00 2001 From: Chuck Lantz Date: Mon, 28 Nov 2022 17:07:38 -0600 Subject: [PATCH 027/478] Use _REMOTE_USER when available (#264) * Use _REMOTE_USER when available * Update src/python/install.sh Co-authored-by: Samruddhi Khandale * Update src/python/install.sh Co-authored-by: Samruddhi Khandale * Fix java test issue - JDK 18 not available for the "open" distro * Bump breakfix numbers Co-authored-by: Samruddhi Khandale Co-authored-by: Josh Spicer --- src/anaconda/devcontainer-feature.json | 2 +- src/anaconda/install.sh | 8 +++---- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/install.sh | 14 ++++++------ src/conda/devcontainer-feature.json | 2 +- src/conda/install.sh | 2 +- src/desktop-lite/devcontainer-feature.json | 2 +- src/desktop-lite/install.sh | 7 +++--- .../devcontainer-feature.json | 2 +- src/docker-from-docker/install.sh | 16 +++++++------- .../devcontainer-feature.json | 2 +- src/docker-in-docker/install.sh | 16 +++++++------- src/dotnet/devcontainer-feature.json | 2 +- src/dotnet/install.sh | 16 +++++++------- src/go/devcontainer-feature.json | 2 +- src/go/install.sh | 12 +++++----- src/hugo/devcontainer-feature.json | 2 +- src/hugo/install.sh | 8 +++---- src/java/devcontainer-feature.json | 2 +- src/java/install.sh | 20 ++++++++--------- src/java/wrapper.sh | 10 ++++----- .../devcontainer-feature.json | 2 +- src/kubectl-helm-minikube/install.sh | 2 +- src/node/devcontainer-feature.json | 2 +- src/node/install.sh | 8 +++---- src/oryx/install.sh | 4 ++-- src/php/devcontainer-feature.json | 2 +- src/php/install.sh | 14 ++++++------ src/python/devcontainer-feature.json | 2 +- src/python/install.sh | 22 +++++++++---------- src/ruby/devcontainer-feature.json | 2 +- src/ruby/install.sh | 10 ++++----- src/rust/devcontainer-feature.json | 2 +- src/rust/install.sh | 16 +++++++------- src/sshd/devcontainer-feature.json | 2 +- src/sshd/install.sh | 10 ++++----- test/java/scenarios.json | 2 +- 37 files changed, 125 insertions(+), 126 deletions(-) mode change 100755 => 100644 src/dotnet/install.sh mode change 100755 => 100644 src/java/install.sh diff --git a/src/anaconda/devcontainer-feature.json b/src/anaconda/devcontainer-feature.json index 7308699cf..cdf1fbf7e 100644 --- a/src/anaconda/devcontainer-feature.json +++ b/src/anaconda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "anaconda", - "version": "1.0.9", + "version": "1.0.10", "name": "Anaconda", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/anaconda", "options": { diff --git a/src/anaconda/install.sh b/src/anaconda/install.sh index 47f3462d5..53c606a1e 100755 --- a/src/anaconda/install.sh +++ b/src/anaconda/install.sh @@ -8,10 +8,10 @@ # Maintainer: The VS Code and Codespaces Teams -VERSION=${VERSION:-"latest"} -USERNAME=${USERNAME:-"automatic"} -UPDATE_RC=${UPDATE_RC:-"true"} -CONDA_DIR=${CONDA_DIR:-"/usr/local/conda"} +VERSION="${VERSION:-"latest"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${UPDATE_RC:-"true"}" +CONDA_DIR="${CONDA_DIR:-"/usr/local/conda"}" set -eux export DEBIAN_FRONTEND=noninteractive diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 74b85081b..812e5e9e0 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "1.1.5", + "version": "1.1.6", "name": "Common Debian 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/install.sh b/src/common-utils/install.sh index 878e9caa1..5530b96d9 100755 --- a/src/common-utils/install.sh +++ b/src/common-utils/install.sh @@ -12,13 +12,13 @@ set -e # Clean up rm -rf /var/lib/apt/lists/* -INSTALL_ZSH=${INSTALLZSH:-"true"} -INSTALL_OH_MY_ZSH=${INSTALLOHMYZSH:-"true"} -UPGRADE_PACKAGES=${UPGRADEPACKAGES:-"true"} -USERNAME=${USERNAME:-"automatic"} -USER_UID=${UID:-"automatic"} -USER_GID=${GID:-"automatic"} -ADD_NON_FREE_PACKAGES=${NONFREEPACKAGES:-"false"} +INSTALL_ZSH="${INSTALLZSH:-"true"}" +INSTALL_OH_MY_ZSH="${INSTALLOHMYZSH:-"true"}" +UPGRADE_PACKAGES="${UPGRADEPACKAGES:-"true"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +USER_UID="${UID:-"automatic"}" +USER_GID="${GID:-"automatic"}" +ADD_NON_FREE_PACKAGES="${NONFREEPACKAGES:-"false"}" MARKER_FILE="/usr/local/etc/vscode-dev-containers/common" diff --git a/src/conda/devcontainer-feature.json b/src/conda/devcontainer-feature.json index da4c6746f..8ff6499dd 100644 --- a/src/conda/devcontainer-feature.json +++ b/src/conda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "conda", - "version": "1.0.5", + "version": "1.0.6", "name": "Conda", "description": "A cross-platform, language-agnostic binary package manager", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/conda", diff --git a/src/conda/install.sh b/src/conda/install.sh index 9b51bbd29..6e9088221 100644 --- a/src/conda/install.sh +++ b/src/conda/install.sh @@ -7,7 +7,7 @@ VERSION=${VERSION:-"latest"} ADD_CONDA_FORGE=$ADDCONDAFORGE -USERNAME="automatic" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" UPDATE_RC="true" CONDA_DIR="/opt/conda" diff --git a/src/desktop-lite/devcontainer-feature.json b/src/desktop-lite/devcontainer-feature.json index 9420dc3dd..e0333867f 100644 --- a/src/desktop-lite/devcontainer-feature.json +++ b/src/desktop-lite/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "desktop-lite", - "version": "1.0.5", + "version": "1.0.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.", diff --git a/src/desktop-lite/install.sh b/src/desktop-lite/install.sh index dc8ee3932..60bec121b 100755 --- a/src/desktop-lite/install.sh +++ b/src/desktop-lite/install.sh @@ -7,14 +7,13 @@ # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/desktop-lite.md # Maintainer: The VS Code and Codespaces Teams -NOVNC_VERSION=${NOVNCVERSION:-"1.2.0"} # TODO: Add in a 'latest' auto-detect and swap name to 'version' +NOVNC_VERSION="${NOVNCVERSION:-"1.2.0"}" # TODO: Add in a 'latest' auto-detect and swap name to 'version' VNC_PASSWORD=${PASSWORD:-"vscode"} NOVNC_PORT="${WEBPORT:-6080}" VNC_PORT="${VNCPORT:-5901}" -INSTALL_NOVNC=${INSTALL_NOVNC:-"true"} -USERNAME=${USERNAME:-"automatic"} - +INSTALL_NOVNC="${INSTALL_NOVNC:-"true"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" WEBSOCKETIFY_VERSION=0.10.0 diff --git a/src/docker-from-docker/devcontainer-feature.json b/src/docker-from-docker/devcontainer-feature.json index dc7208973..2ebdd3833 100644 --- a/src/docker-from-docker/devcontainer-feature.json +++ b/src/docker-from-docker/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "docker-from-docker", - "version": "1.0.6", + "version": "1.0.7", "name": "Docker (Docker-from-Docker)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-from-docker", "descripton": "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-from-docker/install.sh b/src/docker-from-docker/install.sh index d128ab9c9..1307bfc91 100755 --- a/src/docker-from-docker/install.sh +++ b/src/docker-from-docker/install.sh @@ -7,14 +7,14 @@ # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker.md # Maintainer: The VS Code and Codespaces Teams -DOCKER_VERSION=${VERSION:-"latest"} -USE_MOBY=${MOBY:-"true"} -DOCKER_DASH_COMPOSE_VERSION=${DOCKERDASHCOMPOSEVERSION:-"v1"} # v1 or v2 - -ENABLE_NONROOT_DOCKER=${ENABLE_NONROOT_DOCKER:-"true"} -SOURCE_SOCKET=${SOURCE_SOCKET:-"/var/run/docker-host.sock"} -TARGET_SOCKET=${TARGET_SOCKET:-"/var/run/docker.sock"} -USERNAME=${USERNAME:-"automatic"} +DOCKER_VERSION="${VERSION:-"latest"}" +USE_MOBY="${MOBY:-"true"}" +DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2 + +ENABLE_NONROOT_DOCKER="${ENABLE_NONROOT_DOCKER:-"true"}" +SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}" +TARGET_SOCKET="${TARGET_SOCKET:-"/var/run/docker.sock"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="buster bullseye bionic focal jammy" diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 95a6a2c5a..95d6841fd 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": "1.0.8", + "version": "1.0.9", "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-in-docker/install.sh b/src/docker-in-docker/install.sh index fe4692f3e..d35112143 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -8,14 +8,14 @@ # Maintainer: The VS Code and Codespaces Teams -DOCKER_VERSION=${VERSION:-"latest"} # The Docker/Moby Engine + CLI should match in version -USE_MOBY=${MOBY:-"true"} -DOCKER_DASH_COMPOSE_VERSION=${DOCKERDASHCOMPOSEVERSION:-"v1"} # v1 or v2 -AZURE_DNS_AUTO_DETECTION=${AZUREDNSAUTODETECTION:-"true"} -DOCKER_DEFAULT_ADDRESS_POOL=${DOCKERDEFAULTADDRESSPOOL} - -ENABLE_NONROOT_DOCKER=${ENABLE_NONROOT_DOCKER:-"true"} -USERNAME=${USERNAME:-"automatic"} +DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version +USE_MOBY="${MOBY:-"true"}" +DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2 +AZURE_DNS_AUTO_DETECTION="${AZUREDNSAUTODETECTION:-"true"}" +DOCKER_DEFAULT_ADDRESS_POOL="${DOCKERDEFAULTADDRESSPOOL}" + +ENABLE_NONROOT_DOCKER="${ENABLE_NONROOT_DOCKER:-"true"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="buster bullseye bionic focal jammy" diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index 42eb1c287..e8bb9f16c 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "1.1.0", + "version": "1.1.1", "name": "Dotnet CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet", "description": "Installs the .NET CLI. Provides option of installing sdk or runtime, and option of versions to install. Uses latest version of .NET sdk as defaults to install.", diff --git a/src/dotnet/install.sh b/src/dotnet/install.sh old mode 100755 new mode 100644 index 78cd691df..13285abbd --- a/src/dotnet/install.sh +++ b/src/dotnet/install.sh @@ -7,18 +7,18 @@ # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/dotnet.md # Maintainer: The VS Code and Codespaces Teams -DOTNET_VERSION=${VERSION:-"latest"} -DOTNET_RUNTIME_ONLY=${RUNTIMEONLY:-"false"} -OVERRIDE_DEFAULT_VERSION=${OVERRIDEDEFAULTVERSION:-"true"} -INSTALL_USING_APT=${INSTALLUSINGAPT:-"true"} +DOTNET_VERSION="${VERSION:-"latest"}" +DOTNET_RUNTIME_ONLY="${RUNTIMEONLY:-"false"}" +OVERRIDE_DEFAULT_VERSION="${OVERRIDEDEFAULTVERSION:-"true"}" +INSTALL_USING_APT="${INSTALLUSINGAPT:-"true"}" DOTNET_LATEST="7" DOTNET_LTS="6" -USERNAME=${USERNAME:-"automatic"} -UPDATE_RC=${UPDATE_RC:-"true"} -TARGET_DOTNET_ROOT=${TARGET_DOTNET_ROOT:-"/usr/local/dotnet"} -ACCESS_GROUP=${ACCESS_GROUP:-"dotnet"} +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${UPDATE_RC:-"true"}" +TARGET_DOTNET_ROOT="${TARGET_DOTNET_ROOT:-"/usr/local/dotnet"}" +ACCESS_GROUP="${ACCESS_GROUP:-"dotnet"}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" DOTNET_ARCHIVE_ARCHITECTURES="amd64" diff --git a/src/go/devcontainer-feature.json b/src/go/devcontainer-feature.json index b2aa30bc7..f63d93ec1 100644 --- a/src/go/devcontainer-feature.json +++ b/src/go/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "go", - "version": "1.1.1", + "version": "1.1.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.", diff --git a/src/go/install.sh b/src/go/install.sh index 844411fcd..1b65e50ce 100755 --- a/src/go/install.sh +++ b/src/go/install.sh @@ -7,13 +7,13 @@ # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/go.md # Maintainer: The VS Code and Codespaces Teams -TARGET_GO_VERSION=${VERSION:-"latest"} -GOLANGCILINT_VERSION=${GOLANGCILINTVERSION:-"latest"} +TARGET_GO_VERSION="${VERSION:-"latest"}" +GOLANGCILINT_VERSION="${GOLANGCILINTVERSION:-"latest"}" -TARGET_GOROOT=${TARGET_GOROOT:-"/usr/local/go"} -TARGET_GOPATH=${TARGET_GOPATH:-"/go"} -USERNAME=${USERNAME:-"automatic"} -INSTALL_GO_TOOLS=${INSTALL_GO_TOOLS:-"true"} +TARGET_GOROOT="${TARGET_GOROOT:-"/usr/local/go"}" +TARGET_GOPATH="${TARGET_GOPATH:-"/go"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +INSTALL_GO_TOOLS="${INSTALL_GO_TOOLS:-"true"}" # https://www.google.com/linuxrepositories/ GO_GPG_KEY_URI="https://dl.google.com/linux/linux_signing_key.pub" diff --git a/src/hugo/devcontainer-feature.json b/src/hugo/devcontainer-feature.json index 37a805dce..ffc1a3bdb 100644 --- a/src/hugo/devcontainer-feature.json +++ b/src/hugo/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "hugo", - "version": "1.1.0", + "version": "1.1.1", "name": "Hugo", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/hugo", "options": { diff --git a/src/hugo/install.sh b/src/hugo/install.sh index c5cb628f1..b268e384b 100755 --- a/src/hugo/install.sh +++ b/src/hugo/install.sh @@ -7,12 +7,12 @@ # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/hugo.md # Maintainer: The VS Code and Codespaces Teams -VERSION=${VERSION:-"latest"} +VERSION="${VERSION:-"latest"}" -USERNAME=${USERNAME:-"automatic"} -UPDATE_RC=${UPDATE_RC:-"true"} +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${UPDATE_RC:-"true"}" -HUGO_DIR=${HUGO_DIR:-"/usr/local/hugo"} +HUGO_DIR="${HUGO_DIR:-"/usr/local/hugo"}" set -e diff --git a/src/java/devcontainer-feature.json b/src/java/devcontainer-feature.json index c400fb6c7..4c7df039b 100644 --- a/src/java/devcontainer-feature.json +++ b/src/java/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "java", - "version": "1.1.0", + "version": "1.1.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 old mode 100755 new mode 100644 index 592847800..bf9496304 --- a/src/java/install.sh +++ b/src/java/install.sh @@ -9,20 +9,20 @@ # # Syntax: ./java-debian.sh [JDK version] [SDKMAN_DIR] [non-root user] [Add to rc files flag] -JAVA_VERSION=${VERSION:-"lts"} -INSTALL_GRADLE=${INSTALLGRADLE:-"false"} -GRADLE_VERSION=${GRADLEVERSION:-"latest"} -INSTALL_MAVEN=${INSTALLMAVEN:-"false"} -MAVEN_VERSION=${MAVENVERSION:-"latest"} -JDK_DISTRO=${JDKDISTRO} +JAVA_VERSION="${VERSION:-"lts"}" +INSTALL_GRADLE="${INSTALLGRADLE:-"false"}" +GRADLE_VERSION="${GRADLEVERSION:-"latest"}" +INSTALL_MAVEN="${INSTALLMAVEN:-"false"}" +MAVEN_VERSION="${MAVENVERSION:-"latest"}" +JDK_DISTRO="${JDKDISTRO}" -export SDKMAN_DIR=${SDKMAN_DIR:-"/usr/local/sdkman"} -USERNAME=${USERNAME:-"automatic"} -UPDATE_RC=${UPDATE_RC:-"true"} +export SDKMAN_DIR="${SDKMAN_DIR:-"/usr/local/sdkman"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${UPDATE_RC:-"true"}" # Comma-separated list of java versions to be installed # alongside JAVA_VERSION, but not set as default. -ADDITIONAL_VERSIONS=${ADDITIONALVERSIONS:-""} +ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" set -e diff --git a/src/java/wrapper.sh b/src/java/wrapper.sh index d7f05de6c..bea343f96 100644 --- a/src/java/wrapper.sh +++ b/src/java/wrapper.sh @@ -3,11 +3,11 @@ set -e -JAVA_VERSION=${1:-"default"} -SDKMAN_DIR=${2:-"/usr/local/sdkman"} -USERNAME=${3:-"automatic"} -UPDATE_RC=${4:-"true"} -ADDITIONAL_JAVA_VERSION=11 +JAVA_VERSION="${1:-"default"}" +SDKMAN_DIR="${2:-"/usr/local/sdkman"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${4:-"true"}" +ADDITIONAL_JAVA_VERSION="11" cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" chmod +x install.sh diff --git a/src/kubectl-helm-minikube/devcontainer-feature.json b/src/kubectl-helm-minikube/devcontainer-feature.json index f8098b403..beea80a2e 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.0", + "version": "1.1.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.", diff --git a/src/kubectl-helm-minikube/install.sh b/src/kubectl-helm-minikube/install.sh index c961e5652..3ab65356f 100755 --- a/src/kubectl-helm-minikube/install.sh +++ b/src/kubectl-helm-minikube/install.sh @@ -19,7 +19,7 @@ MINIKUBE_VERSION="${MINIKUBE:-"none"}" # latest is also valid KUBECTL_SHA256="${KUBECTL_SHA256:-"automatic"}" HELM_SHA256="${HELM_SHA256:-"automatic"}" MINIKUBE_SHA256="${MINIKUBE_SHA256:-"automatic"}" -USERNAME=${USERNAME:-"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:80 diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index 49d2160fa..3abfb0400 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.1.2", + "version": "1.1.3", "name": "Node.js (via nvm) and yarn", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/node", "description": "Installs Node.js, nvm, yarn, and needed dependencies.", diff --git a/src/node/install.sh b/src/node/install.sh index 2f2e7aa38..9b027d861 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -7,17 +7,17 @@ # Docs: https://github.com/devcontainers/features/tree/main/src/node # Maintainer: The Dev Container spec maintainers -export NODE_VERSION=${VERSION:-"lts"} +export NODE_VERSION="${VERSION:-"lts"}" export NVM_VERSION="${NVMVERSION:-"0.39.2"}" export NVM_DIR=${NVMINSTALLPATH:-"/usr/local/share/nvm"} INSTALL_TOOLS_FOR_NODE_GYP="${NODEGYPDEPENDENCIES:-true}" # Comma-separated list of node versions to be installed (with nvm) # alongside NODE_VERSION, but not set as default. -ADDITIONAL_VERSIONS=${ADDITIONALVERSIONS:-""} +ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" -USERNAME=${USERNAME:-"automatic"} -UPDATE_RC=${UPDATE_RC:-"true"} +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${UPDATE_RC:-"true"}" set -e diff --git a/src/oryx/install.sh b/src/oryx/install.sh index aa4af2c8c..a1b64d3e9 100755 --- a/src/oryx/install.sh +++ b/src/oryx/install.sh @@ -5,8 +5,8 @@ #------------------------------------------------------------------------------------------------------------- -USERNAME=${USERNAME:-"automatic"} -UPDATE_RC=${UPDATE_RC:-"true"} +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${UPDATE_RC:-"true"}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" diff --git a/src/php/devcontainer-feature.json b/src/php/devcontainer-feature.json index 181851e32..bad987872 100644 --- a/src/php/devcontainer-feature.json +++ b/src/php/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "php", - "version": "1.0.8", + "version": "1.0.9", "name": "PHP", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/php", "options": { diff --git a/src/php/install.sh b/src/php/install.sh index 70b63da69..381bec21b 100755 --- a/src/php/install.sh +++ b/src/php/install.sh @@ -11,17 +11,17 @@ set -eux # Clean up rm -rf /var/lib/apt/lists/* -VERSION=${VERSION:-"latest"} -INSTALL_COMPOSER=${INSTALLCOMPOSER:-"true"} -OVERRIDE_DEFAULT_VERSION=${OVERRIDEDEFAULTVERSION:-"true"} +VERSION="${VERSION:-"latest"}" +INSTALL_COMPOSER="${INSTALLCOMPOSER:-"true"}" +OVERRIDE_DEFAULT_VERSION="${OVERRIDEDEFAULTVERSION:-"true"}" -export PHP_DIR=${PHP_DIR:-"/usr/local/php"} -USERNAME=${USERNAME:-"automatic"} -UPDATE_RC=${UPDATE_RC:-"true"} +export PHP_DIR="${PHP_DIR:-"/usr/local/php"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${UPDATE_RC:-"true"}" # Comma-separated list of php versions to be installed # alongside VERSION, but not set as default. -ADDITIONAL_VERSIONS=${ADDITIONALVERSIONS:-""} +ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" export DEBIAN_FRONTEND=noninteractive diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index ca474ab4c..8daf3e90b 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.0.16", + "version": "1.0.17", "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 0c3f9e0fb..76fd6f09f 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -7,24 +7,24 @@ # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/python.md # Maintainer: The VS Code and Codespaces Teams -PYTHON_VERSION=${VERSION:-"latest"} # 'system' checks the base image first, else installs 'latest' -INSTALL_PYTHON_TOOLS=${INSTALLTOOLS:-"true"} -OPTIMIZE_BUILD_FROM_SOURCE=${OPTIMIZE:-"false"} -PYTHON_INSTALL_PATH=${INSTALLPATH:-"/usr/local/python"} -OVERRIDE_DEFAULT_VERSION=${OVERRIDEDEFAULTVERSION:-"true"} +PYTHON_VERSION="${VERSION:-"latest"}" # 'system' or 'os-provided' checks the base image first, else installs 'latest' +INSTALL_PYTHON_TOOLS="${INSTALLTOOLS:-"true"}" +OPTIMIZE_BUILD_FROM_SOURCE="${OPTIMIZE:-"false"}" +PYTHON_INSTALL_PATH="${INSTALLPATH:-"/usr/local/python"}" +OVERRIDE_DEFAULT_VERSION="${OVERRIDEDEFAULTVERSION:-"true"}" export PIPX_HOME=${PIPX_HOME:-"/usr/local/py-utils"} -USERNAME=${USERNAME:-"automatic"} -UPDATE_RC=${UPDATE_RC:-"true"} -USE_ORYX_IF_AVAILABLE=${USEORYXIFAVAILABLE:-"true"} +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${UPDATE_RC:-"true"}" +USE_ORYX_IF_AVAILABLE="${USEORYXIFAVAILABLE:-"true"}" -INSTALL_JUPYTERLAB=${INSTALLJUPYTERLAB:-"false"} -CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN=${CONFIGUREJUPYTERLABALLOWORIGIN:-""} +INSTALL_JUPYTERLAB="${INSTALLJUPYTERLAB:-"false"}" +CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN="${CONFIGUREJUPYTERLABALLOWORIGIN:-""}" # Comma-separated list of python versions to be installed # alongside PYTHON_VERSION, but not set as default. -ADDITIONAL_VERSIONS=${ADDITIONALVERSIONS:-""} +ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" DEFAULT_UTILS=("pylint" "flake8" "autopep8" "black" "yapf" "mypy" "pydocstyle" "pycodestyle" "bandit" "pipenv" "virtualenv") PYTHON_SOURCE_GPG_KEYS="64E628F8D684696D B26995E310250568 2D347EA6AA65421D FB9921286F5E1540 3A5CA953F73C700D 04C367C218ADD4FF 0EDDC5F26A45C816 6AF053F07D9DC8D2 C9BE28DEE6DF025C 126EB563A74B06BF D9866941EA5BBD71 ED9D77D5" diff --git a/src/ruby/devcontainer-feature.json b/src/ruby/devcontainer-feature.json index c76d85dbc..e11c1727a 100644 --- a/src/ruby/devcontainer-feature.json +++ b/src/ruby/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby", - "version": "1.0.6", + "version": "1.0.7", "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 22285225b..dcf404229 100755 --- a/src/ruby/install.sh +++ b/src/ruby/install.sh @@ -7,15 +7,15 @@ # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/ruby.md # Maintainer: The VS Code and Codespaces Teams -RUBY_VERSION=${VERSION:-"latest"} +RUBY_VERSION="${VERSION:-"latest"}" -USERNAME=${USERNAME:-"automatic"} -UPDATE_RC=${UPDATE_RC:-"true"} -INSTALL_RUBY_TOOLS=${INSTALL_RUBY_TOOLS:-"true"} +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${UPDATE_RC:-"true"}" +INSTALL_RUBY_TOOLS="${INSTALL_RUBY_TOOLS:-"true"}" # Comma-separated list of ruby versions to be installed (with rvm) # alongside RUBY_VERSION, but not set as default. -ADDITIONAL_VERSIONS=${ADDITIONALVERSIONS:-""} +ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" # Note: ruby-debug-ide will install the right version of debase if missing and # installing debase directly fails on Ruby 3.1.0 as of 1/7/2022, so omitting. diff --git a/src/rust/devcontainer-feature.json b/src/rust/devcontainer-feature.json index 2dca581fc..8a7f5b432 100644 --- a/src/rust/devcontainer-feature.json +++ b/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "1.0.8", + "version": "1.0.9", "name": "Rust", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust", "description": "Installs Rust, common Rust utilities, and their required dependencies", diff --git a/src/rust/install.sh b/src/rust/install.sh index e7cfb7151..1a309923a 100755 --- a/src/rust/install.sh +++ b/src/rust/install.sh @@ -7,14 +7,14 @@ # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/rust.md # Maintainer: The VS Code and Codespaces Teams -RUST_VERSION=${VERSION:-"latest"} -RUSTUP_PROFILE=${PROFILE:-"minimal"} - -export CARGO_HOME=${CARGO_HOME:-"/usr/local/cargo"} -export RUSTUP_HOME=${RUSTUP_HOME:-"/usr/local/rustup"} -USERNAME=${USERNAME:-"automatic"} -UPDATE_RC=${UPDATE_RC:-"true"} -UPDATE_RUST=${UPDATE_RUST:-"false"} +RUST_VERSION="${VERSION:-"latest"}" +RUSTUP_PROFILE="${PROFILE:-"minimal"}" + +export CARGO_HOME="${CARGO_HOME:-"/usr/local/cargo"}" +export RUSTUP_HOME="${RUSTUP_HOME:-"/usr/local/rustup"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +UPDATE_RC="${UPDATE_RC:-"true"}" +UPDATE_RUST="${UPDATE_RUST:-"false"}" set -e diff --git a/src/sshd/devcontainer-feature.json b/src/sshd/devcontainer-feature.json index 6433f3f1f..b8b7badaf 100644 --- a/src/sshd/devcontainer-feature.json +++ b/src/sshd/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sshd", - "version": "1.0.5", + "version": "1.0.6", "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.", diff --git a/src/sshd/install.sh b/src/sshd/install.sh index a93b927f5..634f16301 100755 --- a/src/sshd/install.sh +++ b/src/sshd/install.sh @@ -9,11 +9,11 @@ # # Note: You can change your user's password with "sudo passwd $(whoami)" (or just "passwd" if running as root). -SSHD_PORT=${SSHD_PORT:-"2222"} -USERNAME=${USERNAME:-"automatic"} -START_SSHD=${START_SSHD:-"false"} -NEW_PASSWORD=${NEW_PASSWORD:-"skip"} -FIX_ENVIRONMENT=${FIX_ENVIRONMENT:-"true"} +SSHD_PORT="${SSHD_PORT:-"2222"}" +USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +START_SSHD="${START_SSHD:-"false"}" +NEW_PASSWORD="${NEW_PASSWORD:-"skip"}" +FIX_ENVIRONMENT="${FIX_ENVIRONMENT:-"true"}" set -e diff --git a/test/java/scenarios.json b/test/java/scenarios.json index c33a0a7d4..479ee4703 100644 --- a/test/java/scenarios.json +++ b/test/java/scenarios.json @@ -3,7 +3,7 @@ "image": "ubuntu:focal", "features": { "java": { - "version": "11", + "version": "19", "jdkDistro": "open" } } From cf36e7ac3aa76ddf73cdcb082aee4ccdd8b58a08 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 29 Nov 2022 17:08:10 -0800 Subject: [PATCH 028/478] docker-in-docker fix : Use ${devcontainerId} for volume name (#314) Fix --- src/docker-in-docker/devcontainer-feature.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 95d6841fd..0ac565e7b 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": "1.0.9", + "version": "2.0.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,7 +55,7 @@ }, "mounts": [ { - "source": "dind-var-lib-docker", + "source": "dind-var-lib-docker-${devcontainerId}", "target": "/var/lib/docker", "type": "volume" } From 64f0e10fab232f132c566f5c70d419f3106c381b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Nov 2022 17:10:37 -0800 Subject: [PATCH 029/478] Automated documentation update (#315) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/docker-in-docker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docker-in-docker/README.md b/src/docker-in-docker/README.md index 8ee91ef2b..58f72c5a5 100644 --- a/src/docker-in-docker/README.md +++ b/src/docker-in-docker/README.md @@ -7,7 +7,7 @@ Create child containers *inside* a container, independent from the host's docker ```json "features": { - "ghcr.io/devcontainers/features/docker-in-docker:1": {} + "ghcr.io/devcontainers/features/docker-in-docker:2": {} } ``` From 46dfa11ecd3c507187eebbd6784c09d736737255 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 30 Nov 2022 13:42:57 -0800 Subject: [PATCH 030/478] Github cli - Adds retry logic for find git tags (#310) * Github cli - Adds retry logic for find git tags * re-add set -e * address comment --- src/github-cli/devcontainer-feature.json | 2 +- src/github-cli/install.sh | 49 +++++++++++++ src/nix/utils.sh | 13 +++- test/github-cli/test.sh | 88 ++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 4 deletions(-) diff --git a/src/github-cli/devcontainer-feature.json b/src/github-cli/devcontainer-feature.json index 65968c173..824602c53 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.7", + "version": "1.0.8", "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 b46a6a221..65bbfc479 100755 --- a/src/github-cli/install.sh +++ b/src/github-cli/install.sh @@ -158,6 +158,46 @@ find_version_from_git_tags() { echo "${variable_name}=${!variable_name}" } +# Use semver logic to decrement a version number then look for the closest match +find_prev_version_from_git_tags() { + local variable_name=$1 + local current_version=${!variable_name} + local repository=$2 + # Normally a "v" is used before the version number, but support alternate cases + local prefix=${3:-"tags/v"} + # Some repositories use "_" instead of "." for version number part separation, support that + local separator=${4:-"."} + # Some tools release versions that omit the last digit (e.g. go) + local last_part_optional=${5:-"false"} + # Some repositories may have tags that include a suffix (e.g. actions/node-versions) + local version_suffix_regex=$6 + # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios. + set +e + major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')" + minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')" + breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')" + + if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then + ((major=major-1)) + declare -g ${variable_name}="${major}" + # Look for latest version from previous major release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" + # Handle situations like Go's odd version pattern where "0" releases omit the last part + elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then + ((minor=minor-1)) + declare -g ${variable_name}="${major}.${minor}" + # Look for latest version from previous minor release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" + else + ((breakfix=breakfix-1)) + if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then + declare -g ${variable_name}="${major}.${minor}" + else + declare -g ${variable_name}="${major}.${minor}.${breakfix}" + fi + fi + set -e +} # Fall back on direct download if no apt package exists # Fetches .deb file to be installed with dpkg @@ -171,6 +211,15 @@ install_deb_using_github() { mkdir -p /tmp/ghcli pushd /tmp/ghcli wget https://github.com/cli/cli/releases/download/v${CLI_VERSION}/${cli_filename} + 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 "(!) github-cli version ${CLI_VERSION} failed to download. Attempting to fall back one version to retry..." + find_prev_version_from_git_tags CLI_VERSION https://github.com/cli/cli + wget https://github.com/cli/cli/releases/download/v${CLI_VERSION}/${cli_filename} + fi + dpkg -i /tmp/ghcli/${cli_filename} popd rm -rf /tmp/ghcli diff --git a/src/nix/utils.sh b/src/nix/utils.sh index 68cdd9d1b..5753e5a02 100755 --- a/src/nix/utils.sh +++ b/src/nix/utils.sh @@ -282,14 +282,19 @@ find_prev_version_from_git_tags() { major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')" minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')" breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')" - set -e + + if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then + ((major=major-1)) + declare -g ${variable_name}="${major}" + # Look for latest version from previous major release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" # Handle situations like Go's odd version pattern where "0" releases omit the last part - if [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then + elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then ((minor=minor-1)) declare -g ${variable_name}="${major}.${minor}" # Look for latest version from previous minor release find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" - else + else ((breakfix=breakfix-1)) if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then declare -g ${variable_name}="${major}.${minor}" @@ -297,4 +302,6 @@ find_prev_version_from_git_tags() { declare -g ${variable_name}="${major}.${minor}.${breakfix}" fi fi + + set -e } \ No newline at end of file diff --git a/test/github-cli/test.sh b/test/github-cli/test.sh index a419c3463..58df559d7 100755 --- a/test/github-cli/test.sh +++ b/test/github-cli/test.sh @@ -8,5 +8,93 @@ source dev-container-features-test-lib # Definition specific tests check "version" gh --version +find_version_from_git_tags() { + local variable_name=$1 + local requested_version=${!variable_name} + if [ "${requested_version}" = "none" ]; then return; fi + local repository=$2 + local prefix=${3:-"tags/v"} + local separator=${4:-"."} + local last_part_optional=${5:-"false"} + if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then + local escaped_separator=${separator//./\\.} + local last_part + if [ "${last_part_optional}" = "true" ]; then + last_part="(${escaped_separator}[0-9]+)?" + else + 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)" + if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then + declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" + else + set +e + declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" + set -e + fi + fi + if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then + echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 + exit 1 + fi + echo "${variable_name}=${!variable_name}" +} + +find_prev_version_from_git_tags() { + local variable_name=$1 + local current_version=${!variable_name} + local repository=$2 + # Normally a "v" is used before the version number, but support alternate cases + local prefix=${3:-"tags/v"} + # Some repositories use "_" instead of "." for version number part separation, support that + local separator=${4:-"."} + # Some tools release versions that omit the last digit (e.g. go) + local last_part_optional=${5:-"false"} + # Some repositories may have tags that include a suffix (e.g. actions/node-versions) + local version_suffix_regex=$6 + # Try one break fix version number less if we get a failure. Use "set +e" since "set -e" can cause failures in valid scenarios. + set +e + major="$(echo "${current_version}" | grep -oE '^[0-9]+' || echo '')" + minor="$(echo "${current_version}" | grep -oP '^[0-9]+\.\K[0-9]+' || echo '')" + breakfix="$(echo "${current_version}" | grep -oP '^[0-9]+\.[0-9]+\.\K[0-9]+' 2>/dev/null || echo '')" + + if [ "${minor}" = "0" ] && [ "${breakfix}" = "0" ]; then + ((major=major-1)) + declare -g ${variable_name}="${major}" + # Look for latest version from previous major release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" + # Handle situations like Go's odd version pattern where "0" releases omit the last part + elif [ "${breakfix}" = "" ] || [ "${breakfix}" = "0" ]; then + ((minor=minor-1)) + declare -g ${variable_name}="${major}.${minor}" + # Look for latest version from previous minor release + find_version_from_git_tags "${variable_name}" "${repository}" "${prefix}" "${separator}" "${last_part_optional}" + else + ((breakfix=breakfix-1)) + if [ "${breakfix}" = "0" ] && [ "${last_part_optional}" = "true" ]; then + declare -g ${variable_name}="${major}.${minor}" + else + declare -g ${variable_name}="${major}.${minor}.${breakfix}" + fi + fi +} + +CLI_VERSION="2.20.0" +find_prev_version_from_git_tags CLI_VERSION https://github.com/cli/cli +check "pre-version-to-2.20.0" bash -c "echo ${CLI_VERSION} | grep '2.19.0'" + +CLI_VERSION="2.18.1" +find_prev_version_from_git_tags CLI_VERSION https://github.com/cli/cli +check "pre-version-to-2.18.1" bash -c "echo ${CLI_VERSION} | grep '2.18.0'" + +CLI_VERSION="2.15.0" +find_prev_version_from_git_tags CLI_VERSION https://github.com/cli/cli +check "pre-version-to-2.15.0" bash -c "echo ${CLI_VERSION} | grep '2.14.7'" + +CLI_VERSION="2.0.0" +find_prev_version_from_git_tags CLI_VERSION https://github.com/cli/cli +check "pre-version-to-2.0.0" bash -c "echo ${CLI_VERSION} | grep '1.14.0'" + # Report result reportResults \ No newline at end of file From 7a47fbff000bff65bec9fa4687eed87cc0bc39c3 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 2 Dec 2022 09:48:04 -0800 Subject: [PATCH 031/478] Node: Fix regression - Installing in ubuntu 18.04 (#319) Node: Fix regression https://github.com/devcontainers/features/issues/317 --- src/node/devcontainer-feature.json | 2 +- src/node/install.sh | 6 ++++-- test/node/install_node_16_on_bionic.sh | 13 +++++++++++++ test/node/scenarios.json | 10 +++++++++- 4 files changed, 27 insertions(+), 4 deletions(-) create mode 100755 test/node/install_node_16_on_bionic.sh diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index 3abfb0400..216f29b80 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.1.3", + "version": "1.1.4", "name": "Node.js (via nvm) and yarn", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/node", "description": "Installs Node.js, nvm, yarn, and needed dependencies.", diff --git a/src/node/install.sh b/src/node/install.sh index 9b027d861..4c02c9514 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -83,8 +83,10 @@ export DEBIAN_FRONTEND=noninteractive . /etc/os-release if [[ "bionic" = *"${VERSION_CODENAME}"* ]]; then - echo "(!) Unsupported distribution version '${VERSION_CODENAME}'. Details: https://github.com/nodejs/node/issues/42351#issuecomment-1068424442" - exit 1 + if [[ "${NODE_VERSION}" =~ "18" ]] || [[ "${NODE_VERSION}" = "lts" ]]; then + echo "(!) Unsupported distribution version '${VERSION_CODENAME}' for Node 18. Details: https://github.com/nodejs/node/issues/42351#issuecomment-1068424442" + exit 1 + fi fi # Install dependencies diff --git a/test/node/install_node_16_on_bionic.sh b/test/node/install_node_16_on_bionic.sh new file mode 100755 index 000000000..1b301d34c --- /dev/null +++ b/test/node/install_node_16_on_bionic.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" bash -c "node --version | grep 16" +check "nvm" bash -c ". /usr/local/share/nvm/nvm.sh && nvm install 10" + +# Report result +reportResults diff --git a/test/node/scenarios.json b/test/node/scenarios.json index 70e105146..6112a6ea4 100644 --- a/test/node/scenarios.json +++ b/test/node/scenarios.json @@ -34,5 +34,13 @@ "version": "19.1.0" } } + }, + "install_node_16_on_bionic": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-18.04", + "features": { + "node": { + "version": "16" + } + } } -} \ No newline at end of file +} From 57e15bc8e8b6ad1ff677548ae9d9baa8a49754f5 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 2 Dec 2022 09:49:20 -0800 Subject: [PATCH 032/478] Update docker-in-docker version (#320) update dnd --- .devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer.json b/.devcontainer.json index 81b3c1ff6..c24649ab6 100644 --- a/.devcontainer.json +++ b/.devcontainer.json @@ -9,7 +9,7 @@ } }, "features": { - "ghcr.io/devcontainers/features/docker-in-docker:1": {} + "ghcr.io/devcontainers/features/docker-in-docker:2": {} }, "postCreateCommand": "npm install -g @devcontainers/cli", "hostRequirements": { From 779fa44930a7348523ec62c9201dd167412a05eb Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Fri, 2 Dec 2022 11:52:53 -0800 Subject: [PATCH 033/478] add 'vim' as a common util to install --- src/common-utils/install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common-utils/install.sh b/src/common-utils/install.sh index 5530b96d9..e7f60e5cf 100755 --- a/src/common-utils/install.sh +++ b/src/common-utils/install.sh @@ -91,6 +91,7 @@ if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then bzip2 \ zip \ nano \ + vim \ vim-tiny \ less \ jq \ From e28358e33b98998e00c2c62d5d561626d96bed24 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Fri, 2 Dec 2022 11:53:32 -0800 Subject: [PATCH 034/478] revert accidental push --- src/common-utils/install.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common-utils/install.sh b/src/common-utils/install.sh index e7f60e5cf..5530b96d9 100755 --- a/src/common-utils/install.sh +++ b/src/common-utils/install.sh @@ -91,7 +91,6 @@ if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then bzip2 \ zip \ nano \ - vim \ vim-tiny \ less \ jq \ From aae9de7ebc96170ddbaf8996d8ee2289176000aa Mon Sep 17 00:00:00 2001 From: Jacob Woffenden Date: Fri, 9 Dec 2022 22:08:20 +0000 Subject: [PATCH 035/478] Change default shell if installing ZSH (#325) * Added new option to configure zsh as default shell Added test scenario Bumped feature version * Update test/common-utils/scenarios.json Co-authored-by: Samruddhi Khandale * Update src/common-utils/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * Update test/common-utils/configure_zsh_as_default_shell.sh Co-authored-by: Samruddhi Khandale Co-authored-by: Samruddhi Khandale --- src/common-utils/devcontainer-feature.json | 7 ++++++- src/common-utils/install.sh | 7 +++++++ test/common-utils/configure_zsh_as_default_shell.sh | 12 ++++++++++++ test/common-utils/scenarios.json | 10 ++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/common-utils/configure_zsh_as_default_shell.sh create mode 100644 test/common-utils/scenarios.json diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 812e5e9e0..d2a97d6c9 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "1.1.6", + "version": "1.2.0", "name": "Common Debian 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.", @@ -10,6 +10,11 @@ "default": true, "description": "Install ZSH?" }, + "configureZshAsDefaultShell": { + "type": "boolean", + "default": false, + "description": "Change default shell to ZSH?" + }, "installOhMyZsh": { "type": "boolean", "default": true, diff --git a/src/common-utils/install.sh b/src/common-utils/install.sh index 5530b96d9..eb0e62425 100755 --- a/src/common-utils/install.sh +++ b/src/common-utils/install.sh @@ -13,6 +13,7 @@ set -e rm -rf /var/lib/apt/lists/* INSTALL_ZSH="${INSTALLZSH:-"true"}" +CONFIGURE_ZSH_AS_DEFAULT_SHELL="${CONFIGUREZSHASDEFAULTSHELL:-"false"}" INSTALL_OH_MY_ZSH="${INSTALLOHMYZSH:-"true"}" UPGRADE_PACKAGES="${UPGRADEPACKAGES:-"true"}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" @@ -378,6 +379,12 @@ if [ "${INSTALL_ZSH}" = "true" ]; then ZSH_ALREADY_INSTALLED="true" fi + # Change shell of determined user + if [[ "${CONFIGURE_ZSH_AS_DEFAULT_SHELL}" == "true" ]]; then + chsh --shell /bin/zsh ${USERNAME} + fi + + # Adapted, simplified inline Oh My Zsh! install steps that adds, defaults to a codespaces theme. # See https://github.com/ohmyzsh/ohmyzsh/blob/master/tools/install.sh for official script. oh_my_install_dir="${user_rc_path}/.oh-my-zsh" diff --git a/test/common-utils/configure_zsh_as_default_shell.sh b/test/common-utils/configure_zsh_as_default_shell.sh new file mode 100644 index 000000000..e5cc89e51 --- /dev/null +++ b/test/common-utils/configure_zsh_as_default_shell.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "default-shell-is-zsh" bash -c "getent passwd $(whoami) | awk -F: '{ print $7 }' | grep '/bin/zsh'" + +# Report result +reportResults diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json new file mode 100644 index 000000000..aa36fcb6e --- /dev/null +++ b/test/common-utils/scenarios.json @@ -0,0 +1,10 @@ +{ + "configure_zsh_as_default_shell": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "common-utils": { + "configureZshAsDefaultShell": true + } + } + } +} From 7b009e661f13085629b19fc157b577916587f6bc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Dec 2022 14:10:41 -0800 Subject: [PATCH 036/478] Automated documentation update (#328) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/common-utils/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common-utils/README.md b/src/common-utils/README.md index 06af48460..123b7d5f8 100644 --- a/src/common-utils/README.md +++ b/src/common-utils/README.md @@ -16,6 +16,7 @@ Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-r | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | installZsh | Install ZSH? | boolean | true | +| configureZshAsDefaultShell | Change default shell to ZSH? | boolean | false | | installOhMyZsh | Install Oh My Zsh!? | boolean | true | | upgradePackages | Upgrade OS packages? | boolean | true | | username | Enter name of non-root user to configure or none to skip | string | automatic | From 84f3e62d1c5ea8a62152606e7aec81ef711eae0a Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Mercier Date: Tue, 13 Dec 2022 19:58:22 +0100 Subject: [PATCH 037/478] Add TFSec and Terraform Docs to Terraform features (#327) * Add TFSec and Terraform Docs * PR Review * code review --- src/terraform/devcontainer-feature.json | 14 ++++++-- src/terraform/install.sh | 44 ++++++++++++++++++++++++ test/terraform/install_terraform_docs.sh | 15 ++++++++ test/terraform/install_tfsec.sh | 15 ++++++++ test/terraform/scenarios.json | 18 ++++++++++ 5 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 test/terraform/install_terraform_docs.sh create mode 100644 test/terraform/install_tfsec.sh create mode 100644 test/terraform/scenarios.json diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index f8274c62b..66e53f09d 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.0.7", + "version": "1.1.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.", @@ -32,6 +32,16 @@ ], "default": "latest", "description": "Terragrunt version" + }, + "installTFsec": { + "type": "boolean", + "default": false, + "description": "Install tfsec, a tool to spot potential misconfigurations for your terraform code" + }, + "installTerraformDocs": { + "type": "boolean", + "default": false, + "description": "Install terraform-docs, a utility to generate documentation from Terraform modules" } }, "customizations": { @@ -52,4 +62,4 @@ "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] -} +} \ No newline at end of file diff --git a/src/terraform/install.sh b/src/terraform/install.sh index fc523b8ca..0f9e4db54 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -15,10 +15,14 @@ rm -rf /var/lib/apt/lists/* TERRAFORM_VERSION="${VERSION:-"latest"}" TFLINT_VERSION="${TFLINT:-"latest"}" TERRAGRUNT_VERSION="${TERRAGRUNT:-"latest"}" +INSTALL_TFSEC=${INSTALLTFSEC:-false} +INSTALL_TERRAFORM_DOCS=${INSTALLTERRAFORMDOCS:-false} TERRAFORM_SHA256="${TERRAFORM_SHA256:-"automatic"}" TFLINT_SHA256="${TFLINT_SHA256:-"automatic"}" TERRAGRUNT_SHA256="${TERRAGRUNT_SHA256:-"automatic"}" +TFSEC_SHA256="${TFSEC_SHA256:-"automatic"}" +TERRAFORM_DOCS_SHA256="${TERRAFORM_DOCS_SHA256:-"automatic"}" TERRAFORM_GPG_KEY="72D7468F" TFLINT_GPG_KEY_URI="https://raw.githubusercontent.com/terraform-linters/tflint/master/8CE69160EB3F2FE9.key" @@ -212,6 +216,46 @@ if [ "${TERRAGRUNT_VERSION}" != "none" ]; then mv -f /tmp/tf-downloads/${terragrunt_filename} /usr/local/bin/terragrunt fi +if [ "${INSTALL_TFSEC}" = "true" ]; then + TFSEC_VERSION="latest" + find_version_from_git_tags TFSEC_VERSION 'https://github.com/aquasecurity/tfsec' + tfsec_filename="tfsec_${TFSEC_VERSION}_linux_${architecture}.tar.gz" + echo "(*) Downloading TFSec... ${tfsec_filename}" + curl -sSL -o /tmp/tf-downloads/${tfsec_filename} https://github.com/aquasecurity/tfsec/releases/download/v${TFSEC_VERSION}/${tfsec_filename} + if [ "${TFSEC_SHA256}" != "dev-mode" ]; then + if [ "${TFSEC_SHA256}" = "automatic" ]; then + curl -sSL -o tfsec_SHA256SUMS https://github.com/aquasecurity/tfsec/releases/download/v${TFSEC_VERSION}/tfsec_${TFSEC_VERSION}_checksums.txt + else + echo "${TFSEC_SHA256} *${tfsec_filename}" > tfsec_SHA256SUMS + fi + sha256sum --ignore-missing -c tfsec_SHA256SUMS + fi + mkdir -p /tmp/tf-downloads/tfsec + tar -xzf /tmp/tf-downloads/${tfsec_filename} -C /tmp/tf-downloads/tfsec + chmod a+x /tmp/tf-downloads/tfsec/tfsec + mv -f /tmp/tf-downloads/tfsec/tfsec /usr/local/bin/tfsec +fi + +if [ "${INSTALL_TERRAFORM_DOCS}" = "true" ]; then + TERRAFORM_DOCS_VERSION="latest" + find_version_from_git_tags TERRAFORM_DOCS_VERSION 'https://github.com/terraform-docs/terraform-docs' + tfdocs_filename="terraform-docs-v${TERRAFORM_DOCS_VERSION}-linux-${architecture}.tar.gz" + echo "(*) Downloading Terraform docs... ${tfdocs_filename}" + curl -sSL -o /tmp/tf-downloads/${tfdocs_filename} https://github.com/terraform-docs/terraform-docs/releases/download/v${TERRAFORM_DOCS_VERSION}/${tfdocs_filename} + if [ "${TERRAFORM_DOCS_SHA256}" != "dev-mode" ]; then + if [ "${TERRAFORM_DOCS_SHA256}" = "automatic" ]; then + curl -sSL -o tfdocs_SHA256SUMS https://github.com/terraform-docs/terraform-docs/releases/download/v${TERRAFORM_DOCS_VERSION}/terraform-docs-v${TERRAFORM_DOCS_VERSION}.sha256sum + else + echo "${TERRAFORM_DOCS_SHA256} *${tfsec_filename}" > tfdocs_SHA256SUMS + fi + sha256sum --ignore-missing -c tfdocs_SHA256SUMS + fi + mkdir -p /tmp/tf-downloads/tfdocs + tar -xzf /tmp/tf-downloads/${tfdocs_filename} -C /tmp/tf-downloads/tfdocs + chmod a+x /tmp/tf-downloads/tfdocs/terraform-docs + mv -f /tmp/tf-downloads/tfdocs/terraform-docs /usr/local/bin/terraform-docs +fi + rm -rf /tmp/tf-downloads ${GNUPGHOME} # Clean up diff --git a/test/terraform/install_terraform_docs.sh b/test/terraform/install_terraform_docs.sh new file mode 100644 index 000000000..4ca0b161d --- /dev/null +++ b/test/terraform/install_terraform_docs.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Check to make sure the user is vscode +check "user is vscode" whoami | grep vscode + +# Terraform Docs specific tests +check "tfsec" terraform-docs --version + +# Report result +reportResults \ No newline at end of file diff --git a/test/terraform/install_tfsec.sh b/test/terraform/install_tfsec.sh new file mode 100644 index 000000000..0c9a48b37 --- /dev/null +++ b/test/terraform/install_tfsec.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Check to make sure the user is vscode +check "user is vscode" whoami | grep vscode + +# TFSec specific tests +check "tfsec" tfsec --version + +# Report result +reportResults \ No newline at end of file diff --git a/test/terraform/scenarios.json b/test/terraform/scenarios.json new file mode 100644 index 000000000..2365643b6 --- /dev/null +++ b/test/terraform/scenarios.json @@ -0,0 +1,18 @@ +{ + "install_tfsec": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "features": { + "terraform": { + "installTFsec": true + } + } + }, + "install_terraform_docs": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "features": { + "terraform": { + "installTerraformDocs": true + } + } + } +} \ No newline at end of file From baf47e22b0c3dc5b418ac57aae2e750d14bbc9a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 10:59:48 -0800 Subject: [PATCH 038/478] Automated documentation update (#332) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/terraform/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/terraform/README.md b/src/terraform/README.md index 8b7a25df2..5d6b47fec 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -18,6 +18,8 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la | version | Terraform version | string | latest | | tflint | Tflint version | string | latest | | terragrunt | Terragrunt version | string | latest | +| installTFsec | Install tfsec, a tool to spot potential misconfigurations for your terraform code | boolean | false | +| installTerraformDocs | Install terraform-docs, a utility to generate documentation from Terraform modules | boolean | false | From 7fa90110d762797cc0b1c2fe8fcc028c9b813d56 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 13 Dec 2022 14:09:16 -0800 Subject: [PATCH 039/478] Git: Build from source with USE_LIBPCRE (#331) --- src/git/devcontainer-feature.json | 2 +- src/git/install.sh | 4 +++- test/git/install_git_from_src.sh | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/git/devcontainer-feature.json b/src/git/devcontainer-feature.json index ef2b85665..a8ea798c7 100644 --- a/src/git/devcontainer-feature.json +++ b/src/git/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git", - "version": "1.0.5", + "version": "1.1.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 index 153b4e13f..7ffa01eb3 100755 --- a/src/git/install.sh +++ b/src/git/install.sh @@ -147,11 +147,13 @@ if [ "$(echo "${GIT_VERSION}" | grep -o '\.' | wc -l)" != "2" ]; then fi fi +check_packages libpcre2-posix2 libpcre2-dev + 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 prefix=/usr/local all && make -s prefix=/usr/local install 2>&1 +make -s USE_LIBPCRE=YesPlease prefix=/usr/local all && make -s USE_LIBPCRE=YesPlease prefix=/usr/local install 2>&1 rm -rf /tmp/git-${GIT_VERSION} rm -rf /var/lib/apt/lists/* echo "Done!" diff --git a/test/git/install_git_from_src.sh b/test/git/install_git_from_src.sh index 226278a39..4bdcf3066 100644 --- a/test/git/install_git_from_src.sh +++ b/test/git/install_git_from_src.sh @@ -8,5 +8,9 @@ source dev-container-features-test-lib check "version" git --version check "gettext" dpkg-query -l gettext +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 From bf058dc49492b3a102a28ed25764a517fcebfb40 Mon Sep 17 00:00:00 2001 From: Chuck Lantz Date: Fri, 16 Dec 2022 09:47:21 -0800 Subject: [PATCH 040/478] Multi-distro support for common script, refactor, fixes (#326) --- README.md | 2 +- src/common-utils/NOTES.md | 19 +- src/common-utils/bin/code | 16 + src/common-utils/bin/devcontainer-info | 27 + src/common-utils/bin/systemctl | 7 + src/common-utils/devcontainer-feature.json | 17 +- src/common-utils/install.sh | 461 +--------------- src/common-utils/main.sh | 496 ++++++++++++++++++ .../scripts/bash_theme_snippet.sh | 25 + .../scripts/devcontainers.zsh-theme | 26 + src/common-utils/scripts/rc_snippet.sh | 26 + test/common-utils/alpine.sh | 14 + test/common-utils/already-run.sh | 18 + test/common-utils/alternate-values.sh | 19 + test/common-utils/bionic.sh | 14 + test/common-utils/bullseye.sh | 14 + test/common-utils/buster.sh | 14 + test/common-utils/centos-7.sh | 14 + test/common-utils/fedora.sh | 14 + test/common-utils/focal.sh | 14 + test/common-utils/jammy.sh | 14 + test/common-utils/rocky-8.sh | 14 + test/common-utils/rocky-9.sh | 14 + test/common-utils/scenarios.json | 115 +++- test/common-utils/test.sh | 5 + test/common-utils/username-default.sh | 15 + test/common-utils/username-detected.sh | 14 + 27 files changed, 979 insertions(+), 469 deletions(-) create mode 100755 src/common-utils/bin/code create mode 100755 src/common-utils/bin/devcontainer-info create mode 100755 src/common-utils/bin/systemctl create mode 100644 src/common-utils/main.sh create mode 100644 src/common-utils/scripts/bash_theme_snippet.sh create mode 100644 src/common-utils/scripts/devcontainers.zsh-theme create mode 100644 src/common-utils/scripts/rc_snippet.sh create mode 100755 test/common-utils/alpine.sh create mode 100755 test/common-utils/already-run.sh create mode 100755 test/common-utils/alternate-values.sh create mode 100755 test/common-utils/bionic.sh create mode 100755 test/common-utils/bullseye.sh create mode 100755 test/common-utils/buster.sh create mode 100755 test/common-utils/centos-7.sh create mode 100755 test/common-utils/fedora.sh create mode 100755 test/common-utils/focal.sh create mode 100755 test/common-utils/jammy.sh create mode 100755 test/common-utils/rocky-8.sh create mode 100755 test/common-utils/rocky-9.sh create mode 100755 test/common-utils/username-default.sh create mode 100755 test/common-utils/username-detected.sh diff --git a/README.md b/README.md index 897d43eab..b887c00d9 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ 'Features' are self-contained units of installation code and development container configuration. Features are designed -to install atop a wide-range of base container images (**this repo focuses on `debian` based images**). +to install atop a wide-range of base container images. Missing a CLI or language in your otherwise _perfect_ container image? Add the relevant Feature to the `features` property of a [`devcontainer.json`](https://containers.dev/implementors/json_reference/#general-properties). A diff --git a/src/common-utils/NOTES.md b/src/common-utils/NOTES.md index 2c0724589..77dfd1d99 100644 --- a/src/common-utils/NOTES.md +++ b/src/common-utils/NOTES.md @@ -1,12 +1,21 @@ -## Speeding up the command prompt in large repositories +## OS Support -This script provides a custom command prompt that includes information about the git repository for the current folder. However, with certain large repositories, this can result in a slow command prompt since the required git status command can be slow. To resolve this, you can update a git setting to remove the git portion of the command prompt. +This Feature should work on recent versions of Debian/Ubuntu, RedHat Enterprise Linux, Fedora, RockyLinux, and Alpine Linux. -To disable the prompt for the current folder's repository, enter the following in a terminal or add it to your `postCreateCommand` or dotfiles: +## Customizing the command prompt + +By default, this script provides a custom command prompt that includes information about the git repository for the current folder. However, with certain large repositories, this can result in a slow command prompt due to the performance of needed git operations. + +For performance reasons, a "dirty" indicator that tells you whether or not there are uncommitted changes is disabled by default. You can opt to turn this on for smaller repositories by entering the following in a terminal or adding it to your `postCreateCommand`: ```bash -git config codespaces-theme.hide-status 1 +git config devcontainers-theme.show-dirty 1 ``` -This setting will survive a rebuild since it is applied to the repository rather than the container. +To completely disable the git portion of the prompt for the current folder's repository, you can use this configuration setting instead: + +```bash +git config devcontainers-theme.hide-status 1 +``` +For `zsh`, the default theme is a [standard Oh My Zsh! theme](https://ohmyz.sh/). You may pick a different one by modifying the `ZSH_THEME` variable in `~/.zshrc`. \ No newline at end of file diff --git a/src/common-utils/bin/code b/src/common-utils/bin/code new file mode 100755 index 000000000..b0d517f84 --- /dev/null +++ b/src/common-utils/bin/code @@ -0,0 +1,16 @@ +#!/bin/sh + +get_in_path_except_current() { + which -a "$1" | grep -A1 "$0" | grep -v "$0" +} + +code="$(get_in_path_except_current code)" + +if [ -n "$code" ]; then + exec "$code" "$@" +elif [ "$(command -v code-insiders)" ]; then + exec code-insiders "$@" +else + echo "code or code-insiders is not installed" >&2 + exit 127 +fi diff --git a/src/common-utils/bin/devcontainer-info b/src/common-utils/bin/devcontainer-info new file mode 100755 index 000000000..2c74fea6e --- /dev/null +++ b/src/common-utils/bin/devcontainer-info @@ -0,0 +1,27 @@ +#!/bin/sh +. /usr/local/etc/vscode-dev-containers/meta.env + +# Minimal output +if [ "$1" = "version" ] || [ "$1" = "image-version" ]; then + echo "${VERSION}" + exit 0 +elif [ "$1" = "release" ]; then + echo "${GIT_REPOSITORY_RELEASE}" + exit 0 +elif [ "$1" = "content" ] || [ "$1" = "content-url" ] || [ "$1" = "contents" ] || [ "$1" = "contents-url" ]; then + echo "${CONTENTS_URL}" + exit 0 +fi + +#Full output +echo +echo "Development container image information" +echo +if [ ! -z "${VERSION}" ]; then echo "- Image version: ${VERSION}"; fi +if [ ! -z "${DEFINITION_ID}" ]; then echo "- Definition ID: ${DEFINITION_ID}"; fi +if [ ! -z "${VARIANT}" ]; then echo "- Variant: ${VARIANT}"; fi +if [ ! -z "${GIT_REPOSITORY}" ]; then echo "- Source code repository: ${GIT_REPOSITORY}"; fi +if [ ! -z "${GIT_REPOSITORY_RELEASE}" ]; then echo "- Source code release/branch: ${GIT_REPOSITORY_RELEASE}"; fi +if [ ! -z "${BUILD_TIMESTAMP}" ]; then echo "- Timestamp: ${BUILD_TIMESTAMP}"; fi +if [ ! -z "${CONTENTS_URL}" ]; then echo && echo "More info: ${CONTENTS_URL}"; fi +echo diff --git a/src/common-utils/bin/systemctl b/src/common-utils/bin/systemctl new file mode 100755 index 000000000..4ead9853d --- /dev/null +++ b/src/common-utils/bin/systemctl @@ -0,0 +1,7 @@ +#!/bin/sh +set -e +if [ -d "/run/systemd/system" ]; then + exec /bin/systemctl "$@" +else + echo '\n"systemd" is not running in this container due to its overhead.\nUse the "service" command to start services instead. e.g.: \n\nservice --status-all' +fi diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index d2a97d6c9..05bf067e7 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,7 +1,7 @@ { "id": "common-utils", - "version": "1.2.0", - "name": "Common Debian Utilities", + "version": "2.0.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.", "options": { @@ -28,36 +28,37 @@ "username": { "type": "string", "proposals": [ + "devcontainer", "vscode", "codespace", "none", "automatic" ], "default": "automatic", - "description": "Enter name of non-root user to configure or none to skip" + "description": "Enter name of a non-root user to configure or none to skip" }, - "uid": { + "userUid": { "type": "string", "proposals": [ "1000", "automatic" ], "default": "automatic", - "description": "Enter uid for non-root user" + "description": "Enter UID for non-root user" }, - "gid": { + "userGid": { "type": "string", "proposals": [ "1000", "automatic" ], "default": "automatic", - "description": "Enter gid for non-root user" + "description": "Enter GID for non-root user" }, "nonFreePackages": { "type": "boolean", "default": false, - "description": "Add packages from non-free Debian repository?" + "description": "Add packages from non-free Debian repository? (Debian only)" } } } diff --git a/src/common-utils/install.sh b/src/common-utils/install.sh index eb0e62425..d08a2f2c1 100755 --- a/src/common-utils/install.sh +++ b/src/common-utils/install.sh @@ -1,22 +1,19 @@ -#!/usr/bin/env bash -#------------------------------------------------------------------------------------------------------------- +#!/bin/sh +#------------------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. -#------------------------------------------------------------------------------------------------------------- +# Licensed under the MIT License. See https://github.com/devcontainers/features/blob/main/LICENSE for license information. +#------------------------------------------------------------------------------------------------------------------------- # -# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/common.md -# Maintainer: The VS Code and Codespaces Teams +# Docs: https://github.com/devcontainers/features/tree/main/src/common-utils +# Maintainer: The Dev Container spec maintainers set -e -# Clean up -rm -rf /var/lib/apt/lists/* - INSTALL_ZSH="${INSTALLZSH:-"true"}" CONFIGURE_ZSH_AS_DEFAULT_SHELL="${CONFIGUREZSHASDEFAULTSHELL:-"false"}" INSTALL_OH_MY_ZSH="${INSTALLOHMYZSH:-"true"}" UPGRADE_PACKAGES="${UPGRADEPACKAGES:-"true"}" -USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" +USERNAME="${USERNAME:-"automatic"}" USER_UID="${UID:-"automatic"}" USER_GID="${GID:-"automatic"}" ADD_NON_FREE_PACKAGES="${NONFREEPACKAGES:-"false"}" @@ -28,443 +25,11 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi -# 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 -echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh -chmod +x /etc/profile.d/00-restore-env.sh - -# If in automatic mode, determine if a user already exists, if not use vscode -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 - USERNAME=${CURRENT_USER} - break - fi - done - if [ "${USERNAME}" = "" ]; then - USERNAME=vscode - fi -elif [ "${USERNAME}" = "none" ]; then - USERNAME=root - USER_UID=0 - USER_GID=0 -fi - -# Load markers to see which steps have already run -if [ -f "${MARKER_FILE}" ]; then - echo "Marker file found:" - cat "${MARKER_FILE}" - source "${MARKER_FILE}" -fi - -# Ensure apt is in non-interactive to avoid prompts -export DEBIAN_FRONTEND=noninteractive - -apt_get_update() -{ - if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then - echo "Running apt-get update..." - apt-get update -y - fi -} - -# Run install apt-utils to avoid debconf warning then verify presence of other common developer tools and dependencies -if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then - - package_list="apt-utils \ - openssh-client \ - gnupg2 \ - dirmngr \ - iproute2 \ - procps \ - lsof \ - htop \ - net-tools \ - psmisc \ - curl \ - tree \ - wget \ - rsync \ - ca-certificates \ - unzip \ - bzip2 \ - zip \ - nano \ - vim-tiny \ - less \ - jq \ - lsb-release \ - apt-transport-https \ - dialog \ - libc6 \ - libgcc1 \ - libkrb5-3 \ - libgssapi-krb5-2 \ - libicu[0-9][0-9] \ - liblttng-ust[0-9] \ - libstdc++6 \ - zlib1g \ - locales \ - sudo \ - ncdu \ - man-db \ - strace \ - manpages \ - manpages-dev \ - init-system-helpers" - - # Needed for adding manpages-posix and manpages-posix-dev which are non-free packages in Debian - if [ "${ADD_NON_FREE_PACKAGES}" = "true" ]; then - # Bring in variables from /etc/os-release like VERSION_CODENAME - . /etc/os-release - sed -i -E "s/deb http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME} main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME} main contrib non-free/" /etc/apt/sources.list - sed -i -E "s/deb-src http:\/\/(deb|httredir)\.debian\.org\/debian ${VERSION_CODENAME} main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME} main contrib non-free/" /etc/apt/sources.list - sed -i -E "s/deb http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list - sed -i -E "s/deb-src http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb-src http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb-src http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list - # Handle bullseye location for security https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html - sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb-src http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main contrib non-free/" /etc/apt/sources.list - echo "Running apt-get update..." - apt-get update - package_list="${package_list} manpages-posix manpages-posix-dev" - else - apt_get_update - fi - - # Install libssl1.1 if available - if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then - package_list="${package_list} libssl1.1" - fi - - # Install libssl3 if available - if [[ ! -z $(apt-cache --names-only search ^libssl3$) ]]; then - package_list="${package_list} libssl3" - fi - - # Install appropriate version of libssl1.0.x if available - libssl_package=$(dpkg-query -f '${db:Status-Abbrev}\t${binary:Package}\n' -W 'libssl1\.0\.?' 2>&1 || echo '') - if [ "$(echo "$LIlibssl_packageBSSL" | grep -o 'libssl1\.0\.[0-9]:' | uniq | sort | wc -l)" -eq 0 ]; then - if [[ ! -z $(apt-cache --names-only search ^libssl1.0.2$) ]]; then - # Debian 9 - package_list="${package_list} libssl1.0.2" - elif [[ ! -z $(apt-cache --names-only search ^libssl1.0.0$) ]]; then - # Ubuntu 18.04, 16.04, earlier - package_list="${package_list} libssl1.0.0" - fi - fi - - echo "Packages to verify are installed: ${package_list}" - apt-get -y install --no-install-recommends ${package_list} 2> >( grep -v 'debconf: delaying package configuration, since apt-utils is not installed' >&2 ) - - # Install git if not already installed (may be more recent than distro version) - if ! type git > /dev/null 2>&1; then - apt-get -y install --no-install-recommends git - fi - - PACKAGES_ALREADY_INSTALLED="true" -fi - -# Get to latest versions of all packages -if [ "${UPGRADE_PACKAGES}" = "true" ]; then - apt_get_update - apt-get -y upgrade --no-install-recommends - apt-get autoremove -y -fi - -# Ensure at least the en_US.UTF-8 UTF-8 locale is available. -# Common need for both applications and things like the agnoster ZSH theme. -if [ "${LOCALE_ALREADY_SET}" != "true" ] && ! grep -o -E '^\s*en_US.UTF-8\s+UTF-8' /etc/locale.gen > /dev/null; then - echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen - locale-gen - LOCALE_ALREADY_SET="true" -fi - -# Create or update a non-root user to match UID/GID. -group_name="${USERNAME}" -if id -u ${USERNAME} > /dev/null 2>&1; then - # User exists, update if needed - if [ "${USER_GID}" != "automatic" ] && [ "$USER_GID" != "$(id -g $USERNAME)" ]; then - group_name="$(id -gn $USERNAME)" - groupmod --gid $USER_GID ${group_name} - usermod --gid $USER_GID $USERNAME - fi - if [ "${USER_UID}" != "automatic" ] && [ "$USER_UID" != "$(id -u $USERNAME)" ]; then - usermod --uid $USER_UID $USERNAME - fi -else - # Create user - if [ "${USER_GID}" = "automatic" ]; then - groupadd $USERNAME - else - groupadd --gid $USER_GID $USERNAME - fi - if [ "${USER_UID}" = "automatic" ]; then - useradd -s /bin/bash --gid $USERNAME -m $USERNAME - else - useradd -s /bin/bash --uid $USER_UID --gid $USERNAME -m $USERNAME - fi -fi - -# Add add sudo support for non-root user -if [ "${USERNAME}" != "root" ] && [ "${EXISTING_NON_ROOT_USER}" != "${USERNAME}" ]; then - echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME - chmod 0440 /etc/sudoers.d/$USERNAME - EXISTING_NON_ROOT_USER="${USERNAME}" -fi - -# ** Shell customization section ** -if [ "${USERNAME}" = "root" ]; then - user_rc_path="/root" -else - user_rc_path="/home/${USERNAME}" -fi - -# Restore user .bashrc defaults from skeleton file if it doesn't exist or is empty -if [ ! -f "${user_rc_path}/.bashrc" ] || [ ! -s "${user_rc_path}/.bashrc" ] ; then - cp /etc/skel/.bashrc "${user_rc_path}/.bashrc" -fi - -# Restore user .profile defaults from skeleton file if it doesn't exist or is empty -if [ ! -f "${user_rc_path}/.profile" ] || [ ! -s "${user_rc_path}/.profile" ] ; then - cp /etc/skel/.profile "${user_rc_path}/.profile" -fi - -# .bashrc/.zshrc snippet -rc_snippet="$(cat << 'EOF' - -if [ -z "${USER}" ]; then export USER=$(whoami); fi -if [[ "${PATH}" != *"$HOME/.local/bin"* ]]; then export PATH="${PATH}:$HOME/.local/bin"; fi - -# Display optional first run image specific notice if configured and terminal is interactive -if [ -t 1 ] && [[ "${TERM_PROGRAM}" = "vscode" || "${TERM_PROGRAM}" = "codespaces" ]] && [ ! -f "$HOME/.config/vscode-dev-containers/first-run-notice-already-displayed" ]; then - if [ -f "/usr/local/etc/vscode-dev-containers/first-run-notice.txt" ]; then - cat "/usr/local/etc/vscode-dev-containers/first-run-notice.txt" - elif [ -f "/workspaces/.codespaces/shared/first-run-notice.txt" ]; then - cat "/workspaces/.codespaces/shared/first-run-notice.txt" - fi - mkdir -p "$HOME/.config/vscode-dev-containers" - # Mark first run notice as displayed after 10s to avoid problems with fast terminal refreshes hiding it - ((sleep 10s; touch "$HOME/.config/vscode-dev-containers/first-run-notice-already-displayed") &) -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 - export GIT_EDITOR="code-insiders --wait" - else - export GIT_EDITOR="code --wait" - fi - fi +# If we're using Alpine, install bash before executing +. /etc/os-release +if [ "${ID}" = "alpine" ]; then + apk add --no-cache bash fi -EOF -)" - -# code shim, it fallbacks to code-insiders if code is not available -cat << 'EOF' > /usr/local/bin/code -#!/bin/sh - -get_in_path_except_current() { - which -a "$1" | grep -A1 "$0" | grep -v "$0" -} - -code="$(get_in_path_except_current code)" - -if [ -n "$code" ]; then - exec "$code" "$@" -elif [ "$(command -v code-insiders)" ]; then - exec code-insiders "$@" -else - echo "code or code-insiders is not installed" >&2 - exit 127 -fi -EOF -chmod +x /usr/local/bin/code - -# systemctl shim - tells people to use 'service' if systemd is not running -cat << 'EOF' > /usr/local/bin/systemctl -#!/bin/sh -set -e -if [ -d "/run/systemd/system" ]; then - exec /bin/systemctl "$@" -else - echo '\n"systemd" is not running in this container due to its overhead.\nUse the "service" command to start services instead. e.g.: \n\nservice --status-all' -fi -EOF -chmod +x /usr/local/bin/systemctl - -# Codespaces bash and OMZ themes - partly inspired by https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/robbyrussell.zsh-theme -codespaces_bash="$(cat \ -<<'EOF' - -# Codespaces bash prompt theme -__bash_prompt() { - local userpart='`export XIT=$? \ - && [ ! -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 codespaces-theme.hide-status 2>/dev/null)" != 1 ]; then \ - export BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD 2>/dev/null); \ - if [ "${BRANCH}" != "" ]; then \ - echo -n "\[\033[0;36m\](\[\033[1;31m\]${BRANCH}" \ - && if git ls-files --error-unmatch -m --directory --no-empty-directory -o --exclude-standard ":/*" > /dev/null 2>&1; then \ - echo -n " \[\033[1;33m\]โœ—"; \ - fi \ - && echo -n "\[\033[0;36m\]) "; \ - fi; \ - fi`' - local lightblue='\[\033[1;34m\]' - local removecolor='\[\033[0m\]' - PS1="${userpart} ${lightblue}\w ${gitbranch}${removecolor}\$ " - unset -f __bash_prompt -} -__bash_prompt - -EOF -)" - -codespaces_zsh="$(cat \ -<<'EOF' -# Codespaces zsh prompt theme -__zsh_prompt() { - local prompt_username - if [ ! -z "${GITHUB_USER}" ]; then - prompt_username="@${GITHUB_USER}" - else - prompt_username="%n" - fi - PROMPT="%{$fg[green]%}${prompt_username} %(?:%{$reset_color%}โžœ :%{$fg_bold[red]%}โžœ )" # User/exit code arrow - PROMPT+='%{$fg_bold[blue]%}%(5~|%-1~/โ€ฆ/%3~|%4~)%{$reset_color%} ' # cwd - PROMPT+='$([ "$(git config --get codespaces-theme.hide-status 2>/dev/null)" != 1 ] && git_prompt_info)' # Git status - PROMPT+='%{$fg[white]%}$ %{$reset_color%}' - unset -f __zsh_prompt -} -ZSH_THEME_GIT_PROMPT_PREFIX="%{$fg_bold[cyan]%}(%{$fg_bold[red]%}" -ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} " -ZSH_THEME_GIT_PROMPT_DIRTY=" %{$fg_bold[yellow]%}โœ—%{$fg_bold[cyan]%})" -ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[cyan]%})" -__zsh_prompt - -EOF -)" - -# Add RC snippet and custom bash prompt -if [ "${RC_SNIPPET_ALREADY_ADDED}" != "true" ]; then - echo "${rc_snippet}" >> /etc/bash.bashrc - echo "${codespaces_bash}" >> "${user_rc_path}/.bashrc" - echo 'export PROMPT_DIRTRIM=4' >> "${user_rc_path}/.bashrc" - if [ "${USERNAME}" != "root" ]; then - echo "${codespaces_bash}" >> "/root/.bashrc" - echo 'export PROMPT_DIRTRIM=4' >> "/root/.bashrc" - fi - chown ${USERNAME}:${group_name} "${user_rc_path}/.bashrc" - RC_SNIPPET_ALREADY_ADDED="true" -fi - -# Optionally install and configure zsh and Oh My Zsh! -if [ "${INSTALL_ZSH}" = "true" ]; then - if ! type zsh > /dev/null 2>&1; then - apt_get_update - apt-get install -y zsh - fi - if [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then - echo "${rc_snippet}" >> /etc/zsh/zshrc - ZSH_ALREADY_INSTALLED="true" - fi - - # Change shell of determined user - if [[ "${CONFIGURE_ZSH_AS_DEFAULT_SHELL}" == "true" ]]; then - chsh --shell /bin/zsh ${USERNAME} - fi - - - # Adapted, simplified inline Oh My Zsh! install steps that adds, defaults to a codespaces theme. - # See https://github.com/ohmyzsh/ohmyzsh/blob/master/tools/install.sh for official script. - oh_my_install_dir="${user_rc_path}/.oh-my-zsh" - if [ ! -d "${oh_my_install_dir}" ] && [ "${INSTALL_OH_MY_ZSH}" = "true" ]; then - template_path="${oh_my_install_dir}/templates/zshrc.zsh-template" - user_rc_file="${user_rc_path}/.zshrc" - umask g-w,o-w - mkdir -p ${oh_my_install_dir} - git clone --depth=1 \ - -c core.eol=lf \ - -c core.autocrlf=false \ - -c fsck.zeroPaddedFilemode=ignore \ - -c fetch.fsck.zeroPaddedFilemode=ignore \ - -c receive.fsck.zeroPaddedFilemode=ignore \ - "https://github.com/ohmyzsh/ohmyzsh" "${oh_my_install_dir}" 2>&1 - echo -e "$(cat "${template_path}")\nDISABLE_AUTO_UPDATE=true\nDISABLE_UPDATE_PROMPT=true" > ${user_rc_file} - sed -i -e 's/ZSH_THEME=.*/ZSH_THEME="codespaces"/g' ${user_rc_file} - - mkdir -p ${oh_my_install_dir}/custom/themes - echo "${codespaces_zsh}" > "${oh_my_install_dir}/custom/themes/codespaces.zsh-theme" - # Shrink git while still enabling updates - cd "${oh_my_install_dir}" - git repack -a -d -f --depth=1 --window=1 - # Copy to non-root user if one is specified - if [ "${USERNAME}" != "root" ]; then - cp -rf "${user_rc_file}" "${oh_my_install_dir}" /root - chown -R ${USERNAME}:${group_name} "${user_rc_path}" - fi - fi -fi - -# Persist image metadata info, script if meta.env found in same directory -meta_info_script="$(cat << 'EOF' -#!/bin/sh -. /usr/local/etc/vscode-dev-containers/meta.env - -# Minimal output -if [ "$1" = "version" ] || [ "$1" = "image-version" ]; then - echo "${VERSION}" - exit 0 -elif [ "$1" = "release" ]; then - echo "${GIT_REPOSITORY_RELEASE}" - exit 0 -elif [ "$1" = "content" ] || [ "$1" = "content-url" ] || [ "$1" = "contents" ] || [ "$1" = "contents-url" ]; then - echo "${CONTENTS_URL}" - exit 0 -fi - -#Full output -echo -echo "Development container image information" -echo -if [ ! -z "${VERSION}" ]; then echo "- Image version: ${VERSION}"; fi -if [ ! -z "${DEFINITION_ID}" ]; then echo "- Definition ID: ${DEFINITION_ID}"; fi -if [ ! -z "${VARIANT}" ]; then echo "- Variant: ${VARIANT}"; fi -if [ ! -z "${GIT_REPOSITORY}" ]; then echo "- Source code repository: ${GIT_REPOSITORY}"; fi -if [ ! -z "${GIT_REPOSITORY_RELEASE}" ]; then echo "- Source code release/branch: ${GIT_REPOSITORY_RELEASE}"; fi -if [ ! -z "${BUILD_TIMESTAMP}" ]; then echo "- Timestamp: ${BUILD_TIMESTAMP}"; fi -if [ ! -z "${CONTENTS_URL}" ]; then echo && echo "More info: ${CONTENTS_URL}"; fi -echo -EOF -)" -if [ -f "/usr/local/etc/vscode-dev-containers/meta.env" ]; then - echo "${meta_info_script}" > /usr/local/bin/devcontainer-info - chmod +x /usr/local/bin/devcontainer-info -fi - -if [ ! -d "/usr/local/etc/vscode-dev-containers" ]; then - mkdir -p "$(dirname "${MARKER_FILE}")" -fi - -# Write marker file -echo -e "\ - PACKAGES_ALREADY_INSTALLED=${PACKAGES_ALREADY_INSTALLED}\n\ - LOCALE_ALREADY_SET=${LOCALE_ALREADY_SET}\n\ - EXISTING_NON_ROOT_USER=${EXISTING_NON_ROOT_USER}\n\ - RC_SNIPPET_ALREADY_ADDED=${RC_SNIPPET_ALREADY_ADDED}\n\ - ZSH_ALREADY_INSTALLED=${ZSH_ALREADY_INSTALLED}" > "${MARKER_FILE}" - -# Clean up -rm -rf /var/lib/apt/lists/* - -echo "Done!" +exec /bin/bash "$(dirname $0)/main.sh" "$@" +exit $? diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh new file mode 100644 index 000000000..63f64ab60 --- /dev/null +++ b/src/common-utils/main.sh @@ -0,0 +1,496 @@ +#!/bin/bash +#------------------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://github.com/devcontainers/features/blob/main/LICENSE for license information. +#------------------------------------------------------------------------------------------------------------------------- +# +# Docs: https://github.com/devcontainers/features/tree/main/src/common-utils +# Maintainer: The Dev Container spec maintainers + +set -e + +INSTALL_ZSH="${INSTALLZSH:-"true"}" +CONFIGURE_ZSH_AS_DEFAULT_SHELL="${CONFIGUREZSHASDEFAULTSHELL:-"false"}" +INSTALL_OH_MY_ZSH="${INSTALLOHMYZSH:-"true"}" +UPGRADE_PACKAGES="${UPGRADEPACKAGES:-"true"}" +USERNAME="${USERNAME:-"automatic"}" +USER_UID="${USERUID:-"automatic"}" +USER_GID="${USERGID:-"automatic"}" +ADD_NON_FREE_PACKAGES="${NONFREEPACKAGES:-"false"}" + +MARKER_FILE="/usr/local/etc/vscode-dev-containers/common" + +FEATURE_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# Debian / Ubuntu packages +install_debian_packages() { + # Ensure apt is in non-interactive to avoid prompts + export DEBIAN_FRONTEND=noninteractive + + local package_list="apt-utils \ + openssh-client \ + gnupg2 \ + dirmngr \ + iproute2 \ + procps \ + lsof \ + htop \ + net-tools \ + psmisc \ + curl \ + tree \ + wget \ + rsync \ + ca-certificates \ + unzip \ + bzip2 \ + zip \ + nano \ + vim-tiny \ + less \ + jq \ + lsb-release \ + apt-transport-https \ + dialog \ + libc6 \ + libgcc1 \ + libkrb5-3 \ + libgssapi-krb5-2 \ + libicu[0-9][0-9] \ + liblttng-ust[0-9] \ + libstdc++6 \ + zlib1g \ + locales \ + sudo \ + ncdu \ + man-db \ + strace \ + manpages \ + manpages-dev \ + init-system-helpers" + + # Needed for adding manpages-posix and manpages-posix-dev which are non-free packages in Debian + if [ "${ADD_NON_FREE_PACKAGES}" = "true" ]; then + # Bring in variables from /etc/os-release like VERSION_CODENAME + sed -i -E "s/deb http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME} main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME} main contrib non-free/" /etc/apt/sources.list + sed -i -E "s/deb-src http:\/\/(deb|httredir)\.debian\.org\/debian ${VERSION_CODENAME} main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME} main contrib non-free/" /etc/apt/sources.list + sed -i -E "s/deb http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list + sed -i -E "s/deb-src http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list + sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list + sed -i "s/deb-src http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list + sed -i "s/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list + sed -i "s/deb-src http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list + # Handle bullseye location for security https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html + sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main contrib non-free/" /etc/apt/sources.list + sed -i "s/deb-src http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main contrib non-free/" /etc/apt/sources.list + echo "Running apt-get update..." + package_list="${package_list} manpages-posix manpages-posix-dev" + fi + + # Include libssl1.1 if available + if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then + package_list="${package_list} libssl1.1" + fi + + # Include libssl3 if available + if [[ ! -z $(apt-cache --names-only search ^libssl3$) ]]; then + package_list="${package_list} libssl3" + fi + + # Include appropriate version of libssl1.0.x if available + local libssl_package=$(dpkg-query -f '${db:Status-Abbrev}\t${binary:Package}\n' -W 'libssl1\.0\.?' 2>&1 || echo '') + if [ "$(echo "$libssl_package" | grep -o 'libssl1\.0\.[0-9]:' | uniq | sort | wc -l)" -eq 0 ]; then + if [[ ! -z $(apt-cache --names-only search ^libssl1.0.2$) ]]; then + # Debian 9 + package_list="${package_list} libssl1.0.2" + elif [[ ! -z $(apt-cache --names-only search ^libssl1.0.0$) ]]; then + # Ubuntu 18.04 + package_list="${package_list} libssl1.0.0" + fi + fi + + # Include git if not already installed (may be more recent than distro version) + if ! type git > /dev/null 2>&1; then + package_list="${package_list} git" + fi + + # Install the list of packages + echo "Packages to verify are installed: ${package_list}" + rm -rf /var/lib/apt/lists/* + apt-get update -y + apt-get -y install --no-install-recommends ${package_list} 2> >( grep -v 'debconf: delaying package configuration, since apt-utils is not installed' >&2 ) + + # Install zsh (and recommended packages) if needed + if [ "${INSTALL_ZSH}" = "true" ] && ! type zsh > /dev/null 2>&1; then + apt-get install -y zsh + fi + + # Get to latest versions of all packages + if [ "${UPGRADE_PACKAGES}" = "true" ]; then + apt-get -y upgrade --no-install-recommends + apt-get autoremove -y + fi + + # Ensure at least the en_US.UTF-8 UTF-8 locale is available = common need for both applications and things like the agnoster ZSH theme. + if [ "${LOCALE_ALREADY_SET}" != "true" ] && ! grep -o -E '^\s*en_US.UTF-8\s+UTF-8' /etc/locale.gen > /dev/null; then + echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen + locale-gen + LOCALE_ALREADY_SET="true" + fi + + # Clean up + apt-get -y clean + rm -rf /var/lib/apt/lists/* +} + +# RedHat / RockyLinux / CentOS / Fedora packages +install_redhat_packages() { + local package_list="\ + openssh-clients \ + gnupg2 \ + iproute \ + procps \ + lsof \ + net-tools \ + psmisc \ + curl \ + wget \ + ca-certificates \ + rsync \ + unzip \ + zip \ + nano \ + vim-minimal \ + less \ + jq \ + openssl-libs \ + krb5-libs \ + libicu \ + zlib \ + sudo \ + sed \ + grep \ + which \ + man-db \ + strace" + + # Install OpenSSL 1.0 compat if needed + if ${install_cmd} -q list compat-openssl10 >/dev/null 2>&1; then + package_list="${package_list} compat-openssl10" + fi + + # Install lsb_release if available + if ${install_cmd} -q list redhat-lsb-core >/dev/null 2>&1; then + package_list="${package_list} redhat-lsb-core" + fi + + # Install git if not already installed (may be more recent than distro version) + if ! type git > /dev/null 2>&1; then + package_list="${package_list} git" + fi + + # Install zsh if needed + if [ "${INSTALL_ZSH}" = "true" ] && ! type zsh > /dev/null 2>&1; then + package_list="${package_list} zsh" + fi + + local install_cmd=dnf + if ! type dnf > /dev/null 2>&1; then + install_cmd=yum + fi + ${install_cmd} -y install ${package_list} + + # Get to latest versions of all packages + if [ "${UPGRADE_PACKAGES}" = "true" ]; then + ${install_cmd} upgrade -y + fi +} + +# Alpine Linux packages +install_alpine_packages() { + apk update + apk add --no-cache \ + openssh-client \ + gnupg \ + procps \ + lsof \ + htop \ + net-tools \ + psmisc \ + curl \ + wget \ + rsync \ + ca-certificates \ + unzip \ + zip \ + nano \ + vim \ + less \ + jq \ + libgcc \ + libstdc++ \ + krb5-libs \ + libintl \ + libssl1.1 \ + lttng-ust \ + tzdata \ + userspace-rcu \ + zlib \ + sudo \ + coreutils \ + sed \ + grep \ + which \ + ncdu \ + shadow \ + strace + + # Install man pages - package name varies between 3.12 and earlier versions + if apk info man > /dev/null 2>&1; then + apk add --no-cache man man-pages + else + apk add --no-cache mandoc man-pages + fi + + # Install git if not already installed (may be more recent than distro version) + if ! type git > /dev/null 2>&1; then + apk add --no-cache git + fi + + # Install zsh if needed + if [ "${INSTALL_ZSH}" = "true" ] && ! type zsh > /dev/null 2>&1; then + apk add --no-cache zsh + fi +} + +# ****************** +# ** Main section ** +# ****************** + +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 + +# Load markers to see which steps have already run +if [ -f "${MARKER_FILE}" ]; then + echo "Marker file found:" + cat "${MARKER_FILE}" + source "${MARKER_FILE}" +fi + +# 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 +echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh +chmod +x /etc/profile.d/00-restore-env.sh + +# Bring in ID, ID_LIKE, VERSION_ID, VERSION_CODENAME +. /etc/os-release +# Get an adjusted ID independant of distro variants +if [ "${ID}" = "debian" ] || [ "${ID_LIKE}" = "debian" ]; then + ADJUSTED_ID="debian" +elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* ]]; then + ADJUSTED_ID="rhel" +elif [ "${ID}" = "alpine" ]; then + ADJUSTED_ID="alpine" +else + echo "Linux distro ${ID} not supported." + exit 1 +fi + +# Install packages for appropriate OS +if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then + case "${ADJUSTED_ID}" in + "debian") + install_debian_packages + ;; + "rhel") + install_redhat_packages + ;; + "alpine") + install_alpine_packages + ;; + esac + PACKAGES_ALREADY_INSTALLED="true" +fi + +# If in automatic mode, determine if a user already exists, if not use vscode +if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then + if [ "${_REMOTE_USER}" != "root" ]; then + USERNAME="${_REMOTE_USER}" + else + USERNAME="" + POSSIBLE_USERS=("devcontainer" "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 + USERNAME=${CURRENT_USER} + break + fi + done + if [ "${USERNAME}" = "" ]; then + USERNAME=vscode + fi + fi +elif [ "${USERNAME}" = "none" ]; then + USERNAME=root + USER_UID=0 + USER_GID=0 +fi +# Create or update a non-root user to match UID/GID. +group_name="${USERNAME}" +if id -u ${USERNAME} > /dev/null 2>&1; then + # User exists, update if needed + if [ "${USER_GID}" != "automatic" ] && [ "$USER_GID" != "$(id -g $USERNAME)" ]; then + group_name="$(id -gn $USERNAME)" + groupmod --gid $USER_GID ${group_name} + usermod --gid $USER_GID $USERNAME + fi + if [ "${USER_UID}" != "automatic" ] && [ "$USER_UID" != "$(id -u $USERNAME)" ]; then + usermod --uid $USER_UID $USERNAME + fi +else + # Create user + if [ "${USER_GID}" = "automatic" ]; then + groupadd $USERNAME + else + groupadd --gid $USER_GID $USERNAME + fi + if [ "${USER_UID}" = "automatic" ]; then + useradd -s /bin/bash --gid $USERNAME -m $USERNAME + else + useradd -s /bin/bash --uid $USER_UID --gid $USERNAME -m $USERNAME + fi +fi + +# Add add sudo support for non-root user +if [ "${USERNAME}" != "root" ] && [ "${EXISTING_NON_ROOT_USER}" != "${USERNAME}" ]; then + echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME + chmod 0440 /etc/sudoers.d/$USERNAME + EXISTING_NON_ROOT_USER="${USERNAME}" +fi + +# ********************************* +# ** Shell customization section ** +# ********************************* + +if [ "${USERNAME}" = "root" ]; then + user_rc_path="/root" +else + user_rc_path="/home/${USERNAME}" +fi + +# Restore user .bashrc / .profile / .zshrc defaults from skeleton file if it doesn't exist or is empty +possible_rc_files=( ".bashrc" ".profile" ".zshrc" ) +for rc_file in "${possible_rc_files[@]}"; do + if [ -f "/etc/skel/${rc_file}" ]; then + if [ ! -e "${user_rc_path}/${rc_file}" ] || [ -s "${user_rc_path}/${rc_file}" ]; then + cp "/etc/skel/${rc_file}" "${user_rc_path}/${rc_file}" + chown ${USERNAME}:${group_name} "${user_rc_path}/${rc_file}" + fi + fi +done + +# Add RC snippet and custom bash prompt +if [ "${RC_SNIPPET_ALREADY_ADDED}" != "true" ]; then + case "${ADJUSTED_ID}" in + "debian") + global_rc_path="/etc/bash.bashrc" + ;; + "rhel") + global_rc_path="/etc/bashrc" + ;; + "alpine") + global_rc_path="/etc/bash/bashrc" + ;; + esac + cat "${FEATURE_DIR}/scripts/rc_snippet.sh" >> ${global_rc_path} + cat "${FEATURE_DIR}/scripts/bash_theme_snippet.sh" >> "${user_rc_path}/.bashrc" + if [ "${USERNAME}" != "root" ]; then + cat "${FEATURE_DIR}/scripts/bash_theme_snippet.sh" >> "/root/.bashrc" + chown ${USERNAME}:${group_name} "${user_rc_path}/.bashrc" + fi + RC_SNIPPET_ALREADY_ADDED="true" +fi + +# Optionally configure zsh and Oh My Zsh! +if [ "${INSTALL_ZSH}" = "true" ]; then + if [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then + if [ "${ADJUSTED_ID}" = "rhel" ]; then + global_rc_path="/etc/zshrc" + else + global_rc_path="/etc/zsh/zshrc" + fi + cat "${FEATURE_DIR}/scripts/rc_snippet.sh" >> /etc/zshrc + ZSH_ALREADY_INSTALLED="true" + fi + + if [ "${CONFIGURE_ZSH_AS_DEFAULT_SHELL}" == "true" ]; then + chsh --shell /bin/zsh ${USERNAME} + fi + + # Adapted, simplified inline Oh My Zsh! install steps that adds, defaults to a codespaces theme. + # See https://github.com/ohmyzsh/ohmyzsh/blob/master/tools/install.sh for official script. + oh_my_install_dir="${user_rc_path}/.oh-my-zsh" + if [ ! -d "${oh_my_install_dir}" ] && [ "${INSTALL_OH_MY_ZSH}" = "true" ]; then + template_path="${oh_my_install_dir}/templates/zshrc.zsh-template" + user_rc_file="${user_rc_path}/.zshrc" + umask g-w,o-w + mkdir -p ${oh_my_install_dir} + git clone --depth=1 \ + -c core.eol=lf \ + -c core.autocrlf=false \ + -c fsck.zeroPaddedFilemode=ignore \ + -c fetch.fsck.zeroPaddedFilemode=ignore \ + -c receive.fsck.zeroPaddedFilemode=ignore \ + "https://github.com/ohmyzsh/ohmyzsh" "${oh_my_install_dir}" 2>&1 + 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} + + # Add Dev Containers theme + mkdir -p ${oh_my_install_dir}/custom/themes + cp -f "${FEATURE_DIR}/scripts/devcontainers.zsh-theme" "${oh_my_install_dir}/custom/themes/devcontainers.zsh-theme" + ln -s "${oh_my_install_dir}/custom/themes/devcontainers.zsh-theme" "${oh_my_install_dir}/custom/themes/codespaces.zsh-theme" + + # Shrink git while still enabling updates + cd "${oh_my_install_dir}" + git repack -a -d -f --depth=1 --window=1 + # Copy to non-root user if one is specified + if [ "${USERNAME}" != "root" ]; then + cp -rf "${user_rc_file}" "${oh_my_install_dir}" /root + chown -R ${USERNAME}:${group_name} "${oh_my_install_dir}" "${user_rc_file}" + fi + fi +fi + +# **************************** +# ** Utilities and commands ** +# **************************** + +# code shim, it fallbacks to code-insiders if code is not available +cp -f "${FEATURE_DIR}/bin/code" /usr/local/bin/ +chmod +x /usr/local/bin/code + +# systemctl shim for Debian/Ubuntu - tells people to use 'service' if systemd is not running +if [ "${ADJUSTED_ID}" = "debian" ]; then + cp -f "${FEATURE_DIR}/bin/systemctl" /usr/local/bin/systemctl + chmod +x /usr/local/bin/systemctl +fi + +# Persist image metadata info, script if meta.env found in same directory +if [ -f "/usr/local/etc/vscode-dev-containers/meta.env" ]; then + cp -f "${FEATURE_DIR}/bin/devcontainer-info" /usr/local/bin/devcontainer-info + chmod +x /usr/local/bin/devcontainer-info +fi + +# Write marker file +if [ ! -d "/usr/local/etc/vscode-dev-containers" ]; then + mkdir -p "$(dirname "${MARKER_FILE}")" +fi +echo -e "\ + PACKAGES_ALREADY_INSTALLED=${PACKAGES_ALREADY_INSTALLED}\n\ + LOCALE_ALREADY_SET=${LOCALE_ALREADY_SET}\n\ + EXISTING_NON_ROOT_USER=${EXISTING_NON_ROOT_USER}\n\ + RC_SNIPPET_ALREADY_ADDED=${RC_SNIPPET_ALREADY_ADDED}\n\ + ZSH_ALREADY_INSTALLED=${ZSH_ALREADY_INSTALLED}" > "${MARKER_FILE}" + +echo "Done!" diff --git a/src/common-utils/scripts/bash_theme_snippet.sh b/src/common-utils/scripts/bash_theme_snippet.sh new file mode 100644 index 000000000..a028e4b63 --- /dev/null +++ b/src/common-utils/scripts/bash_theme_snippet.sh @@ -0,0 +1,25 @@ + +# 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 " \ + && [ "$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}" \ + && 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\]โœ—"; \ + fi \ + && echo -n "\[\033[0;36m\]) "; \ + fi; \ + fi`' + local lightblue='\[\033[1;34m\]' + local removecolor='\[\033[0m\]' + PS1="${userpart} ${lightblue}\w ${gitbranch}${removecolor}\$ " + unset -f __bash_prompt +} +__bash_prompt +export PROMPT_DIRTRIM=4 diff --git a/src/common-utils/scripts/devcontainers.zsh-theme b/src/common-utils/scripts/devcontainers.zsh-theme new file mode 100644 index 000000000..ff11c917e --- /dev/null +++ b/src/common-utils/scripts/devcontainers.zsh-theme @@ -0,0 +1,26 @@ +# 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 + prompt_username="@${GITHUB_USER}" + else + prompt_username="%n" + fi + PROMPT="%{$fg[green]%}${prompt_username} %(?:%{$reset_color%}โžœ :%{$fg_bold[red]%}โžœ )" # User/exit code arrow + PROMPT+='%{$fg_bold[blue]%}%(5~|%-1~/โ€ฆ/%3~|%4~)%{$reset_color%} ' # cwd + PROMPT+='`\ + 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 "%{$fg_bold[cyan]%}(%{$fg_bold[red]%}${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 " %{$fg_bold[yellow]%}โœ—"; \ + fi \ + && echo -n "%{$fg_bold[cyan]%})%{$reset_color%} "; \ + fi; \ + fi`' + PROMPT+='%{$fg[white]%}$ %{$reset_color%}' + unset -f __zsh_prompt +} +__zsh_prompt diff --git a/src/common-utils/scripts/rc_snippet.sh b/src/common-utils/scripts/rc_snippet.sh new file mode 100644 index 000000000..3aa319a15 --- /dev/null +++ b/src/common-utils/scripts/rc_snippet.sh @@ -0,0 +1,26 @@ + +if [ -z "${USER}" ]; then export USER=$(whoami); fi +if [[ "${PATH}" != *"$HOME/.local/bin"* ]]; then export PATH="${PATH}:$HOME/.local/bin"; fi + +# Display optional first run image specific notice if configured and terminal is interactive +if [ -t 1 ] && [[ "${TERM_PROGRAM}" = "vscode" || "${TERM_PROGRAM}" = "codespaces" ]] && [ ! -f "$HOME/.config/vscode-dev-containers/first-run-notice-already-displayed" ]; then + if [ -f "/usr/local/etc/vscode-dev-containers/first-run-notice.txt" ]; then + cat "/usr/local/etc/vscode-dev-containers/first-run-notice.txt" + elif [ -f "/workspaces/.codespaces/shared/first-run-notice.txt" ]; then + cat "/workspaces/.codespaces/shared/first-run-notice.txt" + fi + mkdir -p "$HOME/.config/vscode-dev-containers" + # Mark first run notice as displayed after 10s to avoid problems with fast terminal refreshes hiding it + ((sleep 10s; touch "$HOME/.config/vscode-dev-containers/first-run-notice-already-displayed") &) +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 + export GIT_EDITOR="code-insiders --wait" + else + export GIT_EDITOR="code --wait" + fi + fi +fi \ No newline at end of file diff --git a/test/common-utils/alpine.sh b/test/common-utils/alpine.sh new file mode 100755 index 000000000..c5ff86613 --- /dev/null +++ b/test/common-utils/alpine.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${ID}" = "alpine" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/already-run.sh b/test/common-utils/already-run.sh new file mode 100755 index 000000000..39d6f9ee2 --- /dev/null +++ b/test/common-utils/already-run.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "non-root user" test "$(whoami)" = "vscode" +check "jq" jq --version +check "curl" curl --version +check "git" git --version +check "zsh" zsh --version +check "ps" ps --version +check "Oh My Zsh! theme" test -e $HOME/.oh-my-zsh/custom/themes + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/alternate-values.sh b/test/common-utils/alternate-values.sh new file mode 100755 index 000000000..d208a2730 --- /dev/null +++ b/test/common-utils/alternate-values.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "non-root user" id alternate +check "running as root" test "$(whoami)" = "root" +check "jq" jq --version +check "curl" curl --version +check "git" git --version +check "ps" ps --version +check "no zsh" bash -c '! zsh --version' +check "No Oh My Zsh!" test ! -e /home/alternate/.oh-my-zsh/custom/themes/devcontainers.zsh-theme + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/bionic.sh b/test/common-utils/bionic.sh new file mode 100755 index 000000000..349b4c32d --- /dev/null +++ b/test/common-utils/bionic.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${VERSION_CODENAME}" = "bionic" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/bullseye.sh b/test/common-utils/bullseye.sh new file mode 100755 index 000000000..5a396a7f4 --- /dev/null +++ b/test/common-utils/bullseye.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${VERSION_CODENAME}" = "bullseye" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/buster.sh b/test/common-utils/buster.sh new file mode 100755 index 000000000..9fd2f409f --- /dev/null +++ b/test/common-utils/buster.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${VERSION_CODENAME}" = "buster" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/centos-7.sh b/test/common-utils/centos-7.sh new file mode 100755 index 000000000..a81ae2f3e --- /dev/null +++ b/test/common-utils/centos-7.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${VERSION_ID}" = "7" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/fedora.sh b/test/common-utils/fedora.sh new file mode 100755 index 000000000..b32a7f112 --- /dev/null +++ b/test/common-utils/fedora.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${ID}" = "fedora" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/focal.sh b/test/common-utils/focal.sh new file mode 100755 index 000000000..28d8b8bcc --- /dev/null +++ b/test/common-utils/focal.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${VERSION_CODENAME}" = "focal" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/jammy.sh b/test/common-utils/jammy.sh new file mode 100755 index 000000000..f11cac69e --- /dev/null +++ b/test/common-utils/jammy.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${VERSION_CODENAME}" = "jammy" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/rocky-8.sh b/test/common-utils/rocky-8.sh new file mode 100755 index 000000000..f6606dbb2 --- /dev/null +++ b/test/common-utils/rocky-8.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${PLATFORM_ID}" = "platform:el8" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/rocky-9.sh b/test/common-utils/rocky-9.sh new file mode 100755 index 000000000..c4b5244bc --- /dev/null +++ b/test/common-utils/rocky-9.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${PLATFORM_ID}" = "platform:el9" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index aa36fcb6e..9b0bc85c9 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -1,10 +1,111 @@ { - "configure_zsh_as_default_shell": { - "image": "mcr.microsoft.com/devcontainers/base:ubuntu", - "features": { - "common-utils": { - "configureZshAsDefaultShell": true - } + "bionic": { + "image": "ubuntu:bionic", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "focal": { + "image": "ubuntu:focal", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "jammy": { + "image": "ubuntu:jammy", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "buster": { + "image": "debian:buster", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "bullseye": { + "image": "debian:bullseye", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "centos-7": { + "image": "centos:7", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "rocky-8": { + "image": "rockylinux:8", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "rocky-9": { + "image": "rockylinux:9", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "fedora": { + "image": "fedora", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "alpine": { + "image": "alpine", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "alternate-values": { + "image": "debian:bullseye", + "features": { + "common-utils": { + "username": "alternate", + "userUid": "1001", + "userGid": "1002", + "upgradePackages": false, + "installZsh": false, + "nonFreePackages": true + } + } + }, + "username-default": { + "image": "debian:bullseye", + "features": { + "common-utils": {} + } + }, + "username-detected": { + "image": "node", + "features": { + "common-utils": {} + } + }, + "already-run": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "features": { + "common-utils": {} + } + }, + "configure_zsh_as_default_shell": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "common-utils": { + "configureZshAsDefaultShell": true + } + } } - } } diff --git a/test/common-utils/test.sh b/test/common-utils/test.sh index 128201548..5e16a33c7 100755 --- a/test/common-utils/test.sh +++ b/test/common-utils/test.sh @@ -8,6 +8,11 @@ source dev-container-features-test-lib # Definition specific tests check "jq" jq --version check "curl" curl --version +check "git" git --version +check "zsh" zsh --version +check "ps" ps --version +check "Oh My Zsh! theme" test -e $HOME/.oh-my-zsh/custom/themes/devcontainers.zsh-theme +check "zsh theme symlink" test -e $HOME/.oh-my-zsh/custom/themes/codespaces.zsh-theme # Report result reportResults \ No newline at end of file diff --git a/test/common-utils/username-default.sh b/test/common-utils/username-default.sh new file mode 100755 index 000000000..49784b759 --- /dev/null +++ b/test/common-utils/username-default.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +# .oh-my-zsh folder would only exist if user defaulting worked +check "non-root user" ls /home/vscode/.oh-my-zsh + + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/username-detected.sh b/test/common-utils/username-detected.sh new file mode 100755 index 000000000..39c1b2998 --- /dev/null +++ b/test/common-utils/username-detected.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +# .oh-my-zsh folder would only exist if user detection worked +check "non-root user" ls /home/node/.oh-my-zsh + +# Report result +reportResults \ No newline at end of file From a3dc31d31fec8b52c63b756d1df17b602e141b9b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 16 Dec 2022 11:33:40 -0800 Subject: [PATCH 041/478] Automated documentation update (#338) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/common-utils/README.md | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/common-utils/README.md b/src/common-utils/README.md index 123b7d5f8..e028faca7 100644 --- a/src/common-utils/README.md +++ b/src/common-utils/README.md @@ -1,5 +1,5 @@ -# Common Debian Utilities (common-utils) +# Common Utilities (common-utils) Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-root user. @@ -7,7 +7,7 @@ Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-r ```json "features": { - "ghcr.io/devcontainers/features/common-utils:1": {} + "ghcr.io/devcontainers/features/common-utils:2": {} } ``` @@ -19,24 +19,32 @@ Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-r | configureZshAsDefaultShell | Change default shell to ZSH? | boolean | false | | installOhMyZsh | Install Oh My Zsh!? | boolean | true | | upgradePackages | Upgrade OS packages? | boolean | true | -| username | Enter name of non-root user to configure or none to skip | string | automatic | -| uid | Enter uid for non-root user | string | automatic | -| gid | Enter gid for non-root user | string | automatic | -| nonFreePackages | Add packages from non-free Debian repository? | boolean | false | +| username | Enter name of a non-root user to configure or none to skip | string | automatic | +| userUid | Enter UID for non-root user | string | automatic | +| userGid | Enter GID for non-root user | string | automatic | +| nonFreePackages | Add packages from non-free Debian repository? (Debian only) | boolean | false | -## Speeding up the command prompt in large repositories +## OS Support -This script provides a custom command prompt that includes information about the git repository for the current folder. However, with certain large repositories, this can result in a slow command prompt since the required git status command can be slow. To resolve this, you can update a git setting to remove the git portion of the command prompt. +This Feature should work on recent versions of Debian/Ubuntu, RedHat Enterprise Linux, Fedora, RockyLinux, and Alpine Linux. -To disable the prompt for the current folder's repository, enter the following in a terminal or add it to your `postCreateCommand` or dotfiles: +## Customizing the command prompt + +By default, this script provides a custom command prompt that includes information about the git repository for the current folder. However, with certain large repositories, this can result in a slow command prompt due to the performance of needed git operations. + +For performance reasons, a "dirty" indicator that tells you whether or not there are uncommitted changes is disabled by default. You can opt to turn this on for smaller repositories by entering the following in a terminal or adding it to your `postCreateCommand`: ```bash -git config codespaces-theme.hide-status 1 +git config devcontainers-theme.show-dirty 1 ``` -This setting will survive a rebuild since it is applied to the repository rather than the container. +To completely disable the git portion of the prompt for the current folder's repository, you can use this configuration setting instead: +```bash +git config devcontainers-theme.hide-status 1 +``` +For `zsh`, the default theme is a [standard Oh My Zsh! theme](https://ohmyz.sh/). You may pick a different one by modifying the `ZSH_THEME` variable in `~/.zshrc`. --- From e46c73de74942438e079564405c5c4b0291a4aae Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 16 Dec 2022 14:21:05 -0800 Subject: [PATCH 042/478] Git - Bug Fix: Feature fails with "ppa:false" for bionic & jammy (#339) --- src/git/devcontainer-feature.json | 2 +- src/git/install.sh | 10 +++++++++- test/git/install_git_from_src_bionic.sh | 16 ++++++++++++++++ test/git/install_git_from_src_jammy.sh | 16 ++++++++++++++++ test/git/scenarios.json | 18 ++++++++++++++++++ 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 test/git/install_git_from_src_bionic.sh create mode 100644 test/git/install_git_from_src_jammy.sh diff --git a/src/git/devcontainer-feature.json b/src/git/devcontainer-feature.json index a8ea798c7..bc5767534 100644 --- a/src/git/devcontainer-feature.json +++ b/src/git/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git", - "version": "1.1.0", + "version": "1.1.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 7ffa01eb3..2463cc9ff 100755 --- a/src/git/install.sh +++ b/src/git/install.sh @@ -147,7 +147,15 @@ if [ "$(echo "${GIT_VERSION}" | grep -o '\.' | wc -l)" != "2" ]; then fi fi -check_packages libpcre2-posix2 libpcre2-dev +check_packages libpcre2-dev + +if [ "${VERSION_CODENAME}" = "focal" ]; then + check_packages libpcre2-posix2 +elif [ "${VERSION_CODENAME}" = "bionic" ]; then + check_packages libpcre2-posix0 +else + check_packages libpcre2-posix3 +fi echo "Downloading source for ${GIT_VERSION}..." curl -sL https://github.com/git/git/archive/v${GIT_VERSION}.tar.gz | tar -xzC /tmp 2>&1 diff --git a/test/git/install_git_from_src_bionic.sh b/test/git/install_git_from_src_bionic.sh new file mode 100644 index 000000000..4bdcf3066 --- /dev/null +++ b/test/git/install_git_from_src_bionic.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "version" git --version +check "gettext" dpkg-query -l gettext + +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_src_jammy.sh b/test/git/install_git_from_src_jammy.sh new file mode 100644 index 000000000..4bdcf3066 --- /dev/null +++ b/test/git/install_git_from_src_jammy.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "version" git --version +check "gettext" dpkg-query -l gettext + +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 a57bea77f..90aa7e30a 100644 --- a/test/git/scenarios.json +++ b/test/git/scenarios.json @@ -7,5 +7,23 @@ "ppa": "false" } } + }, + "install_git_from_src_jammy": { + "image": "ubuntu:jammy", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_bionic": { + "image": "ubuntu:bionic", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } } } From 2af02c198adabacff30c400b0bfcad972ce5abcc Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 16 Dec 2022 16:08:37 -0800 Subject: [PATCH 043/478] Git - Bug Fix: Feature fails with "ppa:false" for "buster" & "bullseye" (#340) --- src/git/devcontainer-feature.json | 2 +- src/git/install.sh | 4 ++-- test/git/install_git_from_src_bullseye.sh | 16 ++++++++++++++++ test/git/install_git_from_src_buster.sh | 16 ++++++++++++++++ test/git/scenarios.json | 18 ++++++++++++++++++ 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 test/git/install_git_from_src_bullseye.sh create mode 100644 test/git/install_git_from_src_buster.sh diff --git a/src/git/devcontainer-feature.json b/src/git/devcontainer-feature.json index bc5767534..c68d69d9a 100644 --- a/src/git/devcontainer-feature.json +++ b/src/git/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git", - "version": "1.1.1", + "version": "1.1.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.", diff --git a/src/git/install.sh b/src/git/install.sh index 2463cc9ff..24e08e857 100755 --- a/src/git/install.sh +++ b/src/git/install.sh @@ -149,9 +149,9 @@ fi check_packages libpcre2-dev -if [ "${VERSION_CODENAME}" = "focal" ]; then +if [ "${VERSION_CODENAME}" = "focal" ] || [ "${VERSION_CODENAME}" = "bullseye" ]; then check_packages libpcre2-posix2 -elif [ "${VERSION_CODENAME}" = "bionic" ]; then +elif [ "${VERSION_CODENAME}" = "bionic" ] || [ "${VERSION_CODENAME}" = "buster" ]; then check_packages libpcre2-posix0 else check_packages libpcre2-posix3 diff --git a/test/git/install_git_from_src_bullseye.sh b/test/git/install_git_from_src_bullseye.sh new file mode 100644 index 000000000..4bdcf3066 --- /dev/null +++ b/test/git/install_git_from_src_bullseye.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "version" git --version +check "gettext" dpkg-query -l gettext + +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_src_buster.sh b/test/git/install_git_from_src_buster.sh new file mode 100644 index 000000000..4bdcf3066 --- /dev/null +++ b/test/git/install_git_from_src_buster.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "version" git --version +check "gettext" dpkg-query -l gettext + +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 90aa7e30a..22af7a860 100644 --- a/test/git/scenarios.json +++ b/test/git/scenarios.json @@ -25,5 +25,23 @@ "ppa": "false" } } + }, + "install_git_from_src_bullseye": { + "image": "debian:bullseye", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } + }, + "install_git_from_src_buster": { + "image": "debian:buster", + "features": { + "git": { + "version": "latest", + "ppa": "false" + } + } } } From 7867e008c1d87c0e5bc4294a0d36d765b0cbd3ca Mon Sep 17 00:00:00 2001 From: eitsupi <50911393+eitsupi@users.noreply.github.com> Date: Tue, 20 Dec 2022 01:23:05 +0900 Subject: [PATCH 044/478] Fix /etc/bash.bashrc generated by common-utils (#342) * Fix /etc/bash.bashrc generated by common-utils * bump version --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/scripts/rc_snippet.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 05bf067e7..d9ecc8877 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.0", + "version": "2.0.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/rc_snippet.sh b/src/common-utils/scripts/rc_snippet.sh index 3aa319a15..4810cd993 100644 --- a/src/common-utils/scripts/rc_snippet.sh +++ b/src/common-utils/scripts/rc_snippet.sh @@ -23,4 +23,4 @@ if [ -z "$(git config --get core.editor)" ] && [ -z "${GIT_EDITOR}" ]; then export GIT_EDITOR="code --wait" fi fi -fi \ No newline at end of file +fi From 9af65a01c7052821daf7fbbf93e65698c9053f27 Mon Sep 17 00:00:00 2001 From: zephyros-dev <67867662+zephyros-dev@users.noreply.github.com> Date: Mon, 19 Dec 2022 23:24:59 +0700 Subject: [PATCH 045/478] docs: add bind mount docs for docker from docker (#343) Co-authored-by: ptn --- src/docker-from-docker/NOTES.md | 45 +++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/docker-from-docker/NOTES.md b/src/docker-from-docker/NOTES.md index 672904427..fe658bc4f 100644 --- a/src/docker-from-docker/NOTES.md +++ b/src/docker-from-docker/NOTES.md @@ -1,25 +1,54 @@ ## Limitations -* As the name implies, the Feature is expected to work when the host is running Docker (or the OSS Moby container engine it is built on). It may be possible to get running in other container engines, but it has not been tested with them. -* The host and the container must be running on the same chip architecture. You will not be able to use it with an emulated x86 image with Docker Desktop on an Apple Silicon Mac, for example. -* This approach does not currently enable bind mounting the workspace folder by default, and cannot support folders outside of the workspace folder. Consider whether the [Docker-in-Docker Feature](../docker-in-docker) would better meet your needs given it does not have this limitation. +- As the name implies, the Feature is expected to work when the host is running Docker (or the OSS Moby container engine it is built on). It may be possible to get running in other container engines, but it has not been tested with them. +- The host and the container must be running on the same chip architecture. You will not be able to use it with an emulated x86 image with Docker Desktop on an Apple Silicon Mac, for example. +- This approach does not currently enable bind mounting the workspace folder by default, and cannot support folders outside of the workspace folder. Consider whether the [Docker-in-Docker Feature](../docker-in-docker) would better meet your needs given it does not have this limitation. ## Supporting bind mounts from the workspace folder -A common question that comes up is how you can use `bind` mounts from the Docker CLI from within the a dev container using this Feature (e.g. via `-v`). If you cannot use the [Docker-in-Docker Feature](../docker-in-docker), the only way to work around this is to use the **host**'s folder paths instead of the container's paths. +A common question that comes up is how you can use `bind` mounts from the Docker CLI from within the a dev container using this Feature (e.g. via `-v`). If you cannot use the [Docker-in-Docker Feature](../docker-in-docker), the only way to work around this is to use the **host**'s folder paths instead of the container's paths. There are 2 ways to do this -A simple way to do this is to put `${localWorkspaceFolder}` in an environment variable that you then use when doing bind mounts inside the container. +### 1. Use the `${localWorkspaceFolder}` as environment variable in your code -Add the following to `devcontainer.json`: +1. Add the following to `devcontainer.json`: ```json "remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" } ``` -Then reference the env var when running Docker commands from the terminal inside the container. +2. Usage with Docker commands ```bash docker run -it --rm -v ${LOCAL_WORKSPACE_FOLDER}:/workspace debian bash ``` -> **Note:** There is no `${localWorkspaceFolder}` when using the **Clone Repository in Container Volume** command in the VS Code Dev Containers extension ([info](https://github.com/microsoft/vscode-remote-release/issues/6160#issuecomment-1014701007)). \ No newline at end of file +3. Usage with Docker-compose + +```yaml +version: "3.9" + +services: + debian: + image: debian + volumes: + - ${LOCAL_WORKSPACE_FOLDER:-./}:/workspace +``` + +- The defaults value `./` is added so that the `docker-compose.yaml` file can work when it is run outside of the container + +### Change the workspace to `${localWorkspaceFolder}` + +- This is useful if we don't want to edit the `docker-compose.yaml` file + +1. Add the following to `devcontainer.json` + +```json +"workspaceFolder": "${localWorkspaceFolder}", +"workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind" +``` + +2. Rebuild the container. +3. When the container first started with this settings, select the Workspace with the absolute path to the working directory inside the container +4. Docker commands with bind mount should work as they did outside of the devcontainer + +> **Note:** There is no `${localWorkspaceFolder}` when using the **Clone Repository in Container Volume** command in the VS Code Dev Containers extension ([info](https://github.com/microsoft/vscode-remote-release/issues/6160#issuecomment-1014701007)). From fede4055495a9d44efbb65848eb7799771d23f9b Mon Sep 17 00:00:00 2001 From: Mark Phippard Date: Mon, 19 Dec 2022 11:25:32 -0500 Subject: [PATCH 046/478] Add support for mariner (#344) --- src/common-utils/main.sh | 2 +- test/common-utils/mariner.sh | 14 ++++++++++++++ test/common-utils/scenarios.json | 7 +++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100755 test/common-utils/mariner.sh diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index 63f64ab60..f0fedcf82 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -289,7 +289,7 @@ chmod +x /etc/profile.d/00-restore-env.sh # Get an adjusted ID independant of distro variants if [ "${ID}" = "debian" ] || [ "${ID_LIKE}" = "debian" ]; then ADJUSTED_ID="debian" -elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* ]]; then +elif [[ "${ID}" = "rhel" || "${ID}" = "fedora" || "${ID}" = "mariner" || "${ID_LIKE}" = *"rhel"* || "${ID_LIKE}" = *"fedora"* || "${ID_LIKE}" = *"mariner"* ]]; then ADJUSTED_ID="rhel" elif [ "${ID}" = "alpine" ]; then ADJUSTED_ID="alpine" diff --git a/test/common-utils/mariner.sh b/test/common-utils/mariner.sh new file mode 100755 index 000000000..ab6cb6e13 --- /dev/null +++ b/test/common-utils/mariner.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${ID}" = "mariner" + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index 9b0bc85c9..bc1c784bf 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -62,6 +62,13 @@ "common-utils": {} } }, + "mariner": { + "image": "mcr.microsoft.com/cbl-mariner/base/core:2.0", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, "alpine": { "image": "alpine", "remoteUser": "devcontainer", From e46fe0eb3460bf888e84451d727a7ed83f0f0404 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 11:27:18 -0500 Subject: [PATCH 047/478] Automated documentation update (#349) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/docker-from-docker/README.md | 44 +++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/src/docker-from-docker/README.md b/src/docker-from-docker/README.md index 41d984686..e1de84b5e 100644 --- a/src/docker-from-docker/README.md +++ b/src/docker-from-docker/README.md @@ -21,30 +21,60 @@ ## Limitations -* As the name implies, the Feature is expected to work when the host is running Docker (or the OSS Moby container engine it is built on). It may be possible to get running in other container engines, but it has not been tested with them. -* The host and the container must be running on the same chip architecture. You will not be able to use it with an emulated x86 image with Docker Desktop on an Apple Silicon Mac, for example. -* This approach does not currently enable bind mounting the workspace folder by default, and cannot support folders outside of the workspace folder. Consider whether the [Docker-in-Docker Feature](../docker-in-docker) would better meet your needs given it does not have this limitation. +- As the name implies, the Feature is expected to work when the host is running Docker (or the OSS Moby container engine it is built on). It may be possible to get running in other container engines, but it has not been tested with them. +- The host and the container must be running on the same chip architecture. You will not be able to use it with an emulated x86 image with Docker Desktop on an Apple Silicon Mac, for example. +- This approach does not currently enable bind mounting the workspace folder by default, and cannot support folders outside of the workspace folder. Consider whether the [Docker-in-Docker Feature](../docker-in-docker) would better meet your needs given it does not have this limitation. ## Supporting bind mounts from the workspace folder -A common question that comes up is how you can use `bind` mounts from the Docker CLI from within the a dev container using this Feature (e.g. via `-v`). If you cannot use the [Docker-in-Docker Feature](../docker-in-docker), the only way to work around this is to use the **host**'s folder paths instead of the container's paths. +A common question that comes up is how you can use `bind` mounts from the Docker CLI from within the a dev container using this Feature (e.g. via `-v`). If you cannot use the [Docker-in-Docker Feature](../docker-in-docker), the only way to work around this is to use the **host**'s folder paths instead of the container's paths. There are 2 ways to do this -A simple way to do this is to put `${localWorkspaceFolder}` in an environment variable that you then use when doing bind mounts inside the container. +### 1. Use the `${localWorkspaceFolder}` as environment variable in your code -Add the following to `devcontainer.json`: +1. Add the following to `devcontainer.json`: ```json "remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" } ``` -Then reference the env var when running Docker commands from the terminal inside the container. +2. Usage with Docker commands ```bash docker run -it --rm -v ${LOCAL_WORKSPACE_FOLDER}:/workspace debian bash ``` +3. Usage with Docker-compose + +```yaml +version: "3.9" + +services: + debian: + image: debian + volumes: + - ${LOCAL_WORKSPACE_FOLDER:-./}:/workspace +``` + +- The defaults value `./` is added so that the `docker-compose.yaml` file can work when it is run outside of the container + +### Change the workspace to `${localWorkspaceFolder}` + +- This is useful if we don't want to edit the `docker-compose.yaml` file + +1. Add the following to `devcontainer.json` + +```json +"workspaceFolder": "${localWorkspaceFolder}", +"workspaceMount": "source=${localWorkspaceFolder},target=${localWorkspaceFolder},type=bind" +``` + +2. Rebuild the container. +3. When the container first started with this settings, select the Workspace with the absolute path to the working directory inside the container +4. Docker commands with bind mount should work as they did outside of the devcontainer + > **Note:** There is no `${localWorkspaceFolder}` when using the **Clone Repository in Container Volume** command in the VS Code Dev Containers extension ([info](https://github.com/microsoft/vscode-remote-release/issues/6160#issuecomment-1014701007)). + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/docker-from-docker/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ From 2472653c316e318f36eeaf97248665bbc3ed9fc8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 19 Dec 2022 09:11:02 -0800 Subject: [PATCH 048/478] Automated documentation update (#351) Automated documentation update [skip ci] Co-authored-by: github-actions From 42e5a013cc914f87d0ff7bf613a1f80d9ff57579 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Mon, 19 Dec 2022 12:19:46 -0500 Subject: [PATCH 049/478] common-utils 2.0.2 (#350) Will release staged change: https://github.com/devcontainers/features/commit/fede4055495a9d44efbb65848eb7799771d23f9b --- 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 d9ecc8877..cbb853edf 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.1", + "version": "2.0.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.", From 48678001d1e910477390c475165564a38936b058 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 21 Dec 2022 09:11:10 -0800 Subject: [PATCH 050/478] Terraform: Update GPG_KEY_SERVERS (#353) * Terraform: Update GPG_KEY_SERVERS * add check --- src/terraform/devcontainer-feature.json | 2 +- src/terraform/install.sh | 20 +------------------- test/terraform/test.sh | 2 +- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index 66e53f09d..490a05b2d 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.1.0", + "version": "1.1.1", "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 0f9e4db54..b324eb644 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -26,7 +26,7 @@ TERRAFORM_DOCS_SHA256="${TERRAFORM_DOCS_SHA256:-"automatic"}" TERRAFORM_GPG_KEY="72D7468F" TFLINT_GPG_KEY_URI="https://raw.githubusercontent.com/terraform-linters/tflint/master/8CE69160EB3F2FE9.key" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80 +GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" @@ -44,26 +44,9 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi -# Get central common setting -get_common_setting() { - if [ "${common_settings_file_loaded}" != "true" ]; then - curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." - common_settings_file_loaded=true - fi - if [ -f "/tmp/vsdc-settings.env" ]; then - local multi_line="" - if [ "$2" = "true" ]; then multi_line="-z"; fi - local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" - if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi - fi - echo "$1=${!1}" -} - # Import the specified key in a variable name passed in as receive_gpg_keys() { - get_common_setting $1 local keys=${!1} - get_common_setting GPG_KEY_SERVERS true local keyring_args="" if [ ! -z "$2" ]; then keyring_args="--no-default-keyring --keyring $2" @@ -186,7 +169,6 @@ if [ "${TFLINT_VERSION}" != "none" ]; then curl -sSL -o /tmp/tf-downloads/${TFLINT_FILENAME} https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/${TFLINT_FILENAME} if [ "${TFLINT_SHA256}" != "dev-mode" ]; then if [ "${TFLINT_SHA256}" = "automatic" ]; then - get_common_setting TFLINT_GPG_KEY_URI curl -sSL -o tflint_key "${TFLINT_GPG_KEY_URI}" gpg -q --import tflint_key curl -sSL -o tflint_checksums.txt https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt diff --git a/test/terraform/test.sh b/test/terraform/test.sh index bd0a51639..ef7b14e10 100755 --- a/test/terraform/test.sh +++ b/test/terraform/test.sh @@ -5,7 +5,7 @@ set -e # Optional: Import test library source dev-container-features-test-lib -echo 'NO TESTS FOR ME YET!' +check "terraform" terraform -version # Report result reportResults \ No newline at end of file From b9bfe406d211ce5645a165a73b72048e9ea9e88e Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 21 Dec 2022 12:15:24 -0800 Subject: [PATCH 051/478] Update GPG_KEY_SERVERS: Remove `:80` from Ubuntu Keyserver (#354) * Update GPG_KEY_SERVERS: Remove `:80` from Ubuntu Keyserver * Fix ruby tests --- src/git-lfs/devcontainer-feature.json | 2 +- src/git-lfs/install.sh | 20 +------- src/git/devcontainer-feature.json | 2 +- src/git/install.sh | 19 +------ src/github-cli/devcontainer-feature.json | 2 +- src/github-cli/install.sh | 50 +------------------ .../devcontainer-feature.json | 2 +- src/kubectl-helm-minikube/install.sh | 20 +------- src/nix/devcontainer-feature.json | 2 +- src/nix/install.sh | 2 +- src/powershell/devcontainer-feature.json | 2 +- src/powershell/install.sh | 18 +------ src/python/devcontainer-feature.json | 2 +- src/python/install.sh | 19 +------ src/ruby/devcontainer-feature.json | 2 +- src/ruby/install.sh | 19 +------ .../install_git_cli_from_release.sh | 11 ++++ test/github-cli/scenarios.json | 11 ++++ 18 files changed, 38 insertions(+), 167 deletions(-) create mode 100644 test/github-cli/install_git_cli_from_release.sh create mode 100644 test/github-cli/scenarios.json diff --git a/src/git-lfs/devcontainer-feature.json b/src/git-lfs/devcontainer-feature.json index 9911e252b..7916ea1c3 100644 --- a/src/git-lfs/devcontainer-feature.json +++ b/src/git-lfs/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git-lfs", - "version": "1.0.4", + "version": "1.0.5", "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 f24ed9252..f0ce9ff7e 100755 --- a/src/git-lfs/install.sh +++ b/src/git-lfs/install.sh @@ -13,7 +13,7 @@ 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:80 +GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" @@ -27,21 +27,6 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi -# Get central common setting -get_common_setting() { - if [ "${common_settings_file_loaded}" != "true" ]; then - curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." - common_settings_file_loaded=true - fi - if [ -f "/tmp/vsdc-settings.env" ]; then - local multi_line="" - if [ "$2" = "true" ]; then multi_line="-z"; fi - local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" - if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi - fi - echo "$1=${!1}" -} - # Figure out correct version of a three part version number is not passed find_version_from_git_tags() { local variable_name=$1 @@ -78,9 +63,7 @@ find_version_from_git_tags() { # Import the specified key in a variable name passed in as receive_gpg_keys() { - get_common_setting $1 local keys=${!1} - get_common_setting GPG_KEY_SERVERS true # Use a temporary locaiton for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" @@ -133,7 +116,6 @@ install_using_apt() { version_suffix="" fi # Install - get_common_setting GIT_LFS_ARCHIVE_GPG_KEY_URI curl -sSL "${GIT_LFS_ARCHIVE_GPG_KEY_URI}" | gpg --dearmor > /usr/share/keyrings/gitlfs-archive-keyring.gpg echo -e "deb [arch=${architecture} signed-by=/usr/share/keyrings/gitlfs-archive-keyring.gpg] https://packagecloud.io/github/git-lfs/${ID} ${VERSION_CODENAME} main\ndeb-src [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gitlfs-archive-keyring.gpg] https://packagecloud.io/github/git-lfs/${ID} ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/git-lfs.list diff --git a/src/git/devcontainer-feature.json b/src/git/devcontainer-feature.json index c68d69d9a..ea35c4bbe 100644 --- a/src/git/devcontainer-feature.json +++ b/src/git/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git", - "version": "1.1.2", + "version": "1.1.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.", diff --git a/src/git/install.sh b/src/git/install.sh index 24e08e857..52081f17c 100755 --- a/src/git/install.sh +++ b/src/git/install.sh @@ -11,7 +11,7 @@ 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:80 +GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" @@ -25,26 +25,9 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi -# Get central common setting -get_common_setting() { - if [ "${common_settings_file_loaded}" != "true" ]; then - curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." - common_settings_file_loaded=true - fi - if [ -f "/tmp/vsdc-settings.env" ]; then - local multi_line="" - if [ "$2" = "true" ]; then multi_line="-z"; fi - local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" - if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi - fi - echo "$1=${!1}" -} - # Import the specified key in a variable name passed in as receive_gpg_keys() { - get_common_setting $1 local keys=${!1} - get_common_setting GPG_KEY_SERVERS true local keyring_args="" if [ ! -z "$2" ]; then mkdir -p "$(dirname \"$2\")" diff --git a/src/github-cli/devcontainer-feature.json b/src/github-cli/devcontainer-feature.json index 824602c53..0e68a6028 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.8", + "version": "1.0.9", "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 65bbfc479..1856115c5 100755 --- a/src/github-cli/install.sh +++ b/src/github-cli/install.sh @@ -11,7 +11,7 @@ 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:80 +GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" @@ -25,58 +25,10 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi -# Get central common setting -get_common_setting() { - if [ "${common_settings_file_loaded}" != "true" ]; then - curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." - common_settings_file_loaded=true - fi - if [ -f "/tmp/vsdc-settings.env" ]; then - local multi_line="" - if [ "$2" = "true" ]; then multi_line="-z"; fi - local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" - if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi - fi - echo "$1=${!1}" -} - -# Import the specified key in a variable name passed in as -receive_gpg_keys() { - get_common_setting $1 - local keys=${!1} - get_common_setting GPG_KEY_SERVERS true - - # Use a temporary locaiton 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 - # GPG key download sometimes fails for some reason and retrying fixes it. - local retry_count=0 - local gpg_ok="false" - set +e - until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; - do - echo "(*) Downloading GPG key..." - ( echo "${keys}" | xargs -n 1 gpg --recv-keys) 2>&1 && gpg_ok="true" - if [ "${gpg_ok}" != "true" ]; then - echo "(*) Failed getting key, retring in 10s..." - (( retry_count++ )) - sleep 10s - fi - done - set -e - if [ "${gpg_ok}" = "false" ]; then - echo "(!) Failed to get gpg key." - exit 1 - fi -} # Import the specified key in a variable name passed in as receive_gpg_keys() { - get_common_setting $1 local keys=${!1} - get_common_setting GPG_KEY_SERVERS true local keyring_args="" if [ ! -z "$2" ]; then keyring_args="--no-default-keyring --keyring $2" diff --git a/src/kubectl-helm-minikube/devcontainer-feature.json b/src/kubectl-helm-minikube/devcontainer-feature.json index beea80a2e..076af3912 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.1", + "version": "1.1.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 3ab65356f..af8b0ae50 100755 --- a/src/kubectl-helm-minikube/install.sh +++ b/src/kubectl-helm-minikube/install.sh @@ -22,7 +22,7 @@ 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:80 +GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" @@ -53,22 +53,6 @@ if [ "$USERNAME" = "root" ]; then USERHOME="/root" fi - -# Get central common setting -get_common_setting() { - if [ "${common_settings_file_loaded}" != "true" ]; then - curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." - common_settings_file_loaded=true - fi - if [ -f "/tmp/vsdc-settings.env" ]; then - local multi_line="" - if [ "$2" = "true" ]; then multi_line="-z"; fi - local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" - if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi - fi - echo "$1=${!1}" -} - # Figure out correct version of a three part version number is not passed find_version_from_git_tags() { local variable_name=$1 @@ -182,8 +166,6 @@ curl -sSL "https://github.com/helm/helm/releases/download/${HELM_VERSION}/${helm export GNUPGHOME="/tmp/helm/gnupg" mkdir -p "${GNUPGHOME}" chmod 700 ${GNUPGHOME} -get_common_setting HELM_GPG_KEYS_URI -get_common_setting GPG_KEY_SERVERS true curl -sSL "${HELM_GPG_KEYS_URI}" -o /tmp/helm/KEYS echo -e "disable-ipv6\n${GPG_KEY_SERVERS}" > ${GNUPGHOME}/dirmngr.conf gpg -q --import "/tmp/helm/KEYS" diff --git a/src/nix/devcontainer-feature.json b/src/nix/devcontainer-feature.json index 68ccdf78e..b112040d3 100644 --- a/src/nix/devcontainer-feature.json +++ b/src/nix/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nix", - "version": "1.1.0", + "version": "1.1.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.", diff --git a/src/nix/install.sh b/src/nix/install.sh index 6141d7e0b..dcddcfdb4 100755 --- a/src/nix/install.sh +++ b/src/nix/install.sh @@ -14,7 +14,7 @@ USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" # Nix keys for securly verifying installer download signature per https://nixos.org/download.html#nix-verify-installation NIX_GPG_KEYS="B541D55301270E0BCF15CA5D8170B4726D7198DE" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80 +GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" diff --git a/src/powershell/devcontainer-feature.json b/src/powershell/devcontainer-feature.json index 04dbe491a..84c39feb6 100644 --- a/src/powershell/devcontainer-feature.json +++ b/src/powershell/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "powershell", - "version": "1.0.4", + "version": "1.0.5", "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.", diff --git a/src/powershell/install.sh b/src/powershell/install.sh index ea3b6e8bc..3f19f47ea 100755 --- a/src/powershell/install.sh +++ b/src/powershell/install.sh @@ -17,7 +17,7 @@ POWERSHELL_VERSION=${VERSION:-"latest"} 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" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80 +GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" @@ -60,21 +60,6 @@ find_version_from_git_tags() { echo "${variable_name}=${!variable_name}" } -# Get central common setting -get_common_setting() { - if [ "${common_settings_file_loaded}" != "true" ]; then - curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." - common_settings_file_loaded=true - fi - if [ -f "/tmp/vsdc-settings.env" ]; then - local multi_line="" - if [ "$2" = "true" ]; then multi_line="-z"; fi - local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" - if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi - fi - echo "$1=${!1}" -} - apt_get_update() { if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then @@ -95,7 +80,6 @@ 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 - get_common_setting MICROSOFT_GPG_KEYS_URI 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 diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index 8daf3e90b..fa5932035 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.0.17", + "version": "1.0.18", "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 76fd6f09f..92b8368f1 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -28,7 +28,7 @@ ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" DEFAULT_UTILS=("pylint" "flake8" "autopep8" "black" "yapf" "mypy" "pydocstyle" "pycodestyle" "bandit" "pipenv" "virtualenv") PYTHON_SOURCE_GPG_KEYS="64E628F8D684696D B26995E310250568 2D347EA6AA65421D FB9921286F5E1540 3A5CA953F73C700D 04C367C218ADD4FF 0EDDC5F26A45C816 6AF053F07D9DC8D2 C9BE28DEE6DF025C 126EB563A74B06BF D9866941EA5BBD71 ED9D77D5" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80 +GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" @@ -76,26 +76,9 @@ updaterc() { fi } -# Get central common setting -get_common_setting() { - if [ "${common_settings_file_loaded}" != "true" ]; then - curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." - common_settings_file_loaded=true - fi - if [ -f "/tmp/vsdc-settings.env" ]; then - local multi_line="" - if [ "$2" = "true" ]; then multi_line="-z"; fi - local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" - if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi - fi - echo "$1=${!1}" -} - # Import the specified key in a variable name passed in as receive_gpg_keys() { - get_common_setting $1 local keys=${!1} - get_common_setting GPG_KEY_SERVERS true local keyring_args="" if [ ! -z "$2" ]; then mkdir -p "$(dirname \"$2\")" diff --git a/src/ruby/devcontainer-feature.json b/src/ruby/devcontainer-feature.json index e11c1727a..68951d899 100644 --- a/src/ruby/devcontainer-feature.json +++ b/src/ruby/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby", - "version": "1.0.7", + "version": "1.0.8", "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 dcf404229..c879dec7e 100755 --- a/src/ruby/install.sh +++ b/src/ruby/install.sh @@ -22,7 +22,7 @@ ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" DEFAULT_GEMS="rake ruby-debug-ide" RVM_GPG_KEYS="409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com:80 +GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" @@ -70,26 +70,9 @@ updaterc() { fi } -# Get central common setting -get_common_setting() { - if [ "${common_settings_file_loaded}" != "true" ]; then - curl -sfL "https://aka.ms/vscode-dev-containers/script-library/settings.env" 2>/dev/null -o /tmp/vsdc-settings.env || echo "Could not download settings file. Skipping." - common_settings_file_loaded=true - fi - if [ -f "/tmp/vsdc-settings.env" ]; then - local multi_line="" - if [ "$2" = "true" ]; then multi_line="-z"; fi - local result="$(grep ${multi_line} -oP "$1=\"?\K[^\"]+" /tmp/vsdc-settings.env | tr -d '\0')" - if [ ! -z "${result}" ]; then declare -g $1="${result}"; fi - fi - echo "$1=${!1}" -} - # Import the specified key in a variable name passed in as receive_gpg_keys() { - get_common_setting $1 local keys=${!1} - get_common_setting GPG_KEY_SERVERS true local keyring_args="" if [ ! -z "$2" ]; then keyring_args="--no-default-keyring --keyring \"$2\"" diff --git a/test/github-cli/install_git_cli_from_release.sh b/test/github-cli/install_git_cli_from_release.sh new file mode 100644 index 000000000..d81c1c414 --- /dev/null +++ b/test/github-cli/install_git_cli_from_release.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "version" gh --version + +# Report result +reportResults diff --git a/test/github-cli/scenarios.json b/test/github-cli/scenarios.json new file mode 100644 index 000000000..d41019aeb --- /dev/null +++ b/test/github-cli/scenarios.json @@ -0,0 +1,11 @@ +{ + "install_git_cli_from_release": { + "image": "ubuntu:focal", + "features": { + "github-cli": { + "version": "latest", + "installDirectlyFromGitHubRelease": "false" + } + } + } +} \ No newline at end of file From b6921f9b9f594b6674b25189eee41783e6c6f22e Mon Sep 17 00:00:00 2001 From: eitsupi <50911393+eitsupi@users.noreply.github.com> Date: Tue, 27 Dec 2022 22:25:33 +0900 Subject: [PATCH 052/478] feat(common-utils): Support the new path of `meta.env` file and the new field for saving source revisions (#359) * support the new path of meta.env * support the new field for the image revision * minor formatting --- src/common-utils/bin/devcontainer-info | 10 +++++++++- src/common-utils/main.sh | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/common-utils/bin/devcontainer-info b/src/common-utils/bin/devcontainer-info index 2c74fea6e..abbb682eb 100755 --- a/src/common-utils/bin/devcontainer-info +++ b/src/common-utils/bin/devcontainer-info @@ -1,5 +1,12 @@ #!/bin/sh -. /usr/local/etc/vscode-dev-containers/meta.env + +# Load meta.env +if [ -f "/usr/local/etc/vscode-dev-containers/meta.env" ]; then + . /usr/local/etc/vscode-dev-containers/meta.env +fi +if [ -f "/usr/local/etc/dev-containers/meta.env" ]; then + . /usr/local/etc/dev-containers/meta.env +fi # Minimal output if [ "$1" = "version" ] || [ "$1" = "image-version" ]; then @@ -22,6 +29,7 @@ if [ ! -z "${DEFINITION_ID}" ]; then echo "- Definition ID: ${DEFINITION_ID}"; f if [ ! -z "${VARIANT}" ]; then echo "- Variant: ${VARIANT}"; fi if [ ! -z "${GIT_REPOSITORY}" ]; then echo "- Source code repository: ${GIT_REPOSITORY}"; fi if [ ! -z "${GIT_REPOSITORY_RELEASE}" ]; then echo "- Source code release/branch: ${GIT_REPOSITORY_RELEASE}"; fi +if [ ! -z "${GIT_REPOSITORY_REVISION}" ]; then echo "- Source code revision: ${GIT_REPOSITORY_REVISION}"; fi if [ ! -z "${BUILD_TIMESTAMP}" ]; then echo "- Timestamp: ${BUILD_TIMESTAMP}"; fi if [ ! -z "${CONTENTS_URL}" ]; then echo && echo "More info: ${CONTENTS_URL}"; fi echo diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index f0fedcf82..6b1df8a63 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -477,7 +477,7 @@ if [ "${ADJUSTED_ID}" = "debian" ]; then fi # Persist image metadata info, script if meta.env found in same directory -if [ -f "/usr/local/etc/vscode-dev-containers/meta.env" ]; then +if [ -f "/usr/local/etc/vscode-dev-containers/meta.env" ] || [ -f "/usr/local/etc/dev-containers/meta.env" ]; then cp -f "${FEATURE_DIR}/bin/devcontainer-info" /usr/local/bin/devcontainer-info chmod +x /usr/local/bin/devcontainer-info fi From 5fb5c388b5cf00ba9d4c09aa753fbd032f396507 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Tue, 27 Dec 2022 09:32:34 -0500 Subject: [PATCH 053/478] typo --- src/docker-from-docker/devcontainer-feature.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/docker-from-docker/devcontainer-feature.json b/src/docker-from-docker/devcontainer-feature.json index 2ebdd3833..9948a62e1 100644 --- a/src/docker-from-docker/devcontainer-feature.json +++ b/src/docker-from-docker/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "docker-from-docker", - "version": "1.0.7", + "version": "1.0.8", "name": "Docker (Docker-from-Docker)", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-from-docker", - "descripton": "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.", + "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.", "options": { "version": { "type": "string", From 592fdc8177f1993b26e5322be2e5fb82b2dff3d5 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Tue, 27 Dec 2022 09:36:51 -0500 Subject: [PATCH 054/478] typo in 'dotnet' Feature schema --- src/dotnet/devcontainer-feature.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index e8bb9f16c..e66550e76 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "1.1.1", + "version": "1.1.2", "name": "Dotnet CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet", "description": "Installs the .NET CLI. Provides option of installing sdk or runtime, and option of versions to install. Uses latest version of .NET sdk as defaults to install.", @@ -23,7 +23,7 @@ }, "installUsingApt": { "type": "boolean", - "default": "true", + "default": true, "description": "If true, it installs using apt instead of the release URL" } }, From 00dd4f4a198d0172bd1fcf6ef7292407b120dd35 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Tue, 27 Dec 2022 14:49:40 +0000 Subject: [PATCH 055/478] remove unused buildArg in java Feature --- src/java/devcontainer-feature.json | 1 - 1 file changed, 1 deletion(-) diff --git a/src/java/devcontainer-feature.json b/src/java/devcontainer-feature.json index 4c7df039b..113c75d7b 100644 --- a/src/java/devcontainer-feature.json +++ b/src/java/devcontainer-feature.json @@ -61,7 +61,6 @@ "description": "Select or enter a Maven version" } }, - "buildArg": "_VSC_INSTALL_JAVA", "customizations": { "vscode": { "extensions": [ From 80ed2fbc302db2d2e9053dbd042815e700f00a66 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Dec 2022 09:51:25 -0500 Subject: [PATCH 056/478] Automated documentation update (#365) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/docker-from-docker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docker-from-docker/README.md b/src/docker-from-docker/README.md index e1de84b5e..be32ce9dd 100644 --- a/src/docker-from-docker/README.md +++ b/src/docker-from-docker/README.md @@ -1,7 +1,7 @@ # Docker (Docker-from-Docker) (docker-from-docker) - +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. ## Example Usage From 19bc8bb633a8eb41b581296f468b85b7ac31a828 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Tue, 27 Dec 2022 17:27:57 +0000 Subject: [PATCH 057/478] OS support in Feature NOTES.md (#366) * https://github.com/devcontainers/features/issues/360 * omit from common utils --- src/anaconda/NOTES.md | 7 +++++++ src/aws-cli/NOTES.md | 8 +++++++- src/azure-cli/NOTES.md | 7 +++++++ src/common-utils/NOTES.md | 2 +- src/conda/NOTES.md | 7 +++++++ src/desktop-lite/NOTES.md | 7 +++++++ src/docker-from-docker/NOTES.md | 7 +++++++ src/docker-in-docker/NOTES.md | 7 +++++++ src/dotnet/NOTES.md | 7 +++++++ src/git-lfs/NOTES.md | 7 +++++++ src/git/NOTES.md | 7 +++++++ src/github-cli/NOTES.md | 7 +++++++ src/go/NOTES.md | 7 +++++++ src/hugo/NOTES.md | 7 +++++++ src/java/NOTES.md | 7 +++++++ src/kubectl-helm-minikube/NOTES.md | 7 +++++++ src/nix/NOTES.md | 7 +++++++ src/node/NOTES.md | 7 +++++++ src/nvidia-cuda/NOTES.md | 7 +++++++ src/oryx/NOTES.md | 7 +++++++ src/php/NOTES.md | 7 +++++++ src/powershell/NOTES.md | 7 +++++++ src/python/NOTES.md | 7 +++++++ src/ruby/NOTES.md | 7 +++++++ src/rust/NOTES.md | 7 +++++++ src/sshd/NOTES.md | 7 +++++++ src/terraform/NOTES.md | 7 +++++++ 27 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 src/azure-cli/NOTES.md create mode 100644 src/dotnet/NOTES.md create mode 100644 src/git-lfs/NOTES.md create mode 100644 src/git/NOTES.md create mode 100644 src/github-cli/NOTES.md create mode 100644 src/go/NOTES.md create mode 100644 src/hugo/NOTES.md create mode 100644 src/oryx/NOTES.md create mode 100644 src/php/NOTES.md create mode 100644 src/powershell/NOTES.md create mode 100644 src/python/NOTES.md create mode 100644 src/ruby/NOTES.md create mode 100644 src/rust/NOTES.md create mode 100644 src/terraform/NOTES.md diff --git a/src/anaconda/NOTES.md b/src/anaconda/NOTES.md index f2ecdc102..394dd6f1d 100644 --- a/src/anaconda/NOTES.md +++ b/src/anaconda/NOTES.md @@ -11,3 +11,10 @@ As covered in the [user FAQ](https://docs.anaconda.com/anaconda/user-guide/faq) ```bash conda install python=3.7 ``` + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/aws-cli/NOTES.md b/src/aws-cli/NOTES.md index b1cb1f90a..b8a279717 100644 --- a/src/aws-cli/NOTES.md +++ b/src/aws-cli/NOTES.md @@ -1 +1,7 @@ -Available versions of the AWS CLI can be found here: https://github.com/aws/aws-cli/blob/v2/CHANGELOG.rst. \ No newline at end of file +Available versions of the AWS CLI can be found here: https://github.com/aws/aws-cli/blob/v2/CHANGELOG.rst. + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/azure-cli/NOTES.md b/src/azure-cli/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/azure-cli/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/common-utils/NOTES.md b/src/common-utils/NOTES.md index 77dfd1d99..e9b27131e 100644 --- a/src/common-utils/NOTES.md +++ b/src/common-utils/NOTES.md @@ -18,4 +18,4 @@ To completely disable the git portion of the prompt for the current folder's rep git config devcontainers-theme.hide-status 1 ``` -For `zsh`, the default theme is a [standard Oh My Zsh! theme](https://ohmyz.sh/). You may pick a different one by modifying the `ZSH_THEME` variable in `~/.zshrc`. \ No newline at end of file +For `zsh`, the default theme is a [standard Oh My Zsh! theme](https://ohmyz.sh/). You may pick a different one by modifying the `ZSH_THEME` variable in `~/.zshrc`. diff --git a/src/conda/NOTES.md b/src/conda/NOTES.md index 58450c6a0..ef8657ab4 100644 --- a/src/conda/NOTES.md +++ b/src/conda/NOTES.md @@ -11,3 +11,10 @@ As covered in the [user FAQ](https://docs.anaconda.com/anaconda/user-guide/faq) ```bash conda install python=3.7 ``` + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/desktop-lite/NOTES.md b/src/desktop-lite/NOTES.md index 28865a374..891ce6c4a 100644 --- a/src/desktop-lite/NOTES.md +++ b/src/desktop-lite/NOTES.md @@ -62,3 +62,10 @@ If you want the full version of **Google Chrome** in the desktop: 2. Chrome sandbox support requires you set up and run as a non-root user. The [`common-utils`](https://github.com/devcontainers/features/tree/main/src/common-utils) script can do this for you, or you [set one up yourself](https://aka.ms/vscode-remote/containers/non-root). Alternatively, you can start Chrome using `google-chrome --no-sandbox` That's it! + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/docker-from-docker/NOTES.md b/src/docker-from-docker/NOTES.md index fe658bc4f..fede053ae 100644 --- a/src/docker-from-docker/NOTES.md +++ b/src/docker-from-docker/NOTES.md @@ -52,3 +52,10 @@ services: 4. Docker commands with bind mount should work as they did outside of the devcontainer > **Note:** There is no `${localWorkspaceFolder}` when using the **Clone Repository in Container Volume** command in the VS Code Dev Containers extension ([info](https://github.com/microsoft/vscode-remote-release/issues/6160#issuecomment-1014701007)). + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/docker-in-docker/NOTES.md b/src/docker-in-docker/NOTES.md index befd4aae4..a22e61c51 100644 --- a/src/docker-in-docker/NOTES.md +++ b/src/docker-in-docker/NOTES.md @@ -4,3 +4,10 @@ This docker-in-docker Dev Container Feature is roughly based on the [official do * As the name implies, the Feature is expected to work when the host is running Docker (or the OSS Moby container engine it is built on). It may be possible to get running in other container engines, but it has not been tested with them. * The host and the container must be running on the same chip architecture. You will not be able to use it with an emulated x86 image with Docker Desktop on an Apple Silicon Mac, for example. + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/dotnet/NOTES.md b/src/dotnet/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/dotnet/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/git-lfs/NOTES.md b/src/git-lfs/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/git-lfs/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/git/NOTES.md b/src/git/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/git/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/github-cli/NOTES.md b/src/github-cli/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/github-cli/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/go/NOTES.md b/src/go/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/go/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/hugo/NOTES.md b/src/hugo/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/hugo/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/java/NOTES.md b/src/java/NOTES.md index 7e10513ee..63622afaf 100644 --- a/src/java/NOTES.md +++ b/src/java/NOTES.md @@ -1,3 +1,10 @@ ## License For the Java Feature from this repository, see [NOTICE.txt](https://github.com/devcontainers/features/tree/main/src/java/NOTICE.txt) for licensing information on JDK distributions. + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/kubectl-helm-minikube/NOTES.md b/src/kubectl-helm-minikube/NOTES.md index b0d1a8089..6626d2c93 100644 --- a/src/kubectl-helm-minikube/NOTES.md +++ b/src/kubectl-helm-minikube/NOTES.md @@ -10,3 +10,10 @@ minikube addons enable ingress # Run this to forward to localhost in the background nohup kubectl port-forward --pod-running-timeout=24h -n ingress-nginx service/ingress-nginx-controller :80 & ``` + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/nix/NOTES.md b/src/nix/NOTES.md index fc76a44a3..b3b53476a 100644 --- a/src/nix/NOTES.md +++ b/src/nix/NOTES.md @@ -26,3 +26,10 @@ sudo /usr/local/share/nix-entrypoint.sh ``` This same command can be used to restart the daemon if it has stopped for some reason. Logs are available at `/tmp/nix-daemon.log`. + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/node/NOTES.md b/src/node/NOTES.md index a6a4ababd..65eb93bf3 100644 --- a/src/node/NOTES.md +++ b/src/node/NOTES.md @@ -16,3 +16,10 @@ Alternatively, you can start up an interactive shell which will in turn source ` "postCreateCommand": "bash -i -c 'nvm install --lts'" ``` + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/nvidia-cuda/NOTES.md b/src/nvidia-cuda/NOTES.md index b19fde2ac..cab2bbec7 100644 --- a/src/nvidia-cuda/NOTES.md +++ b/src/nvidia-cuda/NOTES.md @@ -17,3 +17,10 @@ Enable GPU passthrough to your devcontainer by adding `["--gpus", "all"]` to you "runArgs": ["--gpus", "all"] } ``` + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/oryx/NOTES.md b/src/oryx/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/oryx/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/php/NOTES.md b/src/php/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/php/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/powershell/NOTES.md b/src/powershell/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/powershell/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/python/NOTES.md b/src/python/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/python/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/ruby/NOTES.md b/src/ruby/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/ruby/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/rust/NOTES.md b/src/rust/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/rust/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/sshd/NOTES.md b/src/sshd/NOTES.md index 3126a1bef..e0e7acc82 100644 --- a/src/sshd/NOTES.md +++ b/src/sshd/NOTES.md @@ -60,3 +60,10 @@ While the some services automates SSH setup (e.g., when using the GitHub CLI for ...where `vscode` above is the user you are running as in the container and `2222` after the `!` is the same local port you used in the `ssh` command in the previous seciton. 4. Your dev container's filesystem should now be available in the `~/sshfs/devcontainer` folder on macOS or Linux or in a new explorer window on Windows. + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. diff --git a/src/terraform/NOTES.md b/src/terraform/NOTES.md new file mode 100644 index 000000000..19fe92f31 --- /dev/null +++ b/src/terraform/NOTES.md @@ -0,0 +1,7 @@ + + +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. From f9de0e43f8a9d2f590ad1d733772d4c25179db07 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Dec 2022 12:42:28 -0500 Subject: [PATCH 058/478] Automated documentation update (#368) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/anaconda/README.md | 7 +++++++ src/aws-cli/README.md | 7 +++++++ src/azure-cli/README.md | 7 +++++++ src/common-utils/README.md | 1 + src/conda/README.md | 7 +++++++ src/desktop-lite/README.md | 7 +++++++ src/docker-from-docker/README.md | 7 +++++++ src/docker-in-docker/README.md | 7 +++++++ src/dotnet/README.md | 7 +++++++ src/git-lfs/README.md | 7 +++++++ src/git/README.md | 7 +++++++ src/github-cli/README.md | 7 +++++++ src/go/README.md | 7 +++++++ src/hugo/README.md | 7 +++++++ src/java/README.md | 7 +++++++ src/kubectl-helm-minikube/README.md | 7 +++++++ src/nix/README.md | 7 +++++++ src/node/README.md | 7 +++++++ src/nvidia-cuda/README.md | 7 +++++++ src/oryx/README.md | 7 +++++++ src/php/README.md | 7 +++++++ src/powershell/README.md | 7 +++++++ src/python/README.md | 7 +++++++ src/ruby/README.md | 7 +++++++ src/rust/README.md | 7 +++++++ src/sshd/README.md | 7 +++++++ src/terraform/README.md | 7 +++++++ 27 files changed, 183 insertions(+) diff --git a/src/anaconda/README.md b/src/anaconda/README.md index b230b50df..3346823b4 100644 --- a/src/anaconda/README.md +++ b/src/anaconda/README.md @@ -32,6 +32,13 @@ conda install python=3.7 ``` +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/anaconda/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/aws-cli/README.md b/src/aws-cli/README.md index 00b8cd583..40cc4ae98 100644 --- a/src/aws-cli/README.md +++ b/src/aws-cli/README.md @@ -19,6 +19,13 @@ Installs the AWS CLI along with needed dependencies. Useful for base Dockerfiles Available versions of the AWS CLI can be found here: https://github.com/aws/aws-cli/blob/v2/CHANGELOG.rst. +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/aws-cli/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/azure-cli/README.md b/src/azure-cli/README.md index 9b7735f70..cb792d120 100644 --- a/src/azure-cli/README.md +++ b/src/azure-cli/README.md @@ -21,6 +21,13 @@ Installs the Azure CLI along with needed dependencies. Useful for base Dockerfil +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/azure-cli/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/common-utils/README.md b/src/common-utils/README.md index e028faca7..9102c950b 100644 --- a/src/common-utils/README.md +++ b/src/common-utils/README.md @@ -46,6 +46,7 @@ git config devcontainers-theme.hide-status 1 For `zsh`, the default theme is a [standard Oh My Zsh! theme](https://ohmyz.sh/). You may pick a different one by modifying the `ZSH_THEME` variable in `~/.zshrc`. + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/common-utils/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/conda/README.md b/src/conda/README.md index 4fb75dd1f..2e123f2c7 100644 --- a/src/conda/README.md +++ b/src/conda/README.md @@ -33,6 +33,13 @@ conda install python=3.7 ``` +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/conda/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/desktop-lite/README.md b/src/desktop-lite/README.md index 9ee8227cc..ad05e4ff2 100644 --- a/src/desktop-lite/README.md +++ b/src/desktop-lite/README.md @@ -87,6 +87,13 @@ If you want the full version of **Google Chrome** in the desktop: That's it! +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/desktop-lite/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/docker-from-docker/README.md b/src/docker-from-docker/README.md index be32ce9dd..e2ddb8472 100644 --- a/src/docker-from-docker/README.md +++ b/src/docker-from-docker/README.md @@ -75,6 +75,13 @@ services: > **Note:** There is no `${localWorkspaceFolder}` when using the **Clone Repository in Container Volume** command in the VS Code Dev Containers extension ([info](https://github.com/microsoft/vscode-remote-release/issues/6160#issuecomment-1014701007)). +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/docker-from-docker/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/docker-in-docker/README.md b/src/docker-in-docker/README.md index 58f72c5a5..4196892b0 100644 --- a/src/docker-in-docker/README.md +++ b/src/docker-in-docker/README.md @@ -29,6 +29,13 @@ This docker-in-docker Dev Container Feature is roughly based on the [official do +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/docker-in-docker/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/dotnet/README.md b/src/dotnet/README.md index 784c7362e..c13c998fd 100644 --- a/src/dotnet/README.md +++ b/src/dotnet/README.md @@ -21,6 +21,13 @@ Installs the .NET CLI. Provides option of installing sdk or runtime, and option +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/dotnet/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/git-lfs/README.md b/src/git-lfs/README.md index a23a639a0..9fc3281fe 100644 --- a/src/git-lfs/README.md +++ b/src/git-lfs/README.md @@ -19,6 +19,13 @@ Installs Git Large File Support (Git LFS) along with needed dependencies. Useful +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/git-lfs/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/git/README.md b/src/git/README.md index 287af4995..a9e54fa18 100644 --- a/src/git/README.md +++ b/src/git/README.md @@ -20,6 +20,13 @@ 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-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/git/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/github-cli/README.md b/src/github-cli/README.md index 3670399da..07945081a 100644 --- a/src/github-cli/README.md +++ b/src/github-cli/README.md @@ -20,6 +20,13 @@ Installs the GitHub CLI. Auto-detects latest version and installs needed depende +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/github-cli/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/go/README.md b/src/go/README.md index 5ea30c1fd..e7a692443 100644 --- a/src/go/README.md +++ b/src/go/README.md @@ -20,6 +20,13 @@ Installs Go and common Go utilities. Auto-detects latest version and installs ne +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/go/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/hugo/README.md b/src/hugo/README.md index bc6b99e7f..3d346c39b 100644 --- a/src/hugo/README.md +++ b/src/hugo/README.md @@ -20,6 +20,13 @@ +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/hugo/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/java/README.md b/src/java/README.md index a9ef433fb..f3e35e38a 100644 --- a/src/java/README.md +++ b/src/java/README.md @@ -27,6 +27,13 @@ Installs Java, SDKMAN! (if not installed), and needed dependencies. For the Java Feature from this repository, see [NOTICE.txt](https://github.com/devcontainers/features/tree/main/src/java/NOTICE.txt) for licensing information on JDK distributions. +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/java/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/kubectl-helm-minikube/README.md b/src/kubectl-helm-minikube/README.md index bbb02028f..81ce8c574 100644 --- a/src/kubectl-helm-minikube/README.md +++ b/src/kubectl-helm-minikube/README.md @@ -33,6 +33,13 @@ nohup kubectl port-forward --pod-running-timeout=24h -n ingress-nginx service/in ``` +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/kubectl-helm-minikube/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/nix/README.md b/src/nix/README.md index d331f8923..3ab9b0017 100644 --- a/src/nix/README.md +++ b/src/nix/README.md @@ -51,6 +51,13 @@ sudo /usr/local/share/nix-entrypoint.sh This same command can be used to restart the daemon if it has stopped for some reason. Logs are available at `/tmp/nix-daemon.log`. +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/nix/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/node/README.md b/src/node/README.md index 0bd837af3..2e5dba386 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -40,6 +40,13 @@ Alternatively, you can start up an interactive shell which will in turn source ` +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/node/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/nvidia-cuda/README.md b/src/nvidia-cuda/README.md index 5e76d7243..38a989a04 100644 --- a/src/nvidia-cuda/README.md +++ b/src/nvidia-cuda/README.md @@ -41,6 +41,13 @@ Enable GPU passthrough to your devcontainer by adding `["--gpus", "all"]` to you ``` +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/nvidia-cuda/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/oryx/README.md b/src/oryx/README.md index 670a6d1a0..7d3d3d11a 100644 --- a/src/oryx/README.md +++ b/src/oryx/README.md @@ -15,6 +15,13 @@ Installs the oryx CLI +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/oryx/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/php/README.md b/src/php/README.md index c979e39b9..3a9be7a98 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -20,6 +20,13 @@ +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/php/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/powershell/README.md b/src/powershell/README.md index 0ff0469c5..ba300d5cd 100644 --- a/src/powershell/README.md +++ b/src/powershell/README.md @@ -19,6 +19,13 @@ Installs PowerShell along with needed dependencies. Useful for base Dockerfiles +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/powershell/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/python/README.md b/src/python/README.md index 47abf5e31..05742910a 100644 --- a/src/python/README.md +++ b/src/python/README.md @@ -24,6 +24,13 @@ Installs the provided version of Python, as well as PIPX, and other common Pytho +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/python/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/ruby/README.md b/src/ruby/README.md index ffb136d47..8a0ff877d 100644 --- a/src/ruby/README.md +++ b/src/ruby/README.md @@ -19,6 +19,13 @@ Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies. +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/ruby/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/rust/README.md b/src/rust/README.md index 14af4ad49..372b56f97 100644 --- a/src/rust/README.md +++ b/src/rust/README.md @@ -20,6 +20,13 @@ Installs Rust, common Rust utilities, and their required dependencies +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/rust/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/sshd/README.md b/src/sshd/README.md index 5245d6805..6e9382c04 100644 --- a/src/sshd/README.md +++ b/src/sshd/README.md @@ -81,6 +81,13 @@ While the some services automates SSH setup (e.g., when using the GitHub CLI for 4. Your dev container's filesystem should now be available in the `~/sshfs/devcontainer` folder on macOS or Linux or in a new explorer window on Windows. +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/sshd/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/terraform/README.md b/src/terraform/README.md index 5d6b47fec..ee87d069d 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -23,6 +23,13 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la +## OS Support + +This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. + +`bash` is required to execute the `install.sh` script. + + --- _Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/terraform/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ From 29babe4245e35bbdfca1f0279f6cf0f6530282ca Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 27 Dec 2022 18:35:13 +0000 Subject: [PATCH 059/478] fix test --- src/common-utils/main.sh | 7 ++++++- test/common-utils/rocky-8.sh | 1 + test/common-utils/rocky-9.sh | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index 6b1df8a63..b6793d603 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -153,7 +153,6 @@ install_redhat_packages() { lsof \ net-tools \ psmisc \ - curl \ wget \ ca-certificates \ rsync \ @@ -174,6 +173,12 @@ install_redhat_packages() { man-db \ strace" + # rockylinux:9 installs 'curl-minimal' which clashes with 'curl' + # Install 'curl' for every OS except this rockylinux:9 + if [[ "${ID}" = "rocky" ]] && [[ "${VERSION}" != *"9."* ]]; then + package_list="${package_list} curl" + fi + # Install OpenSSL 1.0 compat if needed if ${install_cmd} -q list compat-openssl10 >/dev/null 2>&1; then package_list="${package_list} compat-openssl10" diff --git a/test/common-utils/rocky-8.sh b/test/common-utils/rocky-8.sh index f6606dbb2..be1223b3c 100755 --- a/test/common-utils/rocky-8.sh +++ b/test/common-utils/rocky-8.sh @@ -9,6 +9,7 @@ source dev-container-features-test-lib . /etc/os-release check "non-root user" test "$(whoami)" = "devcontainer" check "distro" test "${PLATFORM_ID}" = "platform:el8" +check "curl" curl --version # Report result reportResults \ No newline at end of file diff --git a/test/common-utils/rocky-9.sh b/test/common-utils/rocky-9.sh index c4b5244bc..452c1935f 100755 --- a/test/common-utils/rocky-9.sh +++ b/test/common-utils/rocky-9.sh @@ -9,6 +9,7 @@ source dev-container-features-test-lib . /etc/os-release check "non-root user" test "$(whoami)" = "devcontainer" check "distro" test "${PLATFORM_ID}" = "platform:el9" +check "curl" curl --version # Report result reportResults \ No newline at end of file From dbf069a5db328e0413300094a0dc37f520000375 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 27 Dec 2022 10:50:33 -0800 Subject: [PATCH 060/478] Common-utils : Version bump (#367) Common-utils - Version bump --- 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 cbb853edf..8d1ed8286 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.2", + "version": "2.0.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 6c76a7b4883a2639cedf805ed786b5b84100841d Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Tue, 3 Jan 2023 14:52:56 -0800 Subject: [PATCH 061/478] Add validate workflow (#369) * add validate workflow * make typo to test 3c61c88 * remove unneeded if * fix typo * better names * Update validate-metadata-files.yml --- .github/workflows/validate-metadata-files.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/validate-metadata-files.yml diff --git a/.github/workflows/validate-metadata-files.yml b/.github/workflows/validate-metadata-files.yml new file mode 100644 index 000000000..dbba8e2b4 --- /dev/null +++ b/.github/workflows/validate-metadata-files.yml @@ -0,0 +1,16 @@ +name: "Validate devcontainer-feature.json files" +on: + workflow_dispatch: + pull_request: + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: "Validate devcontainer-feature.json files" + uses: devcontainers/action@v1 + with: + validate-only: "true" + base-path-to-features: "./src" From eef35a4399a17546051fc5597440d38c36022f06 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 4 Jan 2023 11:52:05 -0800 Subject: [PATCH 062/478] Rename "docker-from-docker" to "docker-outside-of-docker" (#373) * Rename to "docker-outside-of-docker" * rename test folder --- .github/workflows/test-all.yaml | 4 ++-- .github/workflows/test-pr.yaml | 2 +- .../NOTES.md | 0 .../README.md | 0 .../devcontainer-feature.json | 11 +++++++---- .../install.sh | 0 .../docker_init.sh | 0 .../scenarios.json | 2 +- .../test.sh | 0 9 files changed, 11 insertions(+), 8 deletions(-) rename src/{docker-from-docker => docker-outside-of-docker}/NOTES.md (100%) rename src/{docker-from-docker => docker-outside-of-docker}/README.md (100%) rename src/{docker-from-docker => docker-outside-of-docker}/devcontainer-feature.json (88%) rename src/{docker-from-docker => docker-outside-of-docker}/install.sh (100%) rename test/{docker-from-docker => docker-outside-of-docker}/docker_init.sh (100%) rename test/{docker-from-docker => docker-outside-of-docker}/scenarios.json (82%) rename test/{docker-from-docker => docker-outside-of-docker}/test.sh (100%) diff --git a/.github/workflows/test-all.yaml b/.github/workflows/test-all.yaml index cf876a481..d2238a707 100644 --- a/.github/workflows/test-all.yaml +++ b/.github/workflows/test-all.yaml @@ -18,7 +18,7 @@ jobs: "common-utils", "conda", "desktop-lite", - "docker-from-docker", + "docker-outside-of-docker", "docker-in-docker", "dotnet", "git", @@ -71,7 +71,7 @@ jobs: "common-utils", "conda", "desktop-lite", - "docker-from-docker", + "docker-outside-of-docker", "docker-in-docker", "dotnet", "git", diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index f89923dc6..69b39423b 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -18,7 +18,7 @@ jobs: common-utils: ./**/common-utils/** conda: ./**/conda/** desktop-lite: ./**/desktop-lite/** - docker-from-docker: ./**/docker-from-docker/** + docker-outside-of-docker: ./**/docker-outside-of-docker/** docker-in-docker: ./**/docker-in-docker/** dotnet: ./**/dotnet/** git: ./**/git/** diff --git a/src/docker-from-docker/NOTES.md b/src/docker-outside-of-docker/NOTES.md similarity index 100% rename from src/docker-from-docker/NOTES.md rename to src/docker-outside-of-docker/NOTES.md diff --git a/src/docker-from-docker/README.md b/src/docker-outside-of-docker/README.md similarity index 100% rename from src/docker-from-docker/README.md rename to src/docker-outside-of-docker/README.md diff --git a/src/docker-from-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json similarity index 88% rename from src/docker-from-docker/devcontainer-feature.json rename to src/docker-outside-of-docker/devcontainer-feature.json index 9948a62e1..69aa2f49a 100644 --- a/src/docker-from-docker/devcontainer-feature.json +++ b/src/docker-outside-of-docker/devcontainer-feature.json @@ -1,8 +1,8 @@ { - "id": "docker-from-docker", - "version": "1.0.8", - "name": "Docker (Docker-from-Docker)", - "documentationURL": "https://github.com/devcontainers/features/tree/main/src/docker-from-docker", + "id": "docker-outside-of-docker", + "version": "1.0.9", + "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.", "options": { "version": { @@ -50,5 +50,8 @@ ], "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" + ], + "legacyIds": [ + "docker-from-docker" ] } diff --git a/src/docker-from-docker/install.sh b/src/docker-outside-of-docker/install.sh similarity index 100% rename from src/docker-from-docker/install.sh rename to src/docker-outside-of-docker/install.sh diff --git a/test/docker-from-docker/docker_init.sh b/test/docker-outside-of-docker/docker_init.sh similarity index 100% rename from test/docker-from-docker/docker_init.sh rename to test/docker-outside-of-docker/docker_init.sh diff --git a/test/docker-from-docker/scenarios.json b/test/docker-outside-of-docker/scenarios.json similarity index 82% rename from test/docker-from-docker/scenarios.json rename to test/docker-outside-of-docker/scenarios.json index 196e00bf6..804b52242 100644 --- a/test/docker-from-docker/scenarios.json +++ b/test/docker-outside-of-docker/scenarios.json @@ -3,7 +3,7 @@ "image": "mcr.microsoft.com/devcontainers/base", "remoteUser": "vscode", "features": { - "docker-from-docker": { + "docker-outside-of-docker": { "version": "latest" } } diff --git a/test/docker-from-docker/test.sh b/test/docker-outside-of-docker/test.sh similarity index 100% rename from test/docker-from-docker/test.sh rename to test/docker-outside-of-docker/test.sh From 2c646ed9fe2e34197e5632f71bce4aa59cdbcc4d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 4 Jan 2023 11:53:48 -0800 Subject: [PATCH 063/478] Automated documentation update (#377) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/anaconda/README.md | 1 + src/aws-cli/README.md | 1 + src/azure-cli/README.md | 1 + src/common-utils/README.md | 1 + src/conda/README.md | 1 + src/desktop-lite/README.md | 1 + src/docker-in-docker/README.md | 1 + src/docker-outside-of-docker/README.md | 9 ++++++--- src/dotnet/README.md | 1 + src/git-lfs/README.md | 1 + src/git/README.md | 1 + src/github-cli/README.md | 1 + src/go/README.md | 1 + src/hugo/README.md | 1 + src/java/README.md | 1 + src/kubectl-helm-minikube/README.md | 1 + src/nix/README.md | 1 + src/node/README.md | 1 + src/nvidia-cuda/README.md | 1 + src/oryx/README.md | 1 + src/php/README.md | 1 + src/powershell/README.md | 1 + src/python/README.md | 1 + src/ruby/README.md | 1 + src/rust/README.md | 1 + src/sshd/README.md | 1 + src/terraform/README.md | 1 + 27 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/anaconda/README.md b/src/anaconda/README.md index 3346823b4..ae91026d3 100644 --- a/src/anaconda/README.md +++ b/src/anaconda/README.md @@ -1,4 +1,5 @@ + # Anaconda (anaconda) diff --git a/src/aws-cli/README.md b/src/aws-cli/README.md index 40cc4ae98..6cac4bc91 100644 --- a/src/aws-cli/README.md +++ b/src/aws-cli/README.md @@ -1,4 +1,5 @@ + # AWS CLI (aws-cli) 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/azure-cli/README.md b/src/azure-cli/README.md index cb792d120..63404beaf 100644 --- a/src/azure-cli/README.md +++ b/src/azure-cli/README.md @@ -1,4 +1,5 @@ + # Azure CLI (azure-cli) Installs the Azure CLI along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg. diff --git a/src/common-utils/README.md b/src/common-utils/README.md index 9102c950b..f127698ff 100644 --- a/src/common-utils/README.md +++ b/src/common-utils/README.md @@ -1,4 +1,5 @@ + # Common Utilities (common-utils) Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-root user. diff --git a/src/conda/README.md b/src/conda/README.md index 2e123f2c7..8bd788d2b 100644 --- a/src/conda/README.md +++ b/src/conda/README.md @@ -1,4 +1,5 @@ + # Conda (conda) A cross-platform, language-agnostic binary package manager diff --git a/src/desktop-lite/README.md b/src/desktop-lite/README.md index ad05e4ff2..27ca32390 100644 --- a/src/desktop-lite/README.md +++ b/src/desktop-lite/README.md @@ -1,4 +1,5 @@ + # Light-weight Desktop (desktop-lite) 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/docker-in-docker/README.md b/src/docker-in-docker/README.md index 4196892b0..cd9ff1a99 100644 --- a/src/docker-in-docker/README.md +++ b/src/docker-in-docker/README.md @@ -1,4 +1,5 @@ + # Docker (Docker-in-Docker) (docker-in-docker) 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/README.md b/src/docker-outside-of-docker/README.md index e2ddb8472..cbd2d63e9 100644 --- a/src/docker-outside-of-docker/README.md +++ b/src/docker-outside-of-docker/README.md @@ -1,5 +1,8 @@ -# Docker (Docker-from-Docker) (docker-from-docker) +### **IMPORTANT NOTE** +- **Ids used to publish this Feature in the past - 'docker-from-docker'** + +# Docker (docker-outside-of-docker) (docker-outside-of-docker) 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. @@ -7,7 +10,7 @@ Re-use the host docker socket, adding the Docker CLI to a container. Feature inv ```json "features": { - "ghcr.io/devcontainers/features/docker-from-docker:1": {} + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {} } ``` @@ -84,4 +87,4 @@ This Feature should work on recent versions of Debian/Ubuntu-based distributions --- -_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/docker-from-docker/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ +_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/devcontainers/features/blob/main/src/docker-outside-of-docker/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/dotnet/README.md b/src/dotnet/README.md index c13c998fd..edd38214a 100644 --- a/src/dotnet/README.md +++ b/src/dotnet/README.md @@ -1,4 +1,5 @@ + # Dotnet CLI (dotnet) Installs the .NET CLI. Provides option of installing sdk or runtime, and option of versions to install. Uses latest version of .NET sdk as defaults to install. diff --git a/src/git-lfs/README.md b/src/git-lfs/README.md index 9fc3281fe..7a6802c84 100644 --- a/src/git-lfs/README.md +++ b/src/git-lfs/README.md @@ -1,4 +1,5 @@ + # Git Large File Support (LFS) (git-lfs) 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/README.md b/src/git/README.md index a9e54fa18..2f88d80d6 100644 --- a/src/git/README.md +++ b/src/git/README.md @@ -1,4 +1,5 @@ + # Git (from source) (git) 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/github-cli/README.md b/src/github-cli/README.md index 07945081a..761ba0852 100644 --- a/src/github-cli/README.md +++ b/src/github-cli/README.md @@ -1,4 +1,5 @@ + # GitHub CLI (github-cli) Installs the GitHub CLI. Auto-detects latest version and installs needed dependencies. diff --git a/src/go/README.md b/src/go/README.md index e7a692443..4ab962b6b 100644 --- a/src/go/README.md +++ b/src/go/README.md @@ -1,4 +1,5 @@ + # Go (go) Installs Go and common Go utilities. Auto-detects latest version and installs needed dependencies. diff --git a/src/hugo/README.md b/src/hugo/README.md index 3d346c39b..405273635 100644 --- a/src/hugo/README.md +++ b/src/hugo/README.md @@ -1,4 +1,5 @@ + # Hugo (hugo) diff --git a/src/java/README.md b/src/java/README.md index f3e35e38a..117575c65 100644 --- a/src/java/README.md +++ b/src/java/README.md @@ -1,4 +1,5 @@ + # Java (via SDKMAN!) (java) Installs Java, SDKMAN! (if not installed), and needed dependencies. diff --git a/src/kubectl-helm-minikube/README.md b/src/kubectl-helm-minikube/README.md index 81ce8c574..0af0f5db7 100644 --- a/src/kubectl-helm-minikube/README.md +++ b/src/kubectl-helm-minikube/README.md @@ -1,4 +1,5 @@ + # Kubectl, Helm, and Minikube (kubectl-helm-minikube) Installs latest version of kubectl, Helm, and optionally minikube. Auto-detects latest versions and installs needed dependencies. diff --git a/src/nix/README.md b/src/nix/README.md index 3ab9b0017..d29b50ffd 100644 --- a/src/nix/README.md +++ b/src/nix/README.md @@ -1,4 +1,5 @@ + # Nix Package Manager (nix) Installs the Nix package manager and optionally a set of packages. diff --git a/src/node/README.md b/src/node/README.md index 2e5dba386..fb00c42da 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -1,4 +1,5 @@ + # Node.js (via nvm) and yarn (node) Installs Node.js, nvm, yarn, and needed dependencies. diff --git a/src/nvidia-cuda/README.md b/src/nvidia-cuda/README.md index 38a989a04..097afd47b 100644 --- a/src/nvidia-cuda/README.md +++ b/src/nvidia-cuda/README.md @@ -1,4 +1,5 @@ + # NVIDIA CUDA (nvidia-cuda) Installs shared libraries for NVIDIA CUDA. diff --git a/src/oryx/README.md b/src/oryx/README.md index 7d3d3d11a..1ee6d790c 100644 --- a/src/oryx/README.md +++ b/src/oryx/README.md @@ -1,4 +1,5 @@ + # Oryx (oryx) Installs the oryx CLI diff --git a/src/php/README.md b/src/php/README.md index 3a9be7a98..9921721b2 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -1,4 +1,5 @@ + # PHP (php) diff --git a/src/powershell/README.md b/src/powershell/README.md index ba300d5cd..e80f43dc8 100644 --- a/src/powershell/README.md +++ b/src/powershell/README.md @@ -1,4 +1,5 @@ + # PowerShell (powershell) Installs PowerShell along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg. diff --git a/src/python/README.md b/src/python/README.md index 05742910a..8ab50effb 100644 --- a/src/python/README.md +++ b/src/python/README.md @@ -1,4 +1,5 @@ + # Python (python) 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/ruby/README.md b/src/ruby/README.md index 8a0ff877d..3e09336e6 100644 --- a/src/ruby/README.md +++ b/src/ruby/README.md @@ -1,4 +1,5 @@ + # Ruby (via rvm) (ruby) Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies. diff --git a/src/rust/README.md b/src/rust/README.md index 372b56f97..57c72821b 100644 --- a/src/rust/README.md +++ b/src/rust/README.md @@ -1,4 +1,5 @@ + # Rust (rust) Installs Rust, common Rust utilities, and their required dependencies diff --git a/src/sshd/README.md b/src/sshd/README.md index 6e9382c04..7f447fa89 100644 --- a/src/sshd/README.md +++ b/src/sshd/README.md @@ -1,4 +1,5 @@ + # SSH server (sshd) Adds a SSH server into a container so that you can use an external terminal, sftp, or SSHFS to interact with it. diff --git a/src/terraform/README.md b/src/terraform/README.md index ee87d069d..4209c7a8f 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -1,4 +1,5 @@ + # Terraform, tflint, and TFGrunt (terraform) Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects latest version and installs needed dependencies. From 8f7eec80d44f74c3aaa20634e938b071d95ff5c3 Mon Sep 17 00:00:00 2001 From: Julien Boudry Date: Wed, 4 Jan 2023 22:12:53 +0100 Subject: [PATCH 064/478] [PHP] Enable Mbstring (#371) Mbstring is such a popular PHP extension that it is used everywhere and most libraries don't work without it. It can be compiled directly with PHP. The official Docker images of PHP include it. --- src/php/devcontainer-feature.json | 2 +- src/php/install.sh | 2 +- test/php/test.sh | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/php/devcontainer-feature.json b/src/php/devcontainer-feature.json index bad987872..edf56eb4d 100644 --- a/src/php/devcontainer-feature.json +++ b/src/php/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "php", - "version": "1.0.9", + "version": "1.0.10", "name": "PHP", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/php", "options": { diff --git a/src/php/install.sh b/src/php/install.sh index 381bec21b..4d0b2eae9 100755 --- a/src/php/install.sh +++ b/src/php/install.sh @@ -169,7 +169,7 @@ install_php() { VERSION_CONFIG="--with-pear" fi - ./configure --prefix="${PHP_INSTALL_DIR}" --with-config-file-path="$PHP_INI_DIR" --with-config-file-scan-dir="$CONF_DIR" --enable-option-checking=fatal --with-curl --with-libedit --with-openssl --with-zlib --with-password-argon2 --with-sodium=shared "$VERSION_CONFIG" EXTENSION_DIR="$PHP_EXT_DIR"; + ./configure --prefix="${PHP_INSTALL_DIR}" --with-config-file-path="$PHP_INI_DIR" --with-config-file-scan-dir="$CONF_DIR" --enable-option-checking=fatal --with-curl --with-libedit --enable-mbstring --with-openssl --with-zlib --with-password-argon2 --with-sodium=shared "$VERSION_CONFIG" EXTENSION_DIR="$PHP_EXT_DIR"; make -j "$(nproc)" find -type f -name '*.a' -delete diff --git a/test/php/test.sh b/test/php/test.sh index 3e4e7223a..0f49c1a18 100755 --- a/test/php/test.sh +++ b/test/php/test.sh @@ -6,6 +6,7 @@ set -e source dev-container-features-test-lib check "PHP version" php --version +check "Mbstring loaded" php -r "extension_loaded('mbstring') || throw new Error('Extension Mbstring is not loaded');" check "Composer version" composer --version # Report result From ef192bf4677f35c18d9f0812ed2902a682c7bdeb Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 4 Jan 2023 14:59:24 -0800 Subject: [PATCH 065/478] PHP: Fix build failures for 'ubuntu:bionic' (#378) * PHP: Fix build failures for 'ubuntu:bionic' * update VERSION --- src/php/devcontainer-feature.json | 2 +- src/php/install.sh | 30 +++++++++++++++++++----------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/php/devcontainer-feature.json b/src/php/devcontainer-feature.json index edf56eb4d..2ea56d2ba 100644 --- a/src/php/devcontainer-feature.json +++ b/src/php/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "php", - "version": "1.0.10", + "version": "1.0.11", "name": "PHP", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/php", "options": { diff --git a/src/php/install.sh b/src/php/install.sh index 4d0b2eae9..c0bcb0426 100755 --- a/src/php/install.sh +++ b/src/php/install.sh @@ -11,7 +11,7 @@ set -eux # Clean up rm -rf /var/lib/apt/lists/* -VERSION="${VERSION:-"latest"}" +PHP_VERSION="${VERSION:-"latest"}" INSTALL_COMPOSER="${INSTALLCOMPOSER:-"true"}" OVERRIDE_DEFAULT_VERSION="${OVERRIDEDEFAULTVERSION:-"true"}" @@ -20,7 +20,7 @@ USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" UPDATE_RC="${UPDATE_RC:-"true"}" # Comma-separated list of php versions to be installed -# alongside VERSION, but not set as default. +# alongside PHP_VERSION, but not set as default. ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" export DEBIAN_FRONTEND=noninteractive @@ -92,7 +92,7 @@ find_version_from_git_tags() { local last_part="${escaped_separator}[0-9]+" local regex="\\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)" - VERSION="$(echo "${version_list}" | head -n 1)" + PHP_VERSION="$(echo "${version_list}" | head -n 1)" } # Install PHP Composer @@ -113,7 +113,15 @@ addcomposer() { RUNTIME_DEPS="wget ca-certificates git build-essential xz-utils" # PHP dependencies -PHP_DEPS="libssl-dev libcurl4-openssl-dev libedit-dev libsqlite3-dev libxml2-dev zlib1g-dev libsodium-dev libargon2-dev libonig-dev" +PHP_DEPS="libssl-dev libcurl4-openssl-dev libedit-dev libsqlite3-dev libxml2-dev zlib1g-dev libsodium-dev libonig-dev" + +. /etc/os-release + +if [ "${VERSION_CODENAME}" = "bionic" ]; then + PHP_DEPS="${PHP_DEPS} libargon2-0-dev" +else + PHP_DEPS="${PHP_DEPS} libargon2-dev" +fi # Dependencies required for running "phpize" PHPIZE_DEPS="autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c" @@ -122,16 +130,16 @@ PHPIZE_DEPS="autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c" check_packages $RUNTIME_DEPS $PHP_DEPS $PHPIZE_DEPS install_php() { - VERSION="$1" + PHP_VERSION="$1" # Fetch latest version of PHP if needed - if [ "${VERSION}" = "latest" ] || [ "${VERSION}" = "lts" ]; then + if [ "${PHP_VERSION}" = "latest" ] || [ "${PHP_VERSION}" = "lts" ]; then find_version_from_git_tags fi - PHP_INSTALL_DIR="${PHP_DIR}/${VERSION}" + PHP_INSTALL_DIR="${PHP_DIR}/${PHP_VERSION}" if [ -d "${PHP_INSTALL_DIR}" ]; then - echo "(!) PHP version ${VERSION} already exists." + echo "(!) PHP version ${PHP_VERSION} already exists." exit 1 fi @@ -140,7 +148,7 @@ install_php() { fi usermod -a -G php "${USERNAME}" - PHP_URL="https://www.php.net/distributions/php-${VERSION}.tar.gz" + PHP_URL="https://www.php.net/distributions/php-${PHP_VERSION}.tar.gz" PHP_INI_DIR="${PHP_INSTALL_DIR}/ini" CONF_DIR="${PHP_INI_DIR}/conf.d" @@ -160,7 +168,7 @@ install_php() { # PHP 7.4+, the pecl/pear installers are officially deprecated and are removed in PHP 8+ # Thus, requiring an explicit "--with-pear" IFS="." - read -a versions <<< "${VERSION}" + read -a versions <<< "${PHP_VERSION}" PHP_MAJOR_VERSION=${versions[0]} PHP_MINOR_VERSION=${versions[1]} @@ -210,7 +218,7 @@ install_php() { updaterc "if [[ \"\${PATH}\" != *\"${CURRENT_DIR}\"* ]]; then export PATH=\"${CURRENT_DIR}/bin:\${PATH}\"; fi" } -install_php "${VERSION}" +install_php "${PHP_VERSION}" # Additional php versions to be installed but not be set as default. if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then From c546f4bf8c462247c954ee3b549e63db2fc687dd Mon Sep 17 00:00:00 2001 From: Marko Bausch <60338487+mrkbac@users.noreply.github.com> Date: Thu, 5 Jan 2023 18:27:12 +0100 Subject: [PATCH 066/478] desktop-lite: fixed qemu container (#370) * desktop-lite: fixed qemu container * bump version for desktop-lite --- src/desktop-lite/devcontainer-feature.json | 2 +- src/desktop-lite/install.sh | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/desktop-lite/devcontainer-feature.json b/src/desktop-lite/devcontainer-feature.json index e0333867f..84c99db93 100644 --- a/src/desktop-lite/devcontainer-feature.json +++ b/src/desktop-lite/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "desktop-lite", - "version": "1.0.6", + "version": "1.0.7", "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 60bec121b..ffd39d50b 100755 --- a/src/desktop-lite/install.sh +++ b/src/desktop-lite/install.sh @@ -299,9 +299,9 @@ startInBackgroundIfNotRunning() { log "Starting \$1." echo -e "\n** \$(date) **" | sudoIf tee -a /tmp/\$1.log > /dev/null - if ! pidof \$1 > /dev/null; then + if ! pgrep -x \$1 > /dev/null; then keepRunningInBackground "\$@" - while ! pidof \$1 > /dev/null; do + while ! pgrep -x \$1 > /dev/null; do sleep 1 done log "\$1 started." @@ -347,16 +347,16 @@ log "** SCRIPT START **" # Start dbus. log 'Running "/etc/init.d/dbus start".' -if [ -f "/var/run/dbus/pid" ] && ! pidof dbus-daemon > /dev/null; then +if [ -f "/var/run/dbus/pid" ] && ! pgrep -x dbus-daemon > /dev/null; then sudoIf rm -f /var/run/dbus/pid fi sudoIf /etc/init.d/dbus start 2>&1 | sudoIf tee -a /tmp/dbus-daemon-system.log > /dev/null -while ! pidof dbus-daemon > /dev/null; do +while ! pgrep -x dbus-daemon > /dev/null; do sleep 1 done # Startup tigervnc server and fluxbox -sudo rm -rf /tmp/.X11-unix /tmp/.X*-lock +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 From a9a7a25d60585ce2145374ec6825cbdc7f16cb90 Mon Sep 17 00:00:00 2001 From: Mark Phippard Date: Thu, 5 Jan 2023 16:21:34 -0500 Subject: [PATCH 067/478] Install gawk RPM (#380) * Install gawk RPM This script requires awk and it may not be available on a minimal distro like Mariner * Bump version number --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 8d1ed8286..33cd19d92 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.3", + "version": "2.0.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.", diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index b6793d603..20214850e 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -146,6 +146,7 @@ install_debian_packages() { # RedHat / RockyLinux / CentOS / Fedora packages install_redhat_packages() { local package_list="\ + gawk \ openssh-clients \ gnupg2 \ iproute \ From 04143e31ff4ef64f44603492a4052fe7b03de7bd Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Mon, 9 Jan 2023 14:48:41 -0800 Subject: [PATCH 068/478] Options: Switch from 'enum' to 'proposals' (#382) --- src/git-lfs/devcontainer-feature.json | 4 ++-- src/nvidia-cuda/devcontainer-feature.json | 6 +++--- src/python/devcontainer-feature.json | 4 ++-- src/sshd/devcontainer-feature.json | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/git-lfs/devcontainer-feature.json b/src/git-lfs/devcontainer-feature.json index 7916ea1c3..a301a64d6 100644 --- a/src/git-lfs/devcontainer-feature.json +++ b/src/git-lfs/devcontainer-feature.json @@ -1,13 +1,13 @@ { "id": "git-lfs", - "version": "1.0.5", + "version": "1.0.6", "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.", "options": { "version": { "type": "string", - "enum": [ + "proposals": [ "latest", "none" ], diff --git a/src/nvidia-cuda/devcontainer-feature.json b/src/nvidia-cuda/devcontainer-feature.json index 7611b7ef1..dd5c13d8c 100644 --- a/src/nvidia-cuda/devcontainer-feature.json +++ b/src/nvidia-cuda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nvidia-cuda", - "version": "1.0.5", + "version": "1.0.6", "name": "NVIDIA CUDA", "description": "Installs shared libraries for NVIDIA CUDA.", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/nvidia-cuda", @@ -17,7 +17,7 @@ }, "cudaVersion": { "type": "string", - "enum": [ + "proposals": [ "11.8", "11.7", "11.6", @@ -31,7 +31,7 @@ }, "cudnnVersion": { "type": "string", - "enum": [ + "proposals": [ "8.6.0.163", "8.5.0.96", "8.4.1.50", diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index fa5932035..1d5812149 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,13 +1,13 @@ { "id": "python", - "version": "1.0.18", + "version": "1.0.19", "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.", "options": { "version": { "type": "string", - "enum": [ + "proposals": [ "latest", "os-provided", "none", diff --git a/src/sshd/devcontainer-feature.json b/src/sshd/devcontainer-feature.json index b8b7badaf..696a23ba7 100644 --- a/src/sshd/devcontainer-feature.json +++ b/src/sshd/devcontainer-feature.json @@ -1,13 +1,13 @@ { "id": "sshd", - "version": "1.0.6", + "version": "1.0.7", "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.", "options": { "version": { "type": "string", - "enum": [ + "proposals": [ "latest" ], "default": "latest", From 59fa3e3c21fd2c896da2d3272604509ea9a55a91 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Mon, 9 Jan 2023 14:49:43 -0800 Subject: [PATCH 069/478] Conda: Update 'certifi' due to CVE-2022-23491 (#383) --- src/conda/devcontainer-feature.json | 2 +- src/conda/install.sh | 17 +++++++++++++++++ test/conda/test.sh | 20 ++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/conda/devcontainer-feature.json b/src/conda/devcontainer-feature.json index 8ff6499dd..488de41ff 100644 --- a/src/conda/devcontainer-feature.json +++ b/src/conda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "conda", - "version": "1.0.6", + "version": "1.0.7", "name": "Conda", "description": "A cross-platform, language-agnostic binary package manager", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/conda", diff --git a/src/conda/install.sh b/src/conda/install.sh index 6e9088221..55b280c40 100644 --- a/src/conda/install.sh +++ b/src/conda/install.sh @@ -61,6 +61,20 @@ check_packages() { fi } +sudo_if() { + COMMAND="$*" + if [ "$(id -u)" -eq 0 ] && [ "$USERNAME" != "root" ]; then + su - "$USERNAME" -c "$COMMAND" + else + $COMMAND + fi +} + +install_user_package() { + PACKAGE="$1" + sudo_if "${CONDA_DIR}/bin/python3" -m pip install --user --upgrade "$PACKAGE" +} + # Install Conda if it's missing if ! conda --version &> /dev/null ; then if ! cat /etc/group | grep -e "^conda:" > /dev/null 2>&1; then @@ -99,6 +113,9 @@ if ! conda --version &> /dev/null ; then chmod -R g+r+w "${CONDA_DIR}" find "${CONDA_DIR}" -type d -print0 | xargs -n 1 -0 chmod g+s + + # Temporary due to https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23491 + install_user_package certifi fi # Display a notice on conda when not running in GitHub Codespaces diff --git a/test/conda/test.sh b/test/conda/test.sh index f3002176e..8a88511ca 100755 --- a/test/conda/test.sh +++ b/test/conda/test.sh @@ -12,5 +12,25 @@ check "if conda-notice.txt exists" cat /usr/local/etc/vscode-dev-containers/cond # Check env check "CONDA_SCRIPT is set correctly" echo $CONDA_SCRIPT | grep "/opt/conda/etc/profile.d/conda.sh" +check-version-ge() { + LABEL=$1 + CURRENT_VERSION=$2 + REQUIRED_VERSION=$3 + shift + echo -e "\n๐Ÿงช Testing $LABEL: '$CURRENT_VERSION' is >= '$REQUIRED_VERSION'" + local GREATER_VERSION=$((echo ${CURRENT_VERSION}; echo ${REQUIRED_VERSION}) | sort -V | tail -1) + if [ "${CURRENT_VERSION}" == "${GREATER_VERSION}" ]; then + echo "โœ… Passed!" + return 0 + else + echoStderr "โŒ $LABEL check failed." + FAILED+=("$LABEL") + return 1 + fi +} + +certifiVersion=$(python -c "import certifi; print(certifi.__version__)") +check-version-ge "certifi" "${certifiVersion}" "2022.12.07" + # Report result reportResults From 7e32db56c00b79a2d35838ffa6f7081f517805b1 Mon Sep 17 00:00:00 2001 From: eitsupi <50911393+eitsupi@users.noreply.github.com> Date: Wed, 11 Jan 2023 06:50:09 +0900 Subject: [PATCH 070/478] [common-utils] Fix permission of scripts in containers (#388) * fix permission in containers * add test * bump version * more tests * update tests * Update test/common-utils/devcontainer-info/Dockerfile Co-authored-by: Samruddhi Khandale * Update test/common-utils/scenarios.json Co-authored-by: Samruddhi Khandale * Update scenarios.json * Update devcontainer-info.sh Co-authored-by: Samruddhi Khandale --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 6 ++--- test/common-utils/devcontainer-info.sh | 25 +++++++++++++++++++ .../common-utils/devcontainer-info/Dockerfile | 3 +++ test/common-utils/devcontainer-info/meta.env | 8 ++++++ test/common-utils/scenarios.json | 15 +++++++++++ 6 files changed, 55 insertions(+), 4 deletions(-) create mode 100755 test/common-utils/devcontainer-info.sh create mode 100644 test/common-utils/devcontainer-info/Dockerfile create mode 100644 test/common-utils/devcontainer-info/meta.env diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 33cd19d92..82623f9a0 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.4", + "version": "2.0.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 20214850e..7cc94090c 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -474,18 +474,18 @@ fi # code shim, it fallbacks to code-insiders if code is not available cp -f "${FEATURE_DIR}/bin/code" /usr/local/bin/ -chmod +x /usr/local/bin/code +chmod +rx /usr/local/bin/code # systemctl shim for Debian/Ubuntu - tells people to use 'service' if systemd is not running if [ "${ADJUSTED_ID}" = "debian" ]; then cp -f "${FEATURE_DIR}/bin/systemctl" /usr/local/bin/systemctl - chmod +x /usr/local/bin/systemctl + chmod +rx /usr/local/bin/systemctl fi # Persist image metadata info, script if meta.env found in same directory if [ -f "/usr/local/etc/vscode-dev-containers/meta.env" ] || [ -f "/usr/local/etc/dev-containers/meta.env" ]; then cp -f "${FEATURE_DIR}/bin/devcontainer-info" /usr/local/bin/devcontainer-info - chmod +x /usr/local/bin/devcontainer-info + chmod +rx /usr/local/bin/devcontainer-info fi # Write marker file diff --git a/test/common-utils/devcontainer-info.sh b/test/common-utils/devcontainer-info.sh new file mode 100755 index 000000000..65a4a40fb --- /dev/null +++ b/test/common-utils/devcontainer-info.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check_info() { + local info=$1 + check "devcontainer-info ${info}" sh -c "devcontainer-info | grep test-${info}" +} + +# Definition specific tests +check "user" bash -c "whoami | grep vscode" +check_info "version" +check_info "id" +check_info "variant" +check_info "repository" +check_info "release" +check_info "revision" +check_info "time" +check_info "url" + +# Report result +reportResults diff --git a/test/common-utils/devcontainer-info/Dockerfile b/test/common-utils/devcontainer-info/Dockerfile new file mode 100644 index 000000000..28247d907 --- /dev/null +++ b/test/common-utils/devcontainer-info/Dockerfile @@ -0,0 +1,3 @@ +FROM ubuntu:focal + +COPY meta.env /usr/local/etc/dev-containers/meta.env diff --git a/test/common-utils/devcontainer-info/meta.env b/test/common-utils/devcontainer-info/meta.env new file mode 100644 index 000000000..dfc61d31c --- /dev/null +++ b/test/common-utils/devcontainer-info/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 bc1c784bf..dbf9cdc73 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -114,5 +114,20 @@ "configureZshAsDefaultShell": true } } + }, + "devcontainer-info": { + "build": { + "dockerfile": "Dockerfile" + }, + "features": { + "common-utils": { + "username": "vscode", + "userUid": "1000", + "userGid": "1000", + "upgradePackages": true, + "installZsh": true + } + }, + "remoteUser": "vscode" } } From c8f5c3cbee6893b7e7bb970adfa96c54dea8e626 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 10 Jan 2023 13:59:07 -0800 Subject: [PATCH 071/478] Automated documentation update (#394) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/anaconda/README.md | 1 - src/aws-cli/README.md | 1 - src/azure-cli/README.md | 1 - src/common-utils/README.md | 1 - src/conda/README.md | 1 - src/desktop-lite/README.md | 1 - src/docker-in-docker/README.md | 1 - src/docker-outside-of-docker/README.md | 1 - src/dotnet/README.md | 1 - src/git-lfs/README.md | 1 - src/git/README.md | 1 - src/github-cli/README.md | 1 - src/go/README.md | 1 - src/hugo/README.md | 1 - src/java/README.md | 1 - src/kubectl-helm-minikube/README.md | 1 - src/nix/README.md | 1 - src/node/README.md | 1 - src/nvidia-cuda/README.md | 1 - src/oryx/README.md | 1 - src/php/README.md | 1 - src/powershell/README.md | 1 - src/python/README.md | 1 - src/ruby/README.md | 1 - src/rust/README.md | 1 - src/sshd/README.md | 1 - src/terraform/README.md | 1 - 27 files changed, 27 deletions(-) diff --git a/src/anaconda/README.md b/src/anaconda/README.md index ae91026d3..3346823b4 100644 --- a/src/anaconda/README.md +++ b/src/anaconda/README.md @@ -1,5 +1,4 @@ - # Anaconda (anaconda) diff --git a/src/aws-cli/README.md b/src/aws-cli/README.md index 6cac4bc91..40cc4ae98 100644 --- a/src/aws-cli/README.md +++ b/src/aws-cli/README.md @@ -1,5 +1,4 @@ - # AWS CLI (aws-cli) 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/azure-cli/README.md b/src/azure-cli/README.md index 63404beaf..cb792d120 100644 --- a/src/azure-cli/README.md +++ b/src/azure-cli/README.md @@ -1,5 +1,4 @@ - # Azure CLI (azure-cli) Installs the Azure CLI along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg. diff --git a/src/common-utils/README.md b/src/common-utils/README.md index f127698ff..9102c950b 100644 --- a/src/common-utils/README.md +++ b/src/common-utils/README.md @@ -1,5 +1,4 @@ - # Common Utilities (common-utils) Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-root user. diff --git a/src/conda/README.md b/src/conda/README.md index 8bd788d2b..2e123f2c7 100644 --- a/src/conda/README.md +++ b/src/conda/README.md @@ -1,5 +1,4 @@ - # Conda (conda) A cross-platform, language-agnostic binary package manager diff --git a/src/desktop-lite/README.md b/src/desktop-lite/README.md index 27ca32390..ad05e4ff2 100644 --- a/src/desktop-lite/README.md +++ b/src/desktop-lite/README.md @@ -1,5 +1,4 @@ - # Light-weight Desktop (desktop-lite) 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/docker-in-docker/README.md b/src/docker-in-docker/README.md index cd9ff1a99..4196892b0 100644 --- a/src/docker-in-docker/README.md +++ b/src/docker-in-docker/README.md @@ -1,5 +1,4 @@ - # Docker (Docker-in-Docker) (docker-in-docker) 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/README.md b/src/docker-outside-of-docker/README.md index cbd2d63e9..74011a06d 100644 --- a/src/docker-outside-of-docker/README.md +++ b/src/docker-outside-of-docker/README.md @@ -1,4 +1,3 @@ - ### **IMPORTANT NOTE** - **Ids used to publish this Feature in the past - 'docker-from-docker'** diff --git a/src/dotnet/README.md b/src/dotnet/README.md index edd38214a..c13c998fd 100644 --- a/src/dotnet/README.md +++ b/src/dotnet/README.md @@ -1,5 +1,4 @@ - # Dotnet CLI (dotnet) Installs the .NET CLI. Provides option of installing sdk or runtime, and option of versions to install. Uses latest version of .NET sdk as defaults to install. diff --git a/src/git-lfs/README.md b/src/git-lfs/README.md index 7a6802c84..9fc3281fe 100644 --- a/src/git-lfs/README.md +++ b/src/git-lfs/README.md @@ -1,5 +1,4 @@ - # Git Large File Support (LFS) (git-lfs) 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/README.md b/src/git/README.md index 2f88d80d6..a9e54fa18 100644 --- a/src/git/README.md +++ b/src/git/README.md @@ -1,5 +1,4 @@ - # Git (from source) (git) 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/github-cli/README.md b/src/github-cli/README.md index 761ba0852..07945081a 100644 --- a/src/github-cli/README.md +++ b/src/github-cli/README.md @@ -1,5 +1,4 @@ - # GitHub CLI (github-cli) Installs the GitHub CLI. Auto-detects latest version and installs needed dependencies. diff --git a/src/go/README.md b/src/go/README.md index 4ab962b6b..e7a692443 100644 --- a/src/go/README.md +++ b/src/go/README.md @@ -1,5 +1,4 @@ - # Go (go) Installs Go and common Go utilities. Auto-detects latest version and installs needed dependencies. diff --git a/src/hugo/README.md b/src/hugo/README.md index 405273635..3d346c39b 100644 --- a/src/hugo/README.md +++ b/src/hugo/README.md @@ -1,5 +1,4 @@ - # Hugo (hugo) diff --git a/src/java/README.md b/src/java/README.md index 117575c65..f3e35e38a 100644 --- a/src/java/README.md +++ b/src/java/README.md @@ -1,5 +1,4 @@ - # Java (via SDKMAN!) (java) Installs Java, SDKMAN! (if not installed), and needed dependencies. diff --git a/src/kubectl-helm-minikube/README.md b/src/kubectl-helm-minikube/README.md index 0af0f5db7..81ce8c574 100644 --- a/src/kubectl-helm-minikube/README.md +++ b/src/kubectl-helm-minikube/README.md @@ -1,5 +1,4 @@ - # Kubectl, Helm, and Minikube (kubectl-helm-minikube) Installs latest version of kubectl, Helm, and optionally minikube. Auto-detects latest versions and installs needed dependencies. diff --git a/src/nix/README.md b/src/nix/README.md index d29b50ffd..3ab9b0017 100644 --- a/src/nix/README.md +++ b/src/nix/README.md @@ -1,5 +1,4 @@ - # Nix Package Manager (nix) Installs the Nix package manager and optionally a set of packages. diff --git a/src/node/README.md b/src/node/README.md index fb00c42da..2e5dba386 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -1,5 +1,4 @@ - # Node.js (via nvm) and yarn (node) Installs Node.js, nvm, yarn, and needed dependencies. diff --git a/src/nvidia-cuda/README.md b/src/nvidia-cuda/README.md index 097afd47b..38a989a04 100644 --- a/src/nvidia-cuda/README.md +++ b/src/nvidia-cuda/README.md @@ -1,5 +1,4 @@ - # NVIDIA CUDA (nvidia-cuda) Installs shared libraries for NVIDIA CUDA. diff --git a/src/oryx/README.md b/src/oryx/README.md index 1ee6d790c..7d3d3d11a 100644 --- a/src/oryx/README.md +++ b/src/oryx/README.md @@ -1,5 +1,4 @@ - # Oryx (oryx) Installs the oryx CLI diff --git a/src/php/README.md b/src/php/README.md index 9921721b2..3a9be7a98 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -1,5 +1,4 @@ - # PHP (php) diff --git a/src/powershell/README.md b/src/powershell/README.md index e80f43dc8..ba300d5cd 100644 --- a/src/powershell/README.md +++ b/src/powershell/README.md @@ -1,5 +1,4 @@ - # PowerShell (powershell) Installs PowerShell along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg. diff --git a/src/python/README.md b/src/python/README.md index 8ab50effb..05742910a 100644 --- a/src/python/README.md +++ b/src/python/README.md @@ -1,5 +1,4 @@ - # Python (python) 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/ruby/README.md b/src/ruby/README.md index 3e09336e6..8a0ff877d 100644 --- a/src/ruby/README.md +++ b/src/ruby/README.md @@ -1,5 +1,4 @@ - # Ruby (via rvm) (ruby) Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies. diff --git a/src/rust/README.md b/src/rust/README.md index 57c72821b..372b56f97 100644 --- a/src/rust/README.md +++ b/src/rust/README.md @@ -1,5 +1,4 @@ - # Rust (rust) Installs Rust, common Rust utilities, and their required dependencies diff --git a/src/sshd/README.md b/src/sshd/README.md index 7f447fa89..6e9382c04 100644 --- a/src/sshd/README.md +++ b/src/sshd/README.md @@ -1,5 +1,4 @@ - # SSH server (sshd) Adds a SSH server into a container so that you can use an external terminal, sftp, or SSHFS to interact with it. diff --git a/src/terraform/README.md b/src/terraform/README.md index 4209c7a8f..ee87d069d 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -1,5 +1,4 @@ - # Terraform, tflint, and TFGrunt (terraform) Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects latest version and installs needed dependencies. From e67f4dc0fd053d7bac56a8c802b3a1af68da5bf6 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 10 Jan 2023 15:09:56 -0800 Subject: [PATCH 072/478] Common-utils: Fix build failures for alpine 3.14 & 3.15 (#393) * Common-utils: Fix build failures for alpine 3.14 & 3.15 * version bump --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 2 ++ test/common-utils/alpine-3-14.sh | 15 +++++++++++++++ test/common-utils/alpine-3-15.sh | 15 +++++++++++++++ test/common-utils/scenarios.json | 14 ++++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) create mode 100755 test/common-utils/alpine-3-14.sh create mode 100755 test/common-utils/alpine-3-15.sh diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 82623f9a0..36c87bc7c 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.5", + "version": "2.0.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 7cc94090c..ff2c54ca9 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -407,6 +407,8 @@ if [ "${RC_SNIPPET_ALREADY_ADDED}" != "true" ]; then ;; "alpine") global_rc_path="/etc/bash/bashrc" + # /etc/bash/bashrc does not exist in alpine 3.14 & 3.15 + mkdir -p /etc/bash ;; esac cat "${FEATURE_DIR}/scripts/rc_snippet.sh" >> ${global_rc_path} diff --git a/test/common-utils/alpine-3-14.sh b/test/common-utils/alpine-3-14.sh new file mode 100755 index 000000000..5ed334c61 --- /dev/null +++ b/test/common-utils/alpine-3-14.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${ID}" = "alpine" +check "bashrc" ls /etc/bash/bashrc + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/alpine-3-15.sh b/test/common-utils/alpine-3-15.sh new file mode 100755 index 000000000..5ed334c61 --- /dev/null +++ b/test/common-utils/alpine-3-15.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +. /etc/os-release +check "non-root user" test "$(whoami)" = "devcontainer" +check "distro" test "${ID}" = "alpine" +check "bashrc" ls /etc/bash/bashrc + +# Report result +reportResults \ No newline at end of file diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index dbf9cdc73..43d11c9a1 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -115,6 +115,20 @@ } } }, + "alpine-3-14": { + "image": "alpine:3.14", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, + "alpine-3-15": { + "image": "alpine:3.15", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + } + }, "devcontainer-info": { "build": { "dockerfile": "Dockerfile" From 74dd2710dc77b85d6ad72c4534f4c7d7f67b86b2 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 11 Jan 2023 11:02:28 -0800 Subject: [PATCH 073/478] Git: Use sysconfdir=/etc for git built from source (#395) * Git: Adds a new 'addGitConfigSymlink' option * Use sysconfdir --- src/git/devcontainer-feature.json | 2 +- src/git/install.sh | 2 +- test/git/install_git_from_src.sh | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/git/devcontainer-feature.json b/src/git/devcontainer-feature.json index ea35c4bbe..4123aed6b 100644 --- a/src/git/devcontainer-feature.json +++ b/src/git/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git", - "version": "1.1.3", + "version": "1.1.4", "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 52081f17c..679e4975c 100755 --- a/src/git/install.sh +++ b/src/git/install.sh @@ -144,7 +144,7 @@ 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 all && make -s USE_LIBPCRE=YesPlease prefix=/usr/local install 2>&1 +make -s USE_LIBPCRE=YesPlease prefix=/usr/local sysconfdir=/etc all && make -s USE_LIBPCRE=YesPlease prefix=/usr/local sysconfdir=/etc install 2>&1 rm -rf /tmp/git-${GIT_VERSION} rm -rf /var/lib/apt/lists/* echo "Done!" diff --git a/test/git/install_git_from_src.sh b/test/git/install_git_from_src.sh index 4bdcf3066..c3552240d 100644 --- a/test/git/install_git_from_src.sh +++ b/test/git/install_git_from_src.sh @@ -12,5 +12,13 @@ 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'" +check "git-location" bash -c "which git | grep /usr/local/bin/git" + +check "set-git-config-user-name" bash -c "git config --system user.name devcontainers" +check "gitconfig-file-location" bash -c "ls /etc/gitconfig" +check "gitconfig-contains-name" bash -c "cat /etc/gitconfig | grep 'name = devcontainers'" + +check "usr-local-etc-config-does-not-exist" test ! -f "/usr/local/etc/gitconfig" + # Report result reportResults From 1726222515e9d03c05f48bb4a03895afd09525a7 Mon Sep 17 00:00:00 2001 From: "Stephen A. Imhoff" Date: Fri, 13 Jan 2023 11:05:53 -0800 Subject: [PATCH 074/478] CommonUtils - ensure home directory exists. (#398) * CommonUtils - ensure home directory exists. * Only create non-root home directory Root directory will always exist. * Bump version --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 36c87bc7c..03b2fe37f 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.6", + "version": "2.0.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 ff2c54ca9..893f53aa5 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -383,6 +383,10 @@ if [ "${USERNAME}" = "root" ]; then user_rc_path="/root" else user_rc_path="/home/${USERNAME}" + if [ ! -d "${user_rc_path}" ]; then + mkdir -p "${user_rc_path}" + chown ${USERNAME}:${group_name} "${user_rc_path}" + fi fi # Restore user .bashrc / .profile / .zshrc defaults from skeleton file if it doesn't exist or is empty From 79588ef3da9abb2b536583130653b05030e8e5a6 Mon Sep 17 00:00:00 2001 From: Stephan <34886888+steled@users.noreply.github.com> Date: Tue, 17 Jan 2023 18:18:13 +0100 Subject: [PATCH 075/478] checkout action update (#404) - updated the action checkout from v2 to 3 as required by action warning --- .github/workflows/linter-automated.yaml | 2 +- .github/workflows/linter-manual.yaml | 2 +- .github/workflows/release.yaml | 2 +- .github/workflows/test-all.yaml | 6 +++--- .github/workflows/test-manual.yaml | 2 +- .github/workflows/test-pr.yaml | 4 ++-- .github/workflows/update-documentation.yml | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/linter-automated.yaml b/.github/workflows/linter-automated.yaml index 0c3420a62..98921bf68 100644 --- a/.github/workflows/linter-automated.yaml +++ b/.github/workflows/linter-automated.yaml @@ -9,7 +9,7 @@ jobs: shellchecker: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - 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 1a808939a..ec2e5f0a7 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@v2 + - uses: actions/checkout@v3 - name: Shell Linter uses: azohra/shell-linter@v0.6.0 diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f8dfc7210..485096b5f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -10,7 +10,7 @@ jobs: if: ${{ github.ref == 'refs/heads/main' }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Publish" uses: devcontainers/action@v1 diff --git a/.github/workflows/test-all.yaml b/.github/workflows/test-all.yaml index d2238a707..ab51a737c 100644 --- a/.github/workflows/test-all.yaml +++ b/.github/workflows/test-all.yaml @@ -51,7 +51,7 @@ jobs: "mcr.microsoft.com/devcontainers/base:debian", ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli @@ -94,7 +94,7 @@ jobs: "nix", ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - 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@v2 + - uses: actions/checkout@v3 - 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 333dbb801..f163eb8ea 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@v2 + - uses: actions/checkout@v3 - 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 69b39423b..fb586fb8b 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -58,7 +58,7 @@ jobs: "mcr.microsoft.com/devcontainers/base:debian", ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - 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@v2 + - uses: actions/checkout@v3 - name: "Install latest devcontainer CLI" run: npm install -g @devcontainers/cli diff --git a/.github/workflows/update-documentation.yml b/.github/workflows/update-documentation.yml index 711c49256..6d7bb5cbb 100644 --- a/.github/workflows/update-documentation.yml +++ b/.github/workflows/update-documentation.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest if: "github.ref == 'refs/heads/main'" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Generate Documentation uses: devcontainers/action@v1 From 58b8fe093da506595118076cedbdeee4aa6d20b0 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 17 Jan 2023 09:34:53 -0800 Subject: [PATCH 076/478] Fix typos in comments / *.md (#396) --- src/common-utils/main.sh | 2 +- src/desktop-lite/install.sh | 4 ++-- src/docker-in-docker/install.sh | 4 ++-- src/docker-outside-of-docker/install.sh | 6 +++--- src/dotnet/install.sh | 4 ++-- src/git-lfs/install.sh | 2 +- src/git/install.sh | 2 +- src/github-cli/install.sh | 2 +- src/go/install.sh | 2 +- src/nix/install.sh | 2 +- src/nix/nix-entrypoint.sh | 2 +- src/nix/utils.sh | 2 +- src/python/install.sh | 2 +- src/ruby/install.sh | 2 +- src/sshd/NOTES.md | 2 +- src/terraform/install.sh | 2 +- 16 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index 893f53aa5..c8541cd51 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -292,7 +292,7 @@ chmod +x /etc/profile.d/00-restore-env.sh # Bring in ID, ID_LIKE, VERSION_ID, VERSION_CODENAME . /etc/os-release -# Get an adjusted ID independant of distro variants +# 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 diff --git a/src/desktop-lite/install.sh b/src/desktop-lite/install.sh index ffd39d50b..df4390eca 100755 --- a/src/desktop-lite/install.sh +++ b/src/desktop-lite/install.sh @@ -176,7 +176,7 @@ export DEBIAN_FRONTEND=noninteractive apt_get_update -# On older Ubuntu, Tilix is in a PPA. on Debian strech its in backports. +# On older Ubuntu, Tilix is in a PPA. on Debian stretch its in backports. if [[ -z $(apt-cache --names-only search ^tilix$) ]]; then . /etc/os-release if [ "${ID}" = "ubuntu" ]; then @@ -365,7 +365,7 @@ screen_geometry="\${VNC_RESOLUTION%*x*}" screen_depth="\${VNC_RESOLUTION##*x}" startInBackgroundIfNotRunning "Xtigervnc" sudoUserIf "tigervncserver \${DISPLAY} -geometry \${screen_geometry} -depth \${screen_depth} -rfbport ${VNC_PORT} -dpi \${VNC_DPI:-96} -localhost -desktop fluxbox -fg -passwd /usr/local/etc/vscode-dev-containers/vnc-passwd" -# Spin up noVNC if installed and not runnning. +# 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 keepRunningInBackground "noVNC" sudoIf "/usr/local/novnc/noVNC*/utils/launch.sh --listen ${NOVNC_PORT} --vnc localhost:${VNC_PORT}" log "noVNC started." diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index d35112143..dff11393f 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -137,7 +137,7 @@ export DEBIAN_FRONTEND=noninteractive # Fetch host/container arch. architecture="$(dpkg --print-architecture)" -# Check if distro is suppported +# Check if distro is supported if [ "${USE_MOBY}" = "true" ]; then # 'get_common_setting' allows attribute to be updated remotely get_common_setting DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES @@ -305,7 +305,7 @@ if [ -f "/usr/local/share/docker-init.sh" ]; then rm -rf /var/lib/apt/lists/* exit 0 fi -echo "docker-init doesnt exist, adding..." +echo "docker-init doesn't exist, adding..." # Add user to the docker group if [ "${ENABLE_NONROOT_DOCKER}" = "true" ]; then diff --git a/src/docker-outside-of-docker/install.sh b/src/docker-outside-of-docker/install.sh index 1307bfc91..dc5a9034b 100755 --- a/src/docker-outside-of-docker/install.sh +++ b/src/docker-outside-of-docker/install.sh @@ -126,7 +126,7 @@ fi # Fetch host/container arch. architecture="$(dpkg --print-architecture)" -# Check if distro is suppported +# Check if distro is supported if [ "${USE_MOBY}" = "true" ]; then # 'get_common_setting' allows attribute to be updated remotely get_common_setting DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES @@ -209,7 +209,7 @@ else TARGET_COMPOSE_ARCH="x86_64" fi if [ "${TARGET_COMPOSE_ARCH}" != "x86_64" ]; then - # Use pip to get a version that runns on this architecture + # 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} @@ -260,7 +260,7 @@ if [ -f "/usr/local/share/docker-init.sh" ]; then rm -rf /var/lib/apt/lists/* exit 0 fi -echo "docker-init doesnt exist, adding..." +echo "docker-init doesn't exist, adding..." # By default, make the source and target sockets the same if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then diff --git a/src/dotnet/install.sh b/src/dotnet/install.sh index 13285abbd..1c7430aa0 100644 --- a/src/dotnet/install.sh +++ b/src/dotnet/install.sh @@ -316,8 +316,8 @@ install_using_dotnet_releases_url() { local sdk_or_runtime="$1" local version="$2" - # Check listed package dependecies and install them if they are not already installed. - # NOTE: icu-devtools is a small package with similar dependecies to .NET. + # Check listed package dependencies and install them if they are not already installed. + # NOTE: icu-devtools is a small package with similar dependencies to .NET. # It will install the appropriate dependencies based on the OS: # - libgcc-s1 OR libgcc1 depending on OS # - the latest libicuXX depending on OS (eg libicu57 for stretch) diff --git a/src/git-lfs/install.sh b/src/git-lfs/install.sh index f0ce9ff7e..d6f914f81 100755 --- a/src/git-lfs/install.sh +++ b/src/git-lfs/install.sh @@ -65,7 +65,7 @@ find_version_from_git_tags() { receive_gpg_keys() { local keys=${!1} - # Use a temporary locaiton for gpg keys to avoid polluting image + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} diff --git a/src/git/install.sh b/src/git/install.sh index 679e4975c..7bfa490e7 100755 --- a/src/git/install.sh +++ b/src/git/install.sh @@ -34,7 +34,7 @@ receive_gpg_keys() { keyring_args="--no-default-keyring --keyring $2" fi - # Use a temporary locaiton for gpg keys to avoid polluting image + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} diff --git a/src/github-cli/install.sh b/src/github-cli/install.sh index 1856115c5..c1dd6924e 100755 --- a/src/github-cli/install.sh +++ b/src/github-cli/install.sh @@ -34,7 +34,7 @@ receive_gpg_keys() { keyring_args="--no-default-keyring --keyring $2" fi - # Use a temporary locaiton for gpg keys to avoid polluting image + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} diff --git a/src/go/install.sh b/src/go/install.sh index 1b65e50ce..365421e4a 100755 --- a/src/go/install.sh +++ b/src/go/install.sh @@ -144,7 +144,7 @@ usermod -a -G golang "${USERNAME}" mkdir -p "${TARGET_GOROOT}" "${TARGET_GOPATH}" if [[ "${TARGET_GO_VERSION}" != "none" ]] && [[ "$(go version)" != *"${TARGET_GO_VERSION}"* ]]; then - # Use a temporary locaiton for gpg keys to avoid polluting image + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} diff --git a/src/nix/install.sh b/src/nix/install.sh index dcddcfdb4..80f9ace0d 100755 --- a/src/nix/install.sh +++ b/src/nix/install.sh @@ -12,7 +12,7 @@ FLAKEURI="${FLAKEURI:-""}" EXTRANIXCONFIG="${EXTRANIXCONFIG:-""}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" -# Nix keys for securly verifying installer download signature per https://nixos.org/download.html#nix-verify-installation +# Nix keys for securely verifying installer download signature per https://nixos.org/download.html#nix-verify-installation NIX_GPG_KEYS="B541D55301270E0BCF15CA5D8170B4726D7198DE" GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org diff --git a/src/nix/nix-entrypoint.sh b/src/nix/nix-entrypoint.sh index cac3e63b0..0ec7188db 100755 --- a/src/nix/nix-entrypoint.sh +++ b/src/nix/nix-entrypoint.sh @@ -15,7 +15,7 @@ if ! pidof nix-daemon > /dev/null 2>&1; then fi fi if [ "${start_ok}" = "false" ]; then - echo -e 'Failed to start nix-daemon as root. Set multiUser to false in your feature configuraiton if you would\nprefer to run the container as a non-root. You may also start the daemon manually if you have sudo\ninstalled and configured for your user by running "sudo -c nix-daemon &"' + echo -e 'Failed to start nix-daemon as root. Set multiUser to false in your feature configuration if you would\nprefer to run the container as a non-root. You may also start the daemon manually if you have sudo\ninstalled and configured for your user by running "sudo -c nix-daemon &"' fi fi exec "$@" diff --git a/src/nix/utils.sh b/src/nix/utils.sh index 5753e5a02..7cb55f218 100755 --- a/src/nix/utils.sh +++ b/src/nix/utils.sh @@ -91,7 +91,7 @@ receive_gpg_keys() { keyring_args="--no-default-keyring --keyring $2" fi - # Use a temporary locaiton for gpg keys to avoid polluting image + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} diff --git a/src/python/install.sh b/src/python/install.sh index 92b8368f1..3f6b4d9ac 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -85,7 +85,7 @@ receive_gpg_keys() { keyring_args="--no-default-keyring --keyring $2" fi - # Use a temporary locaiton for gpg keys to avoid polluting image + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} diff --git a/src/ruby/install.sh b/src/ruby/install.sh index c879dec7e..daae7faa1 100755 --- a/src/ruby/install.sh +++ b/src/ruby/install.sh @@ -78,7 +78,7 @@ receive_gpg_keys() { keyring_args="--no-default-keyring --keyring \"$2\"" fi - # Use a temporary locaiton for gpg keys to avoid polluting image + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} diff --git a/src/sshd/NOTES.md b/src/sshd/NOTES.md index e0e7acc82..c2ca8c8ad 100644 --- a/src/sshd/NOTES.md +++ b/src/sshd/NOTES.md @@ -57,7 +57,7 @@ While the some services automates SSH setup (e.g., when using the GitHub CLI for ``` \\sshfs.r\vscode@localhost!2222\workspaces ``` - ...where `vscode` above is the user you are running as in the container and `2222` after the `!` is the same local port you used in the `ssh` command in the previous seciton. + ...where `vscode` above is the user you are running as in the container and `2222` after the `!` is the same local port you used in the `ssh` command in the previous section. 4. Your dev container's filesystem should now be available in the `~/sshfs/devcontainer` folder on macOS or Linux or in a new explorer window on Windows. diff --git a/src/terraform/install.sh b/src/terraform/install.sh index b324eb644..1fec7563f 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -52,7 +52,7 @@ receive_gpg_keys() { keyring_args="--no-default-keyring --keyring $2" fi - # Use a temporary locaiton for gpg keys to avoid polluting image + # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" mkdir -p ${GNUPGHOME} chmod 700 ${GNUPGHOME} From f7314671e1654cd47263a09b134ddd0286f9eccc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 17 Jan 2023 09:46:27 -0800 Subject: [PATCH 077/478] Automated documentation update (#405) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/sshd/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sshd/README.md b/src/sshd/README.md index 6e9382c04..7314e16af 100644 --- a/src/sshd/README.md +++ b/src/sshd/README.md @@ -76,7 +76,7 @@ While the some services automates SSH setup (e.g., when using the GitHub CLI for ``` \\sshfs.r\vscode@localhost!2222\workspaces ``` - ...where `vscode` above is the user you are running as in the container and `2222` after the `!` is the same local port you used in the `ssh` command in the previous seciton. + ...where `vscode` above is the user you are running as in the container and `2222` after the `!` is the same local port you used in the `ssh` command in the previous section. 4. Your dev container's filesystem should now be available in the `~/sshfs/devcontainer` folder on macOS or Linux or in a new explorer window on Windows. From d78a1534925e7e424355d214c683e946cbb97d05 Mon Sep 17 00:00:00 2001 From: Tobias Gesellchen Date: Wed, 18 Jan 2023 22:24:10 +0100 Subject: [PATCH 078/478] Java: add Apache Ant (#409) * Java: add Apache Ant * Update src/java/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * revert the changes in README.md * Add tests for Java/Ant * Fix Java feature version Co-authored-by: Samruddhi Khandale --- src/java/devcontainer-feature.json | 19 +++++++++++++++++-- src/java/install.sh | 7 +++++++ ...sh => install_ant_and_gradle_and_maven.sh} | 9 ++++++++- ...tall_ant_and_gradle_and_maven_for_user.sh} | 9 ++++++++- ...gradle_and_maven_with_specific_version.sh} | 9 ++++++++- test/java/scenarios.json | 10 +++++++--- 6 files changed, 55 insertions(+), 8 deletions(-) rename test/java/{install_gradle_and_maven.sh => install_ant_and_gradle_and_maven.sh} (75%) rename test/java/{install_gradle_and_maven_for_user.sh => install_ant_and_gradle_and_maven_for_user.sh} (76%) rename test/java/{install_gradle_and_maven_with_specific_version.sh => install_ant_and_gradle_and_maven_with_specific_version.sh} (73%) diff --git a/src/java/devcontainer-feature.json b/src/java/devcontainer-feature.json index 113c75d7b..f55276aa3 100644 --- a/src/java/devcontainer-feature.json +++ b/src/java/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "java", - "version": "1.1.1", + "version": "1.2.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.", @@ -59,6 +59,21 @@ ], "default": "latest", "description": "Select or enter a Maven version" + }, + "installAnt": { + "type": "boolean", + "default": false, + "description": "Install Ant, a software tool for automating software build processes" + }, + "antVersion": { + "type": "string", + "proposals": [ + "latest", + "1.10.12", + "1.9.15" + ], + "default": "latest", + "description": "Select or enter an Ant version" } }, "customizations": { @@ -74,7 +89,7 @@ "containerEnv": { "SDKMAN_DIR": "/usr/local/sdkman", "JAVA_HOME": "/usr/local/sdkman/candidates/java/current", - "PATH": "/usr/local/sdkman/bin:/usr/local/sdkman/candidates/java/current/bin:/usr/local/sdkman/candidates/gradle/current/bin:/usr/local/sdkman/candidates/maven/current/bin:${PATH}" + "PATH": "/usr/local/sdkman/bin:/usr/local/sdkman/candidates/java/current/bin:/usr/local/sdkman/candidates/gradle/current/bin:/usr/local/sdkman/candidates/maven/current/bin:/usr/local/sdkman/candidates/ant/current/bin:${PATH}" }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" diff --git a/src/java/install.sh b/src/java/install.sh index bf9496304..ea43dd3e9 100644 --- a/src/java/install.sh +++ b/src/java/install.sh @@ -14,6 +14,8 @@ INSTALL_GRADLE="${INSTALLGRADLE:-"false"}" GRADLE_VERSION="${GRADLEVERSION:-"latest"}" INSTALL_MAVEN="${INSTALLMAVEN:-"false"}" MAVEN_VERSION="${MAVENVERSION:-"latest"}" +INSTALL_ANT="${INSTALLANT:-"false"}" +ANT_VERSION="${ANTVERSION:-"latest"}" JDK_DISTRO="${JDKDISTRO}" export SDKMAN_DIR="${SDKMAN_DIR:-"/usr/local/sdkman"}" @@ -173,6 +175,11 @@ if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then su ${USERNAME} -c ". ${SDKMAN_DIR}/bin/sdkman-init.sh && sdk default java ${JAVA_VERSION}" fi +# Install Ant +if [[ "${INSTALL_ANT}" = "true" ]] && ! ant -version > /dev/null; then + sdk_install ant ${ANT_VERSION} +fi + # Install Gradle if [[ "${INSTALL_GRADLE}" = "true" ]] && ! gradle --version > /dev/null; then sdk_install gradle ${GRADLE_VERSION} diff --git a/test/java/install_gradle_and_maven.sh b/test/java/install_ant_and_gradle_and_maven.sh similarity index 75% rename from test/java/install_gradle_and_maven.sh rename to test/java/install_ant_and_gradle_and_maven.sh index 636fd92a0..599f8d9d5 100644 --- a/test/java/install_gradle_and_maven.sh +++ b/test/java/install_ant_and_gradle_and_maven.sh @@ -8,8 +8,15 @@ source dev-container-features-test-lib check "user is root" grep root <(whoami) check "java" java --version -check "gradle" gradle --version +check "ant" ant -version +cat << EOF > /tmp/build.xml + +EOF +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 check "GRADLE_USER_HOME exists" grep ".gradle" <(ls -la /root) diff --git a/test/java/install_gradle_and_maven_for_user.sh b/test/java/install_ant_and_gradle_and_maven_for_user.sh similarity index 76% rename from test/java/install_gradle_and_maven_for_user.sh rename to test/java/install_ant_and_gradle_and_maven_for_user.sh index b6ea4266b..4e8b43134 100644 --- a/test/java/install_gradle_and_maven_for_user.sh +++ b/test/java/install_ant_and_gradle_and_maven_for_user.sh @@ -8,8 +8,15 @@ source dev-container-features-test-lib check "user is vscode" grep vscode <(whoami) check "java" java --version -check "gradle" gradle --version +check "ant" ant -version +cat << EOF > /tmp/build.xml + +EOF +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 check "GRADLE_USER_HOME exists" grep ".gradle" <(ls -la /home/vscode) diff --git a/test/java/install_gradle_and_maven_with_specific_version.sh b/test/java/install_ant_and_gradle_and_maven_with_specific_version.sh similarity index 73% rename from test/java/install_gradle_and_maven_with_specific_version.sh rename to test/java/install_ant_and_gradle_and_maven_with_specific_version.sh index c6ae6160c..7727f51b6 100644 --- a/test/java/install_gradle_and_maven_with_specific_version.sh +++ b/test/java/install_ant_and_gradle_and_maven_with_specific_version.sh @@ -8,8 +8,15 @@ source dev-container-features-test-lib check "user is root" grep root <(whoami) check "java" java --version -check "gradle version" grep "Gradle 6.8.3" <(gradle --version) +check "ant version" grep "Ant(TM) version 1.10.12" <(ant -version) +cat << EOF > /tmp/build.xml + +EOF +cd /tmp && ant init +check "ant-src exists" grep "ant-src" <(ls -la /tmp) + +check "gradle version" grep "Gradle 6.8.3" <(gradle --version) cd /tmp && gradle init --type basic --dsl groovy --project-name test check "GRADLE_USER_HOME exists" grep ".gradle" <(ls -la /root) diff --git a/test/java/scenarios.json b/test/java/scenarios.json index 479ee4703..11fb7ba33 100644 --- a/test/java/scenarios.json +++ b/test/java/scenarios.json @@ -17,7 +17,7 @@ } } }, - "install_gradle_and_maven_for_user": { + "install_ant_and_gradle_and_maven_for_user": { "image": "ubuntu:focal", "remoteUser": "vscode", "features": { @@ -26,26 +26,30 @@ }, "java": { "version": "latest", + "installAnt": true, "installGradle": true, "installMaven": true } } }, - "install_gradle_and_maven": { + "install_ant_and_gradle_and_maven": { "image": "ubuntu:focal", "features": { "java": { "version": "latest", + "installAnt": true, "installGradle": true, "installMaven": true } } }, - "install_gradle_and_maven_with_specific_version": { + "install_ant_and_gradle_and_maven_with_specific_version": { "image": "ubuntu:focal", "features": { "java": { "version": "latest", + "installAnt": "true", + "antVersion": "1.10.12", "installGradle": "true", "gradleVersion": "6.8.3", "installMaven": "true", From 24b33c5f79a38684a4433fcb1310db256b264c00 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 18 Jan 2023 13:42:35 -0800 Subject: [PATCH 079/478] Automated documentation update (#410) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/java/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/java/README.md b/src/java/README.md index f3e35e38a..e74cd5a10 100644 --- a/src/java/README.md +++ b/src/java/README.md @@ -21,6 +21,8 @@ Installs Java, SDKMAN! (if not installed), and needed dependencies. | gradleVersion | Select or enter a Gradle version | string | latest | | installMaven | Install Maven, a management tool for Java | boolean | false | | mavenVersion | Select or enter a Maven version | string | latest | +| installAnt | Install Ant, a software tool for automating software build processes | boolean | false | +| antVersion | Select or enter an Ant version | string | latest | ## License From 7a3a9c5fcaa59cf4d7dbbcece47094a6d642a9b0 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 20 Jan 2023 09:22:39 -0800 Subject: [PATCH 080/478] Php: Auto configure if a three part version is not provided (#406) * Php: Auto configure if a three part version is not provided * fix test * update checks * Bump version --- src/php/devcontainer-feature.json | 6 ++-- src/php/install.sh | 49 ++++++++++++++++++++++--------- test/php/install_php_8.sh | 11 +++++++ test/php/install_php_8_2.sh | 11 +++++++ test/php/scenarios.json | 18 +++++++++++- 5 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 test/php/install_php_8.sh create mode 100644 test/php/install_php_8_2.sh diff --git a/src/php/devcontainer-feature.json b/src/php/devcontainer-feature.json index 2ea56d2ba..201fe481c 100644 --- a/src/php/devcontainer-feature.json +++ b/src/php/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "php", - "version": "1.0.11", + "version": "1.1.0", "name": "PHP", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/php", "options": { @@ -8,7 +8,9 @@ "type": "string", "proposals": [ "latest", - "8.0.16" + "8", + "8.2", + "8.2.0" ], "default": "latest", "description": "Select or enter a PHP version" diff --git a/src/php/install.sh b/src/php/install.sh index c0bcb0426..0c577b165 100755 --- a/src/php/install.sh +++ b/src/php/install.sh @@ -84,15 +84,41 @@ check_packages() { fi } -# Figure out correct version of PHP +# Figure out correct version of a three part version number is not passed find_version_from_git_tags() { - local repository="https://github.com/php/php-src" - local separator="." - local escaped_separator=${separator//./\\.} - local last_part="${escaped_separator}[0-9]+" - local regex="\\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)" - PHP_VERSION="$(echo "${version_list}" | head -n 1)" + local variable_name=$1 + local requested_version=${!variable_name} + if [ "${requested_version}" = "none" ]; then return; fi + local repository=$2 + local prefix=${3:-"tags/v"} + local separator=${4:-"."} + local last_part_optional=${5:-"false"} + echo "${!variable_name}" + echo "$(echo "${requested_version}" | grep -o "." | wc -l)" + if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then + local escaped_separator=${separator//./\\.} + local last_part + if [ "${last_part_optional}" = "true" ]; then + last_part="(${escaped_separator}[0-9]+)?" + else + 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)" + if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then + declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" + else + set +e + declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" + set -e + fi + fi + echo "${!variable_name}" + if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then + echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 + exit 1 + fi + echo "${variable_name}=${!variable_name}" } # Install PHP Composer @@ -131,12 +157,6 @@ check_packages $RUNTIME_DEPS $PHP_DEPS $PHPIZE_DEPS install_php() { PHP_VERSION="$1" - - # Fetch latest version of PHP if needed - if [ "${PHP_VERSION}" = "latest" ] || [ "${PHP_VERSION}" = "lts" ]; then - find_version_from_git_tags - fi - PHP_INSTALL_DIR="${PHP_DIR}/${PHP_VERSION}" if [ -d "${PHP_INSTALL_DIR}" ]; then echo "(!) PHP version ${PHP_VERSION} already exists." @@ -218,6 +238,7 @@ install_php() { updaterc "if [[ \"\${PATH}\" != *\"${CURRENT_DIR}\"* ]]; then export PATH=\"${CURRENT_DIR}/bin:\${PATH}\"; fi" } +find_version_from_git_tags PHP_VERSION https://github.com/php/php-src "tags/php-" install_php "${PHP_VERSION}" # Additional php versions to be installed but not be set as default. diff --git a/test/php/install_php_8.sh b/test/php/install_php_8.sh new file mode 100644 index 000000000..a510525f6 --- /dev/null +++ b/test/php/install_php_8.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "php-version-8-is-installed" bash -c "php --version | grep '8.'" + +# Report result +reportResults diff --git a/test/php/install_php_8_2.sh b/test/php/install_php_8_2.sh new file mode 100644 index 000000000..9320268ef --- /dev/null +++ b/test/php/install_php_8_2.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "php-version-8.2-is-installed" bash -c "php --version | grep '8.2'" + +# Report result +reportResults diff --git a/test/php/scenarios.json b/test/php/scenarios.json index f24753b11..dac799875 100644 --- a/test/php/scenarios.json +++ b/test/php/scenarios.json @@ -7,5 +7,21 @@ "additionalVersions": "8.0.17,8.0.3" } } + }, + "install_php_8": { + "image": "ubuntu:focal", + "features": { + "php": { + "version": "8" + } + } + }, + "install_php_8_2": { + "image": "ubuntu:focal", + "features": { + "php": { + "version": "8.2" + } + } } -} \ No newline at end of file +} From bebf87e33cc792d448cfc34ccac64097b18243b6 Mon Sep 17 00:00:00 2001 From: Pamela Fox Date: Mon, 23 Jan 2023 15:18:50 -0800 Subject: [PATCH 081/478] Add more detail to note about architecture (#416) * Add more detail to note about architecture * Update src/docker-in-docker/NOTES.md Co-authored-by: Samruddhi Khandale * Update src/docker-in-docker/NOTES.md Co-authored-by: Samruddhi Khandale Co-authored-by: Samruddhi Khandale --- src/docker-in-docker/NOTES.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/docker-in-docker/NOTES.md b/src/docker-in-docker/NOTES.md index a22e61c51..b8156f8b6 100644 --- a/src/docker-in-docker/NOTES.md +++ b/src/docker-in-docker/NOTES.md @@ -2,8 +2,11 @@ This docker-in-docker Dev Container Feature is roughly based on the [official docker-in-docker wrapper script](https://github.com/moby/moby/blob/master/hack/dind) that is part of the [Moby project](https://mobyproject.org/). With this in mind: * As the name implies, the Feature is expected to work when the host is running Docker (or the OSS Moby container engine it is built on). It may be possible to get running in other container engines, but it has not been tested with them. -* The host and the container must be running on the same chip architecture. You will not be able to use it with an emulated x86 image with Docker Desktop on an Apple Silicon Mac, for example. - +* The host and the container must be running on the same chip architecture. You will not be able to use it with an emulated x86 image with Docker Desktop on an Apple Silicon Mac, like in this example: + ``` + FROM --platform=linux/amd64 mcr.microsoft.com/devcontainers/typescript-node:16 + ``` + See [Issue #219](https://github.com/devcontainers/features/issues/219) for more details. ## OS Support From 3a579894a02c7eb76184cf7305d67fe3f69b789f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 23 Jan 2023 15:21:02 -0800 Subject: [PATCH 082/478] Automated documentation update (#417) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/docker-in-docker/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/docker-in-docker/README.md b/src/docker-in-docker/README.md index 4196892b0..d74639bb1 100644 --- a/src/docker-in-docker/README.md +++ b/src/docker-in-docker/README.md @@ -25,8 +25,11 @@ Create child containers *inside* a container, independent from the host's docker This docker-in-docker Dev Container Feature is roughly based on the [official docker-in-docker wrapper script](https://github.com/moby/moby/blob/master/hack/dind) that is part of the [Moby project](https://mobyproject.org/). With this in mind: * As the name implies, the Feature is expected to work when the host is running Docker (or the OSS Moby container engine it is built on). It may be possible to get running in other container engines, but it has not been tested with them. -* The host and the container must be running on the same chip architecture. You will not be able to use it with an emulated x86 image with Docker Desktop on an Apple Silicon Mac, for example. - +* The host and the container must be running on the same chip architecture. You will not be able to use it with an emulated x86 image with Docker Desktop on an Apple Silicon Mac, like in this example: + ``` + FROM --platform=linux/amd64 mcr.microsoft.com/devcontainers/typescript-node:16 + ``` + See [Issue #219](https://github.com/devcontainers/features/issues/219) for more details. ## OS Support From 676e824e92c7b2abe45f46c89580c96f99a8d43f Mon Sep 17 00:00:00 2001 From: "dylhack.dev" Date: Tue, 24 Jan 2023 12:28:54 -0600 Subject: [PATCH 083/478] features/nix: remove PGP check (#414) * nix: remove PGP check * fix issues --- src/nix/devcontainer-feature.json | 2 +- src/nix/install.sh | 10 --------- src/nix/utils.sh | 35 ------------------------------- 3 files changed, 1 insertion(+), 46 deletions(-) diff --git a/src/nix/devcontainer-feature.json b/src/nix/devcontainer-feature.json index b112040d3..664f68c91 100644 --- a/src/nix/devcontainer-feature.json +++ b/src/nix/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nix", - "version": "1.1.1", + "version": "1.1.2", "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.", diff --git a/src/nix/install.sh b/src/nix/install.sh index 80f9ace0d..ed048fe8d 100755 --- a/src/nix/install.sh +++ b/src/nix/install.sh @@ -12,12 +12,6 @@ FLAKEURI="${FLAKEURI:-""}" EXTRANIXCONFIG="${EXTRANIXCONFIG:-""}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" -# Nix keys for securely verifying installer download signature per https://nixos.org/download.html#nix-verify-installation -NIX_GPG_KEYS="B541D55301270E0BCF15CA5D8170B4726D7198DE" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com -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.' exit 1 @@ -61,10 +55,6 @@ else 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 - curl -sSLf -o "${tmpdir}/install-nix.asc" https://releases.nixos.org/nix/nix-${VERSION}/install.asc - cd "${tmpdir}" - receive_gpg_keys NIX_GPG_KEYS - gpg2 --verify ./install-nix.asc cd "${FEATURE_DIR}" # Do a multi or single-user setup based on feature config diff --git a/src/nix/utils.sh b/src/nix/utils.sh index 7cb55f218..f94fd3d4e 100755 --- a/src/nix/utils.sh +++ b/src/nix/utils.sh @@ -82,41 +82,6 @@ detect_user() { fi } -# Import the specified key in a variable name passed in as -receive_gpg_keys() { - local keys=${!1} - local keyring_args="" - if [ ! -z "$2" ]; then - mkdir -p "$(dirname \"$2\")" - keyring_args="--no-default-keyring --keyring $2" - 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 - # GPG key download sometimes fails for some reason and retrying fixes it. - local retry_count=0 - local gpg_ok="false" - set +e - 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" - if [ "${gpg_ok}" != "true" ]; then - echo "(*) Failed getting key, retring in 10s..." - (( retry_count++ )) - sleep 10s - fi - done - set -e - if [ "${gpg_ok}" = "false" ]; then - echo "(!) Failed to get gpg key." - 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 From 258d5029a58e35d62c9d39400c92b41ed90825ee Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Wed, 25 Jan 2023 10:24:25 -0800 Subject: [PATCH 084/478] Republish all Features to add repo tags (#422) republish all features to add repo tags --- src/anaconda/devcontainer-feature.json | 2 +- src/aws-cli/devcontainer-feature.json | 2 +- src/azure-cli/devcontainer-feature.json | 2 +- src/common-utils/devcontainer-feature.json | 2 +- src/conda/devcontainer-feature.json | 2 +- src/desktop-lite/devcontainer-feature.json | 2 +- src/docker-in-docker/devcontainer-feature.json | 2 +- src/docker-outside-of-docker/devcontainer-feature.json | 2 +- src/dotnet/devcontainer-feature.json | 2 +- src/git-lfs/devcontainer-feature.json | 2 +- src/git/devcontainer-feature.json | 2 +- src/github-cli/devcontainer-feature.json | 2 +- src/go/devcontainer-feature.json | 2 +- src/hugo/devcontainer-feature.json | 2 +- src/java/devcontainer-feature.json | 2 +- src/kubectl-helm-minikube/devcontainer-feature.json | 2 +- src/nix/devcontainer-feature.json | 2 +- src/node/devcontainer-feature.json | 2 +- src/nvidia-cuda/devcontainer-feature.json | 2 +- src/oryx/devcontainer-feature.json | 2 +- src/php/devcontainer-feature.json | 2 +- src/powershell/devcontainer-feature.json | 2 +- src/python/devcontainer-feature.json | 2 +- src/ruby/devcontainer-feature.json | 2 +- src/rust/devcontainer-feature.json | 2 +- src/sshd/devcontainer-feature.json | 2 +- src/terraform/devcontainer-feature.json | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/anaconda/devcontainer-feature.json b/src/anaconda/devcontainer-feature.json index cdf1fbf7e..e0d013d86 100644 --- a/src/anaconda/devcontainer-feature.json +++ b/src/anaconda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "anaconda", - "version": "1.0.10", + "version": "1.0.11", "name": "Anaconda", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/anaconda", "options": { diff --git a/src/aws-cli/devcontainer-feature.json b/src/aws-cli/devcontainer-feature.json index 2e09d771b..8de431868 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.5", + "version": "1.0.6", "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/azure-cli/devcontainer-feature.json b/src/azure-cli/devcontainer-feature.json index a2ba45221..9ab2cc39b 100644 --- a/src/azure-cli/devcontainer-feature.json +++ b/src/azure-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "azure-cli", - "version": "1.0.7", + "version": "1.0.8", "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.", diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 03b2fe37f..71b6e6687 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.7", + "version": "2.0.8", "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/conda/devcontainer-feature.json b/src/conda/devcontainer-feature.json index 488de41ff..8e1a5fccb 100644 --- a/src/conda/devcontainer-feature.json +++ b/src/conda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "conda", - "version": "1.0.7", + "version": "1.0.8", "name": "Conda", "description": "A cross-platform, language-agnostic binary package manager", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/conda", diff --git a/src/desktop-lite/devcontainer-feature.json b/src/desktop-lite/devcontainer-feature.json index 84c99db93..5387138b5 100644 --- a/src/desktop-lite/devcontainer-feature.json +++ b/src/desktop-lite/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "desktop-lite", - "version": "1.0.7", + "version": "1.0.8", "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/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 0ac565e7b..58c2d1400 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.0.0", + "version": "2.0.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.", diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index 69aa2f49a..1f3ff4e9a 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.0.9", + "version": "1.0.10", "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/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index e66550e76..4aa264c13 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "1.1.2", + "version": "1.1.3", "name": "Dotnet CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet", "description": "Installs the .NET CLI. Provides option of installing sdk or runtime, and option of versions to install. Uses latest version of .NET sdk as defaults to install.", diff --git a/src/git-lfs/devcontainer-feature.json b/src/git-lfs/devcontainer-feature.json index a301a64d6..021746997 100644 --- a/src/git-lfs/devcontainer-feature.json +++ b/src/git-lfs/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git-lfs", - "version": "1.0.6", + "version": "1.0.7", "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/devcontainer-feature.json b/src/git/devcontainer-feature.json index 4123aed6b..23e1c04f4 100644 --- a/src/git/devcontainer-feature.json +++ b/src/git/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git", - "version": "1.1.4", + "version": "1.1.5", "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/github-cli/devcontainer-feature.json b/src/github-cli/devcontainer-feature.json index 0e68a6028..24ef9802f 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.9", + "version": "1.0.10", "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/go/devcontainer-feature.json b/src/go/devcontainer-feature.json index f63d93ec1..92ed59154 100644 --- a/src/go/devcontainer-feature.json +++ b/src/go/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "go", - "version": "1.1.2", + "version": "1.1.3", "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.", diff --git a/src/hugo/devcontainer-feature.json b/src/hugo/devcontainer-feature.json index ffc1a3bdb..d6358d703 100644 --- a/src/hugo/devcontainer-feature.json +++ b/src/hugo/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "hugo", - "version": "1.1.1", + "version": "1.1.2", "name": "Hugo", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/hugo", "options": { diff --git a/src/java/devcontainer-feature.json b/src/java/devcontainer-feature.json index f55276aa3..7bdec6ab0 100644 --- a/src/java/devcontainer-feature.json +++ b/src/java/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "java", - "version": "1.2.0", + "version": "1.2.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/kubectl-helm-minikube/devcontainer-feature.json b/src/kubectl-helm-minikube/devcontainer-feature.json index 076af3912..78e90d9b7 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.2", + "version": "1.1.3", "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/nix/devcontainer-feature.json b/src/nix/devcontainer-feature.json index 664f68c91..96a75016b 100644 --- a/src/nix/devcontainer-feature.json +++ b/src/nix/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nix", - "version": "1.1.2", + "version": "1.1.3", "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.", diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index 216f29b80..6450ce422 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.1.4", + "version": "1.1.5", "name": "Node.js (via nvm) and yarn", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/node", "description": "Installs Node.js, nvm, yarn, and needed dependencies.", diff --git a/src/nvidia-cuda/devcontainer-feature.json b/src/nvidia-cuda/devcontainer-feature.json index dd5c13d8c..81e1dff8d 100644 --- a/src/nvidia-cuda/devcontainer-feature.json +++ b/src/nvidia-cuda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "nvidia-cuda", - "version": "1.0.6", + "version": "1.0.7", "name": "NVIDIA CUDA", "description": "Installs shared libraries for NVIDIA CUDA.", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/nvidia-cuda", diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json index 5c643445b..9a6bd25c2 100644 --- a/src/oryx/devcontainer-feature.json +++ b/src/oryx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oryx", - "version": "1.0.12", + "version": "1.0.13", "name": "Oryx", "description": "Installs the oryx CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/oryx", diff --git a/src/php/devcontainer-feature.json b/src/php/devcontainer-feature.json index 201fe481c..ae270d0e5 100644 --- a/src/php/devcontainer-feature.json +++ b/src/php/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "php", - "version": "1.1.0", + "version": "1.1.1", "name": "PHP", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/php", "options": { diff --git a/src/powershell/devcontainer-feature.json b/src/powershell/devcontainer-feature.json index 84c39feb6..ef967a6a5 100644 --- a/src/powershell/devcontainer-feature.json +++ b/src/powershell/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "powershell", - "version": "1.0.5", + "version": "1.0.6", "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.", diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index 1d5812149..361270b2a 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.0.19", + "version": "1.0.20", "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/ruby/devcontainer-feature.json b/src/ruby/devcontainer-feature.json index 68951d899..8d2a4e31f 100644 --- a/src/ruby/devcontainer-feature.json +++ b/src/ruby/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby", - "version": "1.0.8", + "version": "1.0.9", "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/rust/devcontainer-feature.json b/src/rust/devcontainer-feature.json index 8a7f5b432..e1b2052c4 100644 --- a/src/rust/devcontainer-feature.json +++ b/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "1.0.9", + "version": "1.0.10", "name": "Rust", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust", "description": "Installs Rust, common Rust utilities, and their required dependencies", diff --git a/src/sshd/devcontainer-feature.json b/src/sshd/devcontainer-feature.json index 696a23ba7..da1f8a9d8 100644 --- a/src/sshd/devcontainer-feature.json +++ b/src/sshd/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sshd", - "version": "1.0.7", + "version": "1.0.8", "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.", diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index 490a05b2d..99c052be9 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.1.1", + "version": "1.1.2", "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 fbdc4556d519512736a8e2abfb3e03fcb2c9e0c7 Mon Sep 17 00:00:00 2001 From: Levin Winter <33220502+levinwinter@users.noreply.github.com> Date: Thu, 26 Jan 2023 00:57:31 +0100 Subject: [PATCH 085/478] [common-utils] Fix nonempty .bashrc being restored (#421) * [common-utils] Fix nonempty .bashrc being restored The user's dotfiles shall only be restored to their defaults if they do not exist or are empty. A missing negation caused the files to be overwritten even when they were nonempty. * [common-utils] Bump patch version after fix Go from 2.0.7 to 2.0.8 because of backwards-compatible fix. --- src/common-utils/main.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index c8541cd51..2a8cd282e 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -393,7 +393,7 @@ fi possible_rc_files=( ".bashrc" ".profile" ".zshrc" ) for rc_file in "${possible_rc_files[@]}"; do if [ -f "/etc/skel/${rc_file}" ]; then - if [ ! -e "${user_rc_path}/${rc_file}" ] || [ -s "${user_rc_path}/${rc_file}" ]; then + if [ ! -e "${user_rc_path}/${rc_file}" ] || [ ! -s "${user_rc_path}/${rc_file}" ]; then cp "/etc/skel/${rc_file}" "${user_rc_path}/${rc_file}" chown ${USERNAME}:${group_name} "${user_rc_path}/${rc_file}" fi From 7763e0b7db6a16f2efececb6ffa9bd917a9eb5de Mon Sep 17 00:00:00 2001 From: Ross Smith Date: Mon, 30 Jan 2023 19:29:13 +0000 Subject: [PATCH 086/478] Install PowerShell Modules (#427) * InstallBicep * Add test for InstallBicep * Install pwsh Modules * Script rename * Add -Command to test * Check version * Install the module for all users * Adding terminating lines to scripts * Update src/powershell/install.sh Co-authored-by: Samruddhi Khandale * Update src/powershell/install.sh Co-authored-by: Samruddhi Khandale * Removed comments in Readme * Remove Bicep from PowerShell install * Increased version number * Update Minor version rather than patch --------- Co-authored-by: Samruddhi Khandale --- src/powershell/devcontainer-feature.json | 11 ++++++++--- src/powershell/install.sh | 12 ++++++++++++ test/powershell/install_modules.sh | 13 +++++++++++++ test/powershell/scenarios.json | 10 ++++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 test/powershell/install_modules.sh create mode 100644 test/powershell/scenarios.json diff --git a/src/powershell/devcontainer-feature.json b/src/powershell/devcontainer-feature.json index ef967a6a5..dce05755e 100644 --- a/src/powershell/devcontainer-feature.json +++ b/src/powershell/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "powershell", - "version": "1.0.6", + "version": "1.1.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.", @@ -14,8 +14,13 @@ ], "default": "latest", "description": "Select or enter a version of PowerShell." - } - }, + }, + "modules": { + "type": "string", + "default": "", + "description": "Optional comma separated list of PowerShell modules to install." + } + }, "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] diff --git a/src/powershell/install.sh b/src/powershell/install.sh index 3f19f47ea..b220c3acf 100755 --- a/src/powershell/install.sh +++ b/src/powershell/install.sh @@ -13,6 +13,7 @@ set -e rm -rf /var/lib/apt/lists/* POWERSHELL_VERSION=${VERSION:-"latest"} +POWERSHELL_MODULES="${MODULES}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" POWERSHELL_ARCHIVE_ARCHITECTURES="amd64" @@ -149,6 +150,17 @@ if [ "${use_github}" = "true" ]; then install_using_github fi +# If PowerShell modules are requested, loop through and install +if [ ${#POWERSHELL_MODULES[@]} -gt 0 ]; then + echo "Installing PowerShell Modules: ${POWERSHELL_MODULES}" + modules=(`echo ${POWERSHELL_MODULES} | tr ',' ' '`) + for i in "${modules[@]}" + do + echo "Installing ${i}" + pwsh -Command "Install-Module -Name ${i} -AllowClobber -Force -Scope AllUsers" || continue + done +fi + # Clean up rm -rf /var/lib/apt/lists/* diff --git a/test/powershell/install_modules.sh b/test/powershell/install_modules.sh new file mode 100644 index 000000000..0bb0172e6 --- /dev/null +++ b/test/powershell/install_modules.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +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()" + +# Report result +reportResults diff --git a/test/powershell/scenarios.json b/test/powershell/scenarios.json new file mode 100644 index 000000000..8ced96498 --- /dev/null +++ b/test/powershell/scenarios.json @@ -0,0 +1,10 @@ +{ + "install_modules": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "features": { + "powershell": { + "modules": "az.resources, az.storage" + } + } + } +} From 6bf4a7dbeccc63c20220fce08a02d0893d75b83a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Jan 2023 11:42:51 -0800 Subject: [PATCH 087/478] Automated documentation update (#431) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/powershell/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/powershell/README.md b/src/powershell/README.md index ba300d5cd..ccc62f7fe 100644 --- a/src/powershell/README.md +++ b/src/powershell/README.md @@ -16,6 +16,7 @@ Installs PowerShell along with needed dependencies. Useful for base Dockerfiles | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | version | Select or enter a version of PowerShell. | string | latest | +| modules | Optional comma separated list of PowerShell modules to install. | string | - | From c997f9af697c6f09143d4b0f5305332e7adb71f5 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 3 Feb 2023 09:27:17 -0800 Subject: [PATCH 088/478] Rust - Clean up unwanted settings (#434) * Rust - Clean up unwanted settings * address comments --- src/rust/devcontainer-feature.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/rust/devcontainer-feature.json b/src/rust/devcontainer-feature.json index e1b2052c4..fd5d02612 100644 --- a/src/rust/devcontainer-feature.json +++ b/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "1.0.10", + "version": "1.0.11", "name": "Rust", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust", "description": "Installs Rust, common Rust utilities, and their required dependencies", @@ -38,11 +38,9 @@ "serayuzgur.crates" ], "settings": { - "lldb.executable": "/usr/bin/lldb", "files.watcherExclude": { "**/target/**": true - }, - "rust-analyzer.checkOnSave.command": "clippy" + } } } }, From 36d7664ebab393f0033bbc25394c67e3aed3efb1 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 7 Feb 2023 09:52:33 -0800 Subject: [PATCH 089/478] PHP: Allow 'version:none' (#439) * PHP: Allow 'version:none' * fix tests --- src/php/devcontainer-feature.json | 5 +- src/php/install.sh | 110 ++++++++++++++++------------- test/php/install_additional_php.sh | 2 + test/php/install_only_composer.sh | 10 +++ test/php/install_php_8.sh | 1 + test/php/install_php_8_2.sh | 1 + test/php/scenarios.json | 9 +++ test/php/test.sh | 2 +- 8 files changed, 87 insertions(+), 53 deletions(-) create mode 100644 test/php/install_only_composer.sh diff --git a/src/php/devcontainer-feature.json b/src/php/devcontainer-feature.json index ae270d0e5..77fcf9812 100644 --- a/src/php/devcontainer-feature.json +++ b/src/php/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "php", - "version": "1.1.1", + "version": "1.1.2", "name": "PHP", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/php", "options": { @@ -10,7 +10,8 @@ "latest", "8", "8.2", - "8.2.0" + "8.2.0", + "none" ], "default": "latest", "description": "Select or enter a PHP version" diff --git a/src/php/install.sh b/src/php/install.sh index 0c577b165..48140e1b3 100755 --- a/src/php/install.sh +++ b/src/php/install.sh @@ -123,38 +123,13 @@ find_version_from_git_tags() { # Install PHP Composer addcomposer() { - "${PHP_INSTALL_DIR}/bin/php" -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" + "${PHP_SRC}" -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" HASH="$(wget -q -O - https://composer.github.io/installer.sig)" - "${PHP_INSTALL_DIR}/bin/php" -r "if (hash_file('sha384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" - "${PHP_INSTALL_DIR}/bin/php" composer-setup.php - "${PHP_INSTALL_DIR}/bin/php" -r "unlink('composer-setup.php');" - - mv composer.phar "${PHP_INSTALL_DIR}/bin/composer" + "${PHP_SRC}" -r "if (hash_file('sha384', 'composer-setup.php') === '$HASH') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" + "${PHP_SRC}" composer-setup.php --install-dir="/usr/local/bin" --filename=composer + "${PHP_SRC}" -r "unlink('composer-setup.php');" } -# Install PHP if it's missing - - -# Persistent / runtime dependencies -RUNTIME_DEPS="wget ca-certificates git build-essential xz-utils" - -# PHP dependencies -PHP_DEPS="libssl-dev libcurl4-openssl-dev libedit-dev libsqlite3-dev libxml2-dev zlib1g-dev libsodium-dev libonig-dev" - -. /etc/os-release - -if [ "${VERSION_CODENAME}" = "bionic" ]; then - PHP_DEPS="${PHP_DEPS} libargon2-0-dev" -else - PHP_DEPS="${PHP_DEPS} libargon2-dev" -fi - -# Dependencies required for running "phpize" -PHPIZE_DEPS="autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c" - -# Install dependencies -check_packages $RUNTIME_DEPS $PHP_DEPS $PHPIZE_DEPS - install_php() { PHP_VERSION="$1" PHP_INSTALL_DIR="${PHP_DIR}/${PHP_VERSION}" @@ -216,30 +191,48 @@ install_php() { echo "xdebug.mode = debug" >> "${XDEBUG_INI}" echo "xdebug.start_with_request = yes" >> "${XDEBUG_INI}" echo "xdebug.client_port = 9003" >> "${XDEBUG_INI}" +} - # Install PHP Composer if needed - if [[ "${INSTALL_COMPOSER}" = "true" ]] || [[ $(composer --version) = "" ]]; then - addcomposer - fi +if [ "${PHP_VERSION}" != "none" ]; then + # Persistent / runtime dependencies + RUNTIME_DEPS="wget ca-certificates git build-essential xz-utils" - CURRENT_DIR="${PHP_DIR}/current" - if [[ ! -d "${CURRENT_DIR}" ]]; then - ln -s -r "${PHP_INSTALL_DIR}" ${CURRENT_DIR} - fi + # PHP dependencies + PHP_DEPS="libssl-dev libcurl4-openssl-dev libedit-dev libsqlite3-dev libxml2-dev zlib1g-dev libsodium-dev libonig-dev" - if [ "${OVERRIDE_DEFAULT_VERSION}" = "true" ]; then - if [[ $(ls -l ${CURRENT_DIR}) != *"-> ${PHP_INSTALL_DIR}"* ]] ; then - rm "${CURRENT_DIR}" - ln -s -r "${PHP_INSTALL_DIR}" "${CURRENT_DIR}" - fi + . /etc/os-release + + if [ "${VERSION_CODENAME}" = "bionic" ]; then + PHP_DEPS="${PHP_DEPS} libargon2-0-dev" + else + PHP_DEPS="${PHP_DEPS} libargon2-dev" fi - rm -rf "${PHP_SRC_DIR}" - updaterc "if [[ \"\${PATH}\" != *\"${CURRENT_DIR}\"* ]]; then export PATH=\"${CURRENT_DIR}/bin:\${PATH}\"; fi" -} + # Dependencies required for running "phpize" + PHPIZE_DEPS="autoconf dpkg-dev file g++ gcc libc-dev make pkg-config re2c" -find_version_from_git_tags PHP_VERSION https://github.com/php/php-src "tags/php-" -install_php "${PHP_VERSION}" + # Install dependencies + check_packages $RUNTIME_DEPS $PHP_DEPS $PHPIZE_DEPS + + find_version_from_git_tags PHP_VERSION https://github.com/php/php-src "tags/php-" + install_php "${PHP_VERSION}" + + PHP_SRC="${PHP_INSTALL_DIR}/bin/php" +else + set +e + PHP_SRC=$(which php) + set -e +fi + +# Install PHP Composer if needed +if [[ "${INSTALL_COMPOSER}" = "true" ]]; then + if [ -z "${PHP_SRC}" ]; then + echo "(!) Could not install Composer. PHP not found." + exit 1 + fi + + addcomposer +fi # Additional php versions to be installed but not be set as default. if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then @@ -253,9 +246,26 @@ if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then IFS=$OLDIFS fi -chown -R "${USERNAME}:php" "${PHP_DIR}" -chmod -R g+r+w "${PHP_DIR}" -find "${PHP_DIR}" -type d -print0 | xargs -n 1 -0 chmod g+s +if [ "${PHP_VERSION}" != "none" ]; then + CURRENT_DIR="${PHP_DIR}/current" + if [[ ! -d "${CURRENT_DIR}" ]]; then + ln -s -r "${PHP_INSTALL_DIR}" ${CURRENT_DIR} + fi + + if [ "${OVERRIDE_DEFAULT_VERSION}" = "true" ]; then + if [[ $(ls -l ${CURRENT_DIR}) != *"-> ${PHP_INSTALL_DIR}"* ]] ; then + rm "${CURRENT_DIR}" + ln -s -r "${PHP_INSTALL_DIR}" "${CURRENT_DIR}" + fi + fi + + rm -rf "${PHP_SRC_DIR}" + updaterc "if [[ \"\${PATH}\" != *\"${CURRENT_DIR}\"* ]]; then export PATH=\"${CURRENT_DIR}/bin:\${PATH}\"; fi" + + chown -R "${USERNAME}:php" "${PHP_DIR}" + chmod -R g+r+w "${PHP_DIR}" + find "${PHP_DIR}" -type d -print0 | xargs -n 1 -0 chmod g+s +fi # Clean up rm -rf /var/lib/apt/lists/* diff --git a/test/php/install_additional_php.sh b/test/php/install_additional_php.sh index 590187a76..f22315a61 100644 --- a/test/php/install_additional_php.sh +++ b/test/php/install_additional_php.sh @@ -9,5 +9,7 @@ check "php version 8.1.4 installed as default" php --version | grep 8.1.4 check "php version 8.0.17 installed" ls -l /usr/local/php | grep 8.0.17 check "php version 8.0.3 installed" ls -l /usr/local/php | grep 8.0.3 +check "composer-version" composer --version + # Report result reportResults diff --git a/test/php/install_only_composer.sh b/test/php/install_only_composer.sh new file mode 100644 index 000000000..c940ece01 --- /dev/null +++ b/test/php/install_only_composer.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "composer-version" composer --version + +# Report result +reportResults diff --git a/test/php/install_php_8.sh b/test/php/install_php_8.sh index a510525f6..0b79533a9 100644 --- a/test/php/install_php_8.sh +++ b/test/php/install_php_8.sh @@ -6,6 +6,7 @@ set -e source dev-container-features-test-lib check "php-version-8-is-installed" bash -c "php --version | grep '8.'" +check "composer-version" composer --version # Report result reportResults diff --git a/test/php/install_php_8_2.sh b/test/php/install_php_8_2.sh index 9320268ef..7427229ef 100644 --- a/test/php/install_php_8_2.sh +++ b/test/php/install_php_8_2.sh @@ -6,6 +6,7 @@ set -e source dev-container-features-test-lib check "php-version-8.2-is-installed" bash -c "php --version | grep '8.2'" +check "composer-version" composer --version # Report result reportResults diff --git a/test/php/scenarios.json b/test/php/scenarios.json index dac799875..1e4df063d 100644 --- a/test/php/scenarios.json +++ b/test/php/scenarios.json @@ -23,5 +23,14 @@ "version": "8.2" } } + }, + "install_only_composer": { + "image": "mcr.microsoft.com/devcontainers/php:latest", + "features": { + "php": { + "version": "none", + "installComposer": true + } + } } } diff --git a/test/php/test.sh b/test/php/test.sh index 0f49c1a18..c75f7ea96 100755 --- a/test/php/test.sh +++ b/test/php/test.sh @@ -7,7 +7,7 @@ source dev-container-features-test-lib check "PHP version" php --version check "Mbstring loaded" php -r "extension_loaded('mbstring') || throw new Error('Extension Mbstring is not loaded');" -check "Composer version" composer --version +check "composer-version" composer --version # Report result reportResults \ No newline at end of file From 4a9929f96485061e3778b35848e21d7c3c193480 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 7 Feb 2023 11:45:48 -0800 Subject: [PATCH 090/478] kubectl-helm-minikube: Allow none (#442) --- .../devcontainer-feature.json | 11 +- src/kubectl-helm-minikube/install.sh | 134 +++++++++--------- .../install_only_kubectl.sh | 22 +++ test/kubectl-helm-minikube/scenarios.json | 12 ++ test/kubectl-helm-minikube/test.sh | 1 + 5 files changed, 112 insertions(+), 68 deletions(-) create mode 100644 test/kubectl-helm-minikube/install_only_kubectl.sh create mode 100644 test/kubectl-helm-minikube/scenarios.json diff --git a/src/kubectl-helm-minikube/devcontainer-feature.json b/src/kubectl-helm-minikube/devcontainer-feature.json index 78e90d9b7..9229a96e6 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.3", + "version": "1.1.4", "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.", @@ -12,7 +12,8 @@ "none", "1.23", "1.22", - "1.21" + "1.21", + "none" ], "default": "latest", "description": "Select or enter a Kubernetes version to install" @@ -20,7 +21,8 @@ "helm": { "type": "string", "proposals": [ - "latest" + "latest", + "none" ], "default": "latest", "description": "Select or enter a Helm version to install" @@ -28,7 +30,8 @@ "minikube": { "type": "string", "proposals": [ - "latest" + "latest", + "none" ], "default": "latest", "description": "Select or enter a Minikube version to install" diff --git a/src/kubectl-helm-minikube/install.sh b/src/kubectl-helm-minikube/install.sh index af8b0ae50..d2d11364e 100755 --- a/src/kubectl-helm-minikube/install.sh +++ b/src/kubectl-helm-minikube/install.sh @@ -14,7 +14,7 @@ rm -rf /var/lib/apt/lists/* KUBECTL_VERSION="${VERSION:-"latest"}" HELM_VERSION="${HELM:-"latest"}" -MINIKUBE_VERSION="${MINIKUBE:-"none"}" # latest is also valid +MINIKUBE_VERSION="${MINIKUBE:-"latest"}" # latest is also valid KUBECTL_SHA256="${KUBECTL_SHA256:-"automatic"}" HELM_SHA256="${HELM_SHA256:-"automatic"}" @@ -121,77 +121,83 @@ case $architecture in *) echo "(!) Architecture $architecture unsupported"; exit 1 ;; esac -# Install the kubectl, verify checksum -echo "Downloading kubectl..." -if [ "${KUBECTL_VERSION}" = "latest" ] || [ "${KUBECTL_VERSION}" = "lts" ] || [ "${KUBECTL_VERSION}" = "current" ] || [ "${KUBECTL_VERSION}" = "stable" ]; then - KUBECTL_VERSION="$(curl -sSL https://dl.k8s.io/release/stable.txt)" -else - find_version_from_git_tags KUBECTL_VERSION https://github.com/kubernetes/kubernetes -fi -if [ "${KUBECTL_VERSION::1}" != 'v' ]; then - KUBECTL_VERSION="v${KUBECTL_VERSION}" -fi -curl -sSL -o /usr/local/bin/kubectl "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${architecture}/kubectl" -chmod 0755 /usr/local/bin/kubectl -if [ "$KUBECTL_SHA256" = "automatic" ]; then - KUBECTL_SHA256="$(curl -sSL "https://dl.k8s.io/${KUBECTL_VERSION}/bin/linux/${architecture}/kubectl.sha256")" -fi -([ "${KUBECTL_SHA256}" = "dev-mode" ] || (echo "${KUBECTL_SHA256} */usr/local/bin/kubectl" | sha256sum -c -)) -if ! type kubectl > /dev/null 2>&1; then - echo '(!) kubectl installation failed!' - exit 1 -fi +if [ ${KUBECTL_VERSION} != "none" ]; then + # Install the kubectl, verify checksum + echo "Downloading kubectl..." + if [ "${KUBECTL_VERSION}" = "latest" ] || [ "${KUBECTL_VERSION}" = "lts" ] || [ "${KUBECTL_VERSION}" = "current" ] || [ "${KUBECTL_VERSION}" = "stable" ]; then + KUBECTL_VERSION="$(curl -sSL https://dl.k8s.io/release/stable.txt)" + else + find_version_from_git_tags KUBECTL_VERSION https://github.com/kubernetes/kubernetes + fi + if [ "${KUBECTL_VERSION::1}" != 'v' ]; then + KUBECTL_VERSION="v${KUBECTL_VERSION}" + fi + curl -sSL -o /usr/local/bin/kubectl "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${architecture}/kubectl" + chmod 0755 /usr/local/bin/kubectl + if [ "$KUBECTL_SHA256" = "automatic" ]; then + KUBECTL_SHA256="$(curl -sSL "https://dl.k8s.io/${KUBECTL_VERSION}/bin/linux/${architecture}/kubectl.sha256")" + fi + ([ "${KUBECTL_SHA256}" = "dev-mode" ] || (echo "${KUBECTL_SHA256} */usr/local/bin/kubectl" | sha256sum -c -)) + if ! type kubectl > /dev/null 2>&1; then + echo '(!) kubectl installation failed!' + exit 1 + fi -# kubectl bash completion -kubectl completion bash > /etc/bash_completion.d/kubectl + # kubectl bash completion + kubectl completion bash > /etc/bash_completion.d/kubectl -# kubectl zsh completion -if [ -e "${USERHOME}}/.oh-my-zsh" ]; then - mkdir -p "${USERHOME}/.oh-my-zsh/completions" - kubectl completion zsh > "${USERHOME}/.oh-my-zsh/completions/_kubectl" - chown -R "${USERNAME}" "${USERHOME}/.oh-my-zsh" + # kubectl zsh completion + if [ -e "${USERHOME}}/.oh-my-zsh" ]; then + mkdir -p "${USERHOME}/.oh-my-zsh/completions" + kubectl completion zsh > "${USERHOME}/.oh-my-zsh/completions/_kubectl" + chown -R "${USERNAME}" "${USERHOME}/.oh-my-zsh" + fi fi -# Install Helm, verify signature and checksum -echo "Downloading Helm..." -find_version_from_git_tags HELM_VERSION "https://github.com/helm/helm" -if [ "${HELM_VERSION::1}" != 'v' ]; then - HELM_VERSION="v${HELM_VERSION}" -fi -mkdir -p /tmp/helm -helm_filename="helm-${HELM_VERSION}-linux-${architecture}.tar.gz" -tmp_helm_filename="/tmp/helm/${helm_filename}" -curl -sSL "https://get.helm.sh/${helm_filename}" -o "${tmp_helm_filename}" -curl -sSL "https://github.com/helm/helm/releases/download/${HELM_VERSION}/${helm_filename}.asc" -o "${tmp_helm_filename}.asc" -export GNUPGHOME="/tmp/helm/gnupg" -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 -gpg -q --import "/tmp/helm/KEYS" -if ! gpg --verify "${tmp_helm_filename}.asc" > ${GNUPGHOME}/verify.log 2>&1; then - echo "Verification failed!" - cat /tmp/helm/gnupg/verify.log - exit 1 -fi -if [ "${HELM_SHA256}" = "automatic" ]; then - curl -sSL "https://get.helm.sh/${helm_filename}.sha256" -o "${tmp_helm_filename}.sha256" - curl -sSL "https://github.com/helm/helm/releases/download/${HELM_VERSION}/${helm_filename}.sha256.asc" -o "${tmp_helm_filename}.sha256.asc" - if ! gpg --verify "${tmp_helm_filename}.sha256.asc" > /tmp/helm/gnupg/verify.log 2>&1; then +if [ ${HELM_VERSION} != "none" ]; then + # Install Helm, verify signature and checksum + echo "Downloading Helm..." + find_version_from_git_tags HELM_VERSION "https://github.com/helm/helm" + if [ "${HELM_VERSION::1}" != 'v' ]; then + HELM_VERSION="v${HELM_VERSION}" + fi + mkdir -p /tmp/helm + helm_filename="helm-${HELM_VERSION}-linux-${architecture}.tar.gz" + tmp_helm_filename="/tmp/helm/${helm_filename}" + curl -sSL "https://get.helm.sh/${helm_filename}" -o "${tmp_helm_filename}" + curl -sSL "https://github.com/helm/helm/releases/download/${HELM_VERSION}/${helm_filename}.asc" -o "${tmp_helm_filename}.asc" + export GNUPGHOME="/tmp/helm/gnupg" + 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 + gpg -q --import "/tmp/helm/KEYS" + if ! gpg --verify "${tmp_helm_filename}.asc" > ${GNUPGHOME}/verify.log 2>&1; then echo "Verification failed!" cat /tmp/helm/gnupg/verify.log exit 1 fi - HELM_SHA256="$(cat "${tmp_helm_filename}.sha256")" -fi -([ "${HELM_SHA256}" = "dev-mode" ] || (echo "${HELM_SHA256} *${tmp_helm_filename}" | sha256sum -c -)) -tar xf "${tmp_helm_filename}" -C /tmp/helm -mv -f "/tmp/helm/linux-${architecture}/helm" /usr/local/bin/ -chmod 0755 /usr/local/bin/helm -rm -rf /tmp/helm -if ! type helm > /dev/null 2>&1; then - echo '(!) Helm installation failed!' - exit 1 + + if [ "${HELM_SHA256}" = "automatic" ]; then + curl -sSL "https://get.helm.sh/${helm_filename}.sha256" -o "${tmp_helm_filename}.sha256" + curl -sSL "https://github.com/helm/helm/releases/download/${HELM_VERSION}/${helm_filename}.sha256.asc" -o "${tmp_helm_filename}.sha256.asc" + if ! gpg --verify "${tmp_helm_filename}.sha256.asc" > /tmp/helm/gnupg/verify.log 2>&1; then + echo "Verification failed!" + cat /tmp/helm/gnupg/verify.log + exit 1 + fi + HELM_SHA256="$(cat "${tmp_helm_filename}.sha256")" + fi + + ([ "${HELM_SHA256}" = "dev-mode" ] || (echo "${HELM_SHA256} *${tmp_helm_filename}" | sha256sum -c -)) + tar xf "${tmp_helm_filename}" -C /tmp/helm + mv -f "/tmp/helm/linux-${architecture}/helm" /usr/local/bin/ + chmod 0755 /usr/local/bin/helm + rm -rf /tmp/helm + if ! type helm > /dev/null 2>&1; then + echo '(!) Helm installation failed!' + exit 1 + fi fi # Install Minikube, verify checksum diff --git a/test/kubectl-helm-minikube/install_only_kubectl.sh b/test/kubectl-helm-minikube/install_only_kubectl.sh new file mode 100644 index 000000000..442ef6477 --- /dev/null +++ b/test/kubectl-helm-minikube/install_only_kubectl.sh @@ -0,0 +1,22 @@ +#!/bin/bash +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +set +e + kubectl + exit_code=$? + check "kubectl-is-not-installed" bash -c "echo ${exit_code} | grep 127" + + helm version + exit_code=$? + check "helm-is-not-installed" bash -c "echo ${exit_code} | grep 127" + + minikube version + exit_code=$? + check "minikube is-not-installed" bash -c "echo ${exit_code} | grep 127" +set -e + +# Report result +reportResults diff --git a/test/kubectl-helm-minikube/scenarios.json b/test/kubectl-helm-minikube/scenarios.json new file mode 100644 index 000000000..08ff8cc79 --- /dev/null +++ b/test/kubectl-helm-minikube/scenarios.json @@ -0,0 +1,12 @@ +{ + "install_only_kubectl": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "kubectl-helm-minikube": { + "version": "none", + "helm": "none", + "minikube": "none" + } + } + } +} diff --git a/test/kubectl-helm-minikube/test.sh b/test/kubectl-helm-minikube/test.sh index 94a024abb..9dc41417a 100755 --- a/test/kubectl-helm-minikube/test.sh +++ b/test/kubectl-helm-minikube/test.sh @@ -8,6 +8,7 @@ source dev-container-features-test-lib # Definition specific tests check "kube" kubectl check "helm" helm version +check "minikune" minikube version # Report result reportResults \ No newline at end of file From 900cbfc1f98ca13f99055cf3197e688e21bb0022 Mon Sep 17 00:00:00 2001 From: Stefan Drzazga Date: Wed, 15 Feb 2023 14:59:31 -0500 Subject: [PATCH 091/478] Add sentinel to terraform feature (#452) * Introducing Sentinel installation * Modifying docs for sentinel * Modifying tests for sentinel * Revert "Modifying docs for sentinel" This reverts commit 818894b22fe022d29d59d3748ddd6103616773a6. * Modifying docs for sentinel * Fixing duplication issue for sentinel url * Update src/terraform/install.sh Co-authored-by: Samruddhi Khandale * Increase minor version --------- Co-authored-by: Samruddhi Khandale --- src/terraform/devcontainer-feature.json | 7 +++- src/terraform/install.sh | 51 +++++++++++++++++++++++++ test/terraform/install_sentinel.sh | 15 ++++++++ test/terraform/scenarios.json | 8 ++++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 test/terraform/install_sentinel.sh diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index 99c052be9..bd6f1cc7a 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.1.2", + "version": "1.2.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.", @@ -33,6 +33,11 @@ "default": "latest", "description": "Terragrunt version" }, + "installSentinel": { + "type": "boolean", + "default": false, + "description": "Install sentinel, a language and framework for policy built to be embedded in existing software to enable fine-grained, logic-based policy decisions" + }, "installTFsec": { "type": "boolean", "default": false, diff --git a/src/terraform/install.sh b/src/terraform/install.sh index 1fec7563f..67426cd53 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -15,12 +15,14 @@ rm -rf /var/lib/apt/lists/* TERRAFORM_VERSION="${VERSION:-"latest"}" TFLINT_VERSION="${TFLINT:-"latest"}" TERRAGRUNT_VERSION="${TERRAGRUNT:-"latest"}" +INSTALL_SENTINEL=${INSTALLSENTINEL:-false} INSTALL_TFSEC=${INSTALLTFSEC:-false} INSTALL_TERRAFORM_DOCS=${INSTALLTERRAFORMDOCS:-false} TERRAFORM_SHA256="${TERRAFORM_SHA256:-"automatic"}" TFLINT_SHA256="${TFLINT_SHA256:-"automatic"}" TERRAGRUNT_SHA256="${TERRAGRUNT_SHA256:-"automatic"}" +SENTINEL_SHA256="${SENTINEL_SHA256:-"automatic"}" TFSEC_SHA256="${TFSEC_SHA256:-"automatic"}" TERRAFORM_DOCS_SHA256="${TERRAFORM_DOCS_SHA256:-"automatic"}" @@ -112,6 +114,30 @@ find_version_from_git_tags() { echo "${variable_name}=${!variable_name}" } +find_sentinel_version_from_url() { + local variable_name=$1 + local requested_version=${!variable_name} + if [ "${requested_version}" = "none" ]; then return; fi + local repository=$2 + if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then + local prefix='sentinel_' + local regex="${prefix}\d.\d{2}.\d(?:-\w*)?" + local version_list="$(wget -q $2 -O - | grep -oP ${regex} | tr -d ${prefix} | sort -rV)" + if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then + declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" + else + set +e + declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" + set -e + fi + fi + if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" >/dev/null 2>&1; then + echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 + exit 1 + fi + echo "${variable_name}=${!variable_name}" +} + apt_get_update() { if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then @@ -198,6 +224,31 @@ if [ "${TERRAGRUNT_VERSION}" != "none" ]; then mv -f /tmp/tf-downloads/${terragrunt_filename} /usr/local/bin/terragrunt fi +if [ "${INSTALL_SENTINEL}" = "true" ]; then + SENTINEL_VERSION="latest" + sentinel_releases_url='https://releases.hashicorp.com/sentinel' + find_sentinel_version_from_url SENTINEL_VERSION ${sentinel_releases_url} + sentinel_filename="sentinel_${SENTINEL_VERSION}_linux_${architecture}.zip" + echo "(*) Downloading Sentinel... ${sentinel_filename}" + curl -sSL -o /tmp/tf-downloads/${sentinel_filename} ${sentinel_releases_url}/${SENTINEL_VERSION}/${sentinel_filename} + if [ "${SENTINEL_SHA256}" != "dev-mode" ]; then + if [ "${SENTINEL_SHA256}" = "automatic" ]; then + receive_gpg_keys TERRAFORM_GPG_KEY + curl -sSL -o sentinel_checksums.txt ${sentinel_releases_url}/${SENTINEL_VERSION}/sentinel_${SENTINEL_VERSION}_SHA256SUMS + curl -sSL -o sentinel_checksums.txt.sig ${sentinel_releases_url}/${SENTINEL_VERSION}/sentinel_${SENTINEL_VERSION}_SHA256SUMS.${TERRAFORM_GPG_KEY}.sig + gpg --verify sentinel_checksums.txt.sig sentinel_checksums.txt + # Verify the SHASUM matches the archive + shasum -a 256 --ignore-missing -c sentinel_checksums.txt + else + echo "${SENTINEL_SHA256} *${SENTINEL_FILENAME}" >sentinel_checksums.txt + fi + sha256sum --ignore-missing -c sentinel_checksums.txt + fi + unzip /tmp/tf-downloads/${sentinel_filename} + chmod a+x /tmp/tf-downloads/sentinel + mv -f /tmp/tf-downloads/sentinel /usr/local/bin/sentinel +fi + if [ "${INSTALL_TFSEC}" = "true" ]; then TFSEC_VERSION="latest" find_version_from_git_tags TFSEC_VERSION 'https://github.com/aquasecurity/tfsec' diff --git a/test/terraform/install_sentinel.sh b/test/terraform/install_sentinel.sh new file mode 100644 index 000000000..e26ec33d7 --- /dev/null +++ b/test/terraform/install_sentinel.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Check to make sure the user is vscode +check "user is vscode" whoami | grep vscode + +# Sentinel specific tests +check "sentinel" sentinel --version + +# Report result +reportResults \ No newline at end of file diff --git a/test/terraform/scenarios.json b/test/terraform/scenarios.json index 2365643b6..897763518 100644 --- a/test/terraform/scenarios.json +++ b/test/terraform/scenarios.json @@ -1,4 +1,12 @@ { + "install_sentinel": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "features": { + "terraform": { + "installSentinel": true + } + } + }, "install_tfsec": { "image": "mcr.microsoft.com/devcontainers/base:jammy", "features": { From 8d3685e09f18dd8b0a6bce50abe3e868dac27a69 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 15 Feb 2023 12:01:23 -0800 Subject: [PATCH 092/478] Automated documentation update (#455) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/terraform/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/terraform/README.md b/src/terraform/README.md index ee87d069d..9c474ab5c 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -18,6 +18,7 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la | version | Terraform version | string | latest | | tflint | Tflint version | string | latest | | terragrunt | Terragrunt version | string | latest | +| installSentinel | Install sentinel, a language and framework for policy built to be embedded in existing software to enable fine-grained, logic-based policy decisions | boolean | false | | installTFsec | Install tfsec, a tool to spot potential misconfigurations for your terraform code | boolean | false | | installTerraformDocs | Install terraform-docs, a utility to generate documentation from Terraform modules | boolean | false | From d84e46be47867e596fdd2f2efaefb63f67597a07 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 22 Feb 2023 12:23:22 -0800 Subject: [PATCH 093/478] "Update Documentation" workflow - use gh api to create a documentation PR (#459) --- .github/workflows/update-documentation.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update-documentation.yml b/.github/workflows/update-documentation.yml index 6d7bb5cbb..6976e62ea 100644 --- a/.github/workflows/update-documentation.yml +++ b/.github/workflows/update-documentation.yml @@ -8,6 +8,7 @@ on: jobs: generate: runs-on: ubuntu-latest + environment: documentation if: "github.ref == 'refs/heads/main'" steps: - uses: actions/checkout@v3 @@ -18,10 +19,10 @@ jobs: generate-docs: "true" base-path-to-features: "./src" - - name: Add and Commit Documentation + - 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." @@ -42,5 +43,12 @@ jobs: # Push if [ "$NO_UPDATES" != "true" ] ; then git push origin "$branch" - gh pr create --title "$message" --body "$message" + 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='main' fi From 83c6103db23ce383a23097832bdf15d71f775665 Mon Sep 17 00:00:00 2001 From: Akihiro Nagai <77012577+akihironagai@users.noreply.github.com> Date: Tue, 28 Feb 2023 02:12:21 +0900 Subject: [PATCH 094/478] Add pnpm in Node (#450) * Add pnpm in Node * pnpm from npm * Restore README.md * Update install.sh * Update tests --- src/node/devcontainer-feature.json | 6 +++--- src/node/install.sh | 11 +++++++++++ test/node/install_additional_node.sh | 1 + test/node/install_node_16_on_bionic.sh | 1 + test/node/install_node_on_universal_image.sh | 1 + test/node/non_root_user.sh | 1 + test/node/test.sh | 1 + 7 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index 6450ce422..9bf90b67f 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,9 +1,9 @@ { "id": "node", - "version": "1.1.5", - "name": "Node.js (via nvm) and yarn", + "version": "1.2.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, and needed dependencies.", + "description": "Installs Node.js, nvm, yarn, pnpm, and needed dependencies.", "options": { "version": { "type": "string", diff --git a/src/node/install.sh b/src/node/install.sh index 4c02c9514..9048ac22e 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -183,6 +183,17 @@ if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then IFS=$OLDIFS fi +# Install pnpm +if type pnpm > /dev/null 2>&1; then + echo "pnpm already installed." +else + if type npm > /dev/null 2>&1; then + npm install -g pnpm + else + echo "Skip installing pnpm because npm is missing" + fi +fi + # If enabled, verify "python3", "make", "gcc", "g++" commands are available so node-gyp works - https://github.com/nodejs/node-gyp if [ "${INSTALL_TOOLS_FOR_NODE_GYP}" = "true" ]; then echo "Verifying node-gyp OS requirements..." diff --git a/test/node/install_additional_node.sh b/test/node/install_additional_node.sh index 1a1abca4c..f47f928c0 100644 --- a/test/node/install_additional_node.sh +++ b/test/node/install_additional_node.sh @@ -7,6 +7,7 @@ source dev-container-features-test-lib # 'lts' is some version of node 18 for a while. check "version_on_path" node -v | grep 18 +check "pnpm" pnpm -v check "v18_installed" ls -1 /usr/local/share/nvm/versions/node | grep 18 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 1b301d34c..500e0070e 100755 --- a/test/node/install_node_16_on_bionic.sh +++ b/test/node/install_node_16_on_bionic.sh @@ -7,6 +7,7 @@ source dev-container-features-test-lib # Definition specific tests check "version" bash -c "node --version | grep 16" +check "pnpm" pnpm -v check "nvm" bash -c ". /usr/local/share/nvm/nvm.sh && nvm install 10" # Report result diff --git a/test/node/install_node_on_universal_image.sh b/test/node/install_node_on_universal_image.sh index faca1ebef..33a9d41c3 100644 --- a/test/node/install_node_on_universal_image.sh +++ b/test/node/install_node_on_universal_image.sh @@ -6,6 +6,7 @@ set -e source dev-container-features-test-lib check "version_on_path" bash -c "node -v | grep 'v19.1.0'" +check "pnpm" pnpm -v # Report result reportResults diff --git a/test/node/non_root_user.sh b/test/node/non_root_user.sh index 6b6804d0b..499dbe68a 100755 --- a/test/node/non_root_user.sh +++ b/test/node/non_root_user.sh @@ -7,6 +7,7 @@ source dev-container-features-test-lib # Definition specific tests check "version" node --version +check "pnpm" pnpm -v check "nvm" bash -c ". /usr/local/share/nvm/nvm.sh && nvm install 10" # Report result diff --git a/test/node/test.sh b/test/node/test.sh index 6b6804d0b..499dbe68a 100755 --- a/test/node/test.sh +++ b/test/node/test.sh @@ -7,6 +7,7 @@ source dev-container-features-test-lib # Definition specific tests check "version" node --version +check "pnpm" pnpm -v check "nvm" bash -c ". /usr/local/share/nvm/nvm.sh && nvm install 10" # Report result From 4b7efebea1c19b69a345728bab8cd3f58335c428 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 1 Mar 2023 15:29:11 -0800 Subject: [PATCH 095/478] Turn off linting by default in VS Code for Python (#449) * Turn off linting by default in VS Code for Python Linting is on by default if you specify the paths to any linters, so the previous settings would turn on **all** linters. Also drop linters that don't see much use. * Fix tests * Revert all changes * Remove paths to under-utilized tools and turn off all linting by default * Bump the version number --- src/python/devcontainer-feature.json | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index 361270b2a..c5f0d76f9 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.0.20", + "version": "1.0.21", "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.", @@ -63,13 +63,12 @@ "python.defaultInterpreterPath": "/usr/local/python/current/bin/python", "python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8", "python.formatting.blackPath": "/usr/local/py-utils/bin/black", - "python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf", - "python.linting.banditPath": "/usr/local/py-utils/bin/bandit", "python.linting.flake8Path": "/usr/local/py-utils/bin/flake8", + "python.linting.flake8Enabled": false, "python.linting.mypyPath": "/usr/local/py-utils/bin/mypy", - "python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle", - "python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", - "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint" + "python.linting.mypyEnabled": false, + "python.linting.pylintPath": "/usr/local/py-utils/bin/pylint", + "python.linting.pylintEnabled": false } } }, From 3cc059ea8abf3a909468fafabca481f82b6f8924 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 1 Mar 2023 15:54:58 -0800 Subject: [PATCH 096/478] Automated documentation update (#462) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/node/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node/README.md b/src/node/README.md index 2e5dba386..877ea5877 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -1,7 +1,7 @@ -# Node.js (via nvm) and yarn (node) +# Node.js (via nvm), yarn and pnpm (node) -Installs Node.js, nvm, yarn, and needed dependencies. +Installs Node.js, nvm, yarn, pnpm, and needed dependencies. ## Example Usage From 3e6ee966baed62e195091bb4ea7fb11cd8668868 Mon Sep 17 00:00:00 2001 From: ksaito1125 Date: Tue, 7 Mar 2023 01:51:35 +0900 Subject: [PATCH 097/478] Terraform: Add proxy setting (#435) (#451) * Terraform: Add proxy setting (#435) * Terraform: Remove unused variable GPG_OPTS (#435) * Terraform: Increment minor version (#435) * Update src/terraform/install.sh Co-authored-by: Samruddhi Khandale * Add feature option * Update src/terraform/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * Update src/terraform/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * Update src/terraform/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * Terraform: Change environment variables to upper case (#435) * Terraform: Use HTTP_PROXY as the default for connecting to keyservers (#435) * Update src/terraform/install.sh Co-authored-by: Samruddhi Khandale --------- Co-authored-by: Samruddhi Khandale Co-authored-by: Samruddhi Khandale --- src/terraform/devcontainer-feature.json | 7 ++++++- src/terraform/install.sh | 8 ++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index bd6f1cc7a..7ea73eea9 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.2.0", + "version": "1.3.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.", @@ -47,6 +47,11 @@ "type": "boolean", "default": false, "description": "Install terraform-docs, a utility to generate documentation from Terraform modules" + }, + "httpProxy": { + "type": "string", + "default": "", + "description": "Connect to a keyserver using a proxy by configuring this option" } }, "customizations": { diff --git a/src/terraform/install.sh b/src/terraform/install.sh index 67426cd53..75653c392 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -28,9 +28,10 @@ TERRAFORM_DOCS_SHA256="${TERRAFORM_DOCS_SHA256:-"automatic"}" TERRAFORM_GPG_KEY="72D7468F" TFLINT_GPG_KEY_URI="https://raw.githubusercontent.com/terraform-linters/tflint/master/8CE69160EB3F2FE9.key" -GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com +GPG_KEY_SERVERS="keyserver hkps://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org -keyserver hkp://keyserver.pgp.com" +keyserver hkps://keyserver.pgp.com" +KEYSERVER_PROXY="${HTTPPROXY:-"${HTTP_PROXY:-""}"}" architecture="$(uname -m)" case ${architecture} in @@ -53,6 +54,9 @@ receive_gpg_keys() { if [ ! -z "$2" ]; then keyring_args="--no-default-keyring --keyring $2" fi + if [ ! -z "${KEYSERVER_PROXY}" ]; then + keyring_args="${keyring_args} --keyserver-options http-proxy=${KEYSERVER_PROXY}" + fi # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" From fe449253f138f3c028627d3e9cc3d500d650b159 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 7 Mar 2023 11:43:06 -0800 Subject: [PATCH 098/478] Automated documentation update (#475) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/terraform/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/terraform/README.md b/src/terraform/README.md index 9c474ab5c..e75da9b20 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -21,6 +21,7 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la | installSentinel | Install sentinel, a language and framework for policy built to be embedded in existing software to enable fine-grained, logic-based policy decisions | boolean | false | | installTFsec | Install tfsec, a tool to spot potential misconfigurations for your terraform code | boolean | false | | installTerraformDocs | Install terraform-docs, a utility to generate documentation from Terraform modules | boolean | false | +| httpProxy | Connect to a keyserver using a proxy by configuring this option | string | - | From de1e634a6755e10b27e52ad4e0aa44f025540074 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 8 Mar 2023 15:30:59 -0800 Subject: [PATCH 099/478] Docker fix - BuildKit is enabled but the buildx component is missing or broken (#478) * Docker fix - BuildKit is enabled but the buildx component is missing or broken * nit * fix test --- .../devcontainer-feature.json | 7 +++- src/docker-in-docker/install.sh | 32 +++++++++++------ .../devcontainer-feature.json | 7 +++- src/docker-outside-of-docker/install.sh | 31 ++++++++++++---- test/docker-in-docker/Dockerfile | 1 + test/docker-in-docker/docker_build.sh | 13 +++++++ test/docker-in-docker/docker_build_2.sh | 13 +++++++ test/docker-in-docker/docker_build_older.sh | 13 +++++++ test/docker-in-docker/scenarios.json | 35 ++++++++++++++++++- test/docker-outside-of-docker/Dockerfile | 1 + test/docker-outside-of-docker/docker_build.sh | 13 +++++++ .../docker_build_2.sh | 13 +++++++ .../docker_build_older.sh | 13 +++++++ test/docker-outside-of-docker/scenarios.json | 33 +++++++++++++++++ 14 files changed, 206 insertions(+), 19 deletions(-) create mode 100644 test/docker-in-docker/Dockerfile create mode 100644 test/docker-in-docker/docker_build.sh create mode 100644 test/docker-in-docker/docker_build_2.sh create mode 100644 test/docker-in-docker/docker_build_older.sh create mode 100644 test/docker-outside-of-docker/Dockerfile create mode 100644 test/docker-outside-of-docker/docker_build.sh create mode 100644 test/docker-outside-of-docker/docker_build_2.sh create mode 100644 test/docker-outside-of-docker/docker_build_older.sh diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 58c2d1400..798b8e87a 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.0.1", + "version": "2.1.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.", @@ -39,6 +39,11 @@ "default": "", "proposals": [], "description": "Define default address pools for Docker networks. e.g. base=192.168.0.0/16,size=24" + }, + "installDockerBuildx": { + "type": "boolean", + "default": true, + "description": "Install Docker Buildx" } }, "entrypoint": "/usr/local/share/docker-init.sh", diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index dff11393f..770519902 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -13,10 +13,8 @@ USE_MOBY="${MOBY:-"true"}" DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2 AZURE_DNS_AUTO_DETECTION="${AZUREDNSAUTODETECTION:-"true"}" DOCKER_DEFAULT_ADDRESS_POOL="${DOCKERDEFAULTADDRESSPOOL}" - -ENABLE_NONROOT_DOCKER="${ENABLE_NONROOT_DOCKER:-"true"}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" - +INSTALL_DOCKER_BUILDX="${INSTALLDOCKERBUILDX:-"true"}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="buster bullseye bionic focal jammy" DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES="buster bullseye bionic focal hirsute impish jammy" @@ -158,7 +156,7 @@ else fi # Install dependencies -check_packages apt-transport-https curl ca-certificates pigz iptables gnupg2 dirmngr +check_packages apt-transport-https curl ca-certificates pigz iptables gnupg2 dirmngr wget if ! type git > /dev/null 2>&1; then check_packages git fi @@ -307,13 +305,27 @@ if [ -f "/usr/local/share/docker-init.sh" ]; then fi echo "docker-init doesn't exist, adding..." -# Add user to the docker group -if [ "${ENABLE_NONROOT_DOCKER}" = "true" ]; then - if ! getent group docker > /dev/null 2>&1; then - groupadd docker - fi +if ! cat /etc/group | grep -e "^docker:" > /dev/null 2>&1; then + groupadd -r docker +fi + +usermod -aG docker ${USERNAME} + +if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then + buildx_version="latest" + find_version_from_git_tags buildx_version "https://github.com/docker/buildx" "refs/tags/v" + + echo "(*) Installing buildx ${buildx_version}..." + buildx_file_name="buildx-v${buildx_version}.linux-${architecture}" + cd /tmp && wget "https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name}" + + mkdir -p ${_REMOTE_USER_HOME}/.docker/cli-plugins + mv ${buildx_file_name} ${_REMOTE_USER_HOME}/.docker/cli-plugins/docker-buildx + chmod +x ${_REMOTE_USER_HOME}/.docker/cli-plugins/docker-buildx - usermod -aG docker ${USERNAME} + chown -R "${USERNAME}:docker" "${_REMOTE_USER_HOME}/.docker" + chmod -R g+r+w "${_REMOTE_USER_HOME}/.docker" + find "${_REMOTE_USER_HOME}/.docker" -type d -print0 | xargs -n 1 -0 chmod g+s fi tee /usr/local/share/docker-init.sh > /dev/null \ diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index 1f3ff4e9a..79bc9febc 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.0.10", + "version": "1.1.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.", @@ -28,6 +28,11 @@ ], "default": "v1", "description": "Compose version to use for docker-compose (v1 or v2)" + }, + "installDockerBuildx": { + "type": "boolean", + "default": true, + "description": "Install Docker Buildx" } }, "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 dc5a9034b..63524101b 100755 --- a/src/docker-outside-of-docker/install.sh +++ b/src/docker-outside-of-docker/install.sh @@ -15,6 +15,7 @@ ENABLE_NONROOT_DOCKER="${ENABLE_NONROOT_DOCKER:-"true"}" 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"}" MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="buster bullseye bionic focal jammy" @@ -116,7 +117,7 @@ find_version_from_git_tags() { export DEBIAN_FRONTEND=noninteractive # Install dependencies -check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr +check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr wget if ! type git > /dev/null 2>&1; then check_packages git fi @@ -254,6 +255,29 @@ else update-alternatives --set docker-compose /usr/local/bin/compose-switch fi +# Setup a docker group in the event the docker socket's group is not root +if ! grep -qE '^docker:' /etc/group; then + groupadd --system docker +fi +usermod -aG docker "${USERNAME}" + +if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then + buildx_version="latest" + find_version_from_git_tags buildx_version "https://github.com/docker/buildx" "refs/tags/v" + + echo "(*) Installing buildx ${buildx_version}..." + buildx_file_name="buildx-v${buildx_version}.linux-${architecture}" + cd /tmp && wget "https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name}" + + mkdir -p ${_REMOTE_USER_HOME}/.docker/cli-plugins + mv ${buildx_file_name} ${_REMOTE_USER_HOME}/.docker/cli-plugins/docker-buildx + chmod +x ${_REMOTE_USER_HOME}/.docker/cli-plugins/docker-buildx + + chown -R "${USERNAME}:docker" "${_REMOTE_USER_HOME}/.docker" + chmod -R g+r+w "${_REMOTE_USER_HOME}/.docker" + find "${_REMOTE_USER_HOME}/.docker" -type d -print0 | xargs -n 1 -0 chmod g+s +fi + # If init file already exists, exit if [ -f "/usr/local/share/docker-init.sh" ]; then # Clean up @@ -277,11 +301,6 @@ if [ "${ENABLE_NONROOT_DOCKER}" = "false" ] || [ "${USERNAME}" = "root" ]; then exit 0 fi -# Setup a docker group in the event the docker socket's group is not root -if ! grep -qE '^docker:' /etc/group; then - groupadd --system docker -fi -usermod -aG docker "${USERNAME}" DOCKER_GID="$(grep -oP '^docker:x:\K[^:]+' /etc/group)" # If enabling non-root access and specified user is found, setup socat and add script diff --git a/test/docker-in-docker/Dockerfile b/test/docker-in-docker/Dockerfile new file mode 100644 index 000000000..9cc9f1a39 --- /dev/null +++ b/test/docker-in-docker/Dockerfile @@ -0,0 +1 @@ +FROM ubuntu:focal diff --git a/test/docker-in-docker/docker_build.sh b/test/docker-in-docker/docker_build.sh new file mode 100644 index 000000000..742b222fb --- /dev/null +++ b/test/docker-in-docker/docker_build.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker-buildx" docker buildx version +check "docker-build" docker build ./ + +# Report result +reportResults diff --git a/test/docker-in-docker/docker_build_2.sh b/test/docker-in-docker/docker_build_2.sh new file mode 100644 index 000000000..742b222fb --- /dev/null +++ b/test/docker-in-docker/docker_build_2.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker-buildx" docker buildx version +check "docker-build" docker build ./ + +# Report result +reportResults diff --git a/test/docker-in-docker/docker_build_older.sh b/test/docker-in-docker/docker_build_older.sh new file mode 100644 index 000000000..742b222fb --- /dev/null +++ b/test/docker-in-docker/docker_build_older.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker-buildx" docker buildx version +check "docker-build" docker build ./ + +# Report result +reportResults diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index d37053ae5..5123d0916 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -25,5 +25,38 @@ "azureDnsAutoDetection": false } } + }, + "docker_build": { + "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "features": { + "docker-in-docker": { + "version": "latest", + "moby": "false", + "dockerDashComposeVersion": "v2" + } + }, + "remoteUser": "node" + }, + "docker_build_2": { + "image": "ubuntu:focal", + "features": { + "docker-in-docker": { + "version": "latest", + "installDockerBuildx": true, + "moby": "false", + "dockerDashComposeVersion": "v2" + } + } + }, + "docker_build_older": { + "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "features": { + "docker-in-docker": { + "version": "20", + "moby": "false", + "dockerDashComposeVersion": "v2" + } + }, + "remoteUser": "node" } -} \ No newline at end of file +} diff --git a/test/docker-outside-of-docker/Dockerfile b/test/docker-outside-of-docker/Dockerfile new file mode 100644 index 000000000..61217d945 --- /dev/null +++ b/test/docker-outside-of-docker/Dockerfile @@ -0,0 +1 @@ +FROM ubuntu:jammy diff --git a/test/docker-outside-of-docker/docker_build.sh b/test/docker-outside-of-docker/docker_build.sh new file mode 100644 index 000000000..742b222fb --- /dev/null +++ b/test/docker-outside-of-docker/docker_build.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker-buildx" docker buildx version +check "docker-build" docker build ./ + +# Report result +reportResults diff --git a/test/docker-outside-of-docker/docker_build_2.sh b/test/docker-outside-of-docker/docker_build_2.sh new file mode 100644 index 000000000..742b222fb --- /dev/null +++ b/test/docker-outside-of-docker/docker_build_2.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker-buildx" docker buildx version +check "docker-build" docker build ./ + +# Report result +reportResults diff --git a/test/docker-outside-of-docker/docker_build_older.sh b/test/docker-outside-of-docker/docker_build_older.sh new file mode 100644 index 000000000..742b222fb --- /dev/null +++ b/test/docker-outside-of-docker/docker_build_older.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker-buildx" docker buildx version +check "docker-build" docker build ./ + +# Report result +reportResults diff --git a/test/docker-outside-of-docker/scenarios.json b/test/docker-outside-of-docker/scenarios.json index 804b52242..ad9b07248 100644 --- a/test/docker-outside-of-docker/scenarios.json +++ b/test/docker-outside-of-docker/scenarios.json @@ -7,5 +7,38 @@ "version": "latest" } } + }, + "docker_build": { + "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "features": { + "docker-outside-of-docker": { + "version": "latest", + "installDockerBuildx": true, + "moby": "false", + "dockerDashComposeVersion": "v2" + } + }, + "remoteUser": "node" + }, + "docker_build_2": { + "image": "ubuntu:focal", + "features": { + "docker-outside-of-docker": { + "version": "latest", + "moby": "false", + "dockerDashComposeVersion": "v2" + } + } + }, + "docker_build_older": { + "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "features": { + "docker-outside-of-docker": { + "version": "20", + "moby": "false", + "dockerDashComposeVersion": "v2" + } + }, + "remoteUser": "node" } } From 5d6f1ae9b93ca3e2ddb9c71c642e4e9204426e3c Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 8 Mar 2023 15:40:30 -0800 Subject: [PATCH 100/478] Automated documentation update (#479) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/docker-in-docker/README.md | 1 + src/docker-outside-of-docker/README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/src/docker-in-docker/README.md b/src/docker-in-docker/README.md index d74639bb1..9a22c2c4e 100644 --- a/src/docker-in-docker/README.md +++ b/src/docker-in-docker/README.md @@ -20,6 +20,7 @@ Create child containers *inside* a container, independent from the host's docker | dockerDashComposeVersion | Default version of Docker Compose (v1 or v2) | string | v1 | | azureDnsAutoDetection | Allow automatically setting the dockerd DNS server when the installation script detects it is running in Azure | boolean | true | | 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 | ## Limitations diff --git a/src/docker-outside-of-docker/README.md b/src/docker-outside-of-docker/README.md index 74011a06d..793d5d0ba 100644 --- a/src/docker-outside-of-docker/README.md +++ b/src/docker-outside-of-docker/README.md @@ -20,6 +20,7 @@ Re-use the host docker socket, adding the Docker CLI to a container. Feature inv | version | Select or enter a Docker/Moby CLI version. (Availability can vary by OS version.) | string | latest | | moby | Install OSS Moby build instead of Docker CE | boolean | true | | dockerDashComposeVersion | Compose version to use for docker-compose (v1 or v2) | string | v1 | +| installDockerBuildx | Install Docker Buildx | boolean | true | ## Limitations From adf7240a7cfbaecfb84597359843212a870f6682 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Fri, 10 Mar 2023 08:50:32 -0800 Subject: [PATCH 101/478] oryx-supported-platforms (#482) --- src/oryx/NOTES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oryx/NOTES.md b/src/oryx/NOTES.md index 19fe92f31..ec69ec059 100644 --- a/src/oryx/NOTES.md +++ b/src/oryx/NOTES.md @@ -2,6 +2,6 @@ ## OS Support -This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. +See [supportedPlatformVersions.md](https://github.com/microsoft/Oryx/blob/main/doc/supportedPlatformVersions.md) on the Oryx repository for supported platforms. Notably, `oryx` does not support Debian "jammy". `bash` is required to execute the `install.sh` script. From 1449f416a0d5c65fbd7e7bfac041eb43f1ecd98d Mon Sep 17 00:00:00 2001 From: Eljo George Date: Fri, 10 Mar 2023 12:27:28 -0800 Subject: [PATCH 102/478] Remove duplicate env var sourcing for codespaces (#481) * Remove duplicate env var sourcing for codespaces --- src/sshd/devcontainer-feature.json | 2 +- src/sshd/install.sh | 39 ------------------------------ 2 files changed, 1 insertion(+), 40 deletions(-) diff --git a/src/sshd/devcontainer-feature.json b/src/sshd/devcontainer-feature.json index da1f8a9d8..a5d464f69 100644 --- a/src/sshd/devcontainer-feature.json +++ b/src/sshd/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "sshd", - "version": "1.0.8", + "version": "1.0.9", "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.", diff --git a/src/sshd/install.sh b/src/sshd/install.sh index 634f16301..146040896 100755 --- a/src/sshd/install.sh +++ b/src/sshd/install.sh @@ -13,7 +13,6 @@ SSHD_PORT="${SSHD_PORT:-"2222"}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" START_SSHD="${START_SSHD:-"false"}" NEW_PASSWORD="${NEW_PASSWORD:-"skip"}" -FIX_ENVIRONMENT="${FIX_ENVIRONMENT:-"true"}" set -e @@ -93,35 +92,6 @@ sed -i -E "s/#*\s*Port\s+.+/Port ${SSHD_PORT}/g" /etc/ssh/sshd_config # Need to UsePAM so /etc/environment is processed sed -i -E "s/#?\s*UsePAM\s+.+/UsePAM yes/g" /etc/ssh/sshd_config -# Script to store variables that exist at the time the ENTRYPOINT is fired -store_env_script="$(cat << 'EOF' -# Wire in codespaces secret processing to zsh if present (since may have been added to image after script was run) -if [ -f /etc/zsh/zlogin ] && ! grep '/etc/profile.d/00-restore-secrets.sh' /etc/zsh/zlogin > /dev/null 2>&1; then - echo -e "if [ -f /etc/profile.d/00-restore-secrets.sh ]; then . /etc/profile.d/00-restore-secrets.sh; fi\n$(cat /etc/zsh/zlogin 2>/dev/null || echo '')" | sudoIf tee /etc/zsh/zlogin > /dev/null -fi -EOF -)" - -# Script to ensure login shells get the latest Codespaces secrets -restore_secrets_script="$(cat << 'EOF' -#!/bin/sh -if [ "${CODESPACES}" != "true" ] || [ "${VSCDC_FIXED_SECRETS}" = "true" ] || [ ! -z "${GITHUB_CODESPACES_TOKEN}" ]; then - # Not codespaces, already run, or secrets already in environment, so return - return -fi -if [ -f /workspaces/.codespaces/shared/.env-secrets ]; then - while read line - do - key=$(echo $line | sed "s/=.*//") - value=$(echo $line | sed "s/$key=//1") - decodedValue=$(echo $value | base64 -d) - export $key="$decodedValue" - done < /workspaces/.codespaces/shared/.env-secrets -fi -export VSCDC_FIXED_SECRETS=true -EOF -)" - # Write out a scripts that can be referenced as an ENTRYPOINT to auto-start sshd and fix login environments tee /usr/local/share/ssh-init.sh > /dev/null \ << 'EOF' @@ -141,15 +111,6 @@ sudoIf() } EOF -if [ "${FIX_ENVIRONMENT}" = "true" ]; then - echo "${store_env_script}" >> /usr/local/share/ssh-init.sh - echo "${restore_secrets_script}" > /etc/profile.d/00-restore-secrets.sh - chmod +x /etc/profile.d/00-restore-secrets.sh - # Wire in zsh if present - if type zsh > /dev/null 2>&1; then - echo -e "if [ -f /etc/profile.d/00-restore-secrets.sh ]; then . /etc/profile.d/00-restore-secrets.sh; fi\n$(cat /etc/zsh/zlogin 2>/dev/null || echo '')" > /etc/zsh/zlogin - fi -fi tee -a /usr/local/share/ssh-init.sh > /dev/null \ << 'EOF' From d4c3fefc4a792193428d9ae91125696c5ac2fa2f Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Tue, 14 Mar 2023 11:23:28 -0400 Subject: [PATCH 103/478] Add pytest to Python Feature (#487) * Update install.sh * Update install_additional_python.sh * Update install_os_provided_python.sh * Update install_via_oryx.sh * Update test.sh * Update devcontainer-feature.json --- src/python/devcontainer-feature.json | 2 +- src/python/install.sh | 2 +- test/python/install_additional_python.sh | 2 ++ test/python/install_os_provided_python.sh | 4 +++- test/python/install_via_oryx.sh | 4 +++- test/python/test.sh | 2 ++ 6 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index c5f0d76f9..a954c3511 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.0.21", + "version": "1.0.22", "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 3f6b4d9ac..053a72aff 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -26,7 +26,7 @@ CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN="${CONFIGUREJUPYTERLABALLOWORIGIN:-""}" # alongside PYTHON_VERSION, but not set as default. ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" -DEFAULT_UTILS=("pylint" "flake8" "autopep8" "black" "yapf" "mypy" "pydocstyle" "pycodestyle" "bandit" "pipenv" "virtualenv") +DEFAULT_UTILS=("pylint" "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" GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org diff --git a/test/python/install_additional_python.sh b/test/python/install_additional_python.sh index caf2a19d1..d584f4be9 100755 --- a/test/python/install_additional_python.sh +++ b/test/python/install_additional_python.sh @@ -21,6 +21,7 @@ check "mypy" mypy --version check "pycodestyle" pycodestyle --version check "pydocstyle" pydocstyle --version check "pylint" pylint --version +check "pytest" pytest --version # Check paths in settings check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python" @@ -34,6 +35,7 @@ check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy" check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle" check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle" check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint" +check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest" # Report result reportResults diff --git a/test/python/install_os_provided_python.sh b/test/python/install_os_provided_python.sh index 3eb014ccb..e39b51412 100755 --- a/test/python/install_os_provided_python.sh +++ b/test/python/install_os_provided_python.sh @@ -20,6 +20,7 @@ check "mypy" mypy --version check "pycodestyle" pycodestyle --version check "pydocstyle" pydocstyle --version check "pylint" pylint --version +check "pytest" pytest --version # Check paths in settings check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python" @@ -33,6 +34,7 @@ check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy" check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle" check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle" check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint" +check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest" # Report result -reportResults \ No newline at end of file +reportResults diff --git a/test/python/install_via_oryx.sh b/test/python/install_via_oryx.sh index 3eb014ccb..e39b51412 100755 --- a/test/python/install_via_oryx.sh +++ b/test/python/install_via_oryx.sh @@ -20,6 +20,7 @@ check "mypy" mypy --version check "pycodestyle" pycodestyle --version check "pydocstyle" pydocstyle --version check "pylint" pylint --version +check "pytest" pytest --version # Check paths in settings check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python" @@ -33,6 +34,7 @@ check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy" check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle" check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle" check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint" +check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest" # Report result -reportResults \ No newline at end of file +reportResults diff --git a/test/python/test.sh b/test/python/test.sh index 832763d9d..038826d5c 100755 --- a/test/python/test.sh +++ b/test/python/test.sh @@ -20,6 +20,7 @@ check "mypy" mypy --version check "pycodestyle" pycodestyle --version check "pydocstyle" pydocstyle --version check "pylint" pylint --version +check "pytest" pytest --version # Check paths in settings check "current symlink is correct" bash -c "which python | grep /usr/local/python/current/bin/python" @@ -33,6 +34,7 @@ check "which mypy" bash -c "which mypy | grep /usr/local/py-utils/bin/mypy" check "which pycodestyle" bash -c "which pycodestyle | grep /usr/local/py-utils/bin/pycodestyle" check "which pydocstyle" bash -c "which pydocstyle | grep /usr/local/py-utils/bin/pydocstyle" check "which pylint" bash -c "which pylint | grep /usr/local/py-utils/bin/pylint" +check "which pytest" bash -c "which pytest | grep /usr/local/py-utils/bin/pytest" # Report result reportResults From e7e4aa8a98cb4eac856d40ea6bf733aa16f33c92 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 14 Mar 2023 09:17:38 -0700 Subject: [PATCH 104/478] Automated documentation update (#490) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/oryx/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oryx/README.md b/src/oryx/README.md index 7d3d3d11a..7f9e62269 100644 --- a/src/oryx/README.md +++ b/src/oryx/README.md @@ -17,7 +17,7 @@ Installs the oryx CLI ## OS Support -This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed. +See [supportedPlatformVersions.md](https://github.com/microsoft/Oryx/blob/main/doc/supportedPlatformVersions.md) on the Oryx repository for supported platforms. Notably, `oryx` does not support Debian "jammy". `bash` is required to execute the `install.sh` script. From 0e079baaf7c67c7df9521d1dd5059a293702c5d5 Mon Sep 17 00:00:00 2001 From: Jacob Hummer Date: Thu, 23 Mar 2023 18:07:08 -0500 Subject: [PATCH 105/478] Add contributing document (#488) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Create CONTRIBUTING.md * Direct questions to slack channel Co-authored-by: Brigit Murtaugh * Use "dev containers" and "Features" Apparently devcontainers is two words, and apparently features is a proper noun? I guess ๐Ÿคทโ€โ™‚๏ธ * Prettier formatting I used https://prettier.io/playground/ since I was editing in the GitHub web editor * Clarify to "only accept improvements and bug fixes" Co-authored-by: Samruddhi Khandale * Be more explicit about custom features Co-authored-by: Samruddhi Khandale * Add link to CLI test docs * Add semver step in guide * More specificity in link text https://github.com/devcontainers/features/pull/488#discussion_r1137819187 * Add CONTRIBUTING.md link in readme --------- Co-authored-by: Brigit Murtaugh Co-authored-by: Samruddhi Khandale --- CONTRIBUTING.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 4 ++++ 2 files changed, 64 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..f6c7e3ab0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,60 @@ +**Thanks for taking the time to contribute! โค๏ธ** + +All types of contributions are encouraged and valued, no matter if it's a bug +report ๐Ÿ›, a feature request ๐Ÿ’ก, or a Pull Request ๐Ÿš€. + +- **โ“ I have a question:** Ask in [our dev container community Slack channel] +- **๐Ÿ› I found a bug:** [Open an Issue] +- **๐Ÿ’ก I have an idea:** [Open an Issue] +- **๐Ÿ’ป I want to code:** See below + +If you like the project, but just don't have time to contribute, that's OK too! +You can also star the project โญ, rave about it online ๐Ÿ’ฌ, or add a link to us +๐Ÿ”— in your project's readme. + +โš ๏ธ You must never report security ๐Ÿ”’ related issues, vulnerabilities or bugs +including sensitive information to the issue tracker, or elsewhere in public. +Instead, please [report them to the Microsoft Security Response Center]. You can +read more about our security policy in [`SECURITY.md`]. + +## Contributing code + +๐Ÿ‘จโ€๐Ÿ’ผ This repository is a collection of dev container Features managed by dev +container spec maintainers. This repository will **only accept improvements and +bug fixes** for the [current set of maintained Features]. + +๐Ÿš€ If you're looking to create a new Feature, then we encourage adding it to a +separate repository of your control. The [devcontainers/feature-starter] +repository has more guidance on self authoring Features. + +๐Ÿ’ก Once you've self authored the Features and if you'd like to share them with +the community, then we'd recommend [adding it to the index]. + +๐Ÿ‘ทโ€ If you've identified an issue and you want to fix it, here's how you can get +started: + +1. ๐Ÿ”€ Fork the repo +2. ๐Ÿ’ป Open the repo in your editor +3. ๐Ÿ‘จโ€๐Ÿ’ป Add your changes to your workspace +4. โœจ [Test your changes using `devcontainer features test`] to make sure + everything still works +5. ๐Ÿ†š Bump the version of the feature you changed according to [semver] +6. ๐Ÿ”– Commit & push your changes +7. ๐Ÿ” Open a PR to get your changes merged +8. ๐Ÿš€ Profit! + +๐Ÿ‘ฉโ€โš–๏ธ When contributing code to this project, you may be asked to agree to our +[Contributor License Agreement]. + + +[our dev container community Slack channel]: https://aka.ms/devcontainer_community +[open an issue]: https://github.com/devcontainers/features/issues/new +[current set of maintained Features]: https://github.com/devcontainers/features/tree/main/src +[devcontainers/feature-starter]: https://github.com/devcontainers/feature-starter#readme +[adding it to the index]: https://github.com/devcontainers/feature-starter#adding-features-to-the-index +[report them to the Microsoft Security Response Center]: https://msrc.microsoft.com/create-report +[`SECURITY.md`]: https://github.com/devcontainers/spec/blob/main/SECURITY.md +[contributor license agreement]: https://opensource.microsoft.com/cla/ +[Test your changes using `devcontainer features test`]: https://github.com/devcontainers/cli/blob/main/docs/features/test.md +[semver]: https://semver.org/ + diff --git a/README.md b/README.md index b887c00d9..bfe35baaa 100644 --- a/README.md +++ b/README.md @@ -109,3 +109,7 @@ We are eager to hear your feedback on self-authoring! Please provide comments a This repository will accept improvement and bug fix contributions related to the [current set of maintained Features](./src). + +๐Ÿค You can read more about how to contribute in [`CONTRIBUTING.md`]. โค๏ธ + +[`CONTRIBUTING.md`]: CONTRIBUTING.md From 1118b992d970b53d92b3379a5b05de7738f3dc8b Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 28 Mar 2023 16:05:17 -0700 Subject: [PATCH 106/478] Ruby: Fix failures - omit "ruby-debug-ide" (#505) * Ruby: Fix failures on debian image due to ruby-debug-ide * omit --- src/ruby/devcontainer-feature.json | 2 +- src/ruby/install.sh | 3 ++- test/ruby/install_additional_ruby.sh | 1 + test/ruby/ruby_debian.sh | 12 ++++++++++++ test/ruby/scenarios.json | 6 ++++++ 5 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 test/ruby/ruby_debian.sh diff --git a/src/ruby/devcontainer-feature.json b/src/ruby/devcontainer-feature.json index 8d2a4e31f..e9fafeefd 100644 --- a/src/ruby/devcontainer-feature.json +++ b/src/ruby/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby", - "version": "1.0.9", + "version": "1.0.10", "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 daae7faa1..087108520 100755 --- a/src/ruby/install.sh +++ b/src/ruby/install.sh @@ -19,7 +19,8 @@ ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}" # Note: ruby-debug-ide will install the right version of debase if missing and # installing debase directly fails on Ruby 3.1.0 as of 1/7/2022, so omitting. -DEFAULT_GEMS="rake ruby-debug-ide" +# installing ruby-debug-ide on debian fails, so omitting. +DEFAULT_GEMS="rake" RVM_GPG_KEYS="409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB" GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com diff --git a/test/ruby/install_additional_ruby.sh b/test/ruby/install_additional_ruby.sh index e5a651c5b..4fa844475 100644 --- a/test/ruby/install_additional_ruby.sh +++ b/test/ruby/install_additional_ruby.sh @@ -10,6 +10,7 @@ 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 "rbenv" bash -c 'eval "$(rbenv init -)" && rbenv --version' +check "rake" bash -c "gem list | grep rake" # Report result reportResults diff --git a/test/ruby/ruby_debian.sh b/test/ruby/ruby_debian.sh new file mode 100644 index 000000000..bc5e6554d --- /dev/null +++ b/test/ruby/ruby_debian.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "ruby" ruby -v +check "rake" bash -c "gem list | grep rake" + +# Report result +reportResults diff --git a/test/ruby/scenarios.json b/test/ruby/scenarios.json index 9f88d9e45..04cac73f5 100644 --- a/test/ruby/scenarios.json +++ b/test/ruby/scenarios.json @@ -7,5 +7,11 @@ "additionalVersions": "2.5,3.0.4" } } + }, + "ruby_debian": { + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ruby": {} + } } } \ No newline at end of file From 2952d87f1db5681330db025e17ab4357a1bdc275 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Tue, 4 Apr 2023 06:47:04 -0700 Subject: [PATCH 107/478] add a postCreateCommand to `git-lfs` Feature (#511) * add a postCreateCommand to git-lfs Feature * debug passing locally but not in CI * update scenario * add GIT_LFS_SKIP_SMUDGE=1 to prevent fetching lfs arifacts in github actions * arguments should be booleans * move example repo to devcontainers org * place script literally anywhere other than /tmp --- src/git-lfs/devcontainer-feature.json | 8 ++++++- src/git-lfs/install.sh | 32 +++++++++++++++++++++++++++ test/git-lfs/autoPullDisabled.sh | 11 +++++++++ test/git-lfs/autoPullEnabled.sh | 11 +++++++++ test/git-lfs/scenarios.json | 22 ++++++++++++++++++ 5 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 test/git-lfs/autoPullDisabled.sh create mode 100644 test/git-lfs/autoPullEnabled.sh create mode 100644 test/git-lfs/scenarios.json diff --git a/src/git-lfs/devcontainer-feature.json b/src/git-lfs/devcontainer-feature.json index 021746997..dc61dead9 100644 --- a/src/git-lfs/devcontainer-feature.json +++ b/src/git-lfs/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "git-lfs", - "version": "1.0.7", + "version": "1.1.0", "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.", @@ -13,8 +13,14 @@ ], "default": "latest", "description": "Select version of Git LFS to install" + }, + "autoPull": { + "type": "boolean", + "default": true, + "description": "Automatically pull LFS files when creating the container. When false, running 'git lfs pull' in the container will have the same effect." } }, + "postCreateCommand": "/usr/local/share/pull-git-lfs-artifacts.sh", "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] diff --git a/src/git-lfs/install.sh b/src/git-lfs/install.sh index d6f914f81..393109995 100755 --- a/src/git-lfs/install.sh +++ b/src/git-lfs/install.sh @@ -8,6 +8,7 @@ # Maintainer: The VS Code and Codespaces Teams GIT_LFS_VERSION=${VERSION:-"latest"} +AUTO_PULL=${AUTOPULL:="true"} GIT_LFS_ARCHIVE_GPG_KEY_URI="https://packagecloud.io/github/git-lfs/gpgkey" GIT_LFS_ARCHIVE_ARCHITECTURES="amd64 arm64" @@ -185,6 +186,37 @@ if [ "${use_github}" = "true" ]; then install_using_github fi +# --- Generate a 'pull-git-lfs-artifacts.sh' script to be executed by the 'postCreateCommand' lifecycle hook +PULL_GIT_LFS_SCRIPT_PATH="/usr/local/share/pull-git-lfs-artifacts.sh" + +tee "$PULL_GIT_LFS_SCRIPT_PATH" > /dev/null \ +<< EOF +#!/bin/sh +set -e +AUTO_PULL=${AUTO_PULL} +EOF + +tee -a "$PULL_GIT_LFS_SCRIPT_PATH" > /dev/null \ +<< 'EOF' + +echo "Fetching git lfs artifacts..." + +if [ "${AUTO_PULL}" != "true" ]; then + echo "(!) Skipping 'git lfs pull' because 'autoPull' is not set to 'true'" + exit 0 +fi + +# Check if repo is a git lfs repo. +if ! git lfs ls-files > /dev/null 2>&1; then + echo "(!) Skipping automatic 'git lfs pull' because no git lfs files were detected" + exit 0 +fi + +git lfs pull +EOF + +chmod 755 "$PULL_GIT_LFS_SCRIPT_PATH" + # Clean up rm -rf /var/lib/apt/lists/* diff --git a/test/git-lfs/autoPullDisabled.sh b/test/git-lfs/autoPullDisabled.sh new file mode 100644 index 000000000..787781c9c --- /dev/null +++ b/test/git-lfs/autoPullDisabled.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "target file exists" cat big-file-1.txt +check "lfs file has not been expanded" cat "big-file-1.txt" | grep "git-lfs\.github\.com" + +reportResults \ No newline at end of file diff --git a/test/git-lfs/autoPullEnabled.sh b/test/git-lfs/autoPullEnabled.sh new file mode 100644 index 000000000..8cdce3f91 --- /dev/null +++ b/test/git-lfs/autoPullEnabled.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "target file exists" cat big-file-1.txt +check "lfs file has been expanded" cat "big-file-1.txt" | grep "this is test file 1" + +reportResults \ No newline at end of file diff --git a/test/git-lfs/scenarios.json b/test/git-lfs/scenarios.json new file mode 100644 index 000000000..6cc3c24a5 --- /dev/null +++ b/test/git-lfs/scenarios.json @@ -0,0 +1,22 @@ +{ + "autoPullEnabled": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "initializeCommand": "(GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/devcontainers/git-lfs-example /tmp/testRepo-1 || true) && (cp -r /tmp/testRepo-1/.git* . && cp -r /tmp/testRepo-1/* .)", + "remoteUser": "vscode", + "features": { + "git-lfs": { + "autoPull": true + } + } + }, + "autoPullDisabled": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "initializeCommand": "(GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/devcontainers/git-lfs-example /tmp/testRepo-2 || true) && (cp -r /tmp/testRepo-2/.git* . && cp -r /tmp/testRepo-2/* .)", + "remoteUser": "vscode", + "features": { + "git-lfs": { + "autoPull": false + } + } + } +} \ No newline at end of file From f0dd470ba898bb62eb0fa425aa81e86072454167 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 4 Apr 2023 10:05:12 -0700 Subject: [PATCH 108/478] Automated documentation update (#512) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/git-lfs/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/git-lfs/README.md b/src/git-lfs/README.md index 9fc3281fe..9a9a06659 100644 --- a/src/git-lfs/README.md +++ b/src/git-lfs/README.md @@ -16,6 +16,7 @@ Installs Git Large File Support (Git LFS) along with needed dependencies. Useful | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | version | Select version of Git LFS to install | string | latest | +| autoPull | Automatically pull LFS files when creating the container. When false, running 'git lfs pull' in the container will have the same effect. | boolean | true | From 7f605b9452ac43316a0b81d78118c5dbe00ee26e Mon Sep 17 00:00:00 2001 From: Felipe Santos Date: Wed, 5 Apr 2023 15:21:36 -0300 Subject: [PATCH 109/478] Fix several issues with docker-outside-of-docker (#443) * Fix several issues with docker-outside-of-docker * Add initial tests and bump version * Add two tests * Fix docker buildx conflict * Fix possible test issue * Add tests for moby * Add buildx test to init * Fix inconsistency * Many fixes and improvements * Make dockeDashCompose v2 by default --- .../devcontainer-feature.json | 7 +- src/docker-outside-of-docker/install.sh | 85 ++++++------- .../docker_build_moby.sh | 1 + ...r_build_2.sh => docker_build_no_buildx.sh} | 2 +- .../docker_build_no_buildx_moby.sh | 1 + .../docker_build_older.sh | 13 -- .../docker_dash_compose_v1.sh | 13 ++ .../docker_dash_compose_v1_moby.sh | 1 + .../docker_dash_compose_v2.sh | 13 ++ .../docker_dash_compose_v2_moby.sh | 1 + test/docker-outside-of-docker/docker_init.sh | 6 +- .../docker_init_debian.sh | 1 + .../docker_init_moby.sh | 1 + .../docker_init_ubuntu_22.sh | 1 + test/docker-outside-of-docker/scenarios.json | 113 +++++++++++++++--- test/docker-outside-of-docker/test.sh | 9 +- 16 files changed, 178 insertions(+), 90 deletions(-) create mode 120000 test/docker-outside-of-docker/docker_build_moby.sh rename test/docker-outside-of-docker/{docker_build_2.sh => docker_build_no_buildx.sh} (68%) create mode 120000 test/docker-outside-of-docker/docker_build_no_buildx_moby.sh delete mode 100644 test/docker-outside-of-docker/docker_build_older.sh create mode 100755 test/docker-outside-of-docker/docker_dash_compose_v1.sh create mode 120000 test/docker-outside-of-docker/docker_dash_compose_v1_moby.sh create mode 100755 test/docker-outside-of-docker/docker_dash_compose_v2.sh create mode 120000 test/docker-outside-of-docker/docker_dash_compose_v2_moby.sh create mode 120000 test/docker-outside-of-docker/docker_init_debian.sh create mode 120000 test/docker-outside-of-docker/docker_init_moby.sh create mode 120000 test/docker-outside-of-docker/docker_init_ubuntu_22.sh mode change 100755 => 100644 test/docker-outside-of-docker/test.sh diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index 79bc9febc..841bb6265 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.1.0", + "version": "1.2.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.", @@ -26,7 +26,7 @@ "v1", "v2" ], - "default": "v1", + "default": "v2", "description": "Compose version to use for docker-compose (v1 or v2)" }, "installDockerBuildx": { @@ -36,9 +36,6 @@ } }, "entrypoint": "/usr/local/share/docker-init.sh", - "containerEnv": { - "DOCKER_BUILDKIT": "1" - }, "customizations": { "vscode": { "extensions": [ diff --git a/src/docker-outside-of-docker/install.sh b/src/docker-outside-of-docker/install.sh index 63524101b..9d8433aed 100755 --- a/src/docker-outside-of-docker/install.sh +++ b/src/docker-outside-of-docker/install.sh @@ -9,7 +9,7 @@ DOCKER_VERSION="${VERSION:-"latest"}" USE_MOBY="${MOBY:-"true"}" -DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2 +DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v2"}" # v1 or v2 ENABLE_NONROOT_DOCKER="${ENABLE_NONROOT_DOCKER:-"true"}" SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}" @@ -87,7 +87,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 @@ -172,7 +172,7 @@ apt-get update if [ "${DOCKER_VERSION}" = "latest" ] || [ "${DOCKER_VERSION}" = "lts" ] || [ "${DOCKER_VERSION}" = "stable" ]; then # Empty, meaning grab whatever "latest" is in apt repo cli_version_suffix="" -else +else # Fetch a valid version from the apt-cache (eg: the Microsoft repo appends +azure, breakfix, etc...) docker_version_dot_escaped="${DOCKER_VERSION//./\\.}" docker_version_dot_plus_escaped="${docker_version_dot_escaped//+/\\+}" @@ -194,17 +194,32 @@ if type docker > /dev/null 2>&1; then echo "Docker / Moby CLI already installed." else if [ "${USE_MOBY}" = "true" ]; then - apt-get -y install --no-install-recommends moby-cli${cli_version_suffix} moby-buildx + buildx=() + if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then + buildx=(moby-buildx) + fi + apt-get -y install --no-install-recommends ${cli_package_name}${cli_version_suffix} "${buildx[@]}" apt-get -y install --no-install-recommends moby-compose || echo "(*) Package moby-compose (Docker Compose v2) not available for OS ${ID} ${VERSION_CODENAME} (${architecture}). Skipping." else - apt-get -y install --no-install-recommends docker-ce-cli${cli_version_suffix} + buildx=() + if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then + buildx=(docker-buildx-plugin) + fi + apt-get -y install --no-install-recommends ${cli_package_name}${cli_version_suffix} "${buildx[@]}" docker-compose-plugin + buildx_path="/usr/libexec/docker/cli-plugins/docker-buildx" + # Older versions of Docker CE installs buildx as part of the CLI package + if [ "${INSTALL_DOCKER_BUILDX}" = "false" ] && [ -f "${buildx_path}" ]; then + echo "(*) Removing docker-buildx installed from docker-ce-cli since installDockerBuildx is disabled..." + rm -f "${buildx_path}" + fi fi + unset buildx buildx_path fi # 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." -else +elif [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then TARGET_COMPOSE_ARCH="$(uname -m)" if [ "${TARGET_COMPOSE_ARCH}" = "amd64" ]; then TARGET_COMPOSE_ARCH="x86_64" @@ -224,60 +239,36 @@ else fi ${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' docker-compose rm -rf /tmp/pip-tmp - else + 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 fi -fi - -# Install docker-compose switch if not already installed - https://github.com/docker/compose-switch#manual-installation -current_v1_compose_path="$(which docker-compose)" -target_v1_compose_path="$(dirname "${current_v1_compose_path}")/docker-compose-v1" -if ! type compose-switch > /dev/null 2>&1; then - echo "(*) Installing compose-switch..." +else + echo "(*) Installing compose-switch as docker-compose..." compose_switch_version="latest" find_version_from_git_tags compose_switch_version "https://github.com/docker/compose-switch" - curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch - chmod +x /usr/local/bin/compose-switch + curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/docker-compose + chmod +x /usr/local/bin/docker-compose # 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_v1_compose_path}" "${target_v1_compose_path}" - update-alternatives --install /usr/local/bin/docker-compose docker-compose /usr/local/bin/compose-switch 99 - update-alternatives --install /usr/local/bin/docker-compose docker-compose "${target_v1_compose_path}" 1 -fi -if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then - update-alternatives --set docker-compose "${target_v1_compose_path}" -else - update-alternatives --set docker-compose /usr/local/bin/compose-switch fi # Setup a docker group in the event the docker socket's group is not root if ! grep -qE '^docker:' /etc/group; then + echo "(*) Creating missing docker group..." groupadd --system docker fi -usermod -aG docker "${USERNAME}" - -if [ "${INSTALL_DOCKER_BUILDX}" = "true" ]; then - buildx_version="latest" - find_version_from_git_tags buildx_version "https://github.com/docker/buildx" "refs/tags/v" - echo "(*) Installing buildx ${buildx_version}..." - buildx_file_name="buildx-v${buildx_version}.linux-${architecture}" - cd /tmp && wget "https://github.com/docker/buildx/releases/download/v${buildx_version}/${buildx_file_name}" - - mkdir -p ${_REMOTE_USER_HOME}/.docker/cli-plugins - mv ${buildx_file_name} ${_REMOTE_USER_HOME}/.docker/cli-plugins/docker-buildx - chmod +x ${_REMOTE_USER_HOME}/.docker/cli-plugins/docker-buildx - - chown -R "${USERNAME}:docker" "${_REMOTE_USER_HOME}/.docker" - chmod -R g+r+w "${_REMOTE_USER_HOME}/.docker" - find "${_REMOTE_USER_HOME}/.docker" -type d -print0 | xargs -n 1 -0 chmod g+s +# Ensure docker group gid is 999 +if [ "$(getent group docker | cut -d: -f3)" != "999" ]; then + echo "(*) Updating docker group gid to 999..." + groupmod -g 999 docker fi +usermod -aG docker "${USERNAME}" + # If init file already exists, exit if [ -f "/usr/local/share/docker-init.sh" ]; then # Clean up @@ -304,10 +295,10 @@ fi DOCKER_GID="$(grep -oP '^docker:x:\K[^:]+' /etc/group)" # If enabling non-root access and specified user is found, setup socat and add script -chown -h "${USERNAME}":root "${TARGET_SOCKET}" +chown -h "${USERNAME}":root "${TARGET_SOCKET}" check_packages socat tee /usr/local/share/docker-init.sh > /dev/null \ -<< EOF +<< EOF #!/usr/bin/env bash #------------------------------------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. @@ -339,8 +330,8 @@ log() echo -e "\n** \$(date) **" | sudoIf tee -a \${SOCAT_LOG} > /dev/null log "Ensuring ${USERNAME} has access to ${SOURCE_SOCKET} via ${TARGET_SOCKET}" -# If enabled, try to update the docker group with the right GID. If the group is root, -# fall back on using socat to forward the docker socket to another unix socket so +# If enabled, try to update the docker group with the right GID. If the group is root, +# fall back on using socat to forward the docker socket to another unix socket so # that we can set permissions on it without affecting the host. if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ] && [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "0" ]; then SOCKET_GID=\$(stat -c '%g' ${SOURCE_SOCKET}) @@ -360,7 +351,7 @@ if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_ log "Success" fi -# Execute whatever commands were passed in (if any). This allows us +# Execute whatever commands were passed in (if any). This allows us # to set this script to ENTRYPOINT while still executing the default CMD. set +e exec "\$@" diff --git a/test/docker-outside-of-docker/docker_build_moby.sh b/test/docker-outside-of-docker/docker_build_moby.sh new file mode 120000 index 000000000..0b420dbf4 --- /dev/null +++ b/test/docker-outside-of-docker/docker_build_moby.sh @@ -0,0 +1 @@ +./docker_build.sh \ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_build_2.sh b/test/docker-outside-of-docker/docker_build_no_buildx.sh similarity index 68% rename from test/docker-outside-of-docker/docker_build_2.sh rename to test/docker-outside-of-docker/docker_build_no_buildx.sh index 742b222fb..7b3870d3b 100644 --- a/test/docker-outside-of-docker/docker_build_2.sh +++ b/test/docker-outside-of-docker/docker_build_no_buildx.sh @@ -6,7 +6,7 @@ set -e source dev-container-features-test-lib # Definition specific tests -check "docker-buildx" docker buildx version +check "no buildx" bash -c "docker buildx version 2>&1 | grep 'not a docker command'" check "docker-build" docker build ./ # Report result diff --git a/test/docker-outside-of-docker/docker_build_no_buildx_moby.sh b/test/docker-outside-of-docker/docker_build_no_buildx_moby.sh new file mode 120000 index 000000000..00b72a39d --- /dev/null +++ b/test/docker-outside-of-docker/docker_build_no_buildx_moby.sh @@ -0,0 +1 @@ +./docker_build_no_buildx.sh \ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_build_older.sh b/test/docker-outside-of-docker/docker_build_older.sh deleted file mode 100644 index 742b222fb..000000000 --- a/test/docker-outside-of-docker/docker_build_older.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -set -e - -# Optional: Import test library -source dev-container-features-test-lib - -# Definition specific tests -check "docker-buildx" docker buildx version -check "docker-build" docker build ./ - -# Report result -reportResults diff --git a/test/docker-outside-of-docker/docker_dash_compose_v1.sh b/test/docker-outside-of-docker/docker_dash_compose_v1.sh new file mode 100755 index 000000000..d95f3cf73 --- /dev/null +++ b/test/docker-outside-of-docker/docker_dash_compose_v1.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +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 '1.[0-9]+.[0-9]+'" + +# Report result +reportResults diff --git a/test/docker-outside-of-docker/docker_dash_compose_v1_moby.sh b/test/docker-outside-of-docker/docker_dash_compose_v1_moby.sh new file mode 120000 index 000000000..51dc7d26b --- /dev/null +++ b/test/docker-outside-of-docker/docker_dash_compose_v1_moby.sh @@ -0,0 +1 @@ +./docker_dash_compose_v1.sh \ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_dash_compose_v2.sh b/test/docker-outside-of-docker/docker_dash_compose_v2.sh new file mode 100755 index 000000000..8f2a104f5 --- /dev/null +++ b/test/docker-outside-of-docker/docker_dash_compose_v2.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +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]+'" + +# Report result +reportResults diff --git a/test/docker-outside-of-docker/docker_dash_compose_v2_moby.sh b/test/docker-outside-of-docker/docker_dash_compose_v2_moby.sh new file mode 120000 index 000000000..78ae9bc70 --- /dev/null +++ b/test/docker-outside-of-docker/docker_dash_compose_v2_moby.sh @@ -0,0 +1 @@ +./docker_dash_compose_v2.sh \ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_init.sh b/test/docker-outside-of-docker/docker_init.sh index 216492129..b47285ead 100644 --- a/test/docker-outside-of-docker/docker_init.sh +++ b/test/docker-outside-of-docker/docker_init.sh @@ -5,11 +5,15 @@ set -e # Optional: Import test library source dev-container-features-test-lib +check "docker buildx" bash -c "docker buildx version" +check "docker compose" bash -c "docker compose version" +check "docker-compose" bash -c "docker-compose --version" + check "docker-init-exists" bash -c "ls /usr/local/share/docker-init.sh" check "log-exists" bash -c "ls /tmp/vscr-docker-from-docker.log" check "log-contents-for-success" bash -c "cat /tmp/vscr-docker-from-docker.log | grep 'Success'" check "log-contents" bash -c "cat /tmp/vscr-docker-from-docker.log | grep 'Proxying /var/run/docker-host.sock to /var/run/docker.sock for vscode'" -check "docker-ps" bash -c "docker ps" +check "docker-ps" bash -c "docker ps >/dev/null" # Report result reportResults \ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_init_debian.sh b/test/docker-outside-of-docker/docker_init_debian.sh new file mode 120000 index 000000000..7458cc9b7 --- /dev/null +++ b/test/docker-outside-of-docker/docker_init_debian.sh @@ -0,0 +1 @@ +./docker_init.sh \ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_init_moby.sh b/test/docker-outside-of-docker/docker_init_moby.sh new file mode 120000 index 000000000..7458cc9b7 --- /dev/null +++ b/test/docker-outside-of-docker/docker_init_moby.sh @@ -0,0 +1 @@ +./docker_init.sh \ No newline at end of file diff --git a/test/docker-outside-of-docker/docker_init_ubuntu_22.sh b/test/docker-outside-of-docker/docker_init_ubuntu_22.sh new file mode 120000 index 000000000..7458cc9b7 --- /dev/null +++ b/test/docker-outside-of-docker/docker_init_ubuntu_22.sh @@ -0,0 +1 @@ +./docker_init.sh \ 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 ad9b07248..be63470c5 100644 --- a/test/docker-outside-of-docker/scenarios.json +++ b/test/docker-outside-of-docker/scenarios.json @@ -1,44 +1,119 @@ { + "docker_init_moby": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": true + } + }, + "containerUser": "vscode" + }, "docker_init": { - "image": "mcr.microsoft.com/devcontainers/base", - "remoteUser": "vscode", + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": false + } + }, + "containerUser": "vscode" + }, + "docker_init_ubuntu_22": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-22.04", "features": { "docker-outside-of-docker": { - "version": "latest" + "moby": false } - } + }, + "containerUser": "vscode" + }, + "docker_init_debian": { + "image": "mcr.microsoft.com/devcontainers/base:debian", + "features": { + "docker-outside-of-docker": { + "moby": false + } + }, + "containerUser": "vscode" }, "docker_build": { - "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", "features": { "docker-outside-of-docker": { - "version": "latest", - "installDockerBuildx": true, - "moby": "false", + "moby": false, "dockerDashComposeVersion": "v2" } }, - "remoteUser": "node" + "containerUser": "vscode" }, - "docker_build_2": { - "image": "ubuntu:focal", + "docker_build_moby": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", "features": { "docker-outside-of-docker": { - "version": "latest", - "moby": "false", - "dockerDashComposeVersion": "v2" + "moby": true } - } + }, + "containerUser": "vscode" }, - "docker_build_older": { - "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "docker_build_no_buildx": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", "features": { "docker-outside-of-docker": { "version": "20", - "moby": "false", + "moby": false, + "installDockerBuildx": false + } + }, + "containerUser": "vscode" + }, + "docker_build_no_buildx_moby": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "version": "20", + "moby": true, + "installDockerBuildx": false + } + }, + "containerUser": "vscode" + }, + "docker_dash_compose_v1": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": false, + "dockerDashComposeVersion": "v1" + } + }, + "containerUser": "vscode" + }, + "docker_dash_compose_v1_moby": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": true, + "dockerDashComposeVersion": "v1" + } + }, + "containerUser": "vscode" + }, + "docker_dash_compose_v2": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": false, + "dockerDashComposeVersion": "v2" + } + }, + "containerUser": "vscode" + }, + "docker_dash_compose_v2_moby": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04", + "features": { + "docker-outside-of-docker": { + "moby": true, "dockerDashComposeVersion": "v2" } }, - "remoteUser": "node" + "containerUser": "vscode" } } diff --git a/test/docker-outside-of-docker/test.sh b/test/docker-outside-of-docker/test.sh old mode 100755 new mode 100644 index 517737ada..fe9098e10 --- a/test/docker-outside-of-docker/test.sh +++ b/test/docker-outside-of-docker/test.sh @@ -5,10 +5,11 @@ set -e # Optional: Import test library source dev-container-features-test-lib -# Definition specific tests -check "version" docker --version -check "docker-init-exists" bash -c "ls /usr/local/share/docker-init.sh" -check "docker-ps" bash -c "docker ps" +check "docker buildx" bash -c "docker buildx version" +check "docker compose" bash -c "docker compose version" +check "docker-compose" bash -c "docker-compose --version" + +check "docker-ps" bash -c "docker ps >/dev/null" # Report result reportResults \ No newline at end of file From 585ee2a42c8c4185d058a324fe1b996b809e52d7 Mon Sep 17 00:00:00 2001 From: Ryan Campbell <89273172+bigtallcampbell@users.noreply.github.com> Date: Wed, 5 Apr 2023 14:33:00 -0500 Subject: [PATCH 110/478] Removing forced gid 999 for docker (#515) * Removing forced gid 999 for docker * version bump --------- Co-authored-by: Ryan Campbell Co-authored-by: Samruddhi Khandale --- src/docker-outside-of-docker/devcontainer-feature.json | 2 +- src/docker-outside-of-docker/install.sh | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index 841bb6265..2b75aa4f3 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.2.0", + "version": "1.2.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 9d8433aed..f32db2f4a 100755 --- a/src/docker-outside-of-docker/install.sh +++ b/src/docker-outside-of-docker/install.sh @@ -261,11 +261,13 @@ if ! grep -qE '^docker:' /etc/group; then groupadd --system docker fi +# Remarking this out to restore functionality in Azure VMs. ID 999 is a reserved group ID # Ensure docker group gid is 999 -if [ "$(getent group docker | cut -d: -f3)" != "999" ]; then - echo "(*) Updating docker group gid to 999..." - groupmod -g 999 docker -fi +# if [ "$(getent group docker | cut -d: -f3)" != "999" ]; then +# echo "(*) Updating docker group gid to 999..." +# groupmod -g 999 docker +# fi + usermod -aG docker "${USERNAME}" From 74959ec14975fe1c95133dc6d3ad5677e4cf66e1 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 5 Apr 2023 16:06:27 -0700 Subject: [PATCH 111/478] Automated documentation update (#517) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/docker-outside-of-docker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docker-outside-of-docker/README.md b/src/docker-outside-of-docker/README.md index 793d5d0ba..f7f411a72 100644 --- a/src/docker-outside-of-docker/README.md +++ b/src/docker-outside-of-docker/README.md @@ -19,7 +19,7 @@ Re-use the host docker socket, adding the Docker CLI to a container. Feature inv |-----|-----|-----|-----| | version | Select or enter a Docker/Moby CLI version. (Availability can vary by OS version.) | string | latest | | moby | Install OSS Moby build instead of Docker CE | boolean | true | -| dockerDashComposeVersion | Compose version to use for docker-compose (v1 or v2) | string | v1 | +| dockerDashComposeVersion | Compose version to use for docker-compose (v1 or v2) | string | v2 | | installDockerBuildx | Install Docker Buildx | boolean | true | ## Limitations From 8d3e9aca9d352a3c4459e321de5d0a0b12062112 Mon Sep 17 00:00:00 2001 From: Alexander Smolyakov Date: Thu, 6 Apr 2023 21:02:49 +0400 Subject: [PATCH 112/478] [features/conda] Address CVE-2023-0286, CVE-2023-23931, and CVE-2022-40897 vulnerabilities (#518) * [features/conda] Address CVE-2023-0286, CVE-2023-23931, and CVE-2022-40897 vulnerabilities - Update `install.sh` to install updates for `cryptography` and `setuptools` packages - Add tests to verify `cryptography` and `setuptools` packages version * Bump feature version --- src/conda/devcontainer-feature.json | 2 +- src/conda/install.sh | 7 ++++++- test/conda/test.sh | 6 ++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/conda/devcontainer-feature.json b/src/conda/devcontainer-feature.json index 8e1a5fccb..9a2365253 100644 --- a/src/conda/devcontainer-feature.json +++ b/src/conda/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "conda", - "version": "1.0.8", + "version": "1.0.9", "name": "Conda", "description": "A cross-platform, language-agnostic binary package manager", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/conda", diff --git a/src/conda/install.sh b/src/conda/install.sh index 55b280c40..43ab82f54 100644 --- a/src/conda/install.sh +++ b/src/conda/install.sh @@ -114,8 +114,13 @@ if ! conda --version &> /dev/null ; then find "${CONDA_DIR}" -type d -print0 | xargs -n 1 -0 chmod g+s - # Temporary due to https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23491 + # Temporary fixes + # Due to https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23491 install_user_package certifi + # Due to https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-0286 and https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-23931 + install_user_package cryptography + # Due to https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-40897 + install_user_package setuptools fi # Display a notice on conda when not running in GitHub Codespaces diff --git a/test/conda/test.sh b/test/conda/test.sh index 8a88511ca..fcb9d7ef8 100755 --- a/test/conda/test.sh +++ b/test/conda/test.sh @@ -32,5 +32,11 @@ check-version-ge() { certifiVersion=$(python -c "import certifi; print(certifi.__version__)") check-version-ge "certifi" "${certifiVersion}" "2022.12.07" +cryptographyVersion=$(python -c "import cryptography; print(cryptography.__version__)") +check-version-ge "cryptography" "${cryptographyVersion}" "39.0.1" + +setuptoolsVersion=$(python -c "import setuptools; print(setuptools.__version__)") +check-version-ge "setuptools" "${setuptoolsVersion}" "65.5.1" + # Report result reportResults From 2237731474ace274b1756e63937a958131cf719e Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 14 Apr 2023 13:48:25 -0700 Subject: [PATCH 113/478] Automated documentation update (#521) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/aws-cli/README.md | 6 ++++++ src/azure-cli/README.md | 6 ++++++ src/docker-in-docker/README.md | 6 ++++++ src/docker-outside-of-docker/README.md | 6 ++++++ src/dotnet/README.md | 6 ++++++ src/go/README.md | 6 ++++++ src/java/README.md | 6 ++++++ src/node/README.md | 6 ++++++ src/php/README.md | 9 +++++++++ src/python/README.md | 7 +++++++ src/ruby/README.md | 6 ++++++ src/rust/README.md | 10 ++++++++++ src/terraform/README.md | 7 +++++++ 13 files changed, 87 insertions(+) diff --git a/src/aws-cli/README.md b/src/aws-cli/README.md index 40cc4ae98..e45cb3f4c 100644 --- a/src/aws-cli/README.md +++ b/src/aws-cli/README.md @@ -17,6 +17,12 @@ Installs the AWS CLI along with needed dependencies. Useful for base Dockerfiles |-----|-----|-----|-----| | version | Select or enter an AWS CLI version. | string | latest | +## Customizations + +### VS Code Extensions + +- `AmazonWebServices.aws-toolkit-vscode` + Available versions of the AWS CLI can be found here: https://github.com/aws/aws-cli/blob/v2/CHANGELOG.rst. ## OS Support diff --git a/src/azure-cli/README.md b/src/azure-cli/README.md index cb792d120..4a9de7b96 100644 --- a/src/azure-cli/README.md +++ b/src/azure-cli/README.md @@ -19,6 +19,12 @@ Installs the Azure CLI along with needed dependencies. Useful for base Dockerfil | extensions | Optional comma separated list of Azure CLI extensions to install in profile. | string | - | | installBicep | Optionally install Azure Bicep | boolean | false | +## Customizations + +### VS Code Extensions + +- `ms-vscode.azurecli` + ## OS Support diff --git a/src/docker-in-docker/README.md b/src/docker-in-docker/README.md index 9a22c2c4e..d519a48fb 100644 --- a/src/docker-in-docker/README.md +++ b/src/docker-in-docker/README.md @@ -22,6 +22,12 @@ 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 | +## Customizations + +### VS Code Extensions + +- `ms-azuretools.vscode-docker` + ## Limitations This docker-in-docker Dev Container Feature is roughly based on the [official docker-in-docker wrapper script](https://github.com/moby/moby/blob/master/hack/dind) that is part of the [Moby project](https://mobyproject.org/). With this in mind: diff --git a/src/docker-outside-of-docker/README.md b/src/docker-outside-of-docker/README.md index f7f411a72..7b558a971 100644 --- a/src/docker-outside-of-docker/README.md +++ b/src/docker-outside-of-docker/README.md @@ -22,6 +22,12 @@ Re-use the host docker socket, adding the Docker CLI to a container. Feature inv | dockerDashComposeVersion | Compose version to use for docker-compose (v1 or v2) | string | v2 | | installDockerBuildx | Install Docker Buildx | boolean | true | +## Customizations + +### VS Code Extensions + +- `ms-azuretools.vscode-docker` + ## Limitations - As the name implies, the Feature is expected to work when the host is running Docker (or the OSS Moby container engine it is built on). It may be possible to get running in other container engines, but it has not been tested with them. diff --git a/src/dotnet/README.md b/src/dotnet/README.md index c13c998fd..83c42494f 100644 --- a/src/dotnet/README.md +++ b/src/dotnet/README.md @@ -19,6 +19,12 @@ Installs the .NET CLI. Provides option of installing sdk or runtime, and option | runtimeOnly | Install just the dotnet runtime if true, and sdk if false. | boolean | false | | installUsingApt | If true, it installs using apt instead of the release URL | boolean | true | +## Customizations + +### VS Code Extensions + +- `ms-dotnettools.csharp` + ## OS Support diff --git a/src/go/README.md b/src/go/README.md index e7a692443..be035ee85 100644 --- a/src/go/README.md +++ b/src/go/README.md @@ -18,6 +18,12 @@ Installs Go and common Go utilities. Auto-detects latest version and installs ne | version | Select or enter a Go version to install | string | latest | | golangciLintVersion | Version of golangci-lint to install | string | latest | +## Customizations + +### VS Code Extensions + +- `golang.Go` + ## OS Support diff --git a/src/java/README.md b/src/java/README.md index e74cd5a10..1ffd6188b 100644 --- a/src/java/README.md +++ b/src/java/README.md @@ -24,6 +24,12 @@ Installs Java, SDKMAN! (if not installed), and needed dependencies. | installAnt | Install Ant, a software tool for automating software build processes | boolean | false | | antVersion | Select or enter an Ant version | string | latest | +## Customizations + +### VS Code Extensions + +- `vscjava.vscode-java-pack` + ## License For the Java Feature from this repository, see [NOTICE.txt](https://github.com/devcontainers/features/tree/main/src/java/NOTICE.txt) for licensing information on JDK distributions. diff --git a/src/node/README.md b/src/node/README.md index 877ea5877..7a4909600 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -20,6 +20,12 @@ Installs Node.js, nvm, yarn, pnpm, and needed dependencies. | nvmInstallPath | The path where NVM will be installed. | string | /usr/local/share/nvm | | nvmVersion | Version of NVM to install. | string | 0.39.2 | +## Customizations + +### VS Code Extensions + +- `dbaeumer.vscode-eslint` + ## Using nvm from postCreateCommand or another lifecycle command Certain operations like `postCreateCommand` run non-interactive, non-login shells. Unfortunately, `nvm` is really particular that it needs to be "sourced" before it is used, which can only happen automatically with interactive and/or login shells. Fortunately, this is easy to work around: diff --git a/src/php/README.md b/src/php/README.md index 3a9be7a98..14f4a1797 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -18,6 +18,15 @@ | version | Select or enter a PHP version | string | latest | | installComposer | Install PHP Composer? | boolean | true | +## Customizations + +### VS Code Extensions + +- `xdebug.php-debug` +- `bmewburn.vscode-intelephense-client` +- `xdebug.php-pack` +- `devsense.phptools-vscode` + ## OS Support diff --git a/src/python/README.md b/src/python/README.md index 05742910a..807d89eb1 100644 --- a/src/python/README.md +++ b/src/python/README.md @@ -22,6 +22,13 @@ Installs the provided version of Python, as well as PIPX, and other common Pytho | installJupyterlab | Install JupyterLab, a web-based interactive development environment for notebooks | boolean | false | | configureJupyterlabAllowOrigin | Configure JupyterLab to accept HTTP requests from the specified origin | string | - | +## Customizations + +### VS Code Extensions + +- `ms-python.python` +- `ms-python.vscode-pylance` + ## OS Support diff --git a/src/ruby/README.md b/src/ruby/README.md index 8a0ff877d..8e8ebe2c3 100644 --- a/src/ruby/README.md +++ b/src/ruby/README.md @@ -17,6 +17,12 @@ Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies. |-----|-----|-----|-----| | version | Select or enter a Ruby version to install | string | latest | +## Customizations + +### VS Code Extensions + +- `rebornix.Ruby` + ## OS Support diff --git a/src/rust/README.md b/src/rust/README.md index 372b56f97..f72b56f82 100644 --- a/src/rust/README.md +++ b/src/rust/README.md @@ -18,6 +18,16 @@ 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 | +## Customizations + +### VS Code Extensions + +- `vadimcn.vscode-lldb` +- `mutantdino.resourcemonitor` +- `rust-lang.rust-analyzer` +- `tamasfe.even-better-toml` +- `serayuzgur.crates` + ## OS Support diff --git a/src/terraform/README.md b/src/terraform/README.md index e75da9b20..e93058718 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -23,6 +23,13 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la | installTerraformDocs | Install terraform-docs, a utility to generate documentation from Terraform modules | boolean | false | | httpProxy | Connect to a keyserver using a proxy by configuring this option | string | - | +## Customizations + +### VS Code Extensions + +- `HashiCorp.terraform` +- `ms-azuretools.vscode-azureterraform` + ## OS Support From fad03b19d48466bb0eec41ccbf4cc456a5c4dea7 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 18 Apr 2023 14:37:51 -0700 Subject: [PATCH 114/478] Oryx - Switch to .NET 7 (#522) * Oryx - Switch to .NET 7 * fix test ; add test * fix test - back compat --- src/oryx/devcontainer-feature.json | 5 ++- src/oryx/install.sh | 16 +++++--- test/oryx/install_prev_dotnet_and_oryx.sh | 47 +++++++++++++++++++++++ test/oryx/scenarios.json | 10 +++++ 4 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 test/oryx/install_prev_dotnet_and_oryx.sh diff --git a/src/oryx/devcontainer-feature.json b/src/oryx/devcontainer-feature.json index 9a6bd25c2..66a528ec5 100644 --- a/src/oryx/devcontainer-feature.json +++ b/src/oryx/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "oryx", - "version": "1.0.13", + "version": "1.1.0", "name": "Oryx", "description": "Installs the oryx CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/oryx", @@ -14,6 +14,7 @@ "PATH": "/usr/local/oryx:${PATH}" }, "installsAfter": [ - "ghcr.io/devcontainers/features/common-utils" + "ghcr.io/devcontainers/features/common-utils", + "ghcr.io/devcontainers/features/dotnet" ] } diff --git a/src/oryx/install.sh b/src/oryx/install.sh index a1b64d3e9..cb2e1b6b7 100755 --- a/src/oryx/install.sh +++ b/src/oryx/install.sh @@ -74,7 +74,7 @@ install_dotnet_using_apt() { echo "Attempting to auto-install dotnet..." install_from_microsoft_feed=false apt_get_update - DOTNET_INSTALLATION_PACKAGE="dotnet6" + DOTNET_INSTALLATION_PACKAGE="dotnet7" apt-get -yq install $DOTNET_INSTALLATION_PACKAGE || install_from_microsoft_feed="true" if [ "${install_from_microsoft_feed}" = "true" ]; then @@ -82,7 +82,7 @@ install_dotnet_using_apt() { curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg echo "deb [arch=${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 apt-get update -y - DOTNET_INSTALLATION_PACKAGE="dotnet-sdk-6.0" + DOTNET_INSTALLATION_PACKAGE="dotnet-sdk-7.0" DOTNET_SKIP_FIRST_TIME_EXPERIENCE="true" apt-get install -yq $DOTNET_INSTALLATION_PACKAGE fi @@ -132,9 +132,9 @@ if dotnet --version > /dev/null ; then DOTNET_BINARY=$(which dotnet) fi -# Oryx needs to be built with .NET 6 -if [[ "${DOTNET_BINARY}" = "" ]] || [[ "$(dotnet --version)" != *"6"* ]] ; then - echo "'dotnet 6' was not detected. Attempting to install .NET 6 to build oryx." +# Oryx needs to be built with .NET 7 +if [[ "${DOTNET_BINARY}" = "" ]] || [[ "$(dotnet --version)" != *"7"* ]] ; then + echo "'dotnet 7' was not detected. Attempting to install .NET 7 to build oryx." install_dotnet_using_apt if ! dotnet --version > /dev/null ; then @@ -154,7 +154,11 @@ mkdir -p ${ORYX} git clone --depth=1 https://github.com/microsoft/Oryx $GIT_ORYX -$GIT_ORYX/build/buildSln.sh +SOLUTION_FILE_NAME="Oryx.sln" +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 diff --git a/test/oryx/install_prev_dotnet_and_oryx.sh b/test/oryx/install_prev_dotnet_and_oryx.sh new file mode 100644 index 000000000..175482847 --- /dev/null +++ b/test/oryx/install_prev_dotnet_and_oryx.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "Oryx version" oryx --version +check "Dotnet is not removed if it is not installed by the Oryx Feature" dotnet --version + +# Install platforms with oryx build tool +check "oryx-install-dotnet-2.1" oryx prep --skip-detection --platforms-and-versions dotnet=2.1.30 +check "dotnet-2-installed-by-oryx" ls /opt/dotnet/ | grep 2.1 + +check "oryx-install-nodejs-12.22.11" oryx prep --skip-detection --platforms-and-versions nodejs=12.22.11 +check "nodejs-12.22.11-installed-by-oryx" ls /opt/nodejs/ | grep 12.22.11 + +check "oryx-install-php-7.3.25" oryx prep --skip-detection --platforms-and-versions php=7.3.25 +check "php-7.3.25-installed-by-oryx" ls /opt/php/ | grep 7.3.25 + +check "oryx-install-java-12.0.2" oryx prep --skip-detection --platforms-and-versions java=12.0.2 +check "java-12.0.2-installed-by-oryx" ls /opt/java/ | grep 12.0.2 + +# Replicates Oryx's behavior for universal image +mkdir -p /opt/oryx +echo "vso-focal" >> /opt/oryx/.imagetype + +mkdir -p /opt/dotnet/lts +cp -R /usr/local/dotnet/current/dotnet /opt/dotnet/lts +cp -R /usr/local/dotnet/current/LICENSE.txt /opt/dotnet/lts +cp -R /usr/local/dotnet/current/ThirdPartyNotices.txt /opt/dotnet/lts + +# Install platforms with oryx build tool +check "oryx-install-dotnet-2.1-universal" oryx prep --skip-detection --platforms-and-versions dotnet=2.1.30 +check "dotnet-2-installed-by-oryx-universal" ls /opt/dotnet/ | grep 2.1 + +check "oryx-install-nodejs-12.22.11-universal" oryx prep --skip-detection --platforms-and-versions nodejs=12.22.11 +check "nodejs-12.22.11-installed-by-oryx-universal" ls /opt/nodejs/ | grep 12.22.11 + +check "oryx-install-php-7.3.25-universal" oryx prep --skip-detection --platforms-and-versions php=7.3.25 +check "php-7.3.25-installed-by-oryx-universal" ls /opt/php/ | grep 7.3.25 + +check "oryx-install-java-12.0.2-universal" oryx prep --skip-detection --platforms-and-versions java=12.0.2 +check "java-12.0.2-installed-by-oryx-universal" ls /opt/java/ | grep 12.0.2 + +# Report result +reportResults diff --git a/test/oryx/scenarios.json b/test/oryx/scenarios.json index bbfc277a9..c61483eb4 100644 --- a/test/oryx/scenarios.json +++ b/test/oryx/scenarios.json @@ -1,5 +1,15 @@ { "install_dotnet_and_oryx": { + "image": "ubuntu:focal", + "features": { + "dotnet": { + "version": "7", + "installUsingApt": "false" + }, + "oryx": {} + } + }, + "install_prev_dotnet_and_oryx": { "image": "ubuntu:focal", "features": { "dotnet": { From f52ff611c55a4e0708edd9c93076603b2704e581 Mon Sep 17 00:00:00 2001 From: Felix Altenberg Date: Fri, 28 Apr 2023 21:38:25 +0100 Subject: [PATCH 115/478] Adds httpProxy option to Python Feature (#532) * Adds httpProxy option to Python Feature This option allows GPG to use a HTTP proxy to fetch keys from remote keyservers * Updating minor version Co-authored-by: Samruddhi Khandale * Fixes minor formatting error --------- Co-authored-by: Samruddhi Khandale --- src/python/devcontainer-feature.json | 7 ++++++- src/python/install.sh | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/python/devcontainer-feature.json b/src/python/devcontainer-feature.json index a954c3511..b4aa21e25 100644 --- a/src/python/devcontainer-feature.json +++ b/src/python/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "python", - "version": "1.0.22", + "version": "1.1.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.", @@ -45,6 +45,11 @@ "type": "string", "default": "", "description": "Configure JupyterLab to accept HTTP requests from the specified origin" + }, + "httpProxy": { + "type": "string", + "default": "", + "description": "Connect to GPG keyservers using a proxy for fetching source code signatures by configuring this option" } }, "containerEnv": { diff --git a/src/python/install.sh b/src/python/install.sh index 053a72aff..0e2b1253c 100755 --- a/src/python/install.sh +++ b/src/python/install.sh @@ -32,6 +32,8 @@ GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com keyserver hkps://keys.openpgp.org keyserver hkp://keyserver.pgp.com" +KEYSERVER_PROXY="${HTTPPROXY:-"${HTTP_PROXY:-""}"}" + set -e # Clean up @@ -84,6 +86,9 @@ receive_gpg_keys() { mkdir -p "$(dirname \"$2\")" keyring_args="--no-default-keyring --keyring $2" fi + if [ ! -z "${KEYSERVER_PROXY}" ]; then + keyring_args="${keyring_args} --keyserver-options http-proxy=${KEYSERVER_PROXY}" + fi # Use a temporary location for gpg keys to avoid polluting image export GNUPGHOME="/tmp/tmp-gnupg" From e2b3b48bc52be49b4e0063012e9ccdf0bf7672f4 Mon Sep 17 00:00:00 2001 From: Raymond <44623277+raymond-chetty@users.noreply.github.com> Date: Mon, 1 May 2023 08:37:43 -0700 Subject: [PATCH 116/478] Update devcontainer-feature.json (#535) #531 Modify proposed UID & GID so as not to conflict with base image. --- src/common-utils/devcontainer-feature.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 71b6e6687..8a532559f 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -40,7 +40,7 @@ "userUid": { "type": "string", "proposals": [ - "1000", + "1001", "automatic" ], "default": "automatic", @@ -49,7 +49,7 @@ "userGid": { "type": "string", "proposals": [ - "1000", + "1001", "automatic" ], "default": "automatic", From b16ff1efb7b092c73ab1e13c3d016d1ab7a9e4b6 Mon Sep 17 00:00:00 2001 From: Raymond <44623277+raymond-chetty@users.noreply.github.com> Date: Mon, 1 May 2023 08:38:01 -0700 Subject: [PATCH 117/478] Update devcontainer-feature.json (#539) #535 update the patch version to 2.0.9 --- 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 8a532559f..9ae905b62 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.8", + "version": "2.0.9", "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 4312340798680a2b148847b124fcf737e5839c2e Mon Sep 17 00:00:00 2001 From: "M. R" <2947595+m-roberts@users.noreply.github.com> Date: Tue, 2 May 2023 20:00:45 +0100 Subject: [PATCH 118/478] Add support for skipping `docker-compose` v1 operations during Docker feature install script (#533) * Add support for skipping docker-compose operations * Move changes from auto-generated files to templates and bump version * Add test * Add test conditions * Add test conditions for docker-outside-of-docker * install.sh set -x for debugging * set -x * Move compose-switch check in docker-outside-of-docker test * Put into correct test * Test for correct path --- .../devcontainer-feature.json | 5 +- src/docker-in-docker/install.sh | 103 +++++++++--------- .../devcontainer-feature.json | 5 +- src/docker-outside-of-docker/install.sh | 71 ++++++------ test/docker-in-docker/docker_build.sh | 3 + .../docker_build_no_compose.sh | 16 +++ test/docker-in-docker/scenarios.json | 10 ++ test/docker-outside-of-docker/docker_build.sh | 2 + .../docker_build_no_compose.sh | 15 +++ .../docker_dash_compose_v2.sh | 2 + test/docker-outside-of-docker/scenarios.json | 9 ++ 11 files changed, 153 insertions(+), 88 deletions(-) mode change 100644 => 100755 test/docker-in-docker/docker_build.sh create mode 100755 test/docker-in-docker/docker_build_no_compose.sh mode change 100644 => 100755 test/docker-outside-of-docker/docker_build.sh create mode 100755 test/docker-outside-of-docker/docker_build_no_compose.sh diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 798b8e87a..1555cd6e7 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.1.0", + "version": "2.2.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.", @@ -23,11 +23,12 @@ "dockerDashComposeVersion": { "type": "string", "enum": [ + "none", "v1", "v2" ], "default": "v1", - "description": "Default version of Docker Compose (v1 or v2)" + "description": "Default version of Docker Compose (v1 or v2 or none)" }, "azureDnsAutoDetection": { "type": "boolean", diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 770519902..9ad807e3c 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -10,7 +10,7 @@ DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version USE_MOBY="${MOBY:-"true"}" -DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2 +DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2 or none AZURE_DNS_AUTO_DETECTION="${AZUREDNSAUTODETECTION:-"true"}" DOCKER_DEFAULT_ADDRESS_POOL="${DOCKERDEFAULTADDRESSPOOL}" USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" @@ -242,58 +242,61 @@ fi echo "Finished installing docker / moby!" -# 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 v1 already installed." -else - target_compose_arch="${architecture}" - if [ "${target_compose_arch}" = "amd64" ]; then - target_compose_arch="x86_64" - fi - if [ "${target_compose_arch}" != "x86_64" ]; then - # 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 +# If 'docker-compose' command is to be included +if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then + # 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 v1 already installed." 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 + target_compose_arch="${architecture}" + if [ "${target_compose_arch}" = "amd64" ]; then + target_compose_arch="x86_64" + fi + if [ "${target_compose_arch}" != "x86_64" ]; then + # 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 + fi fi -fi -# Install docker-compose switch if not already installed - https://github.com/docker/compose-switch#manual-installation -current_v1_compose_path="$(which docker-compose)" -target_v1_compose_path="$(dirname "${current_v1_compose_path}")/docker-compose-v1" -if ! type compose-switch > /dev/null 2>&1; then - echo "(*) Installing compose-switch..." - compose_switch_version="latest" - find_version_from_git_tags compose_switch_version "https://github.com/docker/compose-switch" - curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch - 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_v1_compose_path}" "${target_v1_compose_path}" - update-alternatives --install /usr/local/bin/docker-compose docker-compose /usr/local/bin/compose-switch 99 - update-alternatives --install /usr/local/bin/docker-compose docker-compose "${target_v1_compose_path}" 1 -fi -if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then - update-alternatives --set docker-compose "${target_v1_compose_path}" -else - update-alternatives --set docker-compose /usr/local/bin/compose-switch + # Install docker-compose switch if not already installed - https://github.com/docker/compose-switch#manual-installation + current_v1_compose_path="$(which docker-compose)" + target_v1_compose_path="$(dirname "${current_v1_compose_path}")/docker-compose-v1" + if ! type compose-switch > /dev/null 2>&1; then + echo "(*) Installing compose-switch..." + compose_switch_version="latest" + find_version_from_git_tags compose_switch_version "https://github.com/docker/compose-switch" + curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/compose-switch + 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_v1_compose_path}" "${target_v1_compose_path}" + update-alternatives --install /usr/local/bin/docker-compose docker-compose /usr/local/bin/compose-switch 99 + update-alternatives --install /usr/local/bin/docker-compose docker-compose "${target_v1_compose_path}" 1 + fi + if [ "${DOCKER_DASH_COMPOSE_VERSION}" = "v1" ]; then + update-alternatives --set docker-compose "${target_v1_compose_path}" + else + update-alternatives --set docker-compose /usr/local/bin/compose-switch + fi fi # If init file already exists, exit diff --git a/src/docker-outside-of-docker/devcontainer-feature.json b/src/docker-outside-of-docker/devcontainer-feature.json index 2b75aa4f3..d3123fabe 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.2.1", + "version": "1.3.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.", @@ -23,11 +23,12 @@ "dockerDashComposeVersion": { "type": "string", "enum": [ + "none", "v1", "v2" ], "default": "v2", - "description": "Compose version to use for docker-compose (v1 or v2)" + "description": "Compose version to use for docker-compose (v1 or v2 or none)" }, "installDockerBuildx": { "type": "boolean", diff --git a/src/docker-outside-of-docker/install.sh b/src/docker-outside-of-docker/install.sh index f32db2f4a..7bf2138b4 100755 --- a/src/docker-outside-of-docker/install.sh +++ b/src/docker-outside-of-docker/install.sh @@ -9,7 +9,7 @@ DOCKER_VERSION="${VERSION:-"latest"}" USE_MOBY="${MOBY:-"true"}" -DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v2"}" # v1 or v2 +DOCKER_DASH_COMPOSE_VERSION="${DOCKERDASHCOMPOSEVERSION:-"v1"}" # v1 or v2 or none ENABLE_NONROOT_DOCKER="${ENABLE_NONROOT_DOCKER:-"true"}" SOURCE_SOCKET="${SOURCE_SOCKET:-"/var/run/docker-host.sock"}" @@ -216,43 +216,46 @@ else unset buildx buildx_path fi -# 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 - # 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 +# If 'docker-compose' command is to be included +if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; then + # 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 + # 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 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 + echo "(*) Installing compose-switch as docker-compose..." + compose_switch_version="latest" + find_version_from_git_tags compose_switch_version "https://github.com/docker/compose-switch" + curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose + # TODO: Verify checksum once available: https://github.com/docker/compose-switch/issues/11 fi -else - echo "(*) Installing compose-switch as docker-compose..." - compose_switch_version="latest" - find_version_from_git_tags compose_switch_version "https://github.com/docker/compose-switch" - curl -fsSL "https://github.com/docker/compose-switch/releases/download/v${compose_switch_version}/docker-compose-linux-${architecture}" -o /usr/local/bin/docker-compose - chmod +x /usr/local/bin/docker-compose - # TODO: Verify checksum once available: https://github.com/docker/compose-switch/issues/11 fi # Setup a docker group in the event the docker socket's group is not root diff --git a/test/docker-in-docker/docker_build.sh b/test/docker-in-docker/docker_build.sh old mode 100644 new mode 100755 index 742b222fb..d51e7d644 --- a/test/docker-in-docker/docker_build.sh +++ b/test/docker-in-docker/docker_build.sh @@ -9,5 +9,8 @@ source dev-container-features-test-lib check "docker-buildx" docker buildx version check "docker-build" docker build ./ +check "installs docker-compose v1 install" bash -c "type docker-compose" +check "installs compose-switch" bash -c "[[ -f /usr/local/bin/compose-switch ]]" + # Report result reportResults diff --git a/test/docker-in-docker/docker_build_no_compose.sh b/test/docker-in-docker/docker_build_no_compose.sh new file mode 100755 index 000000000..e913be321 --- /dev/null +++ b/test/docker-in-docker/docker_build_no_compose.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker-buildx" docker buildx version +check "docker-build" docker build ./ + +check "not installing compose skips docker-compose v1 install" bash -c "! type docker-compose" +check "not installing compose skips compose-switch" bash -c "[[ ! -f /usr/local/bin/compose-switch ]]" + +# Report result +reportResults diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index 5123d0916..9c44478f1 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -58,5 +58,15 @@ } }, "remoteUser": "node" + }, + "docker_build_no_compose": { + "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "features": { + "docker-in-docker": { + "dockerDashComposeVersion": "none" + } + }, + "remoteUser": "node" } + } diff --git a/test/docker-outside-of-docker/docker_build.sh b/test/docker-outside-of-docker/docker_build.sh old mode 100644 new mode 100755 index 742b222fb..056a76425 --- a/test/docker-outside-of-docker/docker_build.sh +++ b/test/docker-outside-of-docker/docker_build.sh @@ -9,5 +9,7 @@ source dev-container-features-test-lib check "docker-buildx" docker buildx version check "docker-build" docker build ./ +check "installs docker-compose v1 install" bash -c "type docker-compose" + # Report result reportResults diff --git a/test/docker-outside-of-docker/docker_build_no_compose.sh b/test/docker-outside-of-docker/docker_build_no_compose.sh new file mode 100755 index 000000000..477bf2149 --- /dev/null +++ b/test/docker-outside-of-docker/docker_build_no_compose.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker-buildx" docker buildx version +check "docker-build" docker build ./ + +check "not installing compose skips docker-compose v1 install" bash -c "! type docker-compose" + +# Report result +reportResults diff --git a/test/docker-outside-of-docker/docker_dash_compose_v2.sh b/test/docker-outside-of-docker/docker_dash_compose_v2.sh index 8f2a104f5..b24238f0d 100755 --- a/test/docker-outside-of-docker/docker_dash_compose_v2.sh +++ b/test/docker-outside-of-docker/docker_dash_compose_v2.sh @@ -9,5 +9,7 @@ source dev-container-features-test-lib 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 diff --git a/test/docker-outside-of-docker/scenarios.json b/test/docker-outside-of-docker/scenarios.json index be63470c5..3b82c6cc5 100644 --- a/test/docker-outside-of-docker/scenarios.json +++ b/test/docker-outside-of-docker/scenarios.json @@ -115,5 +115,14 @@ } }, "containerUser": "vscode" + }, + "docker_build_no_compose": { + "image": "mcr.microsoft.com/devcontainers/javascript-node:0-18", + "features": { + "docker-in-docker": { + "dockerDashComposeVersion": "none" + } + }, + "remoteUser": "node" } } From 4420cd5d27a551abbaa622bcde71dedb39617283 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 9 May 2023 13:52:06 -0700 Subject: [PATCH 119/478] Automated documentation update (#543) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/docker-in-docker/README.md | 2 +- src/docker-outside-of-docker/README.md | 2 +- src/python/README.md | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/docker-in-docker/README.md b/src/docker-in-docker/README.md index d519a48fb..bfca77357 100644 --- a/src/docker-in-docker/README.md +++ b/src/docker-in-docker/README.md @@ -17,7 +17,7 @@ Create child containers *inside* a container, independent from the host's docker |-----|-----|-----|-----| | version | Select or enter a Docker/Moby Engine version. (Availability can vary by OS version.) | string | latest | | moby | Install OSS Moby build instead of Docker CE | boolean | true | -| dockerDashComposeVersion | Default version of Docker Compose (v1 or v2) | string | v1 | +| dockerDashComposeVersion | Default version of Docker Compose (v1 or v2 or none) | string | v1 | | azureDnsAutoDetection | Allow automatically setting the dockerd DNS server when the installation script detects it is running in Azure | boolean | true | | 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 | diff --git a/src/docker-outside-of-docker/README.md b/src/docker-outside-of-docker/README.md index 7b558a971..94c891564 100644 --- a/src/docker-outside-of-docker/README.md +++ b/src/docker-outside-of-docker/README.md @@ -19,7 +19,7 @@ Re-use the host docker socket, adding the Docker CLI to a container. Feature inv |-----|-----|-----|-----| | version | Select or enter a Docker/Moby CLI version. (Availability can vary by OS version.) | string | latest | | moby | Install OSS Moby build instead of Docker CE | boolean | true | -| dockerDashComposeVersion | Compose version to use for docker-compose (v1 or v2) | string | v2 | +| dockerDashComposeVersion | Compose version to use for docker-compose (v1 or v2 or none) | string | v2 | | installDockerBuildx | Install Docker Buildx | boolean | true | ## Customizations diff --git a/src/python/README.md b/src/python/README.md index 807d89eb1..2dd092ae7 100644 --- a/src/python/README.md +++ b/src/python/README.md @@ -21,6 +21,7 @@ Installs the provided version of Python, as well as PIPX, and other common Pytho | installPath | The path where python will be installed. | string | /usr/local/python | | installJupyterlab | Install JupyterLab, a web-based interactive development environment for notebooks | boolean | false | | configureJupyterlabAllowOrigin | Configure JupyterLab to accept HTTP requests from the specified origin | string | - | +| httpProxy | Connect to GPG keyservers using a proxy for fetching source code signatures by configuring this option | string | - | ## Customizations From 1869e5931cfe0517f75d58cb70863a6b4874c487 Mon Sep 17 00:00:00 2001 From: "Stephen A. Imhoff" Date: Wed, 10 May 2023 10:04:16 -0700 Subject: [PATCH 120/478] Create .config directory in common-utils (#547) * Add test case for mounted subdirectory. * Correct some trailing whitespace. * Correct variable name to better reflect status as user home path. * Add config directory creation. * Remove extra debug line. * Bump feature version. * Mount host user home directory as "subdirectory" * Correct test naming, run test in explicit bash shell. --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 53 +++++++++++++--------- test/common-utils/config-subdirectory.sh | 13 ++++++ test/common-utils/scenarios.json | 10 ++++ 4 files changed, 55 insertions(+), 23 deletions(-) create mode 100755 test/common-utils/config-subdirectory.sh diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 9ae905b62..aadc1bc27 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.9", + "version": "2.0.10", "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 2a8cd282e..144478ee1 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -68,7 +68,7 @@ install_debian_packages() { manpages \ manpages-dev \ init-system-helpers" - + # Needed for adding manpages-posix and manpages-posix-dev which are non-free packages in Debian if [ "${ADD_NON_FREE_PACKAGES}" = "true" ]; then # Bring in variables from /etc/os-release like VERSION_CODENAME @@ -78,7 +78,7 @@ install_debian_packages() { sed -i -E "s/deb-src http:\/\/(deb|httpredir)\.debian\.org\/debian ${VERSION_CODENAME}-updates main/deb http:\/\/\1\.debian\.org\/debian ${VERSION_CODENAME}-updates main contrib non-free/" /etc/apt/sources.list sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list sed -i "s/deb-src http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}\/updates main contrib non-free/" /etc/apt/sources.list - sed -i "s/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list + sed -i "s/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list sed -i "s/deb-src http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main/deb http:\/\/deb\.debian\.org\/debian ${VERSION_CODENAME}-backports main contrib non-free/" /etc/apt/sources.list # Handle bullseye location for security https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html sed -i "s/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main/deb http:\/\/security\.debian\.org\/debian-security ${VERSION_CODENAME}-security main contrib non-free/" /etc/apt/sources.list @@ -133,13 +133,13 @@ install_debian_packages() { # Ensure at least the en_US.UTF-8 UTF-8 locale is available = common need for both applications and things like the agnoster ZSH theme. if [ "${LOCALE_ALREADY_SET}" != "true" ] && ! grep -o -E '^\s*en_US.UTF-8\s+UTF-8' /etc/locale.gen > /dev/null; then - echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen + echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen locale-gen LOCALE_ALREADY_SET="true" fi # Clean up - apt-get -y clean + apt-get -y clean rm -rf /var/lib/apt/lists/* } @@ -254,7 +254,7 @@ install_alpine_packages() { # Install man pages - package name varies between 3.12 and earlier versions if apk info man > /dev/null 2>&1; then apk add --no-cache man man-pages - else + else apk add --no-cache mandoc man-pages fi @@ -324,7 +324,7 @@ fi if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then if [ "${_REMOTE_USER}" != "root" ]; then USERNAME="${_REMOTE_USER}" - else + else USERNAME="" POSSIBLE_USERS=("devcontainer" "vscode" "node" "codespace" "$(awk -v val=1000 -F ":" '$3==val{print $1}' /etc/passwd)") for CURRENT_USER in "${POSSIBLE_USERS[@]}"; do @@ -346,12 +346,12 @@ fi group_name="${USERNAME}" if id -u ${USERNAME} > /dev/null 2>&1; then # User exists, update if needed - if [ "${USER_GID}" != "automatic" ] && [ "$USER_GID" != "$(id -g $USERNAME)" ]; then + if [ "${USER_GID}" != "automatic" ] && [ "$USER_GID" != "$(id -g $USERNAME)" ]; then group_name="$(id -gn $USERNAME)" groupmod --gid $USER_GID ${group_name} usermod --gid $USER_GID $USERNAME fi - if [ "${USER_UID}" != "automatic" ] && [ "$USER_UID" != "$(id -u $USERNAME)" ]; then + if [ "${USER_UID}" != "automatic" ] && [ "$USER_UID" != "$(id -u $USERNAME)" ]; then usermod --uid $USER_UID $USERNAME fi else @@ -361,7 +361,7 @@ else else groupadd --gid $USER_GID $USERNAME fi - if [ "${USER_UID}" = "automatic" ]; then + if [ "${USER_UID}" = "automatic" ]; then useradd -s /bin/bash --gid $USERNAME -m $USERNAME else useradd -s /bin/bash --uid $USER_UID --gid $USERNAME -m $USERNAME @@ -379,13 +379,13 @@ fi # ** Shell customization section ** # ********************************* -if [ "${USERNAME}" = "root" ]; then - user_rc_path="/root" +if [ "${USERNAME}" = "root" ]; then + user_home="/root" else - user_rc_path="/home/${USERNAME}" - if [ ! -d "${user_rc_path}" ]; then - mkdir -p "${user_rc_path}" - chown ${USERNAME}:${group_name} "${user_rc_path}" + user_home="/home/${USERNAME}" + if [ ! -d "${user_home}" ]; then + mkdir -p "${user_home}" + chown ${USERNAME}:${group_name} "${user_home}" fi fi @@ -393,9 +393,9 @@ fi possible_rc_files=( ".bashrc" ".profile" ".zshrc" ) for rc_file in "${possible_rc_files[@]}"; do if [ -f "/etc/skel/${rc_file}" ]; then - if [ ! -e "${user_rc_path}/${rc_file}" ] || [ ! -s "${user_rc_path}/${rc_file}" ]; then - cp "/etc/skel/${rc_file}" "${user_rc_path}/${rc_file}" - chown ${USERNAME}:${group_name} "${user_rc_path}/${rc_file}" + if [ ! -e "${user_home}/${rc_file}" ] || [ ! -s "${user_home}/${rc_file}" ]; then + cp "/etc/skel/${rc_file}" "${user_home}/${rc_file}" + chown ${USERNAME}:${group_name} "${user_home}/${rc_file}" fi fi done @@ -416,10 +416,10 @@ if [ "${RC_SNIPPET_ALREADY_ADDED}" != "true" ]; then ;; esac cat "${FEATURE_DIR}/scripts/rc_snippet.sh" >> ${global_rc_path} - cat "${FEATURE_DIR}/scripts/bash_theme_snippet.sh" >> "${user_rc_path}/.bashrc" + cat "${FEATURE_DIR}/scripts/bash_theme_snippet.sh" >> "${user_home}/.bashrc" if [ "${USERNAME}" != "root" ]; then cat "${FEATURE_DIR}/scripts/bash_theme_snippet.sh" >> "/root/.bashrc" - chown ${USERNAME}:${group_name} "${user_rc_path}/.bashrc" + chown ${USERNAME}:${group_name} "${user_home}/.bashrc" fi RC_SNIPPET_ALREADY_ADDED="true" fi @@ -442,10 +442,10 @@ if [ "${INSTALL_ZSH}" = "true" ]; then # Adapted, simplified inline Oh My Zsh! install steps that adds, defaults to a codespaces theme. # See https://github.com/ohmyzsh/ohmyzsh/blob/master/tools/install.sh for official script. - oh_my_install_dir="${user_rc_path}/.oh-my-zsh" + oh_my_install_dir="${user_home}/.oh-my-zsh" if [ ! -d "${oh_my_install_dir}" ] && [ "${INSTALL_OH_MY_ZSH}" = "true" ]; then template_path="${oh_my_install_dir}/templates/zshrc.zsh-template" - user_rc_file="${user_rc_path}/.zshrc" + user_rc_file="${user_home}/.zshrc" umask g-w,o-w mkdir -p ${oh_my_install_dir} git clone --depth=1 \ @@ -474,6 +474,15 @@ if [ "${INSTALL_ZSH}" = "true" ]; then fi fi +# ********************************* +# ** Ensure config directory ** +# ********************************* +user_config_dir="${user_home}/.config" +if [ ! -d "${user_config_dir}" ]; then + mkdir -p "${user_config_dir}" + chown ${USERNAME}:${group_name} "${user_config_dir}" +fi + # **************************** # ** Utilities and commands ** # **************************** diff --git a/test/common-utils/config-subdirectory.sh b/test/common-utils/config-subdirectory.sh new file mode 100755 index 000000000..ba67fb68f --- /dev/null +++ b/test/common-utils/config-subdirectory.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "owned-config-sub-directory" bash -c "ls -ld ~/.config/subdirectory | awk '{print $3}' | grep 'devcontainer'" +check "owned-config-directory" bash -c "ls -ld ~/.config | awk '{print $3}' | grep 'devcontainer'" + +# Report result +reportResults diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index 43d11c9a1..21cb9408a 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -115,6 +115,16 @@ } } }, + "config-subdirectory": { + "image": "alpine", + "remoteUser": "devcontainer", + "features": { + "common-utils": {} + }, + "mounts": [ + "source=${localEnv:HOME},target=/home/devcontainer/.config/subdirectory,type=bind,readonly" + ] + }, "alpine-3-14": { "image": "alpine:3.14", "remoteUser": "devcontainer", From b48d8700ffe5c0b363c9e8706ba2c1601a2bb94f Mon Sep 17 00:00:00 2001 From: Raymond <44623277+raymond-chetty@users.noreply.github.com> Date: Mon, 22 May 2023 12:23:23 -0700 Subject: [PATCH 121/478] Update NOTES.md (#534) * Update NOTES.md #531: Quick document update about UID & GID using 1000 in devcontainer base images. * Update src/common-utils/NOTES.md @samruddhikhandale The common-utils Feature is used by most of the dev container images, along with the base image. Can we update the text? Co-authored-by: Samruddhi Khandale * Update src/common-utils/NOTES.md @samruddhikhandale Co-authored-by: Samruddhi Khandale --------- Co-authored-by: Samruddhi Khandale --- src/common-utils/NOTES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common-utils/NOTES.md b/src/common-utils/NOTES.md index e9b27131e..f2c7aa72e 100644 --- a/src/common-utils/NOTES.md +++ b/src/common-utils/NOTES.md @@ -2,6 +2,11 @@ This Feature should work on recent versions of Debian/Ubuntu, RedHat Enterprise Linux, Fedora, RockyLinux, and Alpine Linux. +## Using with dev container images + +This Feature is used in many of the [dev container images](https://github.com/search?q=repo%3Adevcontainers%2Fimages+%22ghcr.io%2Fdevcontainers%2Ffeatures%2Fcommon-utils%22&type=code), as a result +these images have already allocated UID & GID 1000. Attempting to add this Feature with UID 1000 and/or GID 1000 on top of such a dev container image will result in an error when building the dev container. + ## Customizing the command prompt By default, this script provides a custom command prompt that includes information about the git repository for the current folder. However, with certain large repositories, this can result in a slow command prompt due to the performance of needed git operations. From cfae3b0f0d016f36229060b0e2abf5d55c9304e3 Mon Sep 17 00:00:00 2001 From: Shunya Hayashi <70781900+devshun@users.noreply.github.com> Date: Thu, 1 Jun 2023 00:53:50 +0900 Subject: [PATCH 122/478] update go tools (#559) * update go tools * update link * add unit tests for confirm installation * fix path install gotests * fix bump the minor version --- src/go/devcontainer-feature.json | 2 +- src/go/install.sh | 11 +++++++---- test/go/test.sh | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/go/devcontainer-feature.json b/src/go/devcontainer-feature.json index 92ed59154..963dc8948 100644 --- a/src/go/devcontainer-feature.json +++ b/src/go/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "go", - "version": "1.1.3", + "version": "1.2.0", "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.", diff --git a/src/go/install.sh b/src/go/install.sh index 365421e4a..f79fc6f3d 100755 --- a/src/go/install.sh +++ b/src/go/install.sh @@ -191,15 +191,18 @@ else fi # Install Go tools that are isImportant && !replacedByGopls based on -# https://github.com/golang/vscode-go/blob/v0.31.1/src/goToolsInformation.ts +# https://github.com/golang/vscode-go/blob/v0.38.0/src/goToolsInformation.ts GO_TOOLS="\ golang.org/x/tools/gopls@latest \ honnef.co/go/tools/cmd/staticcheck@latest \ golang.org/x/lint/golint@latest \ github.com/mgechev/revive@latest \ - github.com/uudashr/gopkgs/v2/cmd/gopkgs@latest \ - github.com/ramya-rao-a/go-outline@latest \ - github.com/go-delve/delve/cmd/dlv@latest" + github.com/go-delve/delve/cmd/dlv@latest \ + github.com/fatih/gomodifytags@latest \ + github.com/haya14busa/goplay/cmd/goplay@latest \ + github.com/cweill/gotests/gotests@latest \ + github.com/josharian/impl@latest" + if [ "${INSTALL_GO_TOOLS}" = "true" ]; then echo "Installing common Go tools..." export PATH=${TARGET_GOROOT}/bin:${PATH} diff --git a/test/go/test.sh b/test/go/test.sh index ccae6da84..0a9e04573 100755 --- a/test/go/test.sh +++ b/test/go/test.sh @@ -5,9 +5,24 @@ set -e # Optional: Import test library source dev-container-features-test-lib +# go check "version" go version + +# revive check "revive version" revive --version check "revive is installed at correct path" bash -c "which revive | grep /go/bin/revive" +# gomodifytags +check "gomodifytags is installed at correct path" bash -c "which gomodifytags | grep /go/bin/gomodifytags" + +# goplay +check "goplay is installed at correct path" bash -c "which goplay | grep /go/bin/goplay" + +# gotests +check "gotests is installed at correct path" bash -c "which gotests | grep /go/bin/gotests" + +# impl +check "impl is installed at correct path" bash -c "which impl | grep /go/bin/impl" + # Report result reportResults \ No newline at end of file From 852f1f0567280b465913b487d5f8c773122c36ab Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 31 May 2023 11:55:51 -0700 Subject: [PATCH 123/478] Automated documentation update (#563) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/common-utils/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common-utils/README.md b/src/common-utils/README.md index 9102c950b..1eddcbcc3 100644 --- a/src/common-utils/README.md +++ b/src/common-utils/README.md @@ -28,6 +28,11 @@ Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-r This Feature should work on recent versions of Debian/Ubuntu, RedHat Enterprise Linux, Fedora, RockyLinux, and Alpine Linux. +## Using with dev container images + +This Feature is used in many of the [dev container images](https://github.com/search?q=repo%3Adevcontainers%2Fimages+%22ghcr.io%2Fdevcontainers%2Ffeatures%2Fcommon-utils%22&type=code), as a result +these images have already allocated UID & GID 1000. Attempting to add this Feature with UID 1000 and/or GID 1000 on top of such a dev container image will result in an error when building the dev container. + ## Customizing the command prompt By default, this script provides a custom command prompt that includes information about the git repository for the current folder. However, with certain large repositories, this can result in a slow command prompt due to the performance of needed git operations. From 367308c73606c03fa1a68e884d6ec37320a46b4f Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Fri, 16 Jun 2023 14:31:40 -0700 Subject: [PATCH 124/478] Add Debian Bookworm as a test base image (#575) test against debian bookworm --- .github/workflows/test-all.yaml | 4 ++-- .github/workflows/test-pr.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-all.yaml b/.github/workflows/test-all.yaml index ab51a737c..8dc206d86 100644 --- a/.github/workflows/test-all.yaml +++ b/.github/workflows/test-all.yaml @@ -42,11 +42,11 @@ jobs: ] baseImage: [ + "ubuntu:bionic", "ubuntu:focal", "ubuntu:jammy", - "ubuntu:bionic", "debian:11", - "debian:10", + "debian:12", "mcr.microsoft.com/devcontainers/base:ubuntu", "mcr.microsoft.com/devcontainers/base:debian", ] diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index fb586fb8b..6b91b612d 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -49,11 +49,11 @@ jobs: features: ${{ fromJSON(needs.detect-changes.outputs.features) }} baseImage: [ + "ubuntu:bionic", "ubuntu:focal", "ubuntu:jammy", - "ubuntu:bionic", "debian:11", - "debian:10", + "debian:12", "mcr.microsoft.com/devcontainers/base:ubuntu", "mcr.microsoft.com/devcontainers/base:debian", ] From ee9f0bfbf09d60c242f2bd96d168ab0ab8c4f5c5 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Mon, 19 Jun 2023 11:23:49 -0700 Subject: [PATCH 125/478] Temporaily pin TFLint to 0.46.1 (#583) temporaily pin TFLint to 0.46.1 https://github.com/devcontainers/features/issues/581 --- src/terraform/devcontainer-feature.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index 7ea73eea9..100bb02a8 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -20,10 +20,12 @@ "tflint": { "type": "string", "proposals": [ - "latest" + "latest", + "0.47.0", + "0.46.1" ], - "default": "latest", - "description": "Tflint version" + "default": "0.46.1", + "description": "Tflint version (Default value temporarily pinned to version 0.46.1: https://github.com/devcontainers/features/issues/581)" }, "terragrunt": { "type": "string", From 931262d20cb505880f44d8572e45cfbb393ae2fb Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Mon, 19 Jun 2023 18:24:44 +0000 Subject: [PATCH 126/478] release terraform --- 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 100bb02a8..523858382 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.3.0", + "version": "1.3.1", "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 2fb386db11231e054012c85b0e1b3c2e879aef34 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Mon, 19 Jun 2023 11:33:35 -0700 Subject: [PATCH 127/478] Automated documentation update (#585) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/terraform/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/terraform/README.md b/src/terraform/README.md index e93058718..6236e4382 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -16,7 +16,7 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | version | Terraform version | string | latest | -| tflint | Tflint version | string | latest | +| tflint | Tflint version (Default value temporarily pinned to version 0.46.1: https://github.com/devcontainers/features/issues/581) | string | 0.46.1 | | terragrunt | Terragrunt version | string | latest | | installSentinel | Install sentinel, a language and framework for policy built to be embedded in existing software to enable fine-grained, logic-based policy decisions | boolean | false | | installTFsec | Install tfsec, a tool to spot potential misconfigurations for your terraform code | boolean | false | From 2258fcb040d74de01dbfc9df7d8800d90a13d56c Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Wed, 21 Jun 2023 00:34:07 +0700 Subject: [PATCH 128/478] feat(rust): add up to version 1.70 options (#579) --- src/rust/devcontainer-feature.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/rust/devcontainer-feature.json b/src/rust/devcontainer-feature.json index fd5d02612..bc9044c60 100644 --- a/src/rust/devcontainer-feature.json +++ b/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "1.0.11", + "version": "1.0.12", "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,13 @@ "proposals": [ "latest", "none", + "1.70", + "1.69", + "1.68", + "1.67", + "1.66", + "1.65", + "1.64", "1.63", "1.62", "1.61" From d934503a050ba84e6b42a006aacd891c4088eb62 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Wed, 21 Jun 2023 11:13:46 -0700 Subject: [PATCH 129/478] Terraform: Add cosign integrity check for TFLint (#586) * add cosign integrity check for tflint * fallback to gpg verification --- src/terraform/devcontainer-feature.json | 6 +-- src/terraform/install.sh | 61 +++++++++++++++++++++---- test/terraform/older_tflint.sh | 13 ++++++ test/terraform/scenarios.json | 8 ++++ 4 files changed, 77 insertions(+), 11 deletions(-) create mode 100644 test/terraform/older_tflint.sh diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index 523858382..00f6ba478 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.3.1", + "version": "1.3.2", "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.", @@ -24,8 +24,8 @@ "0.47.0", "0.46.1" ], - "default": "0.46.1", - "description": "Tflint version (Default value temporarily pinned to version 0.46.1: https://github.com/devcontainers/features/issues/581)" + "default": "latest", + "description": "Tflint version (https://github.com/terraform-linters/tflint/releases)" }, "terragrunt": { "type": "string", diff --git a/src/terraform/install.sh b/src/terraform/install.sh index 75653c392..81682e80e 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -158,6 +158,26 @@ check_packages() { fi } +# Install 'cosign' for validating signatures +# https://docs.sigstore.dev/cosign/overview/ +ensure_cosign() { + check_packages curl ca-certificates gnupg2 + + if ! type cosign > /dev/null 2>&1; then + echo "Installing cosign..." + local LATEST_COSIGN_VERSION=$(curl https://api.github.com/repos/sigstore/cosign/releases/latest | grep tag_name | cut -d : -f2 | tr -d "v\", ") + curl -L "https://github.com/sigstore/cosign/releases/latest/download/cosign_${LATEST_COSIGN_VERSION}_${architecture}.deb" -o /tmp/cosign_${LATEST_COSIGN_VERSION}_${architecture}.deb + + dpkg -i /tmp/cosign_${LATEST_COSIGN_VERSION}_${architecture}.deb + rm /tmp/cosign_${LATEST_COSIGN_VERSION}_${architecture}.deb + fi + if ! type cosign > /dev/null 2>&1; then + echo "(!) Failed to install cosign." + exit 1 + fi + cosign version +} + # Ensure apt is in non-interactive to avoid prompts export DEBIAN_FRONTEND=noninteractive @@ -198,17 +218,42 @@ if [ "${TFLINT_VERSION}" != "none" ]; then TFLINT_FILENAME="tflint_linux_${architecture}.zip" curl -sSL -o /tmp/tf-downloads/${TFLINT_FILENAME} https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/${TFLINT_FILENAME} if [ "${TFLINT_SHA256}" != "dev-mode" ]; then - if [ "${TFLINT_SHA256}" = "automatic" ]; then - curl -sSL -o tflint_key "${TFLINT_GPG_KEY_URI}" - gpg -q --import tflint_key - curl -sSL -o tflint_checksums.txt https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt - curl -sSL -o tflint_checksums.txt.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.sig - gpg --verify tflint_checksums.txt.sig tflint_checksums.txt - else + + if [ "${TFLINT_SHA256}" != "automatic" ]; then echo "${TFLINT_SHA256} *${TFLINT_FILENAME}" > tflint_checksums.txt + sha256sum --ignore-missing -c tflint_checksums.txt + else + curl -sSL -o tflint_checksums.txt https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt + + set +e + curl -sSL -o checksums.txt.keyless.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.keyless.sig + set -e + + # Check that checksums.txt.keyless.sig exists and is not empty + if [ -s checksums.txt.keyless.sig ]; then + # Validate checksums with cosign + curl -sSL -o checksums.txt.pem https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.pem + ensure_cosign + cosign verify-blob \ + --certificate=/tmp/tf-downloads/checksums.txt.pem \ + --signature=/tmp/tf-downloads/checksums.txt.keyless.sig \ + --certificate-identity-regexp="^https://github.com/terraform-linters/tflint" \ + --certificate-oidc-issuer=https://token.actions.githubusercontent.com \ + /tmp/tf-downloads/tflint_checksums.txt + # Ensure that checksums.txt has $TFLINT_FILENAME + grep ${TFLINT_FILENAME} /tmp/tf-downloads/tflint_checksums.txt + # Validate downloaded file + sha256sum --ignore-missing -c tflint_checksums.txt + else + # Fallback to older, GPG-based verification (pre-0.47.0 of tflint) + curl -sSL -o tflint_checksums.txt.sig https://github.com/terraform-linters/tflint/releases/download/v${TFLINT_VERSION}/checksums.txt.sig + curl -sSL -o tflint_key "${TFLINT_GPG_KEY_URI}" + gpg -q --import tflint_key + gpg --verify tflint_checksums.txt.sig tflint_checksums.txt + fi fi - sha256sum --ignore-missing -c tflint_checksums.txt fi + unzip /tmp/tf-downloads/${TFLINT_FILENAME} mv -f tflint /usr/local/bin/ fi diff --git a/test/terraform/older_tflint.sh b/test/terraform/older_tflint.sh new file mode 100644 index 000000000..20009c995 --- /dev/null +++ b/test/terraform/older_tflint.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "terraform" terraform -version + +check "tflint" tflint --version + +# Report result +reportResults \ No newline at end of file diff --git a/test/terraform/scenarios.json b/test/terraform/scenarios.json index 897763518..0a4d8956c 100644 --- a/test/terraform/scenarios.json +++ b/test/terraform/scenarios.json @@ -22,5 +22,13 @@ "installTerraformDocs": true } } + }, + "older_tflint": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "features": { + "terraform": { + "tflint": "0.40.0" + } + } } } \ No newline at end of file From de40074875b7add6b1a0d2ed3496ad05699a02c2 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 23 Jun 2023 16:16:30 -0700 Subject: [PATCH 130/478] Automated documentation update (#587) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/terraform/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/terraform/README.md b/src/terraform/README.md index 6236e4382..2201c8db8 100644 --- a/src/terraform/README.md +++ b/src/terraform/README.md @@ -16,7 +16,7 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| | version | Terraform version | string | latest | -| tflint | Tflint version (Default value temporarily pinned to version 0.46.1: https://github.com/devcontainers/features/issues/581) | string | 0.46.1 | +| tflint | Tflint version (https://github.com/terraform-linters/tflint/releases) | string | latest | | terragrunt | Terragrunt version | string | latest | | installSentinel | Install sentinel, a language and framework for policy built to be embedded in existing software to enable fine-grained, logic-based policy decisions | boolean | false | | installTFsec | Install tfsec, a tool to spot potential misconfigurations for your terraform code | boolean | false | From ccce957d7e4bc1357559b361d4b219872ba57739 Mon Sep 17 00:00:00 2001 From: Josh Spicer Date: Tue, 27 Jun 2023 14:31:18 -0700 Subject: [PATCH 131/478] Azure CLI: Compatibility with Debian `bookworm` (#578) * add flag * try to install via apt version of pipx (will only work on bookworm) * _REMOTE_USER aware * dont change more than you need to,josh * increment azure-cli minor version (v1.1.0) * install globally * make sure env variables are in scope --- src/azure-cli/devcontainer-feature.json | 2 +- src/azure-cli/install.sh | 56 +++++++++++++++---- test/azure-cli/install_bicep.sh | 2 + test/azure-cli/install_extensions.sh | 2 + test/azure-cli/install_extensions_bookworm.sh | 8 +++ test/azure-cli/scenarios.json | 10 ++++ 6 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 test/azure-cli/install_extensions_bookworm.sh diff --git a/src/azure-cli/devcontainer-feature.json b/src/azure-cli/devcontainer-feature.json index 9ab2cc39b..901ba4fc1 100644 --- a/src/azure-cli/devcontainer-feature.json +++ b/src/azure-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "azure-cli", - "version": "1.0.8", + "version": "1.1.0", "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.", diff --git a/src/azure-cli/install.sh b/src/azure-cli/install.sh index 31bc6d864..181d62f05 100755 --- a/src/azure-cli/install.sh +++ b/src/azure-cli/install.sh @@ -25,6 +25,13 @@ if [ "$(id -u)" -ne 0 ]; then exit 1 fi +if [ -z "${_REMOTE_USER}" ]; then + echo -e 'Feature script must be executed by a tool that implements the dev container specification. See https://containers.dev/ for more information.' + exit 1 +fi + +echo "Effective REMOTE_USER: ${_REMOTE_USER}" + # Get central common setting get_common_setting() { if [ "${common_settings_file_loaded}" != "true" ]; then @@ -57,8 +64,6 @@ check_packages() { fi } -export DEBIAN_FRONTEND=noninteractive - # Soft version matching that resolves a version for a given package in the *current apt-cache* # Return value is stored in first argument (the unprocessed version) apt_cache_version_soft_match() { @@ -127,7 +132,39 @@ install_using_apt() { fi } -install_using_pip() { +install_using_pip_strategy() { + local ver="" + if [ "${AZ_VERSION}" = "latest" ] || [ "${AZ_VERSION}" = "lts" ] || [ "${AZ_VERSION}" = "stable" ]; then + # Empty, meaning grab the "latest" in the apt repo + ver="" + else + ver="==${AZ_VERSION}" + fi + + install_with_pipx "${ver}" || install_with_complete_python_installation "${ver}" || return 1 +} + +install_with_pipx() { + echo "(*) Attempting to install globally with pipx..." + local ver="$1" + export + local + + if ! type pipx > /dev/null 2>&1; then + echo "(*) Installing pipx..." + check_packages pipx + pipx ensurepath # Ensures PIPX_BIN_DIR is on the PATH + fi + + PIPX_HOME="/usr/local/pipx" \ + PIPX_BIN_DIR=/usr/local/bin \ + pipx install azure-cli${ver} + + echo "(*) Finished installing globally with pipx." +} + +install_with_complete_python_installation() { + local ver="$1" echo "(*) No pre-built binaries available in apt-cache. Installing via pip3." if ! dpkg -s python3-minimal python3-pip libffi-dev python3-venv > /dev/null 2>&1; then apt_get_update @@ -144,25 +181,20 @@ install_using_pip() { pipx_bin=/tmp/pip-tmp/bin/pipx fi - if [ "${AZ_VERSION}" = "latest" ] || [ "${AZ_VERSION}" = "lts" ] || [ "${AZ_VERSION}" = "stable" ]; then - # Empty, meaning grab the "latest" in the apt repo - ver="" - else - ver="==${AZ_VERSION}" - fi - set +e ${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' -f azure-cli${ver} # Fail gracefully if [ "$?" != 0 ]; then - echo "Could not install azure-cli${ver} via pip" + echo "Could not install azure-cli${ver} via pip3" rm -rf /tmp/pip-tmp return 1 fi set -e } +export DEBIAN_FRONTEND=noninteractive + # See if we're on x86_64 and if so, install via apt-get, otherwise use pip3 echo "(*) Installing Azure CLI..." . /etc/os-release @@ -176,7 +208,7 @@ fi if [ "${use_pip}" = "true" ]; then AZ_VERSION=${CACHED_AZURE_VERSION} - install_using_pip + install_using_pip_strategy if [ "$?" != 0 ]; then echo "Please provide a valid version for your distribution ${ID} ${VERSION_CODENAME} (${architecture})." diff --git a/test/azure-cli/install_bicep.sh b/test/azure-cli/install_bicep.sh index 955507fda..0430c64da 100644 --- a/test/azure-cli/install_bicep.sh +++ b/test/azure-cli/install_bicep.sh @@ -8,6 +8,8 @@ source dev-container-features-test-lib # Check to make sure the user is vscode check "user is vscode" whoami | grep vscode +check "version" az --version + # Bicep-specific tests check "bicep" bicep --version check "az bicep" az bicep version diff --git a/test/azure-cli/install_extensions.sh b/test/azure-cli/install_extensions.sh index 1e66e2633..58d1cfff2 100644 --- a/test/azure-cli/install_extensions.sh +++ b/test/azure-cli/install_extensions.sh @@ -8,6 +8,8 @@ source dev-container-features-test-lib # Check to make sure the user is vscode check "user is vscode" whoami | grep vscode +check "version" az --version + # Extension-specific tests check "aks-preview" az extension show --name aks-preview check "amg" az extension show --name amg diff --git a/test/azure-cli/install_extensions_bookworm.sh b/test/azure-cli/install_extensions_bookworm.sh new file mode 100644 index 000000000..3c281e685 --- /dev/null +++ b/test/azure-cli/install_extensions_bookworm.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +./install_extensions.sh \ No newline at end of file diff --git a/test/azure-cli/scenarios.json b/test/azure-cli/scenarios.json index cc1fd7512..231345225 100644 --- a/test/azure-cli/scenarios.json +++ b/test/azure-cli/scenarios.json @@ -9,6 +9,16 @@ } } }, + "install_extensions_bookworm": { + "image": "mcr.microsoft.com/devcontainers/base:bookworm", + "user": "vscode", + "features": { + "azure-cli": { + "version": "latest", + "extensions": "aks-preview,amg,containerapp" + } + } + }, "install_bicep": { "image": "mcr.microsoft.com/devcontainers/base:jammy", "user": "vscode", From 972fdffa717bad7d5db8d3f8e88a65d7953a34cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Melissa=20Weber=20Mendon=C3=A7a?= Date: Wed, 28 Jun 2023 13:17:04 -0300 Subject: [PATCH 132/478] Add instructions to set up port forwarding on devcontainer.json file (#593) --- src/desktop-lite/NOTES.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/desktop-lite/NOTES.md b/src/desktop-lite/NOTES.md index 891ce6c4a..9080c4335 100644 --- a/src/desktop-lite/NOTES.md +++ b/src/desktop-lite/NOTES.md @@ -6,6 +6,16 @@ This feature provides two ways of connecting to the desktop environment it adds. 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). +To set up the `6080` port from your `devcontainer.json` file, include the following: +```json + "forwardPorts": [6080], + "portsAttributes": { + "6080": { + "label": "desktop" + } + } +``` + 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). From 610286c369717c64610133e9b898a84c9dbecea3 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 28 Jun 2023 14:17:06 -0700 Subject: [PATCH 133/478] Automated documentation update (#596) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/desktop-lite/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/desktop-lite/README.md b/src/desktop-lite/README.md index ad05e4ff2..48397929b 100644 --- a/src/desktop-lite/README.md +++ b/src/desktop-lite/README.md @@ -29,6 +29,16 @@ This feature provides two ways of connecting to the desktop environment it adds. 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). +To set up the `6080` port from your `devcontainer.json` file, include the following: +```json + "forwardPorts": [6080], + "portsAttributes": { + "6080": { + "label": "desktop" + } + } +``` + 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). From b6dbe7051cb3c0491749409351804eef942b4160 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Jun 2023 16:16:30 -0700 Subject: [PATCH 134/478] Bump mpmath from 1.2.1 to 1.3.0 in /test/oryx/sample-python (#554) Bumps [mpmath](https://github.com/fredrik-johansson/mpmath) from 1.2.1 to 1.3.0. - [Release notes](https://github.com/fredrik-johansson/mpmath/releases) - [Changelog](https://github.com/mpmath/mpmath/blob/master/CHANGES) - [Commits](https://github.com/fredrik-johansson/mpmath/compare/1.2.1...1.3.0) --- updated-dependencies: - dependency-name: mpmath dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- test/oryx/sample-python/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/oryx/sample-python/requirements.txt b/test/oryx/sample-python/requirements.txt index c8a04f68a..0f34acb42 100644 --- a/test/oryx/sample-python/requirements.txt +++ b/test/oryx/sample-python/requirements.txt @@ -1,2 +1,2 @@ -mpmath==1.2.1 +mpmath==1.3.0 sympy==1.11.1 From ef76ff97b60f43c7dcff6691427d9fc54e9b2503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20Mendon=C3=A7a=20Fran=C3=A7a?= Date: Thu, 29 Jun 2023 18:00:56 -0400 Subject: [PATCH 135/478] Change Ruby extension to ruby-lsp (#566) This is the extension that is recommended in the VSCode documentation now. https://code.visualstudio.com/docs/languages/ruby --- src/ruby/devcontainer-feature.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ruby/devcontainer-feature.json b/src/ruby/devcontainer-feature.json index e9fafeefd..fdf8b26b3 100644 --- a/src/ruby/devcontainer-feature.json +++ b/src/ruby/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby", - "version": "1.0.10", + "version": "1.1.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.", @@ -21,7 +21,8 @@ "customizations": { "vscode": { "extensions": [ - "rebornix.Ruby" + "rebornix.Ruby", + "shopify.ruby-lsp" ] } }, From 8a51aa906676280364df60010575b7dad3162f37 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Thu, 29 Jun 2023 15:08:34 -0700 Subject: [PATCH 136/478] Automated documentation update (#602) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/ruby/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ruby/README.md b/src/ruby/README.md index 8e8ebe2c3..8184036c6 100644 --- a/src/ruby/README.md +++ b/src/ruby/README.md @@ -22,6 +22,7 @@ Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies. ### VS Code Extensions - `rebornix.Ruby` +- `shopify.ruby-lsp` From 300814be97eaa5b7780886bd2eb37e96b523b3e7 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Thu, 29 Jun 2023 15:14:11 -0700 Subject: [PATCH 137/478] Dotnet: Fix Feature failures on ubuntu:jammy (when installing using apt) (#590) * fix several bugs * fix test: .NET is now installed from ubuntu feeds * add comment ; use dev containers image * address comments * revert debugging cmd * fix test for bookworm --- src/dotnet/devcontainer-feature.json | 2 +- src/dotnet/install.sh | 32 +++++++++++++++++++++++---- test/dotnet/install_dotnet_6_jammy.sh | 17 ++++++++++++++ test/dotnet/install_dotnet_7_jammy.sh | 2 +- test/dotnet/install_dotnet_latest.sh | 2 +- test/dotnet/scenarios.json | 8 +++++++ test/dotnet/test.sh | 2 +- 7 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 test/dotnet/install_dotnet_6_jammy.sh diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index 4aa264c13..4f484ccba 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "dotnet", - "version": "1.1.3", + "version": "1.1.4", "name": "Dotnet CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet", "description": "Installs the .NET CLI. Provides option of installing sdk or runtime, and option of versions to install. Uses latest version of .NET sdk as defaults to install.", diff --git a/src/dotnet/install.sh b/src/dotnet/install.sh index 1c7430aa0..178994d71 100644 --- a/src/dotnet/install.sh +++ b/src/dotnet/install.sh @@ -33,6 +33,16 @@ DOTNET_VERSION_CODENAMES_REQUIRE_OLDER_LIBSSL_1="buster bullseye bionic focal hi # alongside DOTNET_VERSION, but not set as default. ADDITIONAL_VERSIONS=${ADDITIONALVERSIONS:-""} +APT_PREFERENCES_CONTENT="$(cat << 'EOF' +Package: * +Pin: origin "packages.microsoft.com" +Pin-Priority: 1001 +EOF +)" + +APT_PREFERENCES_FILE_ADDED="false" +APT_PREFERENCES_UPDATED="false" + set -e # Clean up @@ -147,9 +157,9 @@ apt_cache_package_and_version_soft_match() { . /etc/os-release local architecture="$(dpkg --print-architecture)" + apt-get update -y major_minor_version="$(echo "${requested_version}" | cut -d "." --field=1,2)" - package_name="$(apt-cache search "${partial_package_name}-[0-9].[0-9]" | awk -F" - " '{print $1}' | grep -m 1 "${partial_package_name}-${major_minor_version}")" - + package_name="$(apt-cache search "${partial_package_name}-[0-9].[0-9]$" | awk -F" - " '{print $1}' | grep -m 1 "${partial_package_name}-${major_minor_version}")" dot_escaped="${requested_version//./\\.}" dot_plus_escaped="${dot_escaped//+/\\+}" # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ @@ -193,6 +203,12 @@ install_using_apt() { # Import key safely and import Microsoft apt repo curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg echo "deb [arch=${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 + + [ ! -f /etc/apt/preferences ] && APT_PREFERENCES_FILE_ADDED="true" + APT_PREFERENCES_UPDATED="true" + + # See https://github.com/dotnet/core/issues/7699 + echo "${APT_PREFERENCES_CONTENT}" >> /etc/apt/preferences apt-get update -y fi @@ -233,8 +249,8 @@ install_using_apt() { mkdir -p "${TARGET_DOTNET_ROOT}" local dotnet_installed_version="$(dotnet --version)" # See if its the distro version - if [[ "$(dotnet --info)" == *"Base Path: /usr/lib/dotnet/dotnet${dotnet_installed_version:0:1}-${dotnet_installed_version}"* ]]; then - ln -s "/usr/lib/dotnet/dotnet${dotnet_installed_version:0:1}" "${CURRENT_DIR}" + if [[ "$(dotnet --info)" == *"Base Path: /usr/lib/dotnet/${DOTNET_SDK_OR_RUNTIME}/${dotnet_installed_version}"* ]]; then + ln -s "/usr/lib/dotnet" "${CURRENT_DIR}" else # Location used by MS repo versions ln -s "/usr/share/dotnet" "${CURRENT_DIR}" @@ -463,6 +479,14 @@ if [ "${CHANGE_OWNERSHIP}" = "true" ]; then fi # Clean up +if [ "${APT_PREFERENCES_UPDATED}" = "true" ]; then + if [ "${APT_PREFERENCES_FILE_ADDED}" = "true" ]; then + rm -f /etc/apt/preferences + else + head -n -3 /etc/apt/preferences > /tmp/preferences-temp && mv /tmp/preferences-temp /etc/apt/preferences + fi +fi + rm -rf /var/lib/apt/lists/* echo "Done!" diff --git a/test/dotnet/install_dotnet_6_jammy.sh b/test/dotnet/install_dotnet_6_jammy.sh new file mode 100644 index 000000000..fd1063473 --- /dev/null +++ b/test/dotnet/install_dotnet_6_jammy.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +check "dotnet sdks" dotnet --list-sdks +check "some major version of dotnet 6 is installed" bash -c "dotnet --list-sdks | grep '6\.[0-9]*\.[0-9]*'" +check "dotnet version 6 installed" bash -c "ls -l /usr/lib/dotnet/sdk | grep '6\.[0-9]*\.[0-9]*'" + +# Verify current symlink exists and works +check "current link dotnet" /usr/local/dotnet/current/dotnet --info +check "current link sdk" ls -l /usr/local/dotnet/current/sdk + +# Report result +reportResults diff --git a/test/dotnet/install_dotnet_7_jammy.sh b/test/dotnet/install_dotnet_7_jammy.sh index 2c015fc0e..139216885 100644 --- a/test/dotnet/install_dotnet_7_jammy.sh +++ b/test/dotnet/install_dotnet_7_jammy.sh @@ -7,7 +7,7 @@ source dev-container-features-test-lib check "dotnet sdks" dotnet --list-sdks check "some major version of dotnet 7 is installed" bash -c "dotnet --list-sdks | grep '7\.[0-9]*\.[0-9]*'" -check "dotnet version 7 installed" bash -c "ls -l /usr/share/dotnet/sdk | grep '7\.[0-9]*\.[0-9]*'" +check "dotnet version 7 installed" bash -c "ls -l /usr/lib/dotnet/sdk | grep '7\.[0-9]*\.[0-9]*'" # Verify current symlink exists and works check "current link dotnet" /usr/local/dotnet/current/dotnet --info diff --git a/test/dotnet/install_dotnet_latest.sh b/test/dotnet/install_dotnet_latest.sh index 2c015fc0e..139216885 100644 --- a/test/dotnet/install_dotnet_latest.sh +++ b/test/dotnet/install_dotnet_latest.sh @@ -7,7 +7,7 @@ source dev-container-features-test-lib check "dotnet sdks" dotnet --list-sdks check "some major version of dotnet 7 is installed" bash -c "dotnet --list-sdks | grep '7\.[0-9]*\.[0-9]*'" -check "dotnet version 7 installed" bash -c "ls -l /usr/share/dotnet/sdk | grep '7\.[0-9]*\.[0-9]*'" +check "dotnet version 7 installed" bash -c "ls -l /usr/lib/dotnet/sdk | grep '7\.[0-9]*\.[0-9]*'" # Verify current symlink exists and works check "current link dotnet" /usr/local/dotnet/current/dotnet --info diff --git a/test/dotnet/scenarios.json b/test/dotnet/scenarios.json index 37f83d5a9..afee26f84 100644 --- a/test/dotnet/scenarios.json +++ b/test/dotnet/scenarios.json @@ -48,6 +48,14 @@ } } }, + "install_dotnet_6_jammy": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "features": { + "dotnet": { + "version": "6" + } + } + }, "install_dotnet_latest": { "image": "ubuntu:jammy", "features": { diff --git a/test/dotnet/test.sh b/test/dotnet/test.sh index 7eb0cf6d5..f433654e6 100755 --- a/test/dotnet/test.sh +++ b/test/dotnet/test.sh @@ -11,7 +11,7 @@ check "sdks" dotnet --list-sdks check "version" dotnet --version echo "Validating expected version present..." -check "some major version of dotnet 7 is installed" bash -c "dotnet --version | grep '7\.[0-9]*\.[0-9]*'" +check "some major version of dotnet (7/8) is installed" bash -c "dotnet --version | grep '[7-8]\.[0-9]*\.[0-9]*'" # Verify current symlink exists and works check "current link dotnet" /usr/local/dotnet/current/dotnet --info From c4ffeebdacc3c7c020ee7c286aae88959aa91671 Mon Sep 17 00:00:00 2001 From: Kazuma Watanabe Date: Fri, 7 Jul 2023 02:23:36 +0900 Subject: [PATCH 138/478] Pin version of TFLint's GPG key URL (#605) --- src/terraform/devcontainer-feature.json | 4 ++-- src/terraform/install.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index 00f6ba478..b1e6df2c8 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.3.2", + "version": "1.3.3", "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.", @@ -74,4 +74,4 @@ "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] -} \ No newline at end of file +} diff --git a/src/terraform/install.sh b/src/terraform/install.sh index 81682e80e..82e3e8d51 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -27,7 +27,7 @@ TFSEC_SHA256="${TFSEC_SHA256:-"automatic"}" TERRAFORM_DOCS_SHA256="${TERRAFORM_DOCS_SHA256:-"automatic"}" TERRAFORM_GPG_KEY="72D7468F" -TFLINT_GPG_KEY_URI="https://raw.githubusercontent.com/terraform-linters/tflint/master/8CE69160EB3F2FE9.key" +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" From 07693965d74d289e9a4035907d2414d9683e0773 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 11 Jul 2023 11:16:23 -0700 Subject: [PATCH 139/478] Nvidia-cuda: Update notes regarding gpu enablement (#608) * Nvidia-cuda: Update notes regarding gpu enablement * use GPU hostRequirements instead * nit * use gpu:optional instead --- src/nvidia-cuda/NOTES.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/nvidia-cuda/NOTES.md b/src/nvidia-cuda/NOTES.md index cab2bbec7..db2b843a2 100644 --- a/src/nvidia-cuda/NOTES.md +++ b/src/nvidia-cuda/NOTES.md @@ -10,14 +10,19 @@ Follow [NVIDIA's instructions to install the NVIDIA Container Toolkit](https://d ### Enable GPU passthrough -Enable GPU passthrough to your devcontainer by adding `["--gpus", "all"]` to your devcontainer's `runArgs` property. Here's an example of a devcontainer with this property: +Enable GPU passthrough to your devcontainer by using `hostRequirements`. Here's an example of a devcontainer with this property: ```json { - "runArgs": ["--gpus", "all"] + "hostRequirements": { + "gpu": "optional" + } } ``` +> Note: Setting `gpu` property's value to `true` will work with GPU machine types, but fail with CPUs. Hence, setting it to `optional` works in both cases. See [schema](https://containers.dev/implementors/json_schema/#base-schema) for more configuration details. + + ## OS Support From 0e8940abead5068668bd78632ec9b20757541c95 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Tue, 11 Jul 2023 12:50:29 -0700 Subject: [PATCH 140/478] Automated documentation update (#610) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/nvidia-cuda/README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/nvidia-cuda/README.md b/src/nvidia-cuda/README.md index 38a989a04..7a0343de4 100644 --- a/src/nvidia-cuda/README.md +++ b/src/nvidia-cuda/README.md @@ -32,14 +32,19 @@ Follow [NVIDIA's instructions to install the NVIDIA Container Toolkit](https://d ### Enable GPU passthrough -Enable GPU passthrough to your devcontainer by adding `["--gpus", "all"]` to your devcontainer's `runArgs` property. Here's an example of a devcontainer with this property: +Enable GPU passthrough to your devcontainer by using `hostRequirements`. Here's an example of a devcontainer with this property: ```json { - "runArgs": ["--gpus", "all"] + "hostRequirements": { + "gpu": "optional" + } } ``` +> Note: Setting `gpu` property's value to `true` will work with GPU machine types, but fail with CPUs. Hence, setting it to `optional` works in both cases. See [schema](https://containers.dev/implementors/json_schema/#base-schema) for more configuration details. + + ## OS Support From 7fcec6e7c9dd587b24096597367ef42e4a37465b Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 19 Jul 2023 08:50:22 -0700 Subject: [PATCH 141/478] Fix: Docker-in-docker for python - Arm64 (#618) Fix: Docker-in-docker for python:3.11 - Arm64 --- src/docker-in-docker/devcontainer-feature.json | 2 +- src/docker-in-docker/install.sh | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 1555cd6e7..334982161 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.2.0", + "version": "2.2.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.", diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 9ad807e3c..6c889f5ac 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -265,7 +265,21 @@ if [ "${DOCKER_DASH_COMPOSE_VERSION}" != "none" ]; 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 + + set +e + ${pipx_bin} install --pip-args '--no-cache-dir --force-reinstall' docker-compose + exit_code=$? + set -e + + if [ ${exit_code} -ne 0 ]; then + # Temporary: https://github.com/devcontainers/features/issues/616 + # See https://github.com/yaml/pyyaml/issues/601 + echo "(*) Failed to install docker-compose via pipx. Trying via pip3..." + + 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 + rm -rf /tmp/pip-tmp else compose_v1_version="1" From ea2d79070ec4e91361412a88ead2ec9b78266b92 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 21 Jul 2023 17:37:10 -0700 Subject: [PATCH 142/478] Azure-cli - Temporary quick fix for jammy (ARM) (#626) --- src/azure-cli/devcontainer-feature.json | 7 ++++++- src/azure-cli/install.sh | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/azure-cli/devcontainer-feature.json b/src/azure-cli/devcontainer-feature.json index 901ba4fc1..09c295c21 100644 --- a/src/azure-cli/devcontainer-feature.json +++ b/src/azure-cli/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "azure-cli", - "version": "1.1.0", + "version": "1.2.0", "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.", @@ -22,6 +22,11 @@ "type": "boolean", "description": "Optionally install Azure Bicep", "default": false + }, + "installUsingPython": { + "type": "boolean", + "description": "Install Azure CLI using Python instead of pipx", + "default": true } }, "customizations": { diff --git a/src/azure-cli/install.sh b/src/azure-cli/install.sh index 181d62f05..9b0d72db3 100755 --- a/src/azure-cli/install.sh +++ b/src/azure-cli/install.sh @@ -15,7 +15,7 @@ rm -rf /var/lib/apt/lists/* AZ_VERSION=${VERSION:-"latest"} AZ_EXTENSIONS=${EXTENSIONS} AZ_INSTALLBICEP=${INSTALLBICEP:-false} - +INSTALL_USING_PYTHON=${INSTALL_USING_PYTHON:-true} MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" AZCLI_ARCHIVE_ARCHITECTURES="amd64" AZCLI_ARCHIVE_VERSION_CODENAMES="stretch buster bullseye bionic focal jammy" @@ -141,7 +141,12 @@ install_using_pip_strategy() { ver="==${AZ_VERSION}" fi - install_with_pipx "${ver}" || install_with_complete_python_installation "${ver}" || return 1 + # Temprary quick fix for https://github.com/devcontainers/features/issues/624 + if [ "${INSTALL_USING_PYTHON}" = "true" ]; then + install_with_complete_python_installation "${ver}" || install_with_pipx "${ver}" || return 1 + else + install_with_pipx "${ver}" || install_with_complete_python_installation "${ver}" || return 1 + fi } install_with_pipx() { From 836ea1e9faea580509b59f7df1e3b29f19c00e17 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 26 Jul 2023 14:43:43 -0700 Subject: [PATCH 143/478] Automated documentation update (#627) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/azure-cli/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/azure-cli/README.md b/src/azure-cli/README.md index 4a9de7b96..c3e23db8a 100644 --- a/src/azure-cli/README.md +++ b/src/azure-cli/README.md @@ -18,6 +18,7 @@ Installs the Azure CLI along with needed dependencies. Useful for base Dockerfil | version | Select or enter an Azure CLI version. (Available versions may vary by Linux distribution.) | string | latest | | extensions | Optional comma separated list of Azure CLI extensions to install in profile. | string | - | | installBicep | Optionally install Azure Bicep | boolean | false | +| installUsingPython | Install Azure CLI using Python instead of pipx | boolean | true | ## Customizations From 685fa2e0f151b4545b444135a5ef6877de20e851 Mon Sep 17 00:00:00 2001 From: Krikchai Pongtaveewould Date: Thu, 3 Aug 2023 05:12:14 +0700 Subject: [PATCH 144/478] Fix: common-utils configureZshAsDefaultShell option not working on alpine linux image (#557) * alpine defaultZsh fix * common-utils: replace pam.d/chsh permission with `sufficient` * common-utils: revert match auth sufficient * common-utils: append auth string instead of replacing a whole file * fix grep 2nd param * fix: line checking condition --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 8 ++++++++ test/common-utils/alpine-base-zsh-default.sh | 13 +++++++++++++ test/common-utils/scenarios.json | 13 +++++++++++-- 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 test/common-utils/alpine-base-zsh-default.sh diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index aadc1bc27..a924aa77a 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.10", + "version": "2.0.11", "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 144478ee1..6d5ac0719 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -437,6 +437,14 @@ if [ "${INSTALL_ZSH}" = "true" ]; then fi if [ "${CONFIGURE_ZSH_AS_DEFAULT_SHELL}" == "true" ]; then + # Fixing chsh always asking for a password on alpine linux + # ref: https://askubuntu.com/questions/812420/chsh-always-asking-a-password-and-get-pam-authentication-failure. + if [ ! -f "/etc/pam.d/chsh" ] || ! grep -Eq '^auth(.*)pam_rootok\.so$' /etc/pam.d/chsh; then + echo "auth sufficient pam_rootok.so" >> /etc/pam.d/chsh + elif [[ -n "$(awk '/^auth(.*)pam_rootok\.so$/ && !/^auth[[:blank:]]+sufficient[[:blank:]]+pam_rootok\.so$/' /etc/pam.d/chsh)" ]]; then + awk '/^auth(.*)pam_rootok\.so$/ { $2 = "sufficient" } { print }' /etc/pam.d/chsh > /tmp/chsh.tmp && mv /tmp/chsh.tmp /etc/pam.d/chsh + fi + chsh --shell /bin/zsh ${USERNAME} fi diff --git a/test/common-utils/alpine-base-zsh-default.sh b/test/common-utils/alpine-base-zsh-default.sh new file mode 100644 index 000000000..9fc00a267 --- /dev/null +++ b/test/common-utils/alpine-base-zsh-default.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "alpine default shell zsh" \ + bash -c "getent passwd $(whoami) | awk -F : '{ print $7 }' | grep '/bin/zsh'" + +# Report result +reportResults diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index 21cb9408a..9800242e9 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -143,6 +143,7 @@ "build": { "dockerfile": "Dockerfile" }, + "remoteUser": "vscode", "features": { "common-utils": { "username": "vscode", @@ -151,7 +152,15 @@ "upgradePackages": true, "installZsh": true } - }, - "remoteUser": "vscode" + } + }, + "alpine-base-zsh-default": { + "image": "mcr.microsoft.com/devcontainers/base:alpine", + "remoteUser": "vscode", + "features": { + "common-utils": { + "configureZshAsDefaultShell": true + } + } } } From 29859aff280dc187d6f508900f8600ebd04c56b7 Mon Sep 17 00:00:00 2001 From: Tom Palmer Date: Mon, 7 Aug 2023 23:12:13 +0100 Subject: [PATCH 145/478] Fix 2 instances of a typo in the desktop-lite NOTES and README (#640) * Amend 'is installed is' to 'installed is'. * Undo typo fix from README 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 9080c4335..924ce9b6e 100644 --- a/src/desktop-lite/NOTES.md +++ b/src/desktop-lite/NOTES.md @@ -25,7 +25,7 @@ You can also connect to the desktop using a [VNC viewer](https://www.realvnc.com ## Customizing Fluxbox -The window manager is installed is [Fluxbox](http://fluxbox.org/). **Right-click** to see the application menu. In addition, any UI-based commands you execute inside the dev container will automatically appear on the desktop. +The window manager installed is [Fluxbox](http://fluxbox.org/). **Right-click** to see the application menu. In addition, any UI-based commands you execute inside the dev container will automatically appear on the desktop. You can customize the desktop using Fluxbox configuration files. The configuration files are located in the `.fluxbox` folder of the home directory of the user you using to connect to the dev container (`$HOME/.fluxbox`). From bbb24d10d417452ef23a8c506fd0e2b141b71f15 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Mon, 7 Aug 2023 15:59:58 -0700 Subject: [PATCH 146/478] Docker-in-docker: Add retries to the docker-init script until docker daemon starts (#637) * Docker-in-docker: Add retries until docker daemon starts * address comments --- .../devcontainer-feature.json | 2 +- src/docker-in-docker/install.sh | 30 +++++++++++++---- test/docker-in-docker/docker_retry.sh | 32 +++++++++++++++++++ test/docker-in-docker/scenarios.json | 7 +++- .../test-scripts/docker-test-init.sh | 26 +++++++++++++++ 5 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 test/docker-in-docker/docker_retry.sh create mode 100644 test/docker-in-docker/test-scripts/docker-test-init.sh diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 334982161..b5e0aeea6 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.2.1", + "version": "2.3.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.", diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index 6c889f5ac..f7e5a7d52 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -5,7 +5,7 @@ #------------------------------------------------------------------------------------------------------------- # # Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md -# Maintainer: The VS Code and Codespaces Teams +# Maintainer: The Dev Container spec maintainers DOCKER_VERSION="${VERSION:-"latest"}" # The Docker/Moby Engine + CLI should match in version @@ -423,12 +423,28 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU INNEREOF )" -# Start using sudo if not invoked as root -if [ "$(id -u)" -ne 0 ]; then - sudo /bin/sh -c "${dockerd_start}" -else - eval "${dockerd_start}" -fi +retry_count=0 +docker_ok="false" + +until [ "${docker_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; +do + # Start using sudo if not invoked as root + if [ "$(id -u)" -ne 0 ]; then + sudo /bin/sh -c "${dockerd_start}" + else + eval "${dockerd_start}" + fi + + set +e + docker info > /dev/null 2>&1 && docker_ok="true" + + if [ "${docker_ok}" != "true" ]; then + echo "(*) Failed to start docker, retrying in 5s..." + retry_count=`expr $retry_count + 1` + sleep 5s + fi + set -e +done set +e diff --git a/test/docker-in-docker/docker_retry.sh b/test/docker-in-docker/docker_retry.sh new file mode 100644 index 000000000..cc35fbb04 --- /dev/null +++ b/test/docker-in-docker/docker_retry.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "docker-buildx" docker buildx version +check "docker-ps" docker ps + +sleep 5s + +# Stop docker +pkill dockerd +pkill containerd + +sleep 5s + +set +e + docker_ok_code="$(docker info > /dev/null 2>&1; echo $?)" +set -e + +check "docker-not-running" bash -c "[[ ${docker_ok_code} == 1 ]]" + +# Testing retry logic +./test-scripts/docker-test-init.sh + +check "docker-started-after-retries" docker ps + +# Report result +reportResults diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index 9c44478f1..525ce6930 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -67,6 +67,11 @@ } }, "remoteUser": "node" + }, + "docker_retry": { + "image": "ubuntu:focal", + "features": { + "docker-in-docker": {} + } } - } diff --git a/test/docker-in-docker/test-scripts/docker-test-init.sh b/test/docker-in-docker/test-scripts/docker-test-init.sh new file mode 100644 index 000000000..b213fb40c --- /dev/null +++ b/test/docker-in-docker/test-scripts/docker-test-init.sh @@ -0,0 +1,26 @@ +#!/bin/sh +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- + +retry_count=0 +docker_ok="false" + +until [ "${docker_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; +do + if [ "${retry_count}" -eq "3" ]; then + echo "Starting docker after 3 retries..." + /usr/local/share/docker-init.sh + fi + + set +e + docker info > /dev/null 2>&1 && docker_ok="true" + + if [ "${docker_ok}" != "true" ]; then + echo "(*) Failed to start docker, retrying in 5s... Retry count: ${retry_count}" + retry_count=`expr $retry_count + 1` + sleep 1s + fi + set -e +done \ No newline at end of file From f2594c5cc85e18450a31865f8387c8dc064006f2 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Mon, 7 Aug 2023 16:29:54 -0700 Subject: [PATCH 147/478] Automated documentation update (#642) 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 48397929b..7094a2425 100644 --- a/src/desktop-lite/README.md +++ b/src/desktop-lite/README.md @@ -48,7 +48,7 @@ You can also connect to the desktop using a [VNC viewer](https://www.realvnc.com ## Customizing Fluxbox -The window manager is installed is [Fluxbox](http://fluxbox.org/). **Right-click** to see the application menu. In addition, any UI-based commands you execute inside the dev container will automatically appear on the desktop. +The window manager installed is [Fluxbox](http://fluxbox.org/). **Right-click** to see the application menu. In addition, any UI-based commands you execute inside the dev container will automatically appear on the desktop. You can customize the desktop using Fluxbox configuration files. The configuration files are located in the `.fluxbox` folder of the home directory of the user you using to connect to the dev container (`$HOME/.fluxbox`). From 9e75db9a1dbcc245f94707c0917470143c17595b Mon Sep 17 00:00:00 2001 From: Shikanime Deva Date: Thu, 10 Aug 2023 01:20:27 +0200 Subject: [PATCH 148/478] Avoid unexpected shell expansion (#645) * Avoid unexpected shell expansion * Add install Node with ZSH as default test * Fix LTS only work on >bionic * Bump Node feature version * Remove huge universal image on scenarios --- src/node/devcontainer-feature.json | 4 ++-- src/node/install.sh | 24 ++++++++++++------------ test/node/scenarios.json | 20 +++++++++++--------- test/node/zsh_default.sh | 12 ++++++++++++ 4 files changed, 37 insertions(+), 23 deletions(-) create mode 100755 test/node/zsh_default.sh diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index 9bf90b67f..80bd91275 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.2.0", + "version": "1.2.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.", @@ -49,4 +49,4 @@ "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] -} +} \ No newline at end of file diff --git a/src/node/install.sh b/src/node/install.sh index 9048ac22e..1ce8fee3f 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -9,7 +9,7 @@ export NODE_VERSION="${VERSION:-"lts"}" export NVM_VERSION="${NVMVERSION:-"0.39.2"}" -export NVM_DIR=${NVMINSTALLPATH:-"/usr/local/share/nvm"} +export NVM_DIR="${NVMINSTALLPATH:-"/usr/local/share/nvm"}" INSTALL_TOOLS_FOR_NODE_GYP="${NODEGYPDEPENDENCIES:-true}" # Comma-separated list of node versions to be installed (with nvm) @@ -118,10 +118,10 @@ set -e umask 0002 # Do not update profile - we'll do this manually export PROFILE=/dev/null -curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh | bash -source ${NVM_DIR}/nvm.sh +curl -so- "https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh" | bash +source "${NVM_DIR}/nvm.sh" if [ "${NODE_VERSION}" != "" ]; then - nvm alias default ${NODE_VERSION} + nvm alias default "${NODE_VERSION}" fi EOF )" @@ -149,9 +149,9 @@ usermod -a -G nvm ${USERNAME} umask 0002 if [ ! -d "${NVM_DIR}" ]; then # Create nvm dir, and set sticky bit - mkdir -p ${NVM_DIR} - chown "${USERNAME}:nvm" ${NVM_DIR} - chmod g+rws ${NVM_DIR} + mkdir -p "${NVM_DIR}" + chown "${USERNAME}:nvm" "${NVM_DIR}" + chmod g+rws "${NVM_DIR}" su ${USERNAME} -c "${nvm_install_snippet}" 2>&1 # Update rc files if [ "${UPDATE_RC}" = "true" ]; then @@ -160,11 +160,11 @@ if [ ! -d "${NVM_DIR}" ]; then else echo "NVM already installed." if [ "${NODE_VERSION}" != "" ]; then - su ${USERNAME} -c "umask 0002 && . $NVM_DIR/nvm.sh && nvm install ${NODE_VERSION} && nvm alias default ${NODE_VERSION}" + su ${USERNAME} -c "umask 0002 && . '$NVM_DIR/nvm.sh' && nvm install '${NODE_VERSION}' && nvm alias default '${NODE_VERSION}'" fi fi -# Additional node versions to be installed but not be set as +# Additional node versions to be installed but not be set as # default we can assume the nvm is the group owner of the nvm # directory and the sticky bit on directories so any installed # files will have will have the correct ownership (nvm) @@ -173,12 +173,12 @@ if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then IFS="," read -a additional_versions <<< "$ADDITIONAL_VERSIONS" for ver in "${additional_versions[@]}"; do - su ${USERNAME} -c "umask 0002 && . $NVM_DIR/nvm.sh && nvm install ${ver}" + su ${USERNAME} -c "umask 0002 && . '$NVM_DIR/nvm.sh' && nvm install '${ver}'" done # Ensure $NODE_VERSION is on the $PATH if [ "${NODE_VERSION}" != "" ]; then - su ${USERNAME} -c "umask 0002 && . $NVM_DIR/nvm.sh && nvm use default" + su ${USERNAME} -c "umask 0002 && . '$NVM_DIR/nvm.sh' && nvm use default" fi IFS=$OLDIFS fi @@ -218,7 +218,7 @@ fi # Clean up -su ${USERNAME} -c "umask 0002 && . $NVM_DIR/nvm.sh && nvm clear-cache" +su ${USERNAME} -c "umask 0002 && . '$NVM_DIR/nvm.sh' && nvm clear-cache" rm -rf /var/lib/apt/lists/* # Ensure privs are correct for installed node versions. Unfortunately the diff --git a/test/node/scenarios.json b/test/node/scenarios.json index 6112a6ea4..5524f5c52 100644 --- a/test/node/scenarios.json +++ b/test/node/scenarios.json @@ -17,21 +17,23 @@ } } }, - "version_none": { - "image": "mcr.microsoft.com/devcontainers/base", - "remoteUser": "vscode", + "zsh_default": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", "features": { "node": { - "version": "none" + "version": "lts" + }, + "common-utils": { + "configureZshAsDefaultShell": true } } }, - "install_node_on_universal_image": { - "image": "mcr.microsoft.com/devcontainers/universal", - "remoteUser": "codespace", + "version_none": { + "image": "mcr.microsoft.com/devcontainers/base", + "remoteUser": "vscode", "features": { "node": { - "version": "19.1.0" + "version": "none" } } }, @@ -43,4 +45,4 @@ } } } -} +} \ No newline at end of file diff --git a/test/node/zsh_default.sh b/test/node/zsh_default.sh new file mode 100755 index 000000000..c7c9e57f4 --- /dev/null +++ b/test/node/zsh_default.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "nvm" bash -c ". /usr/local/share/nvm/nvm.sh && nvm install 10" + +# Report result +reportResults From be082b0ef5f0f3795708cd1a6c37a427d8c0bb73 Mon Sep 17 00:00:00 2001 From: naturedamends <120284608+naturedamends@users.noreply.github.com> Date: Sat, 12 Aug 2023 00:01:57 +0100 Subject: [PATCH 149/478] Common utils: Add config to remove zsh rc files from (#614) * Add config to remove zsh rc files from common-utils. * Bump version and add config to install script. * Checks preventing excess writing to .zshrc. * Change devcontainer feature option name. * Coding standards. * Favour adding feature via config and default to overriding .zshrc with dev-container default template. * Update devcontainer-feature.json * Update devcontainer-feature.json * Update src/common-utils/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * Update src/common-utils/devcontainer-feature.json Co-authored-by: Samruddhi Khandale * Testing for using devcontainer .zshrc template file. * Coding standards. * Coding standards. * Update configure_zsh_as_default_shell_no_template.sh * Grammar in configure_zsh_as_default_shell.sh * Testing accounts for marked file cache (#4) * Account for mark file in testing. * Remove some debugging and tests back * Add back tests? * Update configure_zsh_no_template.sh --------- Co-authored-by: Samruddhi Khandale --- src/common-utils/devcontainer-feature.json | 7 ++- src/common-utils/install.sh | 1 + src/common-utils/main.sh | 51 +++++++++++-------- .../configure_zsh_as_default_shell.sh | 2 + .../common-utils/configure_zsh_no_template.sh | 15 ++++++ test/common-utils/scenarios.json | 11 ++++ 6 files changed, 66 insertions(+), 21 deletions(-) create mode 100644 test/common-utils/configure_zsh_no_template.sh diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index a924aa77a..d70848278 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.0.11", + "version": "2.1.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.", @@ -20,6 +20,11 @@ "default": true, "description": "Install Oh My Zsh!?" }, + "installOhMyZshConfig": { + "type": "boolean", + "default": true, + "description": "Allow installing the default dev container .zshrc templates?" + }, "upgradePackages": { "type": "boolean", "default": true, diff --git a/src/common-utils/install.sh b/src/common-utils/install.sh index d08a2f2c1..8f1ece4d7 100755 --- a/src/common-utils/install.sh +++ b/src/common-utils/install.sh @@ -12,6 +12,7 @@ set -e INSTALL_ZSH="${INSTALLZSH:-"true"}" CONFIGURE_ZSH_AS_DEFAULT_SHELL="${CONFIGUREZSHASDEFAULTSHELL:-"false"}" INSTALL_OH_MY_ZSH="${INSTALLOHMYZSH:-"true"}" +INSTALL_OH_MY_ZSH_CONFIG="${INSTALLOHMYZSHCONFIG:-"true"}" UPGRADE_PACKAGES="${UPGRADEPACKAGES:-"true"}" USERNAME="${USERNAME:-"automatic"}" USER_UID="${UID:-"automatic"}" diff --git a/src/common-utils/main.sh b/src/common-utils/main.sh index 6d5ac0719..d3f7ef267 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -12,6 +12,7 @@ set -e INSTALL_ZSH="${INSTALLZSH:-"true"}" CONFIGURE_ZSH_AS_DEFAULT_SHELL="${CONFIGUREZSHASDEFAULTSHELL:-"false"}" INSTALL_OH_MY_ZSH="${INSTALLOHMYZSH:-"true"}" +INSTALL_OH_MY_ZSH_CONFIG="${INSTALLOHMYZSHCONFIG:-"true"}" UPGRADE_PACKAGES="${UPGRADEPACKAGES:-"true"}" USERNAME="${USERNAME:-"automatic"}" USER_UID="${USERUID:-"automatic"}" @@ -390,7 +391,8 @@ else fi # Restore user .bashrc / .profile / .zshrc defaults from skeleton file if it doesn't exist or is empty -possible_rc_files=( ".bashrc" ".profile" ".zshrc" ) +possible_rc_files=( ".bashrc" ".profile" ) +[ "$INSTALL_OH_MY_ZSH_CONFIG" == "true" ] && possible_rc_files+=('.zshrc') for rc_file in "${possible_rc_files[@]}"; do if [ -f "/etc/skel/${rc_file}" ]; then if [ ! -e "${user_home}/${rc_file}" ] || [ ! -s "${user_home}/${rc_file}" ]; then @@ -450,33 +452,42 @@ if [ "${INSTALL_ZSH}" = "true" ]; then # Adapted, simplified inline Oh My Zsh! install steps that adds, defaults to a codespaces theme. # See https://github.com/ohmyzsh/ohmyzsh/blob/master/tools/install.sh for official script. - oh_my_install_dir="${user_home}/.oh-my-zsh" - if [ ! -d "${oh_my_install_dir}" ] && [ "${INSTALL_OH_MY_ZSH}" = "true" ]; then - template_path="${oh_my_install_dir}/templates/zshrc.zsh-template" + if [ "${INSTALL_OH_MY_ZSH}" = "true" ]; then user_rc_file="${user_home}/.zshrc" - umask g-w,o-w - mkdir -p ${oh_my_install_dir} - git clone --depth=1 \ - -c core.eol=lf \ - -c core.autocrlf=false \ - -c fsck.zeroPaddedFilemode=ignore \ - -c fetch.fsck.zeroPaddedFilemode=ignore \ - -c receive.fsck.zeroPaddedFilemode=ignore \ - "https://github.com/ohmyzsh/ohmyzsh" "${oh_my_install_dir}" 2>&1 - 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} + oh_my_install_dir="${user_home}/.oh-my-zsh" + template_path="${oh_my_install_dir}/templates/zshrc.zsh-template" + if [ ! -d "${oh_my_install_dir}" ]; then + umask g-w,o-w + mkdir -p ${oh_my_install_dir} + git clone --depth=1 \ + -c core.eol=lf \ + -c core.autocrlf=false \ + -c fsck.zeroPaddedFilemode=ignore \ + -c fetch.fsck.zeroPaddedFilemode=ignore \ + -c receive.fsck.zeroPaddedFilemode=ignore \ + "https://github.com/ohmyzsh/ohmyzsh" "${oh_my_install_dir}" 2>&1 + + # Shrink git while still enabling updates + cd "${oh_my_install_dir}" + git repack -a -d -f --depth=1 --window=1 + fi # Add Dev Containers theme mkdir -p ${oh_my_install_dir}/custom/themes cp -f "${FEATURE_DIR}/scripts/devcontainers.zsh-theme" "${oh_my_install_dir}/custom/themes/devcontainers.zsh-theme" - ln -s "${oh_my_install_dir}/custom/themes/devcontainers.zsh-theme" "${oh_my_install_dir}/custom/themes/codespaces.zsh-theme" + ln -sf "${oh_my_install_dir}/custom/themes/devcontainers.zsh-theme" "${oh_my_install_dir}/custom/themes/codespaces.zsh-theme" + + # 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} + sed -i -e 's/ZSH_THEME=.*/ZSH_THEME="devcontainers"/g' ${user_rc_file} + fi - # Shrink git while still enabling updates - cd "${oh_my_install_dir}" - git repack -a -d -f --depth=1 --window=1 # Copy to non-root user if one is specified if [ "${USERNAME}" != "root" ]; then - cp -rf "${user_rc_file}" "${oh_my_install_dir}" /root + copy_to_user_files=("${oh_my_install_dir}") + [ -f "$user_rc_file" ] && copy_to_user_files+=("$user_rc_file") + cp -rf "${copy_to_user_files[@]}" /root chown -R ${USERNAME}:${group_name} "${oh_my_install_dir}" "${user_rc_file}" fi fi diff --git a/test/common-utils/configure_zsh_as_default_shell.sh b/test/common-utils/configure_zsh_as_default_shell.sh index e5cc89e51..6a569a990 100644 --- a/test/common-utils/configure_zsh_as_default_shell.sh +++ b/test/common-utils/configure_zsh_as_default_shell.sh @@ -7,6 +7,8 @@ source dev-container-features-test-lib # Definition specific tests check "default-shell-is-zsh" bash -c "getent passwd $(whoami) | awk -F: '{ print $7 }' | grep '/bin/zsh'" +# check it overrides the ~/.zshrc with default dev containers template +check "default-zshrc-is-dev-container-template" bash -c "cat ~/.zshrc | grep ZSH_THEME | grep devcontainers" # Report result reportResults diff --git a/test/common-utils/configure_zsh_no_template.sh b/test/common-utils/configure_zsh_no_template.sh new file mode 100644 index 000000000..c62cae967 --- /dev/null +++ b/test/common-utils/configure_zsh_no_template.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +function file_not_overridden() { + cat ~/.zshrc | grep 'alias fnomockalias=' | grep testingmock +} +check "default-zsh-with-no-zshrc" file_not_overridden + +# Report result +reportResults diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index 9800242e9..904a47bac 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -115,6 +115,17 @@ } } }, + "configure_zsh_no_template": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "postCreateCommand": "echo alias fnomockalias=testingmock >> /root/.zshrc", + "remoteUser": "root", + "features": { + "common-utils": { + "installZsh": true, + "installOhMyZshConfig": false + } + } + }, "config-subdirectory": { "image": "alpine", "remoteUser": "devcontainer", From 8b6f08825643e2d5835ed3138dee5301a4db4ffa Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 11 Aug 2023 16:17:50 -0700 Subject: [PATCH 150/478] Automated documentation update (#650) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/common-utils/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common-utils/README.md b/src/common-utils/README.md index 1eddcbcc3..b8e37a8c8 100644 --- a/src/common-utils/README.md +++ b/src/common-utils/README.md @@ -18,6 +18,7 @@ Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-r | installZsh | Install ZSH? | boolean | true | | configureZshAsDefaultShell | Change default shell to ZSH? | boolean | false | | installOhMyZsh | Install Oh My Zsh!? | boolean | true | +| installOhMyZshConfig | Allow installing the default dev container .zshrc templates? | boolean | true | | upgradePackages | Upgrade OS packages? | boolean | true | | username | Enter name of a non-root user to configure or none to skip | string | automatic | | userUid | Enter UID for non-root user | string | automatic | From f90cb26c7f15659f3e2be8061295997df2bb76cc Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Mon, 14 Aug 2023 16:12:47 -0700 Subject: [PATCH 151/478] Common-utils: Fixes "No package jq available" errors for CentOS (#644) * add checks for "jq" * install epel-release if necessary * clean up epel-release post installation of "jq" --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 18 +++++++++++++++--- test/common-utils/centos-7.sh | 1 + test/common-utils/fedora.sh | 1 + test/common-utils/mariner.sh | 1 + test/common-utils/rocky-8.sh | 1 + test/common-utils/rocky-9.sh | 1 + 7 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index d70848278..4eaef2128 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.1.0", + "version": "2.1.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/main.sh b/src/common-utils/main.sh index d3f7ef267..3731994de 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -175,6 +175,11 @@ install_redhat_packages() { man-db \ strace" + local install_cmd=dnf + if ! type dnf > /dev/null 2>&1; then + install_cmd=yum + fi + # rockylinux:9 installs 'curl-minimal' which clashes with 'curl' # Install 'curl' for every OS except this rockylinux:9 if [[ "${ID}" = "rocky" ]] && [[ "${VERSION}" != *"9."* ]]; then @@ -201,16 +206,23 @@ install_redhat_packages() { package_list="${package_list} zsh" fi - local install_cmd=dnf - if ! type dnf > /dev/null 2>&1; then - install_cmd=yum + # Install EPEL repository if needed (required to install 'jq' for CentOS) + local remove_epel="false" + if ! ${install_cmd} -q list jq >/dev/null 2>&1; then + ${install_cmd} -y install epel-release + remove_epel="true" fi + ${install_cmd} -y install ${package_list} # Get to latest versions of all packages if [ "${UPGRADE_PACKAGES}" = "true" ]; then ${install_cmd} upgrade -y fi + + if [[ "${remove_epel}" = "true" ]]; then + ${install_cmd} -y remove epel-release + fi } # Alpine Linux packages diff --git a/test/common-utils/centos-7.sh b/test/common-utils/centos-7.sh index a81ae2f3e..69f01d1ed 100755 --- a/test/common-utils/centos-7.sh +++ b/test/common-utils/centos-7.sh @@ -9,6 +9,7 @@ source dev-container-features-test-lib . /etc/os-release check "non-root user" test "$(whoami)" = "devcontainer" check "distro" test "${VERSION_ID}" = "7" +check "jq" jq --version # Report result reportResults \ No newline at end of file diff --git a/test/common-utils/fedora.sh b/test/common-utils/fedora.sh index b32a7f112..67706d49a 100755 --- a/test/common-utils/fedora.sh +++ b/test/common-utils/fedora.sh @@ -9,6 +9,7 @@ source dev-container-features-test-lib . /etc/os-release check "non-root user" test "$(whoami)" = "devcontainer" check "distro" test "${ID}" = "fedora" +check "jq" jq --version # Report result reportResults \ No newline at end of file diff --git a/test/common-utils/mariner.sh b/test/common-utils/mariner.sh index ab6cb6e13..b0d2c91e4 100755 --- a/test/common-utils/mariner.sh +++ b/test/common-utils/mariner.sh @@ -9,6 +9,7 @@ source dev-container-features-test-lib . /etc/os-release check "non-root user" test "$(whoami)" = "devcontainer" check "distro" test "${ID}" = "mariner" +check "jq" jq --version # Report result reportResults \ No newline at end of file diff --git a/test/common-utils/rocky-8.sh b/test/common-utils/rocky-8.sh index be1223b3c..d08731824 100755 --- a/test/common-utils/rocky-8.sh +++ b/test/common-utils/rocky-8.sh @@ -10,6 +10,7 @@ source dev-container-features-test-lib check "non-root user" test "$(whoami)" = "devcontainer" check "distro" test "${PLATFORM_ID}" = "platform:el8" check "curl" curl --version +check "jq" jq --version # Report result reportResults \ No newline at end of file diff --git a/test/common-utils/rocky-9.sh b/test/common-utils/rocky-9.sh index 452c1935f..cb2b339e1 100755 --- a/test/common-utils/rocky-9.sh +++ b/test/common-utils/rocky-9.sh @@ -10,6 +10,7 @@ source dev-container-features-test-lib check "non-root user" test "$(whoami)" = "devcontainer" check "distro" test "${PLATFORM_ID}" = "platform:el9" check "curl" curl --version +check "jq" jq --version # Report result reportResults \ No newline at end of file From 1d1a23625dc714629ab863cbca7e890516d4283d Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 16 Aug 2023 11:38:35 -0700 Subject: [PATCH 152/478] Ruby Feature [bug fix] : Fails if the dev container has the same ruby version installed (#609) * Ruby Feature [bug fix] : Fails if the dev container has the same ruby version installed * add comment * remove scenario --- src/ruby/devcontainer-feature.json | 2 +- src/ruby/install.sh | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/ruby/devcontainer-feature.json b/src/ruby/devcontainer-feature.json index fdf8b26b3..29591e6a6 100644 --- a/src/ruby/devcontainer-feature.json +++ b/src/ruby/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "ruby", - "version": "1.1.0", + "version": "1.1.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.", diff --git a/src/ruby/install.sh b/src/ruby/install.sh index 087108520..2b47d8a27 100755 --- a/src/ruby/install.sh +++ b/src/ruby/install.sh @@ -177,9 +177,11 @@ fi find_version_from_git_tags RUBY_VERSION "https://github.com/ruby/ruby" "tags/v" "_" # Just install Ruby if RVM already installed -if [ $(rvm --version) != "" ]; then +if rvm --version > /dev/null; then echo "Ruby Version Manager already exists." - if [ "${RUBY_VERSION}" != "none" ]; then + if [[ "$(ruby -v)" = *"${RUBY_VERSION}"* ]]; then + echo "(!) Ruby is already installed with version ${RUBY_VERSION}. Skipping..." + elif [ "${RUBY_VERSION}" != "none" ]; then echo "Installing specified Ruby version." su ${USERNAME} -c "rvm install ruby ${RUBY_VERSION}" fi @@ -191,6 +193,9 @@ else # Determine appropriate settings for rvm installer if [ "${RUBY_VERSION}" = "none" ]; then RVM_INSTALL_ARGS="" + elif [[ "$(ruby -v)" = *"${RUBY_VERSION}"* ]]; then + echo "(!) Ruby is already installed with version ${RUBY_VERSION}. Skipping..." + RVM_INSTALL_ARGS="" else if [ "${RUBY_VERSION}" = "latest" ] || [ "${RUBY_VERSION}" = "current" ] || [ "${RUBY_VERSION}" = "lts" ]; then RVM_INSTALL_ARGS="--ruby" @@ -273,8 +278,11 @@ if [ "${SKIP_RBENV_RBUILD}" != "true" ]; then ln -s /usr/local/share/ruby-build /home/${USERNAME}/.rbenv/plugins/ruby-build fi - ln -s /usr/local/rvm/rubies/default/bin/ruby /usr/local/rvm/gems/default/bin - + # Oryx expects ruby to be installed in this specific path, else it breaks the oryx magic for ruby projects. + if [ ! -f /usr/local/rvm/gems/default/bin/ruby ]; then + ln -s /usr/local/rvm/rubies/default/bin/ruby /usr/local/rvm/gems/default/bin + fi + chown -R "${USERNAME}:rvm" "/home/${USERNAME}/.rbenv/" chmod -R g+r+w "/home/${USERNAME}/.rbenv" find "/home/${USERNAME}/.rbenv" -type d | xargs -n 1 chmod g+s From c58b614202d525b2530d0bbfc45a6a6bbc1a9569 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 16 Aug 2023 11:38:49 -0700 Subject: [PATCH 153/478] Azure-cli: Revert temporary fix which installed az with python (#629) --- src/azure-cli/devcontainer-feature.json | 4 ++-- src/azure-cli/install.sh | 1 - test/azure-cli/install_with_python.sh | 14 ++++++++++++++ test/azure-cli/scenarios.json | 10 ++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 test/azure-cli/install_with_python.sh diff --git a/src/azure-cli/devcontainer-feature.json b/src/azure-cli/devcontainer-feature.json index 09c295c21..3d1c0dfa3 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.0", + "version": "1.2.1", "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.", @@ -26,7 +26,7 @@ "installUsingPython": { "type": "boolean", "description": "Install Azure CLI using Python instead of pipx", - "default": true + "default": false } }, "customizations": { diff --git a/src/azure-cli/install.sh b/src/azure-cli/install.sh index 9b0d72db3..51759488d 100755 --- a/src/azure-cli/install.sh +++ b/src/azure-cli/install.sh @@ -141,7 +141,6 @@ install_using_pip_strategy() { ver="==${AZ_VERSION}" fi - # Temprary quick fix for https://github.com/devcontainers/features/issues/624 if [ "${INSTALL_USING_PYTHON}" = "true" ]; then install_with_complete_python_installation "${ver}" || install_with_pipx "${ver}" || return 1 else diff --git a/test/azure-cli/install_with_python.sh b/test/azure-cli/install_with_python.sh new file mode 100644 index 000000000..4848ac55f --- /dev/null +++ b/test/azure-cli/install_with_python.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Import test library for `check` command +source dev-container-features-test-lib + +# Check to make sure the user is vscode +check "user is vscode" whoami | grep vscode +check "version" az --version + + +# Report result +reportResults \ No newline at end of file diff --git a/test/azure-cli/scenarios.json b/test/azure-cli/scenarios.json index 231345225..b7a732395 100644 --- a/test/azure-cli/scenarios.json +++ b/test/azure-cli/scenarios.json @@ -28,5 +28,15 @@ "installBicep": true } } + }, + "install_with_python": { + "image": "mcr.microsoft.com/devcontainers/base:jammy", + "user": "vscode", + "features": { + "azure-cli": { + "version": "latest", + "installUsingPython": true + } + } } } \ No newline at end of file From 9fd5daf06b40794a067c4cdbb8e258d99eeefc24 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Wed, 16 Aug 2023 11:43:06 -0700 Subject: [PATCH 154/478] Automated documentation update (#656) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/azure-cli/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/README.md b/src/azure-cli/README.md index c3e23db8a..2e7b6d39b 100644 --- a/src/azure-cli/README.md +++ b/src/azure-cli/README.md @@ -18,7 +18,7 @@ Installs the Azure CLI along with needed dependencies. Useful for base Dockerfil | version | Select or enter an Azure CLI version. (Available versions may vary by Linux distribution.) | string | latest | | extensions | Optional comma separated list of Azure CLI extensions to install in profile. | string | - | | installBicep | Optionally install Azure Bicep | boolean | false | -| installUsingPython | Install Azure CLI using Python instead of pipx | boolean | true | +| installUsingPython | Install Azure CLI using Python instead of pipx | boolean | false | ## Customizations From a4b31f314fa1385950a9dbc81682d9acb2e2fba9 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Fri, 18 Aug 2023 16:01:50 -0700 Subject: [PATCH 155/478] [docker-in-docker] Reverts the retry logic (#659) * Update install.sh * [docker-in-docker] Update retry logic * revert the retry logic! --- .../devcontainer-feature.json | 2 +- src/docker-in-docker/install.sh | 30 ++++------------- test/docker-in-docker/docker_retry.sh | 32 ------------------- test/docker-in-docker/scenarios.json | 6 ---- .../test-scripts/docker-test-init.sh | 26 --------------- 5 files changed, 7 insertions(+), 89 deletions(-) delete mode 100644 test/docker-in-docker/docker_retry.sh delete mode 100644 test/docker-in-docker/test-scripts/docker-test-init.sh diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index b5e0aeea6..2afdd1142 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.3.0", + "version": "2.3.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.", diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index f7e5a7d52..bdef12697 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -423,30 +423,12 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU INNEREOF )" -retry_count=0 -docker_ok="false" - -until [ "${docker_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; -do - # Start using sudo if not invoked as root - if [ "$(id -u)" -ne 0 ]; then - sudo /bin/sh -c "${dockerd_start}" - else - eval "${dockerd_start}" - fi - - set +e - docker info > /dev/null 2>&1 && docker_ok="true" - - if [ "${docker_ok}" != "true" ]; then - echo "(*) Failed to start docker, retrying in 5s..." - retry_count=`expr $retry_count + 1` - sleep 5s - fi - set -e -done - -set +e +# Start using sudo if not invoked as root +if [ "$(id -u)" -ne 0 ]; then + sudo /bin/sh -c "${dockerd_start}" +else + eval "${dockerd_start}" +fi # Execute whatever commands were passed in (if any). This allows us # to set this script to ENTRYPOINT while still executing the default CMD. diff --git a/test/docker-in-docker/docker_retry.sh b/test/docker-in-docker/docker_retry.sh deleted file mode 100644 index cc35fbb04..000000000 --- a/test/docker-in-docker/docker_retry.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -set -e - -# Optional: Import test library -source dev-container-features-test-lib - -# Definition specific tests -check "docker-buildx" docker buildx version -check "docker-ps" docker ps - -sleep 5s - -# Stop docker -pkill dockerd -pkill containerd - -sleep 5s - -set +e - docker_ok_code="$(docker info > /dev/null 2>&1; echo $?)" -set -e - -check "docker-not-running" bash -c "[[ ${docker_ok_code} == 1 ]]" - -# Testing retry logic -./test-scripts/docker-test-init.sh - -check "docker-started-after-retries" docker ps - -# Report result -reportResults diff --git a/test/docker-in-docker/scenarios.json b/test/docker-in-docker/scenarios.json index 525ce6930..de4e7d6bc 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -67,11 +67,5 @@ } }, "remoteUser": "node" - }, - "docker_retry": { - "image": "ubuntu:focal", - "features": { - "docker-in-docker": {} - } } } diff --git a/test/docker-in-docker/test-scripts/docker-test-init.sh b/test/docker-in-docker/test-scripts/docker-test-init.sh deleted file mode 100644 index b213fb40c..000000000 --- a/test/docker-in-docker/test-scripts/docker-test-init.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -#------------------------------------------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. -#------------------------------------------------------------------------------------------------------------- - -retry_count=0 -docker_ok="false" - -until [ "${docker_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; -do - if [ "${retry_count}" -eq "3" ]; then - echo "Starting docker after 3 retries..." - /usr/local/share/docker-init.sh - fi - - set +e - docker info > /dev/null 2>&1 && docker_ok="true" - - if [ "${docker_ok}" != "true" ]; then - echo "(*) Failed to start docker, retrying in 5s... Retry count: ${retry_count}" - retry_count=`expr $retry_count + 1` - sleep 1s - fi - set -e -done \ No newline at end of file From 71ac2021e1350e673c0602b2ab6526d4353bc293 Mon Sep 17 00:00:00 2001 From: Bulat Khusnimardanov <61210700+bulat-khusnimardanov@users.noreply.github.com> Date: Tue, 22 Aug 2023 02:31:20 +0200 Subject: [PATCH 156/478] Enhancing Terraform Feature Stability (#657) * Added fallback method to retrieve cosign version * Update src/terraform/install.sh Co-authored-by: Samruddhi Khandale * Remove get_cosign_latest_version function --------- Co-authored-by: Samruddhi Khandale --- src/terraform/devcontainer-feature.json | 2 +- src/terraform/install.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/terraform/devcontainer-feature.json b/src/terraform/devcontainer-feature.json index b1e6df2c8..119b4335e 100644 --- a/src/terraform/devcontainer-feature.json +++ b/src/terraform/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "terraform", - "version": "1.3.3", + "version": "1.3.4", "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 82e3e8d51..1156f6d41 100755 --- a/src/terraform/install.sh +++ b/src/terraform/install.sh @@ -165,7 +165,8 @@ ensure_cosign() { if ! type cosign > /dev/null 2>&1; then echo "Installing cosign..." - local LATEST_COSIGN_VERSION=$(curl https://api.github.com/repos/sigstore/cosign/releases/latest | grep tag_name | cut -d : -f2 | tr -d "v\", ") + LATEST_COSIGN_VERSION="latest" + find_version_from_git_tags LATEST_COSIGN_VERSION 'https://github.com/sigstore/cosign' curl -L "https://github.com/sigstore/cosign/releases/latest/download/cosign_${LATEST_COSIGN_VERSION}_${architecture}.deb" -o /tmp/cosign_${LATEST_COSIGN_VERSION}_${architecture}.deb dpkg -i /tmp/cosign_${LATEST_COSIGN_VERSION}_${architecture}.deb From a08434f2b18627f31107a4ef6ab4f578a92aeaec Mon Sep 17 00:00:00 2001 From: nyuyuyu <127820811+nyuyuyu@users.noreply.github.com> Date: Fri, 25 Aug 2023 01:38:40 +0900 Subject: [PATCH 157/478] [Rust] Remove `mutantdino.resourcemonitor` extension (#665) * Remove `mutantdino.resourcemonitor` extension * Bump version * Revert "Bump version" This reverts commit e9c514911dd6de6b03e235536e8602f62cbe5b99. * Bump version --- src/rust/devcontainer-feature.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rust/devcontainer-feature.json b/src/rust/devcontainer-feature.json index bc9044c60..70ed39eab 100644 --- a/src/rust/devcontainer-feature.json +++ b/src/rust/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "rust", - "version": "1.0.12", + "version": "1.1.0", "name": "Rust", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust", "description": "Installs Rust, common Rust utilities, and their required dependencies", @@ -39,7 +39,6 @@ "vscode": { "extensions": [ "vadimcn.vscode-lldb", - "mutantdino.resourcemonitor", "rust-lang.rust-analyzer", "tamasfe.even-better-toml", "serayuzgur.crates" From 0cf690ee14279d9e7ae5e1308950d6067d3aba81 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Thu, 24 Aug 2023 12:31:40 -0700 Subject: [PATCH 158/478] [docker in docker] Adds retries for docker daemon startup and cgroup nesting (#669) * adds retry logic * adds stress test workflow * Adds cgroup retries * update workflow * move sleep cmd * update test * cleanup --- .../docker-in-docker-stress-test.yaml | 37 +++++++ .../devcontainer-feature.json | 2 +- src/docker-in-docker/install.sh | 102 +++++++++++++----- .../docker_with_on_create_command.sh | 18 ++++ test/docker-in-docker/scenarios.json | 9 ++ test/docker-in-docker/test.sh | 2 +- 6 files changed, 139 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/docker-in-docker-stress-test.yaml create mode 100755 test/docker-in-docker/docker_with_on_create_command.sh diff --git a/.github/workflows/docker-in-docker-stress-test.yaml b/.github/workflows/docker-in-docker-stress-test.yaml new file mode 100644 index 000000000..569f94699 --- /dev/null +++ b/.github/workflows/docker-in-docker-stress-test.yaml @@ -0,0 +1,37 @@ +name: "Stress test - Docker in Docker" +on: + pull_request: + paths: + - 'src/docker-in-docker/**' + workflow_dispatch: + +jobs: + test: + strategy: + matrix: + test-pass: [ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50 ] + fail-fast: false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: "Install latest devcontainer CLI" + run: npm install -g @devcontainers/cli + + - name: "Generating tests for 'docker-in-docker' which validates if docker daemon is running" + run: devcontainer features test --skip-scenarios -f docker-in-docker -i mcr.microsoft.com/devcontainers/base:ubuntu . + + test-onCreate: + strategy: + matrix: + test-pass: [ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50 ] + fail-fast: false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: "Install latest devcontainer CLI" + run: npm install -g @devcontainers/cli + + - name: "Generating tests for 'docker-in-docker' which validates if docker daemon is available within 'onCreateCommand'" + run: devcontainer features test -f docker-in-docker --skip-autogenerated --filter "docker_with_on_create_command" \ No newline at end of file diff --git a/src/docker-in-docker/devcontainer-feature.json b/src/docker-in-docker/devcontainer-feature.json index 2afdd1142..edfaa1f09 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.3.1", + "version": "2.4.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.", diff --git a/src/docker-in-docker/install.sh b/src/docker-in-docker/install.sh index bdef12697..a0d4a943c 100755 --- a/src/docker-in-docker/install.sh +++ b/src/docker-in-docker/install.sh @@ -367,7 +367,7 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU find /run /var/run -iname 'docker*.pid' -delete || : find /run /var/run -iname 'container*.pid' -delete || : - ## Dind wrapper script from docker team, adapted to a function + # -- Start: dind wrapper script -- # Maintained: https://github.com/moby/moby/blob/master/hack/dind export container=docker @@ -384,31 +384,52 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU mount -t tmpfs none /tmp fi - # cgroup v2: enable nesting - if [ -f /sys/fs/cgroup/cgroup.controllers ]; then - # move the processes from the root group to the /init group, - # otherwise writing subtree_control fails with EBUSY. - # An error during moving non-existent process (i.e., "cat") is ignored. - mkdir -p /sys/fs/cgroup/init - xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : - # enable controllers - sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \ - > /sys/fs/cgroup/cgroup.subtree_control - fi - ## Dind wrapper over. + set_cgroup_nesting() + { + # cgroup v2: enable nesting + if [ -f /sys/fs/cgroup/cgroup.controllers ]; then + # move the processes from the root group to the /init group, + # otherwise writing subtree_control fails with EBUSY. + # An error during moving non-existent process (i.e., "cat") is ignored. + mkdir -p /sys/fs/cgroup/init + xargs -rn1 < /sys/fs/cgroup/cgroup.procs > /sys/fs/cgroup/init/cgroup.procs || : + # enable controllers + sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \ + > /sys/fs/cgroup/cgroup.subtree_control + fi + } + + # Set cgroup nesting, retrying if necessary + retry_cgroup_nesting=0 + + until [ "${retry_cgroup_nesting}" -eq "5" ]; + do + set +e + set_cgroup_nesting + + if [ $? -ne 0 ]; then + echo "(*) cgroup v2: Failed to enable nesting, retrying..." + else + break + fi + + retry_cgroup_nesting=`expr $retry_cgroup_nesting + 1` + set -e + done + + # -- End: dind wrapper script -- # Handle DNS set +e - cat /etc/resolv.conf | grep -i 'internal.cloudapp.net' - if [ $? -eq 0 ] && [ "${AZURE_DNS_AUTO_DETECTION}" = "true" ] - then - echo "Setting dockerd Azure DNS." - CUSTOMDNS="--dns 168.63.129.16" - else - echo "Not setting dockerd DNS manually." - CUSTOMDNS="" - fi - + cat /etc/resolv.conf | grep -i 'internal.cloudapp.net' > /dev/null 2>&1 + if [ $? -eq 0 ] && [ "${AZURE_DNS_AUTO_DETECTION}" = "true" ] + then + echo "Setting dockerd Azure DNS." + CUSTOMDNS="--dns 168.63.129.16" + else + echo "Not setting dockerd DNS manually." + CUSTOMDNS="" + fi set -e if [ -z "$DOCKER_DEFAULT_ADDRESS_POOL" ] @@ -423,12 +444,35 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU INNEREOF )" -# Start using sudo if not invoked as root -if [ "$(id -u)" -ne 0 ]; then - sudo /bin/sh -c "${dockerd_start}" -else - eval "${dockerd_start}" -fi +retry_docker_start_count=0 +docker_ok="false" + +until [ "${docker_ok}" = "true" ] || [ "${retry_docker_start_count}" -eq "5" ]; +do + # Start using sudo if not invoked as root + if [ "$(id -u)" -ne 0 ]; then + sudo /bin/sh -c "${dockerd_start}" + else + eval "${dockerd_start}" + fi + + retry_count=0 + until [ "${docker_ok}" = "true" ] || [ "${retry_count}" -eq "5" ]; + do + sleep 1s + set +e + docker info > /dev/null 2>&1 && docker_ok="true" + set -e + + retry_count=`expr $retry_count + 1` + done + + if [ "${docker_ok}" != "true" ]; then + echo "(*) Failed to start docker, retrying..." + fi + + retry_docker_start_count=`expr $retry_docker_start_count + 1` +done # Execute whatever commands were passed in (if any). This allows us # to set this script to ENTRYPOINT while still executing the default CMD. diff --git a/test/docker-in-docker/docker_with_on_create_command.sh b/test/docker-in-docker/docker_with_on_create_command.sh new file mode 100755 index 000000000..131304acb --- /dev/null +++ b/test/docker-in-docker/docker_with_on_create_command.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Feature specific tests +check "version" docker --version +check "docker-ps" bash -c "docker ps" + +check "docker-init-exists" bash -c "ls /usr/local/share/docker-init.sh" +check "log-exists" bash -c "ls /tmp/dockerd.log" +check "log-for-completion" bash -c "cat /tmp/dockerd.log | grep 'Daemon has completed initialization'" +check "log-contents" bash -c "cat /tmp/dockerd.log | grep 'API listen on /var/run/docker.sock'" + +# 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 de4e7d6bc..1274877b9 100644 --- a/test/docker-in-docker/scenarios.json +++ b/test/docker-in-docker/scenarios.json @@ -67,5 +67,14 @@ } }, "remoteUser": "node" + }, + // 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", + "features": { + "docker-in-docker": {} + }, + "remoteUser": "vscode", + "onCreateCommand": "docker ps && sleep 5s && docker ps" } } diff --git a/test/docker-in-docker/test.sh b/test/docker-in-docker/test.sh index 1eebfd243..e86a841c2 100755 --- a/test/docker-in-docker/test.sh +++ b/test/docker-in-docker/test.sh @@ -8,10 +8,10 @@ source dev-container-features-test-lib # Feature specific tests check "version" docker --version check "docker-init-exists" bash -c "ls /usr/local/share/docker-init.sh" +check "docker-ps" bash -c "docker ps" check "log-exists" bash -c "ls /tmp/dockerd.log" check "log-for-completion" bash -c "cat /tmp/dockerd.log | grep 'Daemon has completed initialization'" check "log-contents" bash -c "cat /tmp/dockerd.log | grep 'API listen on /var/run/docker.sock'" -check "docker-ps" bash -c "docker ps" # Report result reportResults \ No newline at end of file From 0668db5edea56a0d57575db127b793f59b489e7b Mon Sep 17 00:00:00 2001 From: naturedamends <120284608+naturedamends@users.noreply.github.com> Date: Sat, 26 Aug 2023 00:39:32 +0100 Subject: [PATCH 159/478] Commonutils: chown: cannot access '/home/vscode/.zshrc': No such file or directory (#662) * Update main.sh * Update devcontainer-feature.json * Test install as non root user. --------- Co-authored-by: Samruddhi Khandale --- src/common-utils/devcontainer-feature.json | 2 +- src/common-utils/main.sh | 2 +- .../configure_zsh_no_template_first_step.sh | 12 ++++++++++++ ... => configure_zsh_no_template_second_step.sh} | 5 ++--- test/common-utils/scenarios.json | 16 +++++++++++++--- 5 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 test/common-utils/configure_zsh_no_template_first_step.sh rename test/common-utils/{configure_zsh_no_template.sh => configure_zsh_no_template_second_step.sh} (57%) diff --git a/src/common-utils/devcontainer-feature.json b/src/common-utils/devcontainer-feature.json index 4eaef2128..747be3074 100644 --- a/src/common-utils/devcontainer-feature.json +++ b/src/common-utils/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "common-utils", - "version": "2.1.1", + "version": "2.1.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 3731994de..902f9e694 100644 --- a/src/common-utils/main.sh +++ b/src/common-utils/main.sh @@ -500,7 +500,7 @@ if [ "${INSTALL_ZSH}" = "true" ]; then copy_to_user_files=("${oh_my_install_dir}") [ -f "$user_rc_file" ] && copy_to_user_files+=("$user_rc_file") cp -rf "${copy_to_user_files[@]}" /root - chown -R ${USERNAME}:${group_name} "${oh_my_install_dir}" "${user_rc_file}" + chown -R ${USERNAME}:${group_name} "${copy_to_user_files[@]}" fi fi fi diff --git a/test/common-utils/configure_zsh_no_template_first_step.sh b/test/common-utils/configure_zsh_no_template_first_step.sh new file mode 100644 index 000000000..d26874d3a --- /dev/null +++ b/test/common-utils/configure_zsh_no_template_first_step.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "default-zsh-with-no-zshrc" bash -c "[ ! -e ~/.zshrc ]" + +# Report result +reportResults diff --git a/test/common-utils/configure_zsh_no_template.sh b/test/common-utils/configure_zsh_no_template_second_step.sh similarity index 57% rename from test/common-utils/configure_zsh_no_template.sh rename to test/common-utils/configure_zsh_no_template_second_step.sh index c62cae967..734fa66e9 100644 --- a/test/common-utils/configure_zsh_no_template.sh +++ b/test/common-utils/configure_zsh_no_template_second_step.sh @@ -4,12 +4,11 @@ set -e # Optional: Import test library source dev-container-features-test-lib - # Definition specific tests function file_not_overridden() { - cat ~/.zshrc | grep 'alias fnomockalias=' | grep testingmock + cat $1 | grep 'alias fnomockalias=' | grep testingmock } -check "default-zsh-with-no-zshrc" file_not_overridden +check "default-zsh-with-no-zshrc" file_not_overridden /home/devcontainer/.zshrc # Report result reportResults diff --git a/test/common-utils/scenarios.json b/test/common-utils/scenarios.json index 904a47bac..d7b296d41 100644 --- a/test/common-utils/scenarios.json +++ b/test/common-utils/scenarios.json @@ -115,10 +115,20 @@ } } }, - "configure_zsh_no_template": { + "configure_zsh_no_template_second_step": { "image": "mcr.microsoft.com/devcontainers/base:ubuntu", - "postCreateCommand": "echo alias fnomockalias=testingmock >> /root/.zshrc", - "remoteUser": "root", + "postCreateCommand": "echo alias fnomockalias=testingmock >> /home/devcontainer/.zshrc", + "remoteUser": "devcontainer", + "features": { + "common-utils": { + "installZsh": true, + "installOhMyZshConfig": false + } + } + }, + "configure_zsh_no_template_first_step": { + "image": "debian:bullseye", + "remoteUser": "devcontainer", "features": { "common-utils": { "installZsh": true, From 95a169b9ef92c9dae454df5e87d4c26d56a863c9 Mon Sep 17 00:00:00 2001 From: eitsupi <50911393+eitsupi@users.noreply.github.com> Date: Tue, 29 Aug 2023 06:26:30 +0900 Subject: [PATCH 160/478] [node] Install the latest version of nvm by default (#673) feat(node): install the latest nvm by default --- src/node/devcontainer-feature.json | 10 ++++--- src/node/install.sh | 42 +++++++++++++++++++++++++++++- test/node/install_nvm_0.39.sh | 14 ++++++++++ test/node/scenarios.json | 10 ++++++- 4 files changed, 71 insertions(+), 5 deletions(-) create mode 100755 test/node/install_nvm_0.39.sh diff --git a/src/node/devcontainer-feature.json b/src/node/devcontainer-feature.json index 80bd91275..aee55a1f6 100644 --- a/src/node/devcontainer-feature.json +++ b/src/node/devcontainer-feature.json @@ -1,6 +1,6 @@ { "id": "node", - "version": "1.2.1", + "version": "1.3.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.", @@ -30,7 +30,11 @@ }, "nvmVersion": { "type": "string", - "default": "0.39.2", + "proposals": [ + "latest", + "0.39" + ], + "default": "latest", "description": "Version of NVM to install." } }, @@ -49,4 +53,4 @@ "installsAfter": [ "ghcr.io/devcontainers/features/common-utils" ] -} \ No newline at end of file +} diff --git a/src/node/install.sh b/src/node/install.sh index 1ce8fee3f..809109413 100755 --- a/src/node/install.sh +++ b/src/node/install.sh @@ -8,7 +8,7 @@ # Maintainer: The Dev Container spec maintainers export NODE_VERSION="${VERSION:-"lts"}" -export NVM_VERSION="${NVMVERSION:-"0.39.2"}" +export NVM_VERSION="${NVMVERSION:-"latest"}" export NVM_DIR="${NVMINSTALLPATH:-"/usr/local/share/nvm"}" INSTALL_TOOLS_FOR_NODE_GYP="${NODEGYPDEPENDENCIES:-true}" @@ -78,6 +78,40 @@ check_packages() { fi } +# Figure out correct version of a three part version number is not passed +find_version_from_git_tags() { + local variable_name=$1 + local requested_version=${!variable_name} + if [ "${requested_version}" = "none" ]; then return; fi + local repository=$2 + local prefix=${3:-"tags/v"} + local separator=${4:-"."} + local last_part_optional=${5:-"false"} + if [ "$(echo "${requested_version}" | grep -o "." | wc -l)" != "2" ]; then + local escaped_separator=${separator//./\\.} + local last_part + if [ "${last_part_optional}" = "true" ]; then + last_part="(${escaped_separator}[0-9]+)?" + else + 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)" + if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ] || [ "${requested_version}" = "lts" ]; then + declare -g ${variable_name}="$(echo "${version_list}" | head -n 1)" + else + set +e + declare -g ${variable_name}="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")" + set -e + fi + fi + if [ -z "${!variable_name}" ] || ! echo "${version_list}" | grep "^${!variable_name//./\\.}$" > /dev/null 2>&1; then + echo -e "Invalid ${variable_name} value: ${requested_version}\nValid values:\n${version_list}" >&2 + exit 1 + fi + echo "${variable_name}=${!variable_name}" +} + # Ensure apt is in non-interactive to avoid prompts export DEBIAN_FRONTEND=noninteractive @@ -92,6 +126,10 @@ fi # Install dependencies check_packages apt-transport-https curl ca-certificates tar gnupg2 dirmngr +if ! type git > /dev/null 2>&1; then + check_packages git +fi + # Install yarn if type yarn > /dev/null 2>&1; then echo "Yarn already installed." @@ -112,6 +150,8 @@ elif [ "${NODE_VERSION}" = "latest" ]; then export NODE_VERSION="node" fi +find_version_from_git_tags NVM_VERSION "https://github.com/nvm-sh/nvm" + # Install snipppet that we will run as the user nvm_install_snippet="$(cat << EOF set -e diff --git a/test/node/install_nvm_0.39.sh b/test/node/install_nvm_0.39.sh new file mode 100755 index 000000000..6b96381b5 --- /dev/null +++ b/test/node/install_nvm_0.39.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e + +# Optional: Import test library +source dev-container-features-test-lib + +# Definition specific tests +check "version" bash -c "node --version" +check "pnpm" pnpm -v +check "nvm version" bash -c ". /usr/local/share/nvm/nvm.sh && nvm --version | grep 0.39" + +# Report result +reportResults diff --git a/test/node/scenarios.json b/test/node/scenarios.json index 5524f5c52..a45620fbe 100644 --- a/test/node/scenarios.json +++ b/test/node/scenarios.json @@ -44,5 +44,13 @@ "version": "16" } } + }, + "install_nvm_0.39": { + "image": "mcr.microsoft.com/devcontainers/base", + "features": { + "node": { + "nvmVersion": "0.39" + } + } } -} \ No newline at end of file +} From 96bff0097028001e6e4126c5528d37cb8c13e785 Mon Sep 17 00:00:00 2001 From: Samruddhi Khandale Date: Mon, 28 Aug 2023 15:15:43 -0700 Subject: [PATCH 161/478] Automated documentation update (#676) Automated documentation update [skip ci] Co-authored-by: github-actions --- src/node/README.md | 2 +- src/rust/README.md | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/node/README.md b/src/node/README.md index 7a4909600..b98391922 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -18,7 +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 | -| nvmVersion | Version of NVM to install. | string | 0.39.2 | +| nvmVersion | Version of NVM to install. | string | latest | ## Customizations diff --git a/src/rust/README.md b/src/rust/README.md index f72b56f82..974d78516 100644 --- a/src/rust/README.md +++ b/src/rust/README.md @@ -23,7 +23,6 @@ Installs Rust, common Rust utilities, and their required dependencies ### VS Code Extensions - `vadimcn.vscode-lldb` -- `mutantdino.resourcemonitor` - `rust-lang.rust-analyzer` - `tamasfe.even-better-toml` - `serayuzgur.crates` From 038bed3d58a84885da8a008b80905da17d57a543 Mon Sep 17 00:00:00 2001 From: eitsupi <50911393+eitsupi@users.noreply.github.com> Date: Wed, 30 Aug 2023 01:32:46 +0900 Subject: [PATCH 162/478] ci: remove `ubuntu:bionic` from test matrixes (#677) ci: remove ubuntu:bionic from test matrixes --- .github/workflows/test-all.yaml | 3 +-- .github/workflows/test-pr.yaml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test-all.yaml b/.github/workflows/test-all.yaml index 8dc206d86..40f5efa75 100644 --- a/.github/workflows/test-all.yaml +++ b/.github/workflows/test-all.yaml @@ -42,7 +42,6 @@ jobs: ] baseImage: [ - "ubuntu:bionic", "ubuntu:focal", "ubuntu:jammy", "debian:11", @@ -112,4 +111,4 @@ jobs: run: npm install -g @devcontainers/cli - name: "Testing global scenarios" - run: devcontainer features test --global-scenarios-only . \ No newline at end of file + run: devcontainer features test --global-scenarios-only . diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index 6b91b612d..d60733574 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -49,7 +49,6 @@ jobs: features: ${{ fromJSON(needs.detect-changes.outputs.features) }} baseImage: [ - "ubuntu:bionic", "ubuntu:focal", "ubuntu:jammy", "debian:11", @@ -80,4 +79,4 @@ jobs: run: npm install -g @devcontainers/cli - name: "Testing '${{ matrix.features }}' scenarios" - run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated . \ No newline at end of file + run: devcontainer features test -f ${{ matrix.features }} --skip-autogenerated . From 96c1eea40fc97b471ba0b33fcc79273c7ce586c7 Mon Sep 17 00:00:00 2001 From: Steven Date: Mon, 11 Sep 2023 20:16:24 +0200 Subject: [PATCH 163/478] Use dotnet-install.sh in .NET feature (#628) * Use dotnet-install.sh in .NET feature * Use latest.version files * Cleanup runtime args * Use latest.version files in tests as well * Improve tests, remove code duplication * Add stderr helper * Validate version inputs * Use suggested description Co-authored-by: Samruddhi Khandale * Shorter version description Co-authored-by: Samruddhi Khandale * Shorter version description Co-authored-by: Samruddhi Khandale * Clean up apt lists * Verify 7.0 is latest * Fix PATH, add test for .NET global tools * Include a copy of dotnet-install.sh in the Feature * Configure useful env variables * Use stringly typed booleans * Keep imperative writing style in option hints * Update maintainers Co-authored-by: Samruddhi Khandale * Move dotnet-install.sh into a vendor directory * Refactor variables * Amend * Amend 2 * Use default options from devcontainer-feature.json * Add back variables * Fix shellchek warning in fetch_latest_sdk_version * Inline install_version function * Fix ShellCheck warnings * Improve CSV parsing * Default to latest when configuring an empty version * Add support for runtime-only configurations * Move 'none' check higher up * Deduplicate helper functions, sort into files * Address the user more directly in NOTES * Remove unnecessary defaults * Replace feature -> Feature Co-authored-by: Samruddhi Khandale * Add update-dotnet-install-script workflow * Apply suggestions from code review Co-authored-by: Samruddhi Khandale * Don't skip ci for automated script update --------- Co-authored-by: Samruddhi Khandale --- .../update-dotnet-install-script.yml | 48 + src/dotnet/NOTES.md | 67 + src/dotnet/devcontainer-feature.json | 41 +- src/dotnet/install.sh | 506 +---- src/dotnet/scripts/dotnet-helpers.sh | 119 ++ .../scripts/fetch-latest-dotnet-install.sh | 16 + src/dotnet/scripts/string-helpers.sh | 42 + src/dotnet/scripts/vendor/README.md | 27 + src/dotnet/scripts/vendor/dotnet-install.sh | 1746 +++++++++++++++++ test/dotnet/dotnet_env.sh | 4 + test/dotnet/dotnet_helpers.sh | 71 + test/dotnet/install_additional_dotnet.sh | 17 - .../dotnet/install_aspnetcore_runtime_only.sh | 27 + test/dotnet/install_dotnet_3.sh | 17 - test/dotnet/install_dotnet_6_bullseye.sh | 17 - test/dotnet/install_dotnet_6_focal.sh | 17 - test/dotnet/install_dotnet_6_jammy.sh | 17 - test/dotnet/install_dotnet_7_bullseye.sh | 17 - test/dotnet/install_dotnet_7_jammy.sh | 17 - test/dotnet/install_dotnet_exact_version.sh | 24 + test/dotnet/install_dotnet_global_tool.sh | 25 + test/dotnet/install_dotnet_latest.sh | 17 - ...all_dotnet_latest_when_version_is_empty.sh | 30 + test/dotnet/install_dotnet_lts.sh | 27 +- .../install_dotnet_multiple_versions.sh | 30 + test/dotnet/install_dotnet_runtime_only.sh | 27 + .../dotnet/install_dotnet_specific_release.sh | 26 + ...otnet_specific_release_and_feature_band.sh | 24 + test/dotnet/install_wo_apt.sh | 17 - test/dotnet/projects/.gitignore | 2 + test/dotnet/projects/multitargeting/Class1.cs | 4 + .../multitargeting/example_classlib.csproj | 9 + test/dotnet/projects/net5.0/Program.cs | 32 + .../projects/net5.0/example_project.csproj | 13 + test/dotnet/projects/net6.0/Program.cs | 30 + .../projects/net6.0/example_project.csproj | 14 + test/dotnet/projects/net7.0/Program.cs | 30 + .../projects/net7.0/example_project.csproj | 14 + test/dotnet/projects/net8.0/Program.cs | 32 + .../projects/net8.0/example_project.csproj | 14 + test/dotnet/projects/netcoreapp3.1/Program.cs | 39 + .../netcoreapp3.1/example_project.csproj | 14 + test/dotnet/scenarios.json | 83 +- test/dotnet/test.sh | 31 +- 44 files changed, 2771 insertions(+), 670 deletions(-) create mode 100644 .github/workflows/update-dotnet-install-script.yml create mode 100644 src/dotnet/scripts/dotnet-helpers.sh create mode 100755 src/dotnet/scripts/fetch-latest-dotnet-install.sh create mode 100644 src/dotnet/scripts/string-helpers.sh create mode 100644 src/dotnet/scripts/vendor/README.md create mode 100755 src/dotnet/scripts/vendor/dotnet-install.sh create mode 100644 test/dotnet/dotnet_env.sh create mode 100644 test/dotnet/dotnet_helpers.sh delete mode 100644 test/dotnet/install_additional_dotnet.sh create mode 100644 test/dotnet/install_aspnetcore_runtime_only.sh delete mode 100644 test/dotnet/install_dotnet_3.sh delete mode 100644 test/dotnet/install_dotnet_6_bullseye.sh delete mode 100644 test/dotnet/install_dotnet_6_focal.sh delete mode 100644 test/dotnet/install_dotnet_6_jammy.sh delete mode 100644 test/dotnet/install_dotnet_7_bullseye.sh delete mode 100644 test/dotnet/install_dotnet_7_jammy.sh create mode 100644 test/dotnet/install_dotnet_exact_version.sh create mode 100644 test/dotnet/install_dotnet_global_tool.sh delete mode 100644 test/dotnet/install_dotnet_latest.sh create mode 100644 test/dotnet/install_dotnet_latest_when_version_is_empty.sh create mode 100644 test/dotnet/install_dotnet_multiple_versions.sh create mode 100644 test/dotnet/install_dotnet_runtime_only.sh create mode 100644 test/dotnet/install_dotnet_specific_release.sh create mode 100644 test/dotnet/install_dotnet_specific_release_and_feature_band.sh delete mode 100644 test/dotnet/install_wo_apt.sh create mode 100644 test/dotnet/projects/.gitignore create mode 100644 test/dotnet/projects/multitargeting/Class1.cs create mode 100644 test/dotnet/projects/multitargeting/example_classlib.csproj create mode 100644 test/dotnet/projects/net5.0/Program.cs create mode 100644 test/dotnet/projects/net5.0/example_project.csproj create mode 100644 test/dotnet/projects/net6.0/Program.cs create mode 100644 test/dotnet/projects/net6.0/example_project.csproj create mode 100644 test/dotnet/projects/net7.0/Program.cs create mode 100644 test/dotnet/projects/net7.0/example_project.csproj create mode 100644 test/dotnet/projects/net8.0/Program.cs create mode 100644 test/dotnet/projects/net8.0/example_project.csproj create mode 100644 test/dotnet/projects/netcoreapp3.1/Program.cs create mode 100644 test/dotnet/projects/netcoreapp3.1/example_project.csproj mode change 100755 => 100644 test/dotnet/test.sh diff --git a/.github/workflows/update-dotnet-install-script.yml b/.github/workflows/update-dotnet-install-script.yml new file mode 100644 index 000000000..56adf854d --- /dev/null +++ b/.github/workflows/update-dotnet-install-script.yml @@ -0,0 +1,48 @@ +name: "Updates vendor 'dotnet-install' script" +on: + workflow_dispatch: + schedule: + - cron: '0 0 * * 0' # Runs every Sunday at midnight UTC (adjust as needed) + +jobs: + fetch-latest-dotnet-install: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Run fetch-latest-dotnet-install.sh + run: src/dotnet/scripts/fetch-latest-dotnet-install.sh + + - name: Create a PR for dotnet-install.sh + 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 'dotnet-install' script' + + # Add / update and commit + git add src/dotnet/scripts/vendor/dotnet-install.sh + git commit -m 'Automated dotnet-install script update' || export NO_UPDATES=true + + # Push + if [ "$NO_UPDATES" != "true" ] ; then + 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/dotnet/NOTES.md b/src/dotnet/NOTES.md index 19fe92f31..578aceaf3 100644 --- a/src/dotnet/NOTES.md +++ b/src/dotnet/NOTES.md @@ -1,4 +1,71 @@ +## Configuration examples +Installing only the latest .NET SDK version (the default). + +``` json +{ +"features": { + "ghcr.io/devcontainers/features/dotnet:2": "latest" // or "" or {} +} +``` + +Installing an additional SDK version. Multiple versions can be specified as comma-separated values. + +``` json +{ +"features": { + "ghcr.io/devcontainers/features/dotnet:2": { + "additionalVersions": "lts" + } +} +``` + +Installing specific SDK versions. + +``` json +{ +"features": { + "ghcr.io/devcontainers/features/dotnet:2": { + "version": "6.0", + "additionalVersions": "7.0, 8.0" + } +} +``` + +Installing a specific SDK feature band. + +``` json +{ +"features": { + "ghcr.io/devcontainers/features/dotnet:2": { + "version": "6.0.4xx", + } +} +``` + +Installing a specific SDK patch version. + +``` json +{ +"features": { + "ghcr.io/devcontainers/features/dotnet:2": { + "version": "6.0.412", + } +} +``` + +Installing only the .NET Runtime or the ASP.NET Core Runtime. (The SDK includes all runtimes so this configuration is only useful if you need to run .NET apps without building them from source.) + +``` json +{ +"features": { + "ghcr.io/devcontainers/features/dotnet:2": { + "version": "none", + "dotnetRuntimeVersions": "latest, lts", + "aspnetCoreRuntimeVersions": "latest, lts", + } +} +``` ## OS Support diff --git a/src/dotnet/devcontainer-feature.json b/src/dotnet/devcontainer-feature.json index 4f484ccba..f00e0d3ea 100644 --- a/src/dotnet/devcontainer-feature.json +++ b/src/dotnet/devcontainer-feature.json @@ -1,35 +1,44 @@ { "id": "dotnet", - "version": "1.1.4", + "version": "2.0.0", "name": "Dotnet CLI", "documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet", - "description": "Installs the .NET CLI. Provides option of installing sdk or runtime, and option of versions to install. Uses latest version of .NET sdk as defaults to install.", + "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.", "options": { "version": { "type": "string", "proposals": [ "latest", - "7", - "6", - "3.1" + "lts", + "none", + "8.0", + "7.0", + "6.0" ], "default": "latest", - "description": "Select or enter a dotnet CLI version. (Available versions may vary by Linux distribution.)" + "description": "Select or enter a .NET SDK version. Use 'latest' for the latest version, 'lts' for the latest LTS version, 'X.Y' or 'X.Y.Z' for a specific version." }, - "runtimeOnly": { - "type": "boolean", - "default": false, - "description": "Install just the dotnet runtime if true, and sdk if false." + "additionalVersions": { + "type": "string", + "default": "", + "description": "Enter additional .NET SDK versions, separated by commas. Use 'latest' for the latest version, 'lts' for the latest LTS version, 'X.Y' or 'X.Y.Z' for a specific version." + }, + "dotnetRuntimeVersions": { + "type": "string", + "default": "", + "description": "Enter additional .NET runtime versions, separated by commas. Use 'latest' for the latest version, 'lts' for the latest LTS version, 'X.Y' or 'X.Y.Z' for a specific version." }, - "installUsingApt": { - "type": "boolean", - "default": true, - "description": "If true, it installs using apt instead of the release URL" + "aspNetCoreRuntimeVersions": { + "type": "string", + "default": "", + "description": "Enter additional ASP.NET Core runtime versions, separated by commas. Use 'latest' for the latest version, 'lts' for the latest LTS version, 'X.Y' or 'X.Y.Z' for a specific version." } }, "containerEnv": { - "DOTNET_ROOT": "/usr/local/dotnet/current", - "PATH": "/usr/local/dotnet/current:${PATH}" + "DOTNET_ROOT": "/usr/share/dotnet", + "PATH": "$PATH:$DOTNET_ROOT:~/.dotnet/tools", + "DOTNET_RUNNING_IN_CONTAINER": "true", + "DOTNET_USE_POLLING_FILE_WATCHER": "true" }, "customizations": { "vscode": { diff --git a/src/dotnet/install.sh b/src/dotnet/install.sh index 178994d71..ff9244d3a 100644 --- a/src/dotnet/install.sh +++ b/src/dotnet/install.sh @@ -4,46 +4,20 @@ # Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. #------------------------------------------------------------------------------------------------------------- # -# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/dotnet.md -# Maintainer: The VS Code and Codespaces Teams - +# Docs: https://github.com/devcontainers/features/tree/main/src/dotnet +# Maintainer: The Dev Container spec maintainers DOTNET_VERSION="${VERSION:-"latest"}" -DOTNET_RUNTIME_ONLY="${RUNTIMEONLY:-"false"}" -OVERRIDE_DEFAULT_VERSION="${OVERRIDEDEFAULTVERSION:-"true"}" -INSTALL_USING_APT="${INSTALLUSINGAPT:-"true"}" - -DOTNET_LATEST="7" -DOTNET_LTS="6" - -USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}" -UPDATE_RC="${UPDATE_RC:-"true"}" -TARGET_DOTNET_ROOT="${TARGET_DOTNET_ROOT:-"/usr/local/dotnet"}" -ACCESS_GROUP="${ACCESS_GROUP:-"dotnet"}" - -MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc" -DOTNET_ARCHIVE_ARCHITECTURES="amd64" -DOTNET_ARCHIVE_VERSION_CODENAMES="buster bullseye bionic focal hirsute jammy" -# Feed URI sourced from the official dotnet-install.sh -# https://github.com/dotnet/install-scripts/blob/1b98b94a6f6d81cc4845eb88e0195fac67caa0a6/src/dotnet-install.sh#L1342-L1343 -DOTNET_CDN_FEED_URI="https://dotnetcli.azureedge.net" -# Ubuntu 22.04 and on do not ship with libssl1.1, which is required for versions of .NET < 6.0 -DOTNET_VERSION_CODENAMES_REQUIRE_OLDER_LIBSSL_1="buster bullseye bionic focal hirsute" +ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS}" +DOTNET_RUNTIME_VERSIONS="${DOTNETRUNTIMEVERSIONS}" +ASPNETCORE_RUNTIME_VERSIONS="${ASPNETCORERUNTIMEVERSIONS}" -# Comma-separated list of dotnet versions to be installed -# alongside DOTNET_VERSION, but not set as default. -ADDITIONAL_VERSIONS=${ADDITIONALVERSIONS:-""} - -APT_PREFERENCES_CONTENT="$(cat << 'EOF' -Package: * -Pin: origin "packages.microsoft.com" -Pin-Priority: 1001 -EOF -)" +set -e -APT_PREFERENCES_FILE_ADDED="false" -APT_PREFERENCES_UPDATED="false" +# Import trim_whitespace and split_csv +source "scripts/string-helpers.sh" -set -e +# Import install_sdk and install_runtime +source "scripts/dotnet-helpers.sh" # Clean up rm -rf /var/lib/apt/lists/* @@ -53,72 +27,14 @@ err() { echo "(!) $*" >&2 } -# Ensure the appropriate root user is running the script. -if [ "$(id -u)" -ne 0 ]; then - err 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' - exit 1 -fi - -# 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 -echo "export PATH=${PATH//$(sh -lc 'echo $PATH')/\$PATH}" > /etc/profile.d/00-restore-env.sh -chmod +x /etc/profile.d/00-restore-env.sh - -# Determine the appropriate non-root user. -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 - USERNAME="${CURRENT_USER}" - break - fi - done - if [ "${USERNAME}" = "" ]; then - USERNAME=root - fi -elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then - USERNAME=root -fi - -################### -# Helper Functions -################### - -# Cleanup temporary directory and associated files when exiting the script. -cleanup() { - EXIT_CODE=$? - set +e - if [[ -n "${TMP_DIR}" ]]; then - echo "Executing cleanup of tmp files" - rm -Rf "${TMP_DIR}" - fi - exit $EXIT_CODE -} -trap cleanup EXIT - -# Add dotnet directory to PATH in bashrc/zshrc files if OVERRIDE_DEFAULT_VERSION=true. -updaterc() { - if [ "${UPDATE_RC}" = "true" ]; then - echo "Updating /etc/bash.bashrc and /etc/zsh/zshrc..." - if [[ "$(cat /etc/bash.bashrc)" != *"$1"* ]]; then - echo -e "$1" >> /etc/bash.bashrc - fi - if [ -f "/etc/zsh/zshrc" ] && [[ "$(cat /etc/zsh/zshrc)" != *"$1"* ]]; then - echo -e "$1" >> /etc/zsh/zshrc - fi - fi -} - -apt_get_update() -{ +apt_get_update() { if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then echo "Running apt-get update..." apt-get update -y fi } -# Check if packages are installed and installs them if not. +# Checks if packages are installed and installs them if not check_packages() { if ! dpkg -s "$@" > /dev/null 2>&1; then apt_get_update @@ -126,367 +42,77 @@ check_packages() { fi } -# Get appropriate architecture name for .NET binaries for the target OS -get_architecture_name_for_target_os() { - local architecture - architecture="$(uname -m)" - case $architecture in - x86_64) architecture="x64";; - aarch64 | armv8*) architecture="arm64";; - *) err "Architecture ${architecture} unsupported"; exit 1 ;; - esac - - echo "${architecture}" -} - -# Soft version matching that resolves a version for a given package in the *current apt-cache* -# Return value is stored in first argument (the unprocessed version) -apt_cache_package_and_version_soft_match() { - # Version - local version_variable_name="$1" - local requested_version=${!version_variable_name} - # Package Name - local package_variable_name="$2" - local partial_package_name=${!package_variable_name} - local package_name - # Exit on no match? - local exit_on_no_match="${3:-true}" - local major_minor_version - - # Ensure we've exported useful variables - . /etc/os-release - local architecture="$(dpkg --print-architecture)" - - apt-get update -y - major_minor_version="$(echo "${requested_version}" | cut -d "." --field=1,2)" - package_name="$(apt-cache search "${partial_package_name}-[0-9].[0-9]$" | awk -F" - " '{print $1}' | grep -m 1 "${partial_package_name}-${major_minor_version}")" - dot_escaped="${requested_version//./\\.}" - dot_plus_escaped="${dot_escaped//+/\\+}" - # Regex needs to handle debian package version number format: https://www.systutorials.com/docs/linux/man/5-deb-version/ - version_regex="^(.+:)?${dot_plus_escaped}([\\.\\+ ~:-]|$)" - set +e # Don't exit if finding version fails - handle gracefully - fuzzy_version="$(apt-cache madison ${package_name} | awk -F"|" '{print $2}' | sed -e 's/^[ \t]*//' | grep -E -m 1 "${version_regex}")" - set -e - if [ -z "${fuzzy_version}" ]; then - echo "(!) No full or partial for package \"${partial_package_name}\" (resolved: \"${package_name}\") match found in apt-cache for \"${requested_version}\" on OS ${ID} ${VERSION_CODENAME} (${architecture})." - - if $exit_on_no_match; then - echo "Available versions:" - apt-cache madison ${package_name} | awk -F"|" '{print $2}' | grep -oP '^(.+:)?\K.+' - exit 1 # Fail entire script - else - echo "Continuing to fallback method if available" - return 1; - fi - fi - - # Globally assign fuzzy_version to this value - # Use this value as the return value of this function - declare -g ${version_variable_name}="=${fuzzy_version}" - echo "${version_variable_name} ${!version_variable_name}" - - # Globally assign package to this value - # Use this value as the return value of this function - declare -g ${package_variable_name}="${package_name}" - echo "${package_variable_name} ${!package_variable_name}" -} - -# Install .NET CLI using apt-get package installer -install_using_apt() { - local sdk_or_runtime="$1" - local target_dotnet_version="$2" - local use_msft_repo="$3" - - if [ "${use_msft_repo}" = "true" ]; then - # Install dependencies - check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr - # Import key safely and import Microsoft apt repo - curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg - echo "deb [arch=${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 - - [ ! -f /etc/apt/preferences ] && APT_PREFERENCES_FILE_ADDED="true" - APT_PREFERENCES_UPDATED="true" - - # See https://github.com/dotnet/core/issues/7699 - echo "${APT_PREFERENCES_CONTENT}" >> /etc/apt/preferences - apt-get update -y - fi - - # .NET 7 is not a LTS version, so handle latest and LTS versions differently - export APT_DOTNET_VERSION="$target_dotnet_version" - if [ "${APT_DOTNET_VERSION}" = "latest" ]; then - APT_DOTNET_VERSION="${DOTNET_LATEST}.0" - elif [ "${APT_DOTNET_VERSION}" = "lts" ]; then - APT_DOTNET_VERSION="${DOTNET_LTS}.0" - fi - - # Sets target_dotnet_version and dotnet_package if matches found. - local base_dotnet_package="dotnet-${sdk_or_runtime}" - export DOTNET_PACKAGE="${base_dotnet_package}" - apt_cache_package_and_version_soft_match APT_DOTNET_VERSION DOTNET_PACKAGE false - if [ "$?" != 0 ] || [ ${DOTNET_PACKAGE} == "${base_dotnet_package}" ]; then - echo "Failed to find requested version." - return 1 - fi - - if type dotnet > /dev/null 2>&1 && [[ "$(dotnet --version)" == *"${APT_DOTNET_VERSION}"* ]] ; then - echo "dotnet version ${APT_DOTNET_VERSION} is already installed" - return 1 - fi - - echo "Installing '${DOTNET_PACKAGE}${APT_DOTNET_VERSION}'..." - apt-get install -yq ${DOTNET_PACKAGE}${APT_DOTNET_VERSION} - if [ "$?" != 0 ]; then - echo "Failed to complete apt install of ${DOTNET_PACKAGE}${TARGET_DOTNET_VERSION}" - return 1 - fi - - # Add symlink for current - CURRENT_DIR="${TARGET_DOTNET_ROOT}/current" - if [[ -d "${CURRENT_DIR}" ]]; then - rm -rf "${CURRENT_DIR}" - fi - mkdir -p "${TARGET_DOTNET_ROOT}" - local dotnet_installed_version="$(dotnet --version)" - # See if its the distro version - if [[ "$(dotnet --info)" == *"Base Path: /usr/lib/dotnet/${DOTNET_SDK_OR_RUNTIME}/${dotnet_installed_version}"* ]]; then - ln -s "/usr/lib/dotnet" "${CURRENT_DIR}" - else - # Location used by MS repo versions - ln -s "/usr/share/dotnet" "${CURRENT_DIR}" - fi -} - -# Find and extract .NET binary download details based on user-requested version -# args: -# sdk_or_runtime $1 -# dotnet_version_to_download $2 -# exports: -# DOTNET_DOWNLOAD_URL -# DOTNET_DOWNLOAD_HASH -# DOTNET_DOWNLOAD_NAME -get_full_version_details() { - local sdk_or_runtime="$1" - local architecture - local dotnet_channel_version - local dotnet_releases_url - local dotnet_releases_json - local dotnet_latest_version - local dotnet_download_details - - export DOTNET_DOWNLOAD_VERSION="$2" - export DOTNET_DOWNLOAD_URL - export DOTNET_DOWNLOAD_HASH - export DOTNET_DOWNLOAD_NAME - - # Set architecture variable to current user's architecture (x64 or ARM64). - architecture="$(get_architecture_name_for_target_os)" - - # Set VERSION to empty string to ensure jq includes all .NET versions in reverse sort below - if [ "${DOTNET_DOWNLOAD_VERSION}" = "latest" ]; then - DOTNET_DOWNLOAD_VERSION="" - fi - - dotnet_patchless_version="$(echo "${DOTNET_DOWNLOAD_VERSION}" | cut -d "." --field=1,2)" - - set +e - dotnet_channel_version="$(curl -s "${DOTNET_CDN_FEED_URI}/dotnet/release-metadata/releases-index.json" | jq -r --arg channel_version "${dotnet_patchless_version}" '[."releases-index"[]] | sort_by(."channel-version") | reverse | map( select(."channel-version" | startswith($channel_version))) | first | ."channel-version"')" - set -e +if [ "$(id -u)" -ne 0 ]; then + err 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.' + exit 1 +fi - # Construct the releases URL using the official channel-version if one was found. Otherwise make a best-effort using the user input. - if [ -n "${dotnet_channel_version}" ] && [ "${dotnet_channel_version}" != "null" ]; then - dotnet_releases_url="${DOTNET_CDN_FEED_URI}/dotnet/release-metadata/${dotnet_channel_version}/releases.json" - else - dotnet_releases_url="${DOTNET_CDN_FEED_URI}/dotnet/release-metadata/${dotnet_patchless_version}/releases.json" - fi +# For our own convenience, combine DOTNET_VERSION and ADDITIONAL_VERSIONS into a single 'versions' array +versions=() - set +e - dotnet_releases_json="$(curl -s "${dotnet_releases_url}")" - set -e - - if [ -n "${dotnet_releases_json}" ] && [[ ! "${dotnet_releases_json}" = *"Error"* ]]; then - dotnet_latest_version="$(echo "${dotnet_releases_json}" | jq -r --arg sdk_or_runtime "${sdk_or_runtime}" '."latest-\($sdk_or_runtime)"')" - # If user-specified version has 2 or more dots, use it as is. Otherwise use latest version. - if [ "$(echo "${DOTNET_DOWNLOAD_VERSION}" | grep -o "\." | wc -l)" -lt "2" ]; then - DOTNET_DOWNLOAD_VERSION="${dotnet_latest_version}" - fi +# The version can be set to 'none' for runtime-only installations, then the array will just remain empty +# Ensure there are no leading or trailing spaces that can break regex pattern matching +if [ "$DOTNET_VERSION" != "none" ]; then + versions+=("$(trim_whitespace "$DOTNET_VERSION")") + for additional_version in $(split_csv "$ADDITIONAL_VERSIONS"); do + versions+=("$additional_version") + done +fi - dotnet_download_details="$(echo "${dotnet_releases_json}" | jq -r --arg sdk_or_runtime "${sdk_or_runtime}" --arg dotnet_version "${DOTNET_DOWNLOAD_VERSION}" --arg arch "${architecture}" '.releases[]."\($sdk_or_runtime)" | select(.version==$dotnet_version) | .files[] | select(.name=="dotnet-\($sdk_or_runtime)-linux-\($arch).tar.gz")')" - if [ -n "${dotnet_download_details}" ]; then - echo "Found .NET binary version ${DOTNET_DOWNLOAD_VERSION}" - DOTNET_DOWNLOAD_URL="$(echo "${dotnet_download_details}" | jq -r '.url')" - DOTNET_DOWNLOAD_HASH="$(echo "${dotnet_download_details}" | jq -r '.hash')" - DOTNET_DOWNLOAD_NAME="$(echo "${dotnet_download_details}" | jq -r '.name')" - else - err "Unable to find .NET binary for version ${DOTNET_DOWNLOAD_VERSION}" - exit 1 - fi - else - err "Unable to find .NET release details for version ${DOTNET_DOWNLOAD_VERSION} at ${dotnet_releases_url}" +dotnetRuntimeVersions=() +for dotnetRuntimeVersion in $(split_csv "$DOTNET_RUNTIME_VERSIONS"); do + dotnetRuntimeVersions+=("$dotnetRuntimeVersion") +done + +aspNetCoreRuntimeVersions=() +for aspNetCoreRuntimeVersion in $(split_csv "$ASPNETCORE_RUNTIME_VERSIONS"); do + aspNetCoreRuntimeVersions+=("$aspNetCoreRuntimeVersion") +done + +# Fail fast in case of bad input to avoid unneccesary work +# v1 of the .NET feature allowed specifying only a major version 'X' like '3' +# v2 removed this ability +# - because install-dotnet.sh does not support it directly +# - because the previous behavior installed an old version like '3.0.103', not the newest version '3.1.426', which was counterintuitive +for version in "${versions[@]}"; do + if [[ "$version" =~ ^[0-9]+$ ]]; then + err "Unsupported .NET SDK version '${version}'. Use 'latest' for the latest version, 'lts' for the latest LTS version, 'X.Y' or 'X.Y.Z' for a specific version." exit 1 fi -} - -# Install .NET CLI using the .NET releases url -install_using_dotnet_releases_url() { - local sdk_or_runtime="$1" - local version="$2" - - # Check listed package dependencies and install them if they are not already installed. - # NOTE: icu-devtools is a small package with similar dependencies to .NET. - # It will install the appropriate dependencies based on the OS: - # - libgcc-s1 OR libgcc1 depending on OS - # - the latest libicuXX depending on OS (eg libicu57 for stretch) - # - also installs libc6 and libstdc++6 which are required by .NET - check_packages curl ca-certificates tar jq icu-devtools libgssapi-krb5-2 zlib1g - - # Starting with Ubuntu 22.04 (jammy), libssl1.1 does not ship with the OS anymore. - if [[ "${DOTNET_VERSION_CODENAMES_REQUIRE_OLDER_LIBSSL_1}" = *"${VERSION_CODENAME}"* ]]; then - check_packages libssl1.1 - else - check_packages libssl3 - fi +done - get_full_version_details "${sdk_or_runtime}" "${version}" - - DOTNET_INSTALL_PATH="${TARGET_DOTNET_ROOT}/${DOTNET_DOWNLOAD_VERSION}" - if [ -d "${DOTNET_INSTALL_PATH}" ]; then - echo "(!) Dotnet version ${DOTNET_DOWNLOAD_VERSION} already exists." +for version in "${dotnetRuntimeVersions[@]}"; do + if [[ "$version" =~ ^[0-9]+$ ]]; then + err "Unsupported .NET Runtime version '${version}'. Use 'latest' for the latest version, 'lts' for the latest LTS version, 'X.Y' or 'X.Y.Z' for a specific version." exit 1 fi - # exports DOTNET_DOWNLOAD_URL, DOTNET_DOWNLOAD_HASH, DOTNET_DOWNLOAD_NAME - echo "DOWNLOAD LINK: ${DOTNET_DOWNLOAD_URL}" - - # Setup the access group and add the user to it. - umask 0002 - if ! cat /etc/group | grep -e "^${ACCESS_GROUP}:" > /dev/null 2>&1; then - groupadd -r "${ACCESS_GROUP}" - fi - usermod -a -G "${ACCESS_GROUP}" "${USERNAME}" - - # Download the .NET binaries. - echo "DOWNLOADING BINARY..." - TMP_DIR="/tmp/dotnetinstall" - mkdir -p "${TMP_DIR}" - curl -sSL "${DOTNET_DOWNLOAD_URL}" -o "${TMP_DIR}/${DOTNET_DOWNLOAD_NAME}" - - # Get checksum from .NET CLI blob storage using the runtime version and - # run validation (sha512sum) of checksum against the expected checksum hash. - echo "VERIFY CHECKSUM" - cd "${TMP_DIR}" - echo "${DOTNET_DOWNLOAD_HASH} *${DOTNET_DOWNLOAD_NAME}" | sha512sum -c - - - # Extract binaries and add to path. - mkdir -p "${DOTNET_INSTALL_PATH}" - echo "Extract Binary to ${DOTNET_INSTALL_PATH}" - tar -xzf "${TMP_DIR}/${DOTNET_DOWNLOAD_NAME}" -C "${DOTNET_INSTALL_PATH}" --strip-components=1 +done - CURRENT_DIR="${TARGET_DOTNET_ROOT}/current" - if [[ ! -d "${CURRENT_DIR}" ]]; then - ln -s "${DOTNET_INSTALL_PATH}" "${CURRENT_DIR}" - fi - - # Give write permissions to the user. - chown -R "${USERNAME}:${USERNAME}" "${CURRENT_DIR}" - chmod g+r+w+s "${CURRENT_DIR}" - chmod -R g+r+w "${CURRENT_DIR}" - - if [[ "${OVERRIDE_DEFAULT_VERSION}" = "true" ]]; then - if [[ $(ls -l ${CURRENT_DIR}) != *"-> ${DOTNET_INSTALL_PATH}"* ]] ; then - rm "${CURRENT_DIR}" - ln -s "${DOTNET_INSTALL_PATH}" "${CURRENT_DIR}" - fi - fi - - updaterc "if [[ \"\${PATH}\" != *\"${CURRENT_DIR}\"* ]]; then export PATH=${CURRENT_DIR}:\${PATH}; fi" -} - -########################### -# Start .NET installation -########################### - -export DEBIAN_FRONTEND=noninteractive - -. /etc/os-release -architecture="$(dpkg --print-architecture)" - -# Dotnet 3.1 and 5 are not supported on Ubuntu 22.04 (jammy)+, -# due to lack of libssl3.0 support. -# See: https://github.com/microsoft/vscode-dev-containers/issues/1458#issuecomment-1135077775 -# NOTE: This will only guard against installation of the dotnet versions we propose via 'features'. -# The user can attempt to install any other version at their own risk. -if [[ "${DOTNET_VERSION}" = "3"* ]] || [[ "${DOTNET_VERSION}" = "5"* ]]; then - if [[ ! "${DOTNET_VERSION_CODENAMES_REQUIRE_OLDER_LIBSSL_1}" = *"${VERSION_CODENAME}"* ]]; then - err "Dotnet ${DOTNET_VERSION} is not supported on Ubuntu ${VERSION_CODENAME} due to a change in the 'libssl' dependency across distributions.\n Please upgrade your version of dotnet, or downgrade your OS version." +for version in "${aspNetCoreRuntimeVersions[@]}"; do + if [[ "$version" =~ ^[0-9]+$ ]]; then + err "Unsupported ASP.NET Core Runtime version '${version}'. Use 'latest' for the latest version, 'lts' for the latest LTS version, 'X.Y' or 'X.Y.Z' for a specific version." exit 1 fi -fi +done -# Determine if the user wants to download .NET Runtime only, or .NET SDK & Runtime -# and set the appropriate variables. -if [ "${DOTNET_RUNTIME_ONLY}" = "true" ]; then - DOTNET_SDK_OR_RUNTIME="runtime" -elif [ "${DOTNET_RUNTIME_ONLY}" = "false" ]; then - DOTNET_SDK_OR_RUNTIME="sdk" -else - err "Expected true for installing dotnet Runtime only or false for installing SDK and Runtime. Received ${DOTNET_RUNTIME_ONLY}." - exit 1 -fi +# Install .NET versions and dependencies +# icu-devtools includes dependencies for .NET +check_packages wget ca-certificates icu-devtools -# Install the .NET CLI -echo "(*) Installing .NET CLI..." +for version in "${versions[@]}"; do + install_sdk "$version" +done -CHANGE_OWNERSHIP="false" -if [[ "${DOTNET_ARCHIVE_ARCHITECTURES}" = *"${architecture}"* ]] && [[ "${DOTNET_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]] && [[ "${INSTALL_USING_APT}" = "true" ]]; then - echo "Detected ${VERSION_CODENAME} on ${architecture}. Attempting to install dotnet from apt" +for version in "${dotnetRuntimeVersions[@]}"; do + install_runtime "dotnet" "$version" +done - install_using_apt "${DOTNET_SDK_OR_RUNTIME}" "${DOTNET_VERSION}" false || install_using_apt "${DOTNET_SDK_OR_RUNTIME}" "${DOTNET_VERSION}" true - if [ "$?" != 0 ]; then - echo "Could not install requested version from apt on current distribution." - exit 1 - fi -else - if [[ "${INSTALL_USING_APT}" = "false" ]]; then - echo "Installing dotnet from releases url" - else - echo "Attempting to install dotnet from releases url" - fi - install_using_dotnet_releases_url "${DOTNET_SDK_OR_RUNTIME}" "${DOTNET_VERSION}" - CHANGE_OWNERSHIP="true" -fi - -# Additional dotnet versions to be installed but not be set as default. -if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then - OLDIFS=$IFS - IFS="," - read -a additional_versions <<< "$ADDITIONAL_VERSIONS" - for version in "${additional_versions[@]}"; do - OVERRIDE_DEFAULT_VERSION="false" - install_using_dotnet_releases_url "${DOTNET_SDK_OR_RUNTIME}" "${version}" - done - IFS=$OLDIFS -fi - -if [ "${CHANGE_OWNERSHIP}" = "true" ]; then - if ! cat /etc/group | grep -e "^dotnet:" > /dev/null 2>&1; then - groupadd -r dotnet - fi - usermod -a -G dotnet "${USERNAME}" - - chown -R "${USERNAME}:dotnet" "${TARGET_DOTNET_ROOT}" - chmod -R g+r+w "${TARGET_DOTNET_ROOT}" - find "${TARGET_DOTNET_ROOT}" -type d -print0 | xargs -n 1 -0 chmod g+s -fi +for version in "${aspNetCoreRuntimeVersions[@]}"; do + install_runtime "aspnetcore" "$version" +done # Clean up -if [ "${APT_PREFERENCES_UPDATED}" = "true" ]; then - if [ "${APT_PREFERENCES_FILE_ADDED}" = "true" ]; then - rm -f /etc/apt/preferences - else - head -n -3 /etc/apt/preferences > /tmp/preferences-temp && mv /tmp/preferences-temp /etc/apt/preferences - fi -fi - rm -rf /var/lib/apt/lists/* +rm -rf scripts echo "Done!" diff --git a/src/dotnet/scripts/dotnet-helpers.sh b/src/dotnet/scripts/dotnet-helpers.sh new file mode 100644 index 000000000..bda0c9c3a --- /dev/null +++ b/src/dotnet/scripts/dotnet-helpers.sh @@ -0,0 +1,119 @@ +#!/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/dotnet +# Maintainer: The Dev Container spec maintainers +DOTNET_SCRIPTS=$(dirname "${BASH_SOURCE[0]}") +DOTNET_INSTALL_SCRIPT="$DOTNET_SCRIPTS/vendor/dotnet-install.sh" +DOTNET_INSTALL_DIR='/usr/share/dotnet' + +# Prints the latest dotnet version in the specified channel +# Usage: fetch_latest_version_in_channel [] +# Example: fetch_latest_version_in_channel "LTS" +# Example: fetch_latest_version_in_channel "6.0" "dotnet" +# Example: fetch_latest_version_in_channel "6.0" "aspnetcore" +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" + elif [ "$runtime" = "aspnetcore" ]; then + wget -qO- "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/$channel/latest.version" + else + wget -qO- "https://dotnetcli.azureedge.net/dotnet/Sdk/$channel/latest.version" + fi + +} + +# Prints the latest dotnet version +# Usage: fetch_latest_version [] +# Example: fetch_latest_version +# Example: fetch_latest_version "dotnet" +# Example: fetch_latest_version "aspnetcore" +fetch_latest_version() { + local runtime="$1" + local sts_version + local lts_version + sts_version=$(fetch_latest_version_in_channel "STS" "$runtime") + lts_version=$(fetch_latest_version_in_channel "LTS" "$runtime") + if [[ "$sts_version" > "$lts_version" ]]; then + echo "$sts_version" + else + echo "$lts_version" + fi +} + +# Installs a version of the .NET SDK +# Usage: install_sdk +install_sdk() { + local inputVersion="$1" + local version="" + local channel="" + if [[ "$inputVersion" == "latest" ]]; then + # Fetch the latest version manually, because dotnet-install.sh does not support it directly + version=$(fetch_latest_version) + elif [[ "$inputVersion" == "lts" ]]; then + # When user input is 'lts' + # Then version=latest, channel=LTS + version="latest" + channel="LTS" + elif [[ "$inputVersion" =~ ^[0-9]+\.[0-9]+$ ]]; then + # When user input is form 'A.B' like '3.1' + # Then version=latest, channel=3.1 + version="latest" + channel="$inputVersion" + elif [[ "$inputVersion" =~ ^[0-9]+\.[0-9]+\.[0-9]xx$ ]]; then + # When user input is form 'A.B.Cxx' like '6.0.4xx' + # Then version=latest, channel=6.0.4xx + version="latest" + channel="$inputVersion" + else + # Assume version is an exact version string like '6.0.413' or '8.0.100-rc.2.23425.18' + version="$inputVersion" + fi + + # Currently this script does not make it possible to qualify the version, 'GA' is always implied + echo "Executing $DOTNET_INSTALL_SCRIPT --version $version --channel $channel --install-dir $DOTNET_INSTALL_DIR --no-path" + "$DOTNET_INSTALL_SCRIPT" \ + --version "$version" \ + --channel "$channel" \ + --install-dir "$DOTNET_INSTALL_DIR" \ + --no-path +} + +# Installs a version of the .NET Runtime +# Usage: install_runtime +install_runtime() { + local runtime="$1" + local inputVersion="$2" + local version="" + local channel="" + if [[ "$inputVersion" == "latest" ]]; then + # Fetch the latest version manually, because dotnet-install.sh does not support it directly + version=$(fetch_latest_version "$runtime") + elif [[ "$inputVersion" == "lts" ]]; then + # When user input is 'lts' + # Then version=latest, channel=LTS + version="latest" + channel="LTS" + elif [[ "$inputVersion" =~ ^[0-9]+\.[0-9]+$ ]]; then + # When user input is form 'A.B' like '3.1' + # Then version=latest, channel=3.1 + version="latest" + channel="$inputVersion" + else + # Assume version is an exact version string like '6.0.21' or '8.0.0-preview.7.23375.6' + version="$inputVersion" + fi + + echo "Executing $DOTNET_INSTALL_SCRIPT --runtime $runtime --version $version --channel $channel --install-dir $DOTNET_INSTALL_DIR --no-path" + "$DOTNET_INSTALL_SCRIPT" \ + --runtime "$runtime" \ + --version "$version" \ + --channel "$channel" \ + --install-dir "$DOTNET_INSTALL_DIR" \ + --no-path +} diff --git a/src/dotnet/scripts/fetch-latest-dotnet-install.sh b/src/dotnet/scripts/fetch-latest-dotnet-install.sh new file mode 100755 index 000000000..361d539c4 --- /dev/null +++ b/src/dotnet/scripts/fetch-latest-dotnet-install.sh @@ -0,0 +1,16 @@ +#!/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/dotnet +# Maintainer: The Dev Container spec maintainers +# +# Run this script to replace dotnet-install.sh with the latest and greatest available version +# +DOTNET_SCRIPTS=$(dirname "${BASH_SOURCE[0]}") +DOTNET_INSTALL_SCRIPT="$DOTNET_SCRIPTS/vendor/dotnet-install.sh" + +wget https://dot.net/v1/dotnet-install.sh -O "$DOTNET_INSTALL_SCRIPT" +chmod +x "$DOTNET_INSTALL_SCRIPT" diff --git a/src/dotnet/scripts/string-helpers.sh b/src/dotnet/scripts/string-helpers.sh new file mode 100644 index 000000000..35b4017c8 --- /dev/null +++ b/src/dotnet/scripts/string-helpers.sh @@ -0,0 +1,42 @@ +#!/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/dotnet +# Maintainer: The Dev Container spec maintainers + +# Removes leading and trailing whitespace from an input string +# Usage: trim_whitespace +trim_whitespace() { + text="$1" + + # Remove leading spaces + while [ "${text:0:1}" == " " ]; do + text="${text:1}" + done + + # Remove trailing spaces + while [ "${text: -1}" == " " ]; do + text="${text:0:-1}" + done + + echo "$text" +} + +# Splits comma-separated values into an array while ignoring empty entries +# Usage: split_csv +split_csv() { + local -a values=() + while IFS="," read -ra entries; do + for entry in "${entries[@]}"; do + entry="$(trim_whitespace "$entry")" + if [ -n "$entry" ]; then + values+=("$entry") + fi + done + done <<< "$1" + + echo "${values[@]}" +} \ No newline at end of file diff --git a/src/dotnet/scripts/vendor/README.md b/src/dotnet/scripts/vendor/README.md new file mode 100644 index 000000000..181b53781 --- /dev/null +++ b/src/dotnet/scripts/vendor/README.md @@ -0,0 +1,27 @@ +### **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. + +## dotnet-install.sh + +`dotnet-install.sh` is a copy of . ([Script reference](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script)) + +Quick options reminder for `dotnet-install.sh`: + +- `--version`: `"latest"` (default) or an exact version in the form A.B.C like `"6.0.413"` +- `--channel`: `"LTS"` (default), `"STS"`, a two-part version in the form A.B like `"6.0"` or three-part form A.B.Cxx like `"6.0.1xx"` +- `--quality`: `"daily"`, `"preview"` or `"GA"` +- The channel option is only used when version is 'latest' because an exact version overrides the channel option +- The quality option is only used when channel is 'A.B' or 'A.B.Cxx' because it can't be used with STS or LTS + +Examples + +``` +dotnet-install.sh [--version latest] [--channel LTS] +dotnet-install.sh [--version latest] --channel STS +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 6.0.413 +``` \ No newline at end of file diff --git a/src/dotnet/scripts/vendor/dotnet-install.sh b/src/dotnet/scripts/vendor/dotnet-install.sh new file mode 100755 index 000000000..a830583cd --- /dev/null +++ b/src/dotnet/scripts/vendor/dotnet-install.sh @@ -0,0 +1,1746 @@ +#!/usr/bin/env bash +# Copyright (c) .NET Foundation and contributors. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. +# + +# Stop script on NZEC +set -e +# Stop script if unbound variable found (use ${var:-} if intentional) +set -u +# By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success +# This is causing it to fail +set -o pipefail + +# Use in the the functions: eval $invocation +invocation='say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"' + +# standard output may be used as a return value in the functions +# we need a way to write text on the screen in the functions so that +# it won't interfere with the return value. +# Exposing stream 3 as a pipe to standard output of the script itself +exec 3>&1 + +# Setup some colors to use. These need to work in fairly limited shells, like the Ubuntu Docker container where there are only 8 colors. +# See if stdout is a terminal +if [ -t 1 ] && command -v tput > /dev/null; then + # see if it supports colors + ncolors=$(tput colors || echo 0) + if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then + bold="$(tput bold || echo)" + normal="$(tput sgr0 || echo)" + black="$(tput setaf 0 || echo)" + red="$(tput setaf 1 || echo)" + green="$(tput setaf 2 || echo)" + yellow="$(tput setaf 3 || echo)" + blue="$(tput setaf 4 || echo)" + magenta="$(tput setaf 5 || echo)" + cyan="$(tput setaf 6 || echo)" + white="$(tput setaf 7 || echo)" + fi +fi + +say_warning() { + printf "%b\n" "${yellow:-}dotnet_install: Warning: $1${normal:-}" >&3 +} + +say_err() { + printf "%b\n" "${red:-}dotnet_install: Error: $1${normal:-}" >&2 +} + +say() { + # using stream 3 (defined in the beginning) to not interfere with stdout of functions + # which may be used as return value + printf "%b\n" "${cyan:-}dotnet-install:${normal:-} $1" >&3 +} + +say_verbose() { + if [ "$verbose" = true ]; then + say "$1" + fi +} + +# This platform list is finite - if the SDK/Runtime has supported Linux distribution-specific assets, +# then and only then should the Linux distribution appear in this list. +# Adding a Linux distribution to this list does not imply distribution-specific support. +get_legacy_os_name_from_platform() { + eval $invocation + + platform="$1" + case "$platform" in + "centos.7") + echo "centos" + return 0 + ;; + "debian.8") + echo "debian" + return 0 + ;; + "debian.9") + echo "debian.9" + return 0 + ;; + "fedora.23") + echo "fedora.23" + return 0 + ;; + "fedora.24") + echo "fedora.24" + return 0 + ;; + "fedora.27") + echo "fedora.27" + return 0 + ;; + "fedora.28") + echo "fedora.28" + return 0 + ;; + "opensuse.13.2") + echo "opensuse.13.2" + return 0 + ;; + "opensuse.42.1") + echo "opensuse.42.1" + return 0 + ;; + "opensuse.42.3") + echo "opensuse.42.3" + return 0 + ;; + "rhel.7"*) + echo "rhel" + return 0 + ;; + "ubuntu.14.04") + echo "ubuntu" + return 0 + ;; + "ubuntu.16.04") + echo "ubuntu.16.04" + return 0 + ;; + "ubuntu.16.10") + echo "ubuntu.16.10" + return 0 + ;; + "ubuntu.18.04") + echo "ubuntu.18.04" + return 0 + ;; + "alpine.3.4.3") + echo "alpine" + return 0 + ;; + esac + return 1 +} + +get_legacy_os_name() { + eval $invocation + + local uname=$(uname) + if [ "$uname" = "Darwin" ]; then + echo "osx" + return 0 + elif [ -n "$runtime_id" ]; then + echo $(get_legacy_os_name_from_platform "${runtime_id%-*}" || echo "${runtime_id%-*}") + return 0 + else + if [ -e /etc/os-release ]; then + . /etc/os-release + os=$(get_legacy_os_name_from_platform "$ID${VERSION_ID:+.${VERSION_ID}}" || echo "") + if [ -n "$os" ]; then + echo "$os" + return 0 + fi + fi + fi + + say_verbose "Distribution specific OS name and version could not be detected: UName = $uname" + return 1 +} + +get_linux_platform_name() { + eval $invocation + + if [ -n "$runtime_id" ]; then + echo "${runtime_id%-*}" + return 0 + else + if [ -e /etc/os-release ]; then + . /etc/os-release + echo "$ID${VERSION_ID:+.${VERSION_ID}}" + return 0 + elif [ -e /etc/redhat-release ]; then + local redhatRelease=$(&1 || true) | grep -q musl +} + +get_current_os_name() { + eval $invocation + + local uname=$(uname) + if [ "$uname" = "Darwin" ]; then + echo "osx" + return 0 + elif [ "$uname" = "FreeBSD" ]; then + echo "freebsd" + return 0 + elif [ "$uname" = "Linux" ]; then + local linux_platform_name="" + linux_platform_name="$(get_linux_platform_name)" || true + + if [ "$linux_platform_name" = "rhel.6" ]; then + echo $linux_platform_name + return 0 + elif is_musl_based_distro; then + echo "linux-musl" + return 0 + elif [ "$linux_platform_name" = "linux-musl" ]; then + echo "linux-musl" + return 0 + else + echo "linux" + return 0 + fi + fi + + say_err "OS name could not be detected: UName = $uname" + return 1 +} + +machine_has() { + eval $invocation + + command -v "$1" > /dev/null 2>&1 + return $? +} + +check_min_reqs() { + local hasMinimum=false + if machine_has "curl"; then + hasMinimum=true + elif machine_has "wget"; then + hasMinimum=true + fi + + if [ "$hasMinimum" = "false" ]; then + say_err "curl (recommended) or wget are required to download dotnet. Install missing prerequisite to proceed." + return 1 + fi + return 0 +} + +# args: +# input - $1 +to_lowercase() { + #eval $invocation + + echo "$1" | tr '[:upper:]' '[:lower:]' + return 0 +} + +# args: +# input - $1 +remove_trailing_slash() { + #eval $invocation + + local input="${1:-}" + echo "${input%/}" + return 0 +} + +# args: +# input - $1 +remove_beginning_slash() { + #eval $invocation + + local input="${1:-}" + echo "${input#/}" + return 0 +} + +# args: +# root_path - $1 +# child_path - $2 - this parameter can be empty +combine_paths() { + eval $invocation + + # TODO: Consider making it work with any number of paths. For now: + if [ ! -z "${3:-}" ]; then + say_err "combine_paths: Function takes two parameters." + return 1 + fi + + local root_path="$(remove_trailing_slash "$1")" + local child_path="$(remove_beginning_slash "${2:-}")" + say_verbose "combine_paths: root_path=$root_path" + say_verbose "combine_paths: child_path=$child_path" + echo "$root_path/$child_path" + return 0 +} + +get_machine_architecture() { + eval $invocation + + if command -v uname > /dev/null; then + CPUName=$(uname -m) + case $CPUName in + armv*l) + echo "arm" + return 0 + ;; + aarch64|arm64) + echo "arm64" + return 0 + ;; + s390x) + echo "s390x" + return 0 + ;; + ppc64le) + echo "ppc64le" + return 0 + ;; + esac + fi + + # Always default to 'x64' + echo "x64" + return 0 +} + +# args: +# architecture - $1 +get_normalized_architecture_from_architecture() { + eval $invocation + + local architecture="$(to_lowercase "$1")" + + if [[ $architecture == \ ]]; then + echo "$(get_machine_architecture)" + return 0 + fi + + case "$architecture" in + amd64|x64) + echo "x64" + return 0 + ;; + arm) + echo "arm" + return 0 + ;; + arm64) + echo "arm64" + return 0 + ;; + s390x) + echo "s390x" + return 0 + ;; + ppc64le) + echo "ppc64le" + return 0 + ;; + esac + + say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues" + return 1 +} + +# args: +# version - $1 +# channel - $2 +# architecture - $3 +get_normalized_architecture_for_specific_sdk_version() { + eval $invocation + + local is_version_support_arm64="$(is_arm64_supported "$1")" + local is_channel_support_arm64="$(is_arm64_supported "$2")" + local architecture="$3"; + local osname="$(get_current_os_name)" + + if [ "$osname" == "osx" ] && [ "$architecture" == "arm64" ] && { [ "$is_version_support_arm64" = false ] || [ "$is_channel_support_arm64" = false ]; }; then + #check if rosetta is installed + if [ "$(/usr/bin/pgrep oahd >/dev/null 2>&1;echo $?)" -eq 0 ]; then + say_verbose "Changing user architecture from '$architecture' to 'x64' because .NET SDKs prior to version 6.0 do not support arm64." + echo "x64" + return 0; + else + say_err "Architecture \`$architecture\` is not supported for .NET SDK version \`$version\`. Please install Rosetta to allow emulation of the \`$architecture\` .NET SDK on this platform" + return 1 + fi + fi + + echo "$architecture" + return 0 +} + +# 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 + esac + + echo true + return 0 +} + +# args: +# user_defined_os - $1 +get_normalized_os() { + eval $invocation + + local osname="$(to_lowercase "$1")" + if [ ! -z "$osname" ]; then + case "$osname" in + osx | freebsd | rhel.6 | linux-musl | linux) + echo "$osname" + return 0 + ;; + *) + say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues." + return 1 + ;; + esac + else + osname="$(get_current_os_name)" || return 1 + fi + echo "$osname" + return 0 +} + +# args: +# quality - $1 +get_normalized_quality() { + eval $invocation + + local quality="$(to_lowercase "$1")" + if [ ! -z "$quality" ]; then + case "$quality" in + daily | signed | validated | preview) + echo "$quality" + return 0 + ;; + ga) + #ga quality is available without specifying quality, so normalizing it to empty + return 0 + ;; + *) + say_err "'$quality' is not a supported value for --quality option. Supported values are: daily, signed, validated, preview, ga. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues." + return 1 + ;; + esac + fi + return 0 +} + +# args: +# channel - $1 +get_normalized_channel() { + eval $invocation + + local channel="$(to_lowercase "$1")" + + if [[ $channel == current ]]; then + say_warning 'Value "Current" is deprecated for -Channel option. Use "STS" instead.' + fi + + if [[ $channel == release/* ]]; then + say_warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead.'; + fi + + if [ ! -z "$channel" ]; then + case "$channel" in + lts) + echo "LTS" + return 0 + ;; + sts) + echo "STS" + return 0 + ;; + current) + echo "STS" + return 0 + ;; + *) + echo "$channel" + return 0 + ;; + esac + fi + + return 0 +} + +# args: +# runtime - $1 +get_normalized_product() { + eval $invocation + + local product="" + local runtime="$(to_lowercase "$1")" + if [[ "$runtime" == "dotnet" ]]; then + product="dotnet-runtime" + elif [[ "$runtime" == "aspnetcore" ]]; then + product="aspnetcore-runtime" + elif [ -z "$runtime" ]; then + product="dotnet-sdk" + fi + echo "$product" + return 0 +} + +# The version text returned from the feeds is a 1-line or 2-line string: +# For the SDK and the dotnet runtime (2 lines): +# Line 1: # commit_hash +# Line 2: # 4-part version +# For the aspnetcore runtime (1 line): +# Line 1: # 4-part version + +# args: +# version_text - stdin +get_version_from_latestversion_file_content() { + eval $invocation + + cat | tail -n 1 | sed 's/\r$//' + return 0 +} + +# args: +# install_root - $1 +# relative_path_to_package - $2 +# specific_version - $3 +is_dotnet_package_installed() { + eval $invocation + + local install_root="$1" + local relative_path_to_package="$2" + local specific_version="${3//[$'\t\r\n']}" + + local dotnet_package_path="$(combine_paths "$(combine_paths "$install_root" "$relative_path_to_package")" "$specific_version")" + say_verbose "is_dotnet_package_installed: dotnet_package_path=$dotnet_package_path" + + if [ -d "$dotnet_package_path" ]; then + return 0 + else + return 1 + fi +} + +# args: +# azure_feed - $1 +# channel - $2 +# normalized_architecture - $3 +get_version_from_latestversion_file() { + eval $invocation + + local azure_feed="$1" + local channel="$2" + local normalized_architecture="$3" + + local version_file_url=null + if [[ "$runtime" == "dotnet" ]]; then + version_file_url="$azure_feed/Runtime/$channel/latest.version" + elif [[ "$runtime" == "aspnetcore" ]]; then + version_file_url="$azure_feed/aspnetcore/Runtime/$channel/latest.version" + elif [ -z "$runtime" ]; then + version_file_url="$azure_feed/Sdk/$channel/latest.version" + else + say_err "Invalid value for \$runtime" + return 1 + fi + say_verbose "get_version_from_latestversion_file: latest url: $version_file_url" + + download "$version_file_url" || return $? + return 0 +} + +# args: +# json_file - $1 +parse_globaljson_file_for_version() { + eval $invocation + + local json_file="$1" + if [ ! -f "$json_file" ]; then + say_err "Unable to find \`$json_file\`" + return 1 + fi + + sdk_section=$(cat $json_file | tr -d "\r" | awk '/"sdk"/,/}/') + if [ -z "$sdk_section" ]; then + say_err "Unable to parse the SDK node in \`$json_file\`" + return 1 + fi + + sdk_list=$(echo $sdk_section | awk -F"[{}]" '{print $2}') + sdk_list=${sdk_list//[\" ]/} + sdk_list=${sdk_list//,/$'\n'} + + local version_info="" + while read -r line; do + IFS=: + while read -r key value; do + if [[ "$key" == "version" ]]; then + version_info=$value + fi + done <<< "$line" + done <<< "$sdk_list" + if [ -z "$version_info" ]; then + say_err "Unable to find the SDK:version node in \`$json_file\`" + return 1 + fi + + unset IFS; + echo "$version_info" + return 0 +} + +# args: +# azure_feed - $1 +# channel - $2 +# normalized_architecture - $3 +# version - $4 +# json_file - $5 +get_specific_version_from_version() { + eval $invocation + + local azure_feed="$1" + local channel="$2" + local normalized_architecture="$3" + local version="$(to_lowercase "$4")" + local json_file="$5" + + if [ -z "$json_file" ]; then + if [[ "$version" == "latest" ]]; then + local version_info + version_info="$(get_version_from_latestversion_file "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1 + say_verbose "get_specific_version_from_version: version_info=$version_info" + echo "$version_info" | get_version_from_latestversion_file_content + return 0 + else + echo "$version" + return 0 + fi + else + local version_info + version_info="$(parse_globaljson_file_for_version "$json_file")" || return 1 + echo "$version_info" + return 0 + fi +} + +# args: +# azure_feed - $1 +# channel - $2 +# normalized_architecture - $3 +# specific_version - $4 +# normalized_os - $5 +construct_download_link() { + eval $invocation + + local azure_feed="$1" + local channel="$2" + local normalized_architecture="$3" + local specific_version="${4//[$'\t\r\n']}" + local specific_product_version="$(get_specific_product_version "$1" "$4")" + local osname="$5" + + local download_link=null + if [[ "$runtime" == "dotnet" ]]; then + download_link="$azure_feed/Runtime/$specific_version/dotnet-runtime-$specific_product_version-$osname-$normalized_architecture.tar.gz" + elif [[ "$runtime" == "aspnetcore" ]]; then + download_link="$azure_feed/aspnetcore/Runtime/$specific_version/aspnetcore-runtime-$specific_product_version-$osname-$normalized_architecture.tar.gz" + elif [ -z "$runtime" ]; then + download_link="$azure_feed/Sdk/$specific_version/dotnet-sdk-$specific_product_version-$osname-$normalized_architecture.tar.gz" + else + return 1 + fi + + echo "$download_link" + return 0 +} + +# args: +# azure_feed - $1 +# specific_version - $2 +# download link - $3 (optional) +get_specific_product_version() { + # If we find a 'productVersion.txt' at the root of any folder, we'll use its contents + # to resolve the version of what's in the folder, superseding the specified version. + # if 'productVersion.txt' is missing but download link is already available, product version will be taken from download link + eval $invocation + + local azure_feed="$1" + local specific_version="${2//[$'\t\r\n']}" + local package_download_link="" + if [ $# -gt 2 ]; then + local package_download_link="$3" + fi + local specific_product_version=null + + # Try to get the version number, using the productVersion.txt file located next to the installer file. + local download_links=($(get_specific_product_version_url "$azure_feed" "$specific_version" true "$package_download_link") + $(get_specific_product_version_url "$azure_feed" "$specific_version" false "$package_download_link")) + + for download_link in "${download_links[@]}" + do + say_verbose "Checking for the existence of $download_link" + + if machine_has "curl" + then + if ! specific_product_version=$(curl -s --fail "${download_link}${feed_credential}" 2>&1); then + continue + else + echo "${specific_product_version//[$'\t\r\n']}" + return 0 + fi + + elif machine_has "wget" + then + specific_product_version=$(wget -qO- "${download_link}${feed_credential}" 2>&1) + if [ $? = 0 ]; then + echo "${specific_product_version//[$'\t\r\n']}" + return 0 + fi + fi + done + + # Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number. + say_verbose "Failed to get the version using productVersion.txt file. Download link will be parsed instead." + specific_product_version="$(get_product_specific_version_from_download_link "$package_download_link" "$specific_version")" + echo "${specific_product_version//[$'\t\r\n']}" + return 0 +} + +# args: +# azure_feed - $1 +# specific_version - $2 +# is_flattened - $3 +# download link - $4 (optional) +get_specific_product_version_url() { + eval $invocation + + local azure_feed="$1" + local specific_version="$2" + local is_flattened="$3" + local package_download_link="" + if [ $# -gt 3 ]; then + local package_download_link="$4" + fi + + local pvFileName="productVersion.txt" + if [ "$is_flattened" = true ]; then + if [ -z "$runtime" ]; then + pvFileName="sdk-productVersion.txt" + elif [[ "$runtime" == "dotnet" ]]; then + pvFileName="runtime-productVersion.txt" + else + pvFileName="$runtime-productVersion.txt" + fi + fi + + local download_link=null + + if [ -z "$package_download_link" ]; then + if [[ "$runtime" == "dotnet" ]]; then + download_link="$azure_feed/Runtime/$specific_version/${pvFileName}" + elif [[ "$runtime" == "aspnetcore" ]]; then + download_link="$azure_feed/aspnetcore/Runtime/$specific_version/${pvFileName}" + elif [ -z "$runtime" ]; then + download_link="$azure_feed/Sdk/$specific_version/${pvFileName}" + else + return 1 + fi + else + download_link="${package_download_link%/*}/${pvFileName}" + fi + + say_verbose "Constructed productVersion link: $download_link" + echo "$download_link" + return 0 +} + +# args: +# download link - $1 +# specific version - $2 +get_product_specific_version_from_download_link() +{ + eval $invocation + + local download_link="$1" + local specific_version="$2" + local specific_product_version="" + + if [ -z "$download_link" ]; then + echo "$specific_version" + return 0 + fi + + #get filename + filename="${download_link##*/}" + + #product specific version follows the product name + #for filename 'dotnet-sdk-3.1.404-linux-x64.tar.gz': the product version is 3.1.404 + IFS='-' + read -ra filename_elems <<< "$filename" + count=${#filename_elems[@]} + if [[ "$count" -gt 2 ]]; then + specific_product_version="${filename_elems[2]}" + else + specific_product_version=$specific_version + fi + unset IFS; + echo "$specific_product_version" + return 0 +} + +# args: +# azure_feed - $1 +# channel - $2 +# normalized_architecture - $3 +# specific_version - $4 +construct_legacy_download_link() { + eval $invocation + + local azure_feed="$1" + local channel="$2" + local normalized_architecture="$3" + local specific_version="${4//[$'\t\r\n']}" + + local distro_specific_osname + distro_specific_osname="$(get_legacy_os_name)" || return 1 + + local legacy_download_link=null + if [[ "$runtime" == "dotnet" ]]; then + legacy_download_link="$azure_feed/Runtime/$specific_version/dotnet-$distro_specific_osname-$normalized_architecture.$specific_version.tar.gz" + elif [ -z "$runtime" ]; then + legacy_download_link="$azure_feed/Sdk/$specific_version/dotnet-dev-$distro_specific_osname-$normalized_architecture.$specific_version.tar.gz" + else + return 1 + fi + + echo "$legacy_download_link" + return 0 +} + +get_user_install_path() { + eval $invocation + + if [ ! -z "${DOTNET_INSTALL_DIR:-}" ]; then + echo "$DOTNET_INSTALL_DIR" + else + echo "$HOME/.dotnet" + fi + return 0 +} + +# args: +# install_dir - $1 +resolve_installation_path() { + eval $invocation + + local install_dir=$1 + if [ "$install_dir" = "" ]; then + local user_install_path="$(get_user_install_path)" + say_verbose "resolve_installation_path: user_install_path=$user_install_path" + echo "$user_install_path" + return 0 + fi + + echo "$install_dir" + return 0 +} + +# args: +# relative_or_absolute_path - $1 +get_absolute_path() { + eval $invocation + + local relative_or_absolute_path=$1 + echo "$(cd "$(dirname "$1")" && pwd -P)/$(basename "$1")" + return 0 +} + +# args: +# input_files - stdin +# root_path - $1 +# out_path - $2 +# override - $3 +copy_files_or_dirs_from_list() { + eval $invocation + + 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) + + cat | uniq | while read -r file_path; do + local path="$(remove_beginning_slash "${file_path#$root_path}")" + local target="$out_path/$path" + if [ "$override" = true ] || (! ([ -d "$target" ] || [ -e "$target" ])); then + mkdir -p "$out_path/$(dirname "$path")" + if [ -d "$target" ]; then + rm -rf "$target" + fi + cp -R $override_switch "$root_path/$path" "$target" + fi + done +} + +# args: +# zip_path - $1 +# out_path - $2 +extract_dotnet_package() { + eval $invocation + + local zip_path="$1" + local out_path="$2" + + local temp_out_path="$(mktemp -d "$temporary_file_template")" + + local failed=false + tar -xzf "$zip_path" -C "$temp_out_path" > /dev/null || failed=true + + local folders_with_version_regex='^.*/[0-9]+\.[0-9]+[^/]+/' + find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false + find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files" + + rm -rf "$temp_out_path" + rm -f "$zip_path" && say_verbose "Temporary zip file $zip_path was removed" + + if [ "$failed" = true ]; then + say_err "Extraction failed" + return 1 + fi + return 0 +} + +# args: +# remote_path - $1 +# disable_feed_credential - $2 +get_http_header() +{ + eval $invocation + local remote_path="$1" + local disable_feed_credential="$2" + + local failed=false + local response + if machine_has "curl"; then + get_http_header_curl $remote_path $disable_feed_credential || failed=true + elif machine_has "wget"; then + get_http_header_wget $remote_path $disable_feed_credential || failed=true + else + failed=true + fi + if [ "$failed" = true ]; then + say_verbose "Failed to get HTTP header: '$remote_path'." + return 1 + fi + return 0 +} + +# args: +# remote_path - $1 +# disable_feed_credential - $2 +get_http_header_curl() { + eval $invocation + local remote_path="$1" + local disable_feed_credential="$2" + + remote_path_with_credential="$remote_path" + if [ "$disable_feed_credential" = false ]; then + remote_path_with_credential+="$feed_credential" + fi + + curl_options="-I -sSL --retry 5 --retry-delay 2 --connect-timeout 15 " + curl $curl_options "$remote_path_with_credential" 2>&1 || return 1 + return 0 +} + +# args: +# remote_path - $1 +# disable_feed_credential - $2 +get_http_header_wget() { + eval $invocation + local remote_path="$1" + local disable_feed_credential="$2" + local wget_options="-q -S --spider --tries 5 " + + local wget_options_extra='' + + # Test for options that aren't supported on all wget implementations. + if [[ $(wget -h 2>&1 | grep -E 'waitretry|connect-timeout') ]]; then + wget_options_extra="--waitretry 2 --connect-timeout 15 " + else + say "wget extra options are unavailable for this environment" + fi + + remote_path_with_credential="$remote_path" + if [ "$disable_feed_credential" = false ]; then + remote_path_with_credential+="$feed_credential" + fi + + wget $wget_options $wget_options_extra "$remote_path_with_credential" 2>&1 + + return $? +} + +# args: +# remote_path - $1 +# [out_path] - $2 - stdout if not provided +download() { + eval $invocation + + local remote_path="$1" + local out_path="${2:-}" + + if [[ "$remote_path" != "http"* ]]; then + cp "$remote_path" "$out_path" + return $? + fi + + local failed=false + local attempts=0 + while [ $attempts -lt 3 ]; do + attempts=$((attempts+1)) + failed=false + if machine_has "curl"; then + downloadcurl "$remote_path" "$out_path" || failed=true + elif machine_has "wget"; then + downloadwget "$remote_path" "$out_path" || failed=true + else + say_err "Missing dependency: neither curl nor wget was found." + exit 1 + fi + + if [ "$failed" = false ] || [ $attempts -ge 3 ] || { [ ! -z $http_code ] && [ $http_code = "404" ]; }; then + break + fi + + say "Download attempt #$attempts has failed: $http_code $download_error_msg" + say "Attempt #$((attempts+1)) will start in $((attempts*10)) seconds." + sleep $((attempts*10)) + done + + if [ "$failed" = true ]; then + say_verbose "Download failed: $remote_path" + return 1 + fi + return 0 +} + +# Updates global variables $http_code and $download_error_msg +downloadcurl() { + eval $invocation + unset http_code + unset download_error_msg + local remote_path="$1" + local out_path="${2:-}" + # Append feed_credential as late as possible before calling curl to avoid logging feed_credential + # Avoid passing URI with credentials to functions: note, most of them echoing parameters of invocation in verbose output. + local remote_path_with_credential="${remote_path}${feed_credential}" + local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs " + local curl_exit_code=0; + if [ -z "$out_path" ]; then + curl $curl_options "$remote_path_with_credential" 2>&1 + curl_exit_code=$? + else + curl $curl_options -o "$out_path" "$remote_path_with_credential" 2>&1 + curl_exit_code=$? + fi + + if [ $curl_exit_code -gt 0 ]; then + download_error_msg="Unable to download $remote_path." + # Check for curl timeout codes + if [[ $curl_exit_code == 7 || $curl_exit_code == 28 ]]; then + download_error_msg+=" Failed to reach the server: connection timeout." + else + local disable_feed_credential=false + local response=$(get_http_header_curl $remote_path $disable_feed_credential) + http_code=$( echo "$response" | awk '/^HTTP/{print $2}' | tail -1 ) + if [[ ! -z $http_code && $http_code != 2* ]]; then + download_error_msg+=" Returned HTTP status code: $http_code." + fi + fi + say_verbose "$download_error_msg" + return 1 + fi + return 0 +} + + +# Updates global variables $http_code and $download_error_msg +downloadwget() { + eval $invocation + unset http_code + unset download_error_msg + local remote_path="$1" + local out_path="${2:-}" + # Append feed_credential as late as possible before calling wget to avoid logging feed_credential + local remote_path_with_credential="${remote_path}${feed_credential}" + local wget_options="--tries 20 " + + local wget_options_extra='' + local wget_result='' + + # Test for options that aren't supported on all wget implementations. + if [[ $(wget -h 2>&1 | grep -E 'waitretry|connect-timeout') ]]; then + wget_options_extra="--waitretry 2 --connect-timeout 15 " + else + say "wget extra options are unavailable for this environment" + fi + + if [ -z "$out_path" ]; then + wget -q $wget_options $wget_options_extra -O - "$remote_path_with_credential" 2>&1 + wget_result=$? + else + wget $wget_options $wget_options_extra -O "$out_path" "$remote_path_with_credential" 2>&1 + wget_result=$? + fi + + if [[ $wget_result != 0 ]]; then + local disable_feed_credential=false + local response=$(get_http_header_wget $remote_path $disable_feed_credential) + http_code=$( echo "$response" | awk '/^ HTTP/{print $2}' | tail -1 ) + download_error_msg="Unable to download $remote_path." + if [[ ! -z $http_code && $http_code != 2* ]]; then + download_error_msg+=" Returned HTTP status code: $http_code." + # wget exit code 4 stands for network-issue + elif [[ $wget_result == 4 ]]; then + download_error_msg+=" Failed to reach the server: connection timeout." + fi + say_verbose "$download_error_msg" + return 1 + fi + + return 0 +} + +get_download_link_from_aka_ms() { + eval $invocation + + #quality is not supported for LTS or STS channel + #STS maps to current + if [[ ! -z "$normalized_quality" && ("$normalized_channel" == "LTS" || "$normalized_channel" == "STS") ]]; then + normalized_quality="" + say_warning "Specifying quality for STS or LTS channel is not supported, the quality will be ignored." + fi + + say_verbose "Retrieving primary payload URL from aka.ms for channel: '$normalized_channel', quality: '$normalized_quality', product: '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'." + + #construct aka.ms link + aka_ms_link="https://aka.ms/dotnet" + if [ "$internal" = true ]; then + aka_ms_link="$aka_ms_link/internal" + fi + aka_ms_link="$aka_ms_link/$normalized_channel" + if [[ ! -z "$normalized_quality" ]]; then + aka_ms_link="$aka_ms_link/$normalized_quality" + fi + aka_ms_link="$aka_ms_link/$normalized_product-$normalized_os-$normalized_architecture.tar.gz" + say_verbose "Constructed aka.ms link: '$aka_ms_link'." + + #get HTTP response + #do not pass credentials as a part of the $aka_ms_link and do not apply credentials in the get_http_header function + #otherwise the redirect link would have credentials as well + #it would result in applying credentials twice to the resulting link and thus breaking it, and in echoing credentials to the output as a part of redirect link + disable_feed_credential=true + response="$(get_http_header $aka_ms_link $disable_feed_credential)" + + say_verbose "Received response: $response" + # Get results of all the redirects. + 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' ) + + # All HTTP codes are 301 (Moved Permanently), the redirect link exists. + if [[ -z "$broken_redirects" ]]; then + aka_ms_download_link=$( echo "$response" | awk '$1 ~ /^Location/{print $2}' | tail -1 | tr -d '\r') + + if [[ -z "$aka_ms_download_link" ]]; then + say_verbose "The aka.ms link '$aka_ms_link' is not valid: failed to get redirect location." + return 1 + fi + + say_verbose "The redirect location retrieved: '$aka_ms_download_link'." + return 0 + else + say_verbose "The aka.ms link '$aka_ms_link' is not valid: received HTTP code: $(echo "$broken_redirects" | paste -sd "," -)." + return 1 + fi +} + +get_feeds_to_use() +{ + feeds=( + "https://dotnetcli.azureedge.net/dotnet" + "https://dotnetbuilds.azureedge.net/public" + ) + + if [[ -n "$azure_feed" ]]; then + feeds=("$azure_feed") + fi + + if [[ "$no_cdn" == "true" ]]; then + feeds=( + "https://dotnetcli.blob.core.windows.net/dotnet" + "https://dotnetbuilds.blob.core.windows.net/public" + ) + + if [[ -n "$uncached_feed" ]]; then + feeds=("$uncached_feed") + fi + fi +} + +# THIS FUNCTION MAY EXIT (if the determined version is already installed). +generate_download_links() { + + download_links=() + specific_versions=() + effective_versions=() + link_types=() + + # If generate_akams_links returns false, no fallback to old links. Just terminate. + # This function may also 'exit' (if the determined version is already installed). + generate_akams_links || return + + # Check other feeds only if we haven't been able to find an aka.ms link. + if [[ "${#download_links[@]}" -lt 1 ]]; then + for feed in ${feeds[@]} + do + # generate_regular_links may also 'exit' (if the determined version is already installed). + generate_regular_links $feed || return + done + fi + + if [[ "${#download_links[@]}" -eq 0 ]]; then + say_err "Failed to resolve the exact version number." + return 1 + fi + + say_verbose "Generated ${#download_links[@]} links." + for link_index in ${!download_links[@]} + do + say_verbose "Link $link_index: ${link_types[$link_index]}, ${effective_versions[$link_index]}, ${download_links[$link_index]}" + done +} + +# THIS FUNCTION MAY EXIT (if the determined version is already installed). +generate_akams_links() { + local valid_aka_ms_link=true; + + normalized_version="$(to_lowercase "$version")" + if [[ "$normalized_version" != "latest" ]] && [ -n "$normalized_quality" ]; then + say_err "Quality and Version options are not allowed to be specified simultaneously. See https://learn.microsoft.com/dotnet/core/tools/dotnet-install-script#options for details." + return 1 + fi + + if [[ -n "$json_file" || "$normalized_version" != "latest" ]]; then + # aka.ms links are not needed when exact version is specified via command or json file + return + fi + + get_download_link_from_aka_ms || valid_aka_ms_link=false + + if [[ "$valid_aka_ms_link" == true ]]; then + say_verbose "Retrieved primary payload URL from aka.ms link: '$aka_ms_download_link'." + say_verbose "Downloading using legacy url will not be attempted." + + download_link=$aka_ms_download_link + + #get version from the path + IFS='/' + read -ra pathElems <<< "$download_link" + count=${#pathElems[@]} + specific_version="${pathElems[count-2]}" + unset IFS; + say_verbose "Version: '$specific_version'." + + #Retrieve effective version + effective_version="$(get_specific_product_version "$azure_feed" "$specific_version" "$download_link")" + + # Add link info to arrays + download_links+=($download_link) + specific_versions+=($specific_version) + effective_versions+=($effective_version) + link_types+=("aka.ms") + + # Check if the SDK version is already installed. + if [[ "$dry_run" != true ]] && is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then + say "$asset_name with version '$effective_version' is already installed." + exit 0 + fi + + return 0 + fi + + # if quality is specified - exit with error - there is no fallback approach + if [ ! -z "$normalized_quality" ]; then + say_err "Failed to locate the latest version in the channel '$normalized_channel' with '$normalized_quality' quality for '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'." + say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support." + return 1 + fi + say_verbose "Falling back to latest.version file approach." +} + +# THIS FUNCTION MAY EXIT (if the determined version is already installed) +# args: +# feed - $1 +generate_regular_links() { + local feed="$1" + local valid_legacy_download_link=true + + specific_version=$(get_specific_version_from_version "$feed" "$channel" "$normalized_architecture" "$version" "$json_file") || specific_version='0' + + if [[ "$specific_version" == '0' ]]; then + say_verbose "Failed to resolve the specific version number using feed '$feed'" + return + fi + + effective_version="$(get_specific_product_version "$feed" "$specific_version")" + say_verbose "specific_version=$specific_version" + + download_link="$(construct_download_link "$feed" "$channel" "$normalized_architecture" "$specific_version" "$normalized_os")" + say_verbose "Constructed primary named payload URL: $download_link" + + # Add link info to arrays + download_links+=($download_link) + specific_versions+=($specific_version) + effective_versions+=($effective_version) + link_types+=("primary") + + legacy_download_link="$(construct_legacy_download_link "$feed" "$channel" "$normalized_architecture" "$specific_version")" || valid_legacy_download_link=false + + if [ "$valid_legacy_download_link" = true ]; then + say_verbose "Constructed legacy named payload URL: $legacy_download_link" + + download_links+=($legacy_download_link) + specific_versions+=($specific_version) + effective_versions+=($effective_version) + link_types+=("legacy") + else + legacy_download_link="" + say_verbose "Cound not construct a legacy_download_link; omitting..." + fi + + # Check if the SDK version is already installed. + if [[ "$dry_run" != true ]] && is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then + say "$asset_name with version '$effective_version' is already installed." + exit 0 + fi +} + +print_dry_run() { + + say "Payload URLs:" + + for link_index in "${!download_links[@]}" + do + say "URL #$link_index - ${link_types[$link_index]}: ${download_links[$link_index]}" + done + + resolved_version=${specific_versions[0]} + repeatable_command="./$script_name --version "\""$resolved_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"" --os "\""$normalized_os"\""" + + if [ ! -z "$normalized_quality" ]; then + repeatable_command+=" --quality "\""$normalized_quality"\""" + fi + + if [[ "$runtime" == "dotnet" ]]; then + repeatable_command+=" --runtime "\""dotnet"\""" + elif [[ "$runtime" == "aspnetcore" ]]; then + repeatable_command+=" --runtime "\""aspnetcore"\""" + fi + + repeatable_command+="$non_dynamic_parameters" + + if [ -n "$feed_credential" ]; then + repeatable_command+=" --feed-credential "\"""\""" + fi + + say "Repeatable invocation: $repeatable_command" +} + +calculate_vars() { + eval $invocation + + script_name=$(basename "$0") + normalized_architecture="$(get_normalized_architecture_from_architecture "$architecture")" + say_verbose "Normalized architecture: '$normalized_architecture'." + normalized_os="$(get_normalized_os "$user_defined_os")" + say_verbose "Normalized OS: '$normalized_os'." + normalized_quality="$(get_normalized_quality "$quality")" + say_verbose "Normalized quality: '$normalized_quality'." + normalized_channel="$(get_normalized_channel "$channel")" + say_verbose "Normalized channel: '$normalized_channel'." + normalized_product="$(get_normalized_product "$runtime")" + say_verbose "Normalized product: '$normalized_product'." + install_root="$(resolve_installation_path "$install_dir")" + say_verbose "InstallRoot: '$install_root'." + + normalized_architecture="$(get_normalized_architecture_for_specific_sdk_version "$version" "$normalized_channel" "$normalized_architecture")" + + if [[ "$runtime" == "dotnet" ]]; then + asset_relative_path="shared/Microsoft.NETCore.App" + asset_name=".NET Core Runtime" + elif [[ "$runtime" == "aspnetcore" ]]; then + asset_relative_path="shared/Microsoft.AspNetCore.App" + asset_name="ASP.NET Core Runtime" + elif [ -z "$runtime" ]; then + asset_relative_path="sdk" + asset_name=".NET Core SDK" + fi + + get_feeds_to_use +} + +install_dotnet() { + eval $invocation + local download_failed=false + local download_completed=false + + mkdir -p "$install_root" + zip_path="$(mktemp "$temporary_file_template")" + say_verbose "Zip path: $zip_path" + + for link_index in "${!download_links[@]}" + do + download_link="${download_links[$link_index]}" + specific_version="${specific_versions[$link_index]}" + effective_version="${effective_versions[$link_index]}" + link_type="${link_types[$link_index]}" + + say "Attempting to download using $link_type link $download_link" + + # The download function will set variables $http_code and $download_error_msg in case of failure. + download_failed=false + download "$download_link" "$zip_path" 2>&1 || download_failed=true + + if [ "$download_failed" = true ]; then + case $http_code in + 404) + say "The resource at $link_type link '$download_link' is not available." + ;; + *) + 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" + else + download_completed=true + break + fi + done + + if [[ "$download_completed" == false ]]; then + say_err "Could not find \`$asset_name\` with version = $specific_version" + say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support" + return 1 + fi + + say "Extracting zip from $download_link" + extract_dotnet_package "$zip_path" "$install_root" || return 1 + + # Check if the SDK version is installed; if not, fail the installation. + # if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed. + if [[ $specific_version == *"rtm"* || $specific_version == *"servicing"* ]]; then + IFS='-' + read -ra verArr <<< "$specific_version" + release_version="${verArr[0]}" + unset IFS; + say_verbose "Checking installation: version = $release_version" + if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$release_version"; then + say "Installed version is $effective_version" + return 0 + fi + fi + + # Check if the standard SDK version is installed. + say_verbose "Checking installation: version = $effective_version" + if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$effective_version"; then + say "Installed version is $effective_version" + return 0 + fi + + # Version verification failed. More likely something is wrong either with the downloaded content or with the verification algorithm. + say_err "Failed to verify the version of installed \`$asset_name\`.\nInstallation source: $download_link.\nInstallation location: $install_root.\nReport the bug at https://github.com/dotnet/install-scripts/issues." + say_err "\`$asset_name\` with version = $effective_version failed to install with an error." + return 1 +} + +args=("$@") + +local_version_file_relative_path="/.version" +bin_folder_relative_path="" +temporary_file_template="${TMPDIR:-/tmp}/dotnet.XXXXXXXXX" + +channel="LTS" +version="Latest" +json_file="" +install_dir="" +architecture="" +dry_run=false +no_path=false +no_cdn=false +azure_feed="" +uncached_feed="" +feed_credential="" +verbose=false +runtime="" +runtime_id="" +quality="" +internal=false +override_non_versioned_files=true +non_dynamic_parameters="" +user_defined_os="" + +while [ $# -ne 0 ] +do + name="$1" + case "$name" in + -c|--channel|-[Cc]hannel) + shift + channel="$1" + ;; + -v|--version|-[Vv]ersion) + shift + version="$1" + ;; + -q|--quality|-[Qq]uality) + shift + quality="$1" + ;; + --internal|-[Ii]nternal) + internal=true + non_dynamic_parameters+=" $name" + ;; + -i|--install-dir|-[Ii]nstall[Dd]ir) + shift + install_dir="$1" + ;; + --arch|--architecture|-[Aa]rch|-[Aa]rchitecture) + shift + architecture="$1" + ;; + --os|-[Oo][SS]) + shift + user_defined_os="$1" + ;; + --shared-runtime|-[Ss]hared[Rr]untime) + say_warning "The --shared-runtime flag is obsolete and may be removed in a future version of this script. The recommended usage is to specify '--runtime dotnet'." + if [ -z "$runtime" ]; then + runtime="dotnet" + fi + ;; + --runtime|-[Rr]untime) + shift + runtime="$1" + if [[ "$runtime" != "dotnet" ]] && [[ "$runtime" != "aspnetcore" ]]; then + say_err "Unsupported value for --runtime: '$1'. Valid values are 'dotnet' and 'aspnetcore'." + if [[ "$runtime" == "windowsdesktop" ]]; then + say_err "WindowsDesktop archives are manufactured for Windows platforms only." + fi + exit 1 + fi + ;; + --dry-run|-[Dd]ry[Rr]un) + dry_run=true + ;; + --no-path|-[Nn]o[Pp]ath) + no_path=true + non_dynamic_parameters+=" $name" + ;; + --verbose|-[Vv]erbose) + verbose=true + non_dynamic_parameters+=" $name" + ;; + --no-cdn|-[Nn]o[Cc]dn) + no_cdn=true + non_dynamic_parameters+=" $name" + ;; + --azure-feed|-[Aa]zure[Ff]eed) + shift + azure_feed="$1" + non_dynamic_parameters+=" $name "\""$1"\""" + ;; + --uncached-feed|-[Uu]ncached[Ff]eed) + shift + uncached_feed="$1" + non_dynamic_parameters+=" $name "\""$1"\""" + ;; + --feed-credential|-[Ff]eed[Cc]redential) + shift + feed_credential="$1" + #feed_credential should start with "?", for it to be added to the end of the link. + #adding "?" at the beginning of the feed_credential if needed. + [[ -z "$(echo $feed_credential)" ]] || [[ $feed_credential == \?* ]] || feed_credential="?$feed_credential" + ;; + --runtime-id|-[Rr]untime[Ii]d) + shift + runtime_id="$1" + non_dynamic_parameters+=" $name "\""$1"\""" + say_warning "Use of --runtime-id is obsolete and should be limited to the versions below 2.1. To override architecture, use --architecture option instead. To override OS, use --os option instead." + ;; + --jsonfile|-[Jj][Ss]on[Ff]ile) + shift + json_file="$1" + ;; + --skip-non-versioned-files|-[Ss]kip[Nn]on[Vv]ersioned[Ff]iles) + override_non_versioned_files=false + non_dynamic_parameters+=" $name" + ;; + -?|--?|-h|--help|-[Hh]elp) + script_name="$(basename "$0")" + echo ".NET Tools Installer" + echo "Usage: $script_name [-c|--channel ] [-v|--version ] [-p|--prefix ]" + echo " $script_name -h|-?|--help" + echo "" + echo "$script_name is a simple command line interface for obtaining dotnet cli." + echo " Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:" + echo " - The SDK needs to be installed without user interaction and without admin rights." + echo " - The SDK installation doesn't need to persist across multiple CI runs." + echo " To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer." + echo "" + echo "Options:" + echo " -c,--channel Download from the channel specified, Defaults to \`$channel\`." + echo " -Channel" + echo " Possible values:" + echo " - STS - the most recent Standard Term Support release" + echo " - LTS - the most recent Long Term Support release" + echo " - 2-part version in a format A.B - represents a specific release" + echo " examples: 2.0; 1.0" + echo " - 3-part version in a format A.B.Cxx - represents a specific SDK release" + echo " examples: 5.0.1xx, 5.0.2xx." + echo " Supported since 5.0 release" + echo " Warning: Value 'Current' is deprecated for the Channel parameter. Use 'STS' instead." + echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used." + echo " -v,--version Use specific VERSION, Defaults to \`$version\`." + echo " -Version" + echo " Possible values:" + echo " - latest - the latest build on specific channel" + echo " - 3-part version in a format A.B.C - represents specific version of build" + echo " examples: 2.0.0-preview2-006120; 1.1.0" + echo " -q,--quality Download the latest build of specified quality in the channel." + echo " -Quality" + echo " The possible values are: daily, signed, validated, preview, GA." + echo " Works only in combination with channel. Not applicable for STS and LTS channels and will be ignored if those channels are used." + echo " For SDK use channel in A.B.Cxx format. Using quality for SDK together with channel in A.B format is not supported." + echo " Supported since 5.0 release." + echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used, and therefore overrides the quality." + echo " --internal,-Internal Download internal builds. Requires providing credentials via --feed-credential parameter." + echo " --feed-credential Token to access Azure feed. Used as a query string to append to the Azure feed." + echo " -FeedCredential This parameter typically is not specified." + echo " -i,--install-dir Install under specified location (see Install Location below)" + echo " -InstallDir" + echo " --architecture Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`." + echo " --arch,-Architecture,-Arch" + echo " Possible values: x64, arm, arm64, s390x and ppc64le" + echo " --os Specifies operating system to be used when selecting the installer." + echo " Overrides the OS determination approach used by the script. Supported values: osx, linux, linux-musl, freebsd, rhel.6." + echo " In case any other value is provided, the platform will be determined by the script based on machine configuration." + echo " Not supported for legacy links. Use --runtime-id to specify platform for legacy links." + echo " Refer to: https://aka.ms/dotnet-os-lifecycle for more information." + echo " --runtime Installs a shared runtime only, without the SDK." + echo " -Runtime" + echo " Possible values:" + echo " - dotnet - the Microsoft.NETCore.App shared runtime" + echo " - aspnetcore - the Microsoft.AspNetCore.App shared runtime" + echo " --dry-run,-DryRun Do not perform installation. Display download link." + echo " --no-path, -NoPath Do not set PATH for the current process." + echo " --verbose,-Verbose Display diagnostics information." + echo " --azure-feed,-AzureFeed For internal use only." + echo " Allows using a different storage to download SDK archives from." + echo " This parameter is only used if --no-cdn is false." + echo " --uncached-feed,-UncachedFeed For internal use only." + echo " Allows using a different storage to download SDK archives from." + echo " This parameter is only used if --no-cdn is true." + echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable." + echo " -SkipNonVersionedFiles" + echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly." + echo " --jsonfile Determines the SDK version from a user specified global.json file." + echo " Note: global.json must have a value for 'SDK:Version'" + echo " -?,--?,-h,--help,-Help Shows this help message" + echo "" + echo "Install Location:" + echo " Location is chosen in following order:" + echo " - --install-dir option" + echo " - Environmental variable DOTNET_INSTALL_DIR" + echo " - $HOME/.dotnet" + exit 0 + ;; + *) + say_err "Unknown argument \`$name\`" + exit 1 + ;; + esac + + shift +done + +say_verbose "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:" +say_verbose "- The SDK needs to be installed without user interaction and without admin rights." +say_verbose "- The SDK installation doesn't need to persist across multiple CI runs." +say_verbose "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.\n" + +if [ "$internal" = true ] && [ -z "$(echo $feed_credential)" ]; then + message="Provide credentials via --feed-credential parameter." + if [ "$dry_run" = true ]; then + say_warning "$message" + else + say_err "$message" + exit 1 + fi +fi + +check_min_reqs +calculate_vars +# generate_regular_links call below will 'exit' if the determined version is already installed. +generate_download_links + +if [[ "$dry_run" = true ]]; then + print_dry_run + exit 0 +fi + +install_dotnet + +bin_path="$(get_absolute_path "$(combine_paths "$install_root" "$bin_folder_relative_path")")" +if [ "$no_path" = false ]; then + say "Adding to current process PATH: \`$bin_path\`. Note: This change will be visible only when sourcing script." + export PATH="$bin_path":"$PATH" +else + say "Binaries of dotnet can be found in $bin_path" +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." diff --git a/test/dotnet/dotnet_env.sh b/test/dotnet/dotnet_env.sh new file mode 100644 index 000000000..37b14ea2b --- /dev/null +++ b/test/dotnet/dotnet_env.sh @@ -0,0 +1,4 @@ +#!/bin/bash +export DOTNET_NOLOGO=true +export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true +export DOTNET_GENERATE_ASPNET_CERTIFICATE=false \ No newline at end of file diff --git a/test/dotnet/dotnet_helpers.sh b/test/dotnet/dotnet_helpers.sh new file mode 100644 index 000000000..6c833b444 --- /dev/null +++ b/test/dotnet/dotnet_helpers.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +# Prints the latest dotnet version in the specified channel +# Usage: fetch_latest_version_in_channel [] +# Example: fetch_latest_version_in_channel "LTS" +# Example: fetch_latest_version_in_channel "6.0" "dotnet" +# Example: fetch_latest_version_in_channel "6.0" "aspnetcore" +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" + elif [ "$runtime" = "aspnetcore" ]; then + wget -qO- "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/$channel/latest.version" + else + wget -qO- "https://dotnetcli.azureedge.net/dotnet/Sdk/$channel/latest.version" + fi + +} + +# Prints the latest dotnet version +# Usage: fetch_latest_version [] +# Example: fetch_latest_version +# Example: fetch_latest_version "dotnet" +# Example: fetch_latest_version "aspnetcore" +fetch_latest_version() { + local runtime="$1" + local sts_version + local lts_version + sts_version=$(fetch_latest_version_in_channel "STS" "$runtime") + lts_version=$(fetch_latest_version_in_channel "LTS" "$runtime") + if [[ "$sts_version" > "$lts_version" ]]; then + echo "$sts_version" + else + echo "$lts_version" + fi +} + +# Asserts that the specified .NET SDK version is installed +# Returns a non-zero exit code if the check fails +# Usage: is_dotnet_sdk_version_installed +# Example: is_dotnet_sdk_version_installed "6.0" +# Example: is_dotnet_sdk_version_installed "6.0.412" +is_dotnet_sdk_version_installed() { + local expected="$1" + dotnet --list-sdks | grep --fixed-strings --silent "$expected" + return $? +} + + +# Asserts that the specified .NET Runtime version is installed +# Returns a non-zero exit code if the check fails +# Usage: is_dotnet_runtime_version_installed +# Example: is_dotnet_runtime_version_installed "6.0" +# Example: is_dotnet_runtime_version_installed "6.0.412" +is_dotnet_runtime_version_installed() { + local expected="$1" + dotnet --list-runtimes | grep --fixed-strings --silent "Microsoft.NETCore.App $expected" + return $? +} + +# Asserts that the specified ASP.NET Core Runtime version is installed +# Returns a non-zero exit code if the check fails +# Usage: is_aspnetcore_runtime_version_installed +# Example: is_aspnetcore_runtime_version_installed "6.0" +# Example: is_aspnetcore_runtime_version_installed "6.0.412" +is_aspnetcore_runtime_version_installed() { + local expected="$1" + dotnet --list-runtimes | grep --fixed-strings --silent "Microsoft.AspNetCore.App $expected" + return $? +} \ No newline at end of file diff --git a/test/dotnet/install_additional_dotnet.sh b/test/dotnet/install_additional_dotnet.sh deleted file mode 100644 index e69c7dce1..000000000 --- a/test/dotnet/install_additional_dotnet.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -set -e - -# Optional: Import test library -source dev-container-features-test-lib - -check "dotnet version 6.0.301 installed as default" bash -c "dotnet --version | grep 6.0.301" -check "dotnet version 5.0 installed" bash -c "ls -l /usr/local/dotnet | grep 5.0" -check "dotnet version 3.1.420 installed" bash -c "ls -l /usr/local/dotnet | grep 3.1.420" - -# Verify current symlink exists and works -check "current link dotnet" /usr/local/dotnet/current/dotnet --info -check "current link sdk" ls -l /usr/local/dotnet/current/sdk - -# Report result -reportResults diff --git a/test/dotnet/install_aspnetcore_runtime_only.sh b/test/dotnet/install_aspnetcore_runtime_only.sh new file mode 100644 index 000000000..35bd540b7 --- /dev/null +++ b/test/dotnet/install_aspnetcore_runtime_only.sh @@ -0,0 +1,27 @@ +#!/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