Compare commits
1 commit
main
...
automated-
Author | SHA1 | Date | |
---|---|---|---|
|
acc034a9a1 |
114 changed files with 1071 additions and 3753 deletions
|
@ -1,17 +1,18 @@
|
||||||
{
|
{
|
||||||
"image": "mcr.microsoft.com/devcontainers/javascript-node:1-18",
|
"image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:0-18",
|
||||||
"features": {
|
"remoteUser": "node",
|
||||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
|
|
||||||
},
|
|
||||||
"postCreateCommand": "npm install -g @devcontainers/cli",
|
|
||||||
"hostRequirements": {
|
|
||||||
"cpus": 4
|
|
||||||
},
|
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
"mads-hartmann.bash-ide-vscode"
|
"mads-hartmann.bash-ide-vscode"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
|
||||||
|
},
|
||||||
|
"postCreateCommand": "npm install -g @devcontainers/cli",
|
||||||
|
"hostRequirements": {
|
||||||
|
"cpus": 4
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,37 +0,0 @@
|
||||||
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"
|
|
1
.github/workflows/test-all.yaml
vendored
1
.github/workflows/test-all.yaml
vendored
|
@ -42,6 +42,7 @@ jobs:
|
||||||
]
|
]
|
||||||
baseImage:
|
baseImage:
|
||||||
[
|
[
|
||||||
|
"ubuntu:bionic",
|
||||||
"ubuntu:focal",
|
"ubuntu:focal",
|
||||||
"ubuntu:jammy",
|
"ubuntu:jammy",
|
||||||
"debian:11",
|
"debian:11",
|
||||||
|
|
1
.github/workflows/test-pr.yaml
vendored
1
.github/workflows/test-pr.yaml
vendored
|
@ -49,6 +49,7 @@ jobs:
|
||||||
features: ${{ fromJSON(needs.detect-changes.outputs.features) }}
|
features: ${{ fromJSON(needs.detect-changes.outputs.features) }}
|
||||||
baseImage:
|
baseImage:
|
||||||
[
|
[
|
||||||
|
"ubuntu:bionic",
|
||||||
"ubuntu:focal",
|
"ubuntu:focal",
|
||||||
"ubuntu:jammy",
|
"ubuntu:jammy",
|
||||||
"debian:11",
|
"debian:11",
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
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
|
|
||||||
environment: documentation # grants access to secrets.PAT, for creating pull requests
|
|
||||||
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
|
|
||||||
|
|
||||||
# Bump version and push
|
|
||||||
if [ "$NO_UPDATES" != "true" ] ; then
|
|
||||||
echo "$(jq --indent 4 '.version = (.version | split(".") | map(tonumber) | .[2] += 1 | join("."))' src/dotnet/devcontainer-feature.json)" > src/dotnet/devcontainer-feature.json
|
|
||||||
git add src/dotnet/devcontainer-feature.json
|
|
||||||
git commit -m 'Bump version'
|
|
||||||
git push origin "$branch"
|
|
||||||
gh api \
|
|
||||||
--method POST \
|
|
||||||
-H "Accept: application/vnd.github+json" \
|
|
||||||
/repos/${GITHUB_REPOSITORY}/pulls \
|
|
||||||
-f title="$message" \
|
|
||||||
-f body="$message" \
|
|
||||||
-f head="$branch" \
|
|
||||||
-f base="$GITHUB_REF_NAME"
|
|
||||||
fi
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "aws-cli",
|
"id": "aws-cli",
|
||||||
"version": "1.0.7",
|
"version": "1.0.6",
|
||||||
"name": "AWS CLI",
|
"name": "AWS CLI",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/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.",
|
"description": "Installs the AWS CLI along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.",
|
||||||
|
|
|
@ -50,6 +50,21 @@ if [ "$(id -u)" -ne 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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}"
|
||||||
|
}
|
||||||
|
|
||||||
apt_get_update()
|
apt_get_update()
|
||||||
{
|
{
|
||||||
echo "Running apt-get update..."
|
echo "Running apt-get update..."
|
||||||
|
@ -74,6 +89,9 @@ check_packages curl ca-certificates gnupg2 dirmngr unzip
|
||||||
verify_aws_cli_gpg_signature() {
|
verify_aws_cli_gpg_signature() {
|
||||||
local filePath=$1
|
local filePath=$1
|
||||||
local sigFilePath=$2
|
local sigFilePath=$2
|
||||||
|
|
||||||
|
get_common_setting AWSCLI_GPG_KEY
|
||||||
|
get_common_setting AWSCLI_GPG_KEY_MATERIAL true
|
||||||
local awsGpgKeyring=aws-cli-public-key.gpg
|
local awsGpgKeyring=aws-cli-public-key.gpg
|
||||||
|
|
||||||
echo "${AWSCLI_GPG_KEY_MATERIAL}" | gpg --dearmor > "./${awsGpgKeyring}"
|
echo "${AWSCLI_GPG_KEY_MATERIAL}" | gpg --dearmor > "./${awsGpgKeyring}"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "azure-cli",
|
"id": "azure-cli",
|
||||||
"version": "1.2.2",
|
"version": "1.2.1",
|
||||||
"name": "Azure CLI",
|
"name": "Azure CLI",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/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.",
|
"description": "Installs the Azure CLI along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.",
|
||||||
|
|
|
@ -32,6 +32,21 @@ fi
|
||||||
|
|
||||||
echo "Effective REMOTE_USER: ${_REMOTE_USER}"
|
echo "Effective REMOTE_USER: ${_REMOTE_USER}"
|
||||||
|
|
||||||
|
# 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()
|
apt_get_update()
|
||||||
{
|
{
|
||||||
echo "Running apt-get update..."
|
echo "Running apt-get update..."
|
||||||
|
@ -95,6 +110,7 @@ install_using_apt() {
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
check_packages apt-transport-https curl ca-certificates gnupg2 dirmngr
|
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
|
# 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
|
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/azure-cli/ ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/azure-cli.list
|
echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/azure-cli/ ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/azure-cli.list
|
||||||
apt-get update
|
apt-get update
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "common-utils",
|
"id": "common-utils",
|
||||||
"version": "2.3.1",
|
"version": "2.1.1",
|
||||||
"name": "Common Utilities",
|
"name": "Common Utilities",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/common-utils",
|
"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.",
|
"description": "Installs a set of common command line utilities, Oh My Zsh!, and sets up a non-root user.",
|
||||||
|
|
|
@ -28,10 +28,7 @@ install_debian_packages() {
|
||||||
# Ensure apt is in non-interactive to avoid prompts
|
# Ensure apt is in non-interactive to avoid prompts
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
local package_list=""
|
local package_list="apt-utils \
|
||||||
if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then
|
|
||||||
package_list="${package_list} \
|
|
||||||
apt-utils \
|
|
||||||
openssh-client \
|
openssh-client \
|
||||||
gnupg2 \
|
gnupg2 \
|
||||||
dirmngr \
|
dirmngr \
|
||||||
|
@ -73,6 +70,24 @@ install_debian_packages() {
|
||||||
manpages-dev \
|
manpages-dev \
|
||||||
init-system-helpers"
|
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
|
# Include libssl1.1 if available
|
||||||
if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then
|
if [[ ! -z $(apt-cache --names-only search ^libssl1.1$) ]]; then
|
||||||
package_list="${package_list} libssl1.1"
|
package_list="${package_list} libssl1.1"
|
||||||
|
@ -99,25 +114,6 @@ install_debian_packages() {
|
||||||
if ! type git > /dev/null 2>&1; then
|
if ! type git > /dev/null 2>&1; then
|
||||||
package_list="${package_list} git"
|
package_list="${package_list} git"
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# Install the list of packages
|
# Install the list of packages
|
||||||
echo "Packages to verify are installed: ${package_list}"
|
echo "Packages to verify are installed: ${package_list}"
|
||||||
|
@ -143,8 +139,6 @@ install_debian_packages() {
|
||||||
LOCALE_ALREADY_SET="true"
|
LOCALE_ALREADY_SET="true"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PACKAGES_ALREADY_INSTALLED="true"
|
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
apt-get -y clean
|
apt-get -y clean
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
@ -152,15 +146,7 @@ install_debian_packages() {
|
||||||
|
|
||||||
# RedHat / RockyLinux / CentOS / Fedora packages
|
# RedHat / RockyLinux / CentOS / Fedora packages
|
||||||
install_redhat_packages() {
|
install_redhat_packages() {
|
||||||
local package_list=""
|
local package_list="\
|
||||||
local remove_epel="false"
|
|
||||||
local install_cmd=dnf
|
|
||||||
if ! type dnf > /dev/null 2>&1; then
|
|
||||||
install_cmd=yum
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then
|
|
||||||
package_list="${package_list} \
|
|
||||||
gawk \
|
gawk \
|
||||||
openssh-clients \
|
openssh-clients \
|
||||||
gnupg2 \
|
gnupg2 \
|
||||||
|
@ -189,6 +175,11 @@ install_redhat_packages() {
|
||||||
man-db \
|
man-db \
|
||||||
strace"
|
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'
|
# rockylinux:9 installs 'curl-minimal' which clashes with 'curl'
|
||||||
# Install 'curl' for every OS except this rockylinux:9
|
# Install 'curl' for every OS except this rockylinux:9
|
||||||
if [[ "${ID}" = "rocky" ]] && [[ "${VERSION}" != *"9."* ]]; then
|
if [[ "${ID}" = "rocky" ]] && [[ "${VERSION}" != *"9."* ]]; then
|
||||||
|
@ -210,22 +201,20 @@ install_redhat_packages() {
|
||||||
package_list="${package_list} git"
|
package_list="${package_list} git"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Install EPEL repository if needed (required to install 'jq' for CentOS)
|
|
||||||
if ! ${install_cmd} -q list jq >/dev/null 2>&1; then
|
|
||||||
${install_cmd} -y install epel-release
|
|
||||||
remove_epel="true"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install zsh if needed
|
# Install zsh if needed
|
||||||
if [ "${INSTALL_ZSH}" = "true" ] && ! type zsh > /dev/null 2>&1; then
|
if [ "${INSTALL_ZSH}" = "true" ] && ! type zsh > /dev/null 2>&1; then
|
||||||
package_list="${package_list} zsh"
|
package_list="${package_list} zsh"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "${package_list}" ]; then
|
# Install EPEL repository if needed (required to install 'jq' for CentOS)
|
||||||
${install_cmd} -y install ${package_list}
|
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
|
fi
|
||||||
|
|
||||||
|
${install_cmd} -y install ${package_list}
|
||||||
|
|
||||||
# Get to latest versions of all packages
|
# Get to latest versions of all packages
|
||||||
if [ "${UPGRADE_PACKAGES}" = "true" ]; then
|
if [ "${UPGRADE_PACKAGES}" = "true" ]; then
|
||||||
${install_cmd} upgrade -y
|
${install_cmd} upgrade -y
|
||||||
|
@ -234,15 +223,11 @@ install_redhat_packages() {
|
||||||
if [[ "${remove_epel}" = "true" ]]; then
|
if [[ "${remove_epel}" = "true" ]]; then
|
||||||
${install_cmd} -y remove epel-release
|
${install_cmd} -y remove epel-release
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PACKAGES_ALREADY_INSTALLED="true"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Alpine Linux packages
|
# Alpine Linux packages
|
||||||
install_alpine_packages() {
|
install_alpine_packages() {
|
||||||
apk update
|
apk update
|
||||||
|
|
||||||
if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then
|
|
||||||
apk add --no-cache \
|
apk add --no-cache \
|
||||||
openssh-client \
|
openssh-client \
|
||||||
gnupg \
|
gnupg \
|
||||||
|
@ -290,14 +275,11 @@ install_alpine_packages() {
|
||||||
if ! type git > /dev/null 2>&1; then
|
if ! type git > /dev/null 2>&1; then
|
||||||
apk add --no-cache git
|
apk add --no-cache git
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
# Install zsh if needed
|
# Install zsh if needed
|
||||||
if [ "${INSTALL_ZSH}" = "true" ] && ! type zsh > /dev/null 2>&1; then
|
if [ "${INSTALL_ZSH}" = "true" ] && ! type zsh > /dev/null 2>&1; then
|
||||||
apk add --no-cache zsh
|
apk add --no-cache zsh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PACKAGES_ALREADY_INSTALLED="true"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ******************
|
# ******************
|
||||||
|
@ -336,6 +318,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Install packages for appropriate OS
|
# Install packages for appropriate OS
|
||||||
|
if [ "${PACKAGES_ALREADY_INSTALLED}" != "true" ]; then
|
||||||
case "${ADJUSTED_ID}" in
|
case "${ADJUSTED_ID}" in
|
||||||
"debian")
|
"debian")
|
||||||
install_debian_packages
|
install_debian_packages
|
||||||
|
@ -347,6 +330,8 @@ case "${ADJUSTED_ID}" in
|
||||||
install_alpine_packages
|
install_alpine_packages
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
PACKAGES_ALREADY_INSTALLED="true"
|
||||||
|
fi
|
||||||
|
|
||||||
# If in automatic mode, determine if a user already exists, if not use vscode
|
# If in automatic mode, determine if a user already exists, if not use vscode
|
||||||
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
|
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
|
||||||
|
@ -409,9 +394,6 @@ fi
|
||||||
|
|
||||||
if [ "${USERNAME}" = "root" ]; then
|
if [ "${USERNAME}" = "root" ]; then
|
||||||
user_home="/root"
|
user_home="/root"
|
||||||
# Check if user already has a home directory other than /home/${USERNAME}
|
|
||||||
elif [ "/home/${USERNAME}" != $( getent passwd $USERNAME | cut -d: -f6 ) ]; then
|
|
||||||
user_home=$( getent passwd $USERNAME | cut -d: -f6 )
|
|
||||||
else
|
else
|
||||||
user_home="/home/${USERNAME}"
|
user_home="/home/${USERNAME}"
|
||||||
if [ ! -d "${user_home}" ]; then
|
if [ ! -d "${user_home}" ]; then
|
||||||
|
@ -423,7 +405,6 @@ fi
|
||||||
# Restore user .bashrc / .profile / .zshrc defaults from skeleton file if it doesn't exist or is empty
|
# Restore user .bashrc / .profile / .zshrc defaults from skeleton file if it doesn't exist or is empty
|
||||||
possible_rc_files=( ".bashrc" ".profile" )
|
possible_rc_files=( ".bashrc" ".profile" )
|
||||||
[ "$INSTALL_OH_MY_ZSH_CONFIG" == "true" ] && possible_rc_files+=('.zshrc')
|
[ "$INSTALL_OH_MY_ZSH_CONFIG" == "true" ] && possible_rc_files+=('.zshrc')
|
||||||
[ "$INSTALL_ZSH" == "true" ] && possible_rc_files+=('.zprofile')
|
|
||||||
for rc_file in "${possible_rc_files[@]}"; do
|
for rc_file in "${possible_rc_files[@]}"; do
|
||||||
if [ -f "/etc/skel/${rc_file}" ]; then
|
if [ -f "/etc/skel/${rc_file}" ]; then
|
||||||
if [ ! -e "${user_home}/${rc_file}" ] || [ ! -s "${user_home}/${rc_file}" ]; then
|
if [ ! -e "${user_home}/${rc_file}" ] || [ ! -s "${user_home}/${rc_file}" ]; then
|
||||||
|
@ -459,19 +440,13 @@ fi
|
||||||
|
|
||||||
# Optionally configure zsh and Oh My Zsh!
|
# Optionally configure zsh and Oh My Zsh!
|
||||||
if [ "${INSTALL_ZSH}" = "true" ]; then
|
if [ "${INSTALL_ZSH}" = "true" ]; then
|
||||||
if [ ! -f "${user_home}/.zprofile" ]; then
|
|
||||||
touch "${user_home}/.zprofile"
|
|
||||||
echo 'source $HOME/.profile' >> "${user_home}/.zprofile" # TODO: Reconsider adding '.profile' to '.zprofile'
|
|
||||||
chown ${USERNAME}:${group_name} "${user_home}/.zprofile"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then
|
if [ "${ZSH_ALREADY_INSTALLED}" != "true" ]; then
|
||||||
if [ "${ADJUSTED_ID}" = "rhel" ]; then
|
if [ "${ADJUSTED_ID}" = "rhel" ]; then
|
||||||
global_rc_path="/etc/zshrc"
|
global_rc_path="/etc/zshrc"
|
||||||
else
|
else
|
||||||
global_rc_path="/etc/zsh/zshrc"
|
global_rc_path="/etc/zsh/zshrc"
|
||||||
fi
|
fi
|
||||||
cat "${FEATURE_DIR}/scripts/rc_snippet.sh" >> ${global_rc_path}
|
cat "${FEATURE_DIR}/scripts/rc_snippet.sh" >> /etc/zshrc
|
||||||
ZSH_ALREADY_INSTALLED="true"
|
ZSH_ALREADY_INSTALLED="true"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -525,7 +500,7 @@ if [ "${INSTALL_ZSH}" = "true" ]; then
|
||||||
copy_to_user_files=("${oh_my_install_dir}")
|
copy_to_user_files=("${oh_my_install_dir}")
|
||||||
[ -f "$user_rc_file" ] && copy_to_user_files+=("$user_rc_file")
|
[ -f "$user_rc_file" ] && copy_to_user_files+=("$user_rc_file")
|
||||||
cp -rf "${copy_to_user_files[@]}" /root
|
cp -rf "${copy_to_user_files[@]}" /root
|
||||||
chown -R ${USERNAME}:${group_name} "${copy_to_user_files[@]}"
|
chown -R ${USERNAME}:${group_name} "${oh_my_install_dir}" "${user_rc_file}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "docker-in-docker",
|
"id": "docker-in-docker",
|
||||||
"version": "2.7.1",
|
"version": "2.3.1",
|
||||||
"name": "Docker (Docker-in-Docker)",
|
"name": "Docker (Docker-in-Docker)",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/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.",
|
"description": "Create child containers *inside* a container, independent from the host's docker instance. Installs Docker extension in the container along with needed CLIs.",
|
||||||
|
|
|
@ -16,8 +16,8 @@ DOCKER_DEFAULT_ADDRESS_POOL="${DOCKERDEFAULTADDRESSPOOL}"
|
||||||
USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}"
|
USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}"
|
||||||
INSTALL_DOCKER_BUILDX="${INSTALLDOCKERBUILDX:-"true"}"
|
INSTALL_DOCKER_BUILDX="${INSTALLDOCKERBUILDX:-"true"}"
|
||||||
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
|
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
|
||||||
DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal jammy"
|
DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="buster bullseye bionic focal jammy"
|
||||||
DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal hirsute impish jammy"
|
DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES="buster bullseye bionic focal hirsute impish jammy"
|
||||||
|
|
||||||
# Default: Exit on any failure.
|
# Default: Exit on any failure.
|
||||||
set -e
|
set -e
|
||||||
|
@ -57,6 +57,21 @@ elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
|
||||||
USERNAME=root
|
USERNAME=root
|
||||||
fi
|
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}"
|
||||||
|
}
|
||||||
|
|
||||||
apt_get_update()
|
apt_get_update()
|
||||||
{
|
{
|
||||||
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
|
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
|
||||||
|
@ -122,6 +137,8 @@ architecture="$(dpkg --print-architecture)"
|
||||||
|
|
||||||
# Check if distro is supported
|
# Check if distro is supported
|
||||||
if [ "${USE_MOBY}" = "true" ]; then
|
if [ "${USE_MOBY}" = "true" ]; then
|
||||||
|
# 'get_common_setting' allows attribute to be updated remotely
|
||||||
|
get_common_setting DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES
|
||||||
if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
|
if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
|
||||||
err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS distribution"
|
err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS distribution"
|
||||||
err "Support distributions include: ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}"
|
err "Support distributions include: ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}"
|
||||||
|
@ -129,6 +146,7 @@ if [ "${USE_MOBY}" = "true" ]; then
|
||||||
fi
|
fi
|
||||||
echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}'"
|
echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}'"
|
||||||
else
|
else
|
||||||
|
get_common_setting DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES
|
||||||
if [[ "${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
|
if [[ "${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
|
||||||
err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, please choose a compatible OS distribution"
|
err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, please choose a compatible OS distribution"
|
||||||
err "Support distributions include: ${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}"
|
err "Support distributions include: ${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}"
|
||||||
|
@ -159,6 +177,7 @@ if [ "${USE_MOBY}" = "true" ]; then
|
||||||
cli_package_name="moby-cli"
|
cli_package_name="moby-cli"
|
||||||
|
|
||||||
# Import key safely and import Microsoft apt repo
|
# 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
|
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
|
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
|
||||||
else
|
else
|
||||||
|
@ -344,10 +363,11 @@ tee -a /usr/local/share/docker-init.sh > /dev/null \
|
||||||
<< 'EOF'
|
<< 'EOF'
|
||||||
dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} $(cat << 'INNEREOF'
|
dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAULT_ADDRESS_POOL=${DOCKER_DEFAULT_ADDRESS_POOL} $(cat << 'INNEREOF'
|
||||||
# explicitly remove dockerd and containerd PID file to ensure that it can start properly if it was stopped uncleanly
|
# explicitly remove dockerd and containerd PID file to ensure that it can start properly if it was stopped uncleanly
|
||||||
|
# ie: docker kill <ID>
|
||||||
find /run /var/run -iname 'docker*.pid' -delete || :
|
find /run /var/run -iname 'docker*.pid' -delete || :
|
||||||
find /run /var/run -iname 'container*.pid' -delete || :
|
find /run /var/run -iname 'container*.pid' -delete || :
|
||||||
|
|
||||||
# -- Start: dind wrapper script --
|
## Dind wrapper script from docker team, adapted to a function
|
||||||
# Maintained: https://github.com/moby/moby/blob/master/hack/dind
|
# Maintained: https://github.com/moby/moby/blob/master/hack/dind
|
||||||
|
|
||||||
export container=docker
|
export container=docker
|
||||||
|
@ -364,8 +384,6 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU
|
||||||
mount -t tmpfs none /tmp
|
mount -t tmpfs none /tmp
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set_cgroup_nesting()
|
|
||||||
{
|
|
||||||
# cgroup v2: enable nesting
|
# cgroup v2: enable nesting
|
||||||
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
|
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
|
||||||
# move the processes from the root group to the /init group,
|
# move the processes from the root group to the /init group,
|
||||||
|
@ -377,31 +395,11 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU
|
||||||
sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
|
sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
|
||||||
> /sys/fs/cgroup/cgroup.subtree_control
|
> /sys/fs/cgroup/cgroup.subtree_control
|
||||||
fi
|
fi
|
||||||
}
|
## Dind wrapper over.
|
||||||
|
|
||||||
# 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
|
# Handle DNS
|
||||||
set +e
|
set +e
|
||||||
cat /etc/resolv.conf | grep -i 'internal.cloudapp.net' > /dev/null 2>&1
|
cat /etc/resolv.conf | grep -i 'internal.cloudapp.net'
|
||||||
if [ $? -eq 0 ] && [ "${AZURE_DNS_AUTO_DETECTION}" = "true" ]
|
if [ $? -eq 0 ] && [ "${AZURE_DNS_AUTO_DETECTION}" = "true" ]
|
||||||
then
|
then
|
||||||
echo "Setting dockerd Azure DNS."
|
echo "Setting dockerd Azure DNS."
|
||||||
|
@ -410,6 +408,7 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU
|
||||||
echo "Not setting dockerd DNS manually."
|
echo "Not setting dockerd DNS manually."
|
||||||
CUSTOMDNS=""
|
CUSTOMDNS=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ -z "$DOCKER_DEFAULT_ADDRESS_POOL" ]
|
if [ -z "$DOCKER_DEFAULT_ADDRESS_POOL" ]
|
||||||
|
@ -424,21 +423,6 @@ dockerd_start="AZURE_DNS_AUTO_DETECTION=${AZURE_DNS_AUTO_DETECTION} DOCKER_DEFAU
|
||||||
INNEREOF
|
INNEREOF
|
||||||
)"
|
)"
|
||||||
|
|
||||||
sudo_if() {
|
|
||||||
COMMAND="$*"
|
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
|
||||||
sudo $COMMAND
|
|
||||||
else
|
|
||||||
$COMMAND
|
|
||||||
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
|
# Start using sudo if not invoked as root
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
sudo /bin/sh -c "${dockerd_start}"
|
sudo /bin/sh -c "${dockerd_start}"
|
||||||
|
@ -446,28 +430,6 @@ do
|
||||||
eval "${dockerd_start}"
|
eval "${dockerd_start}"
|
||||||
fi
|
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" ] && [ "${retry_docker_start_count}" != "4" ]; then
|
|
||||||
echo "(*) Failed to start docker, retrying..."
|
|
||||||
set +e
|
|
||||||
sudo_if pkill dockerd
|
|
||||||
sudo_if pkill containerd
|
|
||||||
set -e
|
|
||||||
fi
|
|
||||||
|
|
||||||
retry_docker_start_count=`expr $retry_docker_start_count + 1`
|
|
||||||
done
|
|
||||||
|
|
||||||
# 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.
|
# to set this script to ENTRYPOINT while still executing the default CMD.
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "docker-outside-of-docker",
|
"id": "docker-outside-of-docker",
|
||||||
"version": "1.3.1",
|
"version": "1.3.0",
|
||||||
"name": "Docker (docker-outside-of-docker)",
|
"name": "Docker (docker-outside-of-docker)",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/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.",
|
"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.",
|
||||||
|
|
|
@ -18,8 +18,8 @@ USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}"
|
||||||
INSTALL_DOCKER_BUILDX="${INSTALLDOCKERBUILDX:-"true"}"
|
INSTALL_DOCKER_BUILDX="${INSTALLDOCKERBUILDX:-"true"}"
|
||||||
|
|
||||||
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
|
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
|
||||||
DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal jammy"
|
DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES="buster bullseye bionic focal jammy"
|
||||||
DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES="bookworm buster bullseye bionic focal hirsute impish jammy"
|
DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES="buster bullseye bionic focal hirsute impish jammy"
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
@ -48,6 +48,21 @@ elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
|
||||||
USERNAME=root
|
USERNAME=root
|
||||||
fi
|
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}"
|
||||||
|
}
|
||||||
|
|
||||||
apt_get_update()
|
apt_get_update()
|
||||||
{
|
{
|
||||||
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
|
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
|
||||||
|
@ -114,6 +129,8 @@ architecture="$(dpkg --print-architecture)"
|
||||||
|
|
||||||
# Check if distro is supported
|
# Check if distro is supported
|
||||||
if [ "${USE_MOBY}" = "true" ]; then
|
if [ "${USE_MOBY}" = "true" ]; then
|
||||||
|
# 'get_common_setting' allows attribute to be updated remotely
|
||||||
|
get_common_setting DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES
|
||||||
if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
|
if [[ "${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
|
||||||
err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS distribution"
|
err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, either: (1) set feature option '\"moby\": false' , or (2) choose a compatible OS distribution"
|
||||||
err "Support distributions include: ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}"
|
err "Support distributions include: ${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}"
|
||||||
|
@ -121,6 +138,7 @@ if [ "${USE_MOBY}" = "true" ]; then
|
||||||
fi
|
fi
|
||||||
echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}'"
|
echo "Distro codename '${VERSION_CODENAME}' matched filter '${DOCKER_MOBY_ARCHIVE_VERSION_CODENAMES}'"
|
||||||
else
|
else
|
||||||
|
get_common_setting DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES
|
||||||
if [[ "${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
|
if [[ "${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}" != *"${VERSION_CODENAME}"* ]]; then
|
||||||
err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, please choose a compatible OS distribution"
|
err "Unsupported distribution version '${VERSION_CODENAME}'. To resolve, please choose a compatible OS distribution"
|
||||||
err "Support distributions include: ${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}"
|
err "Support distributions include: ${DOCKER_LICENSED_ARCHIVE_VERSION_CODENAMES}"
|
||||||
|
@ -135,6 +153,7 @@ if [ "${USE_MOBY}" = "true" ]; then
|
||||||
cli_package_name="moby-cli"
|
cli_package_name="moby-cli"
|
||||||
|
|
||||||
# Import key safely and import Microsoft apt repo
|
# 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
|
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
|
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
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,71 +1,4 @@
|
||||||
## 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
|
## OS Support
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
|
|
||||||
# Dotnet CLI (dotnet)
|
# Dotnet CLI (dotnet)
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
## Example Usage
|
## Example Usage
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"features": {
|
"features": {
|
||||||
"ghcr.io/devcontainers/features/dotnet:2": {}
|
"ghcr.io/devcontainers/features/dotnet:1": {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -15,10 +15,9 @@ This Feature installs the latest .NET SDK, which includes the .NET CLI and the s
|
||||||
|
|
||||||
| Options Id | Description | Type | Default Value |
|
| Options Id | Description | Type | Default Value |
|
||||||
|-----|-----|-----|-----|
|
|-----|-----|-----|-----|
|
||||||
| version | 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. | string | latest |
|
| version | Select or enter a dotnet CLI version. (Available versions may vary by Linux distribution.) | string | latest |
|
||||||
| additionalVersions | 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. | string | - |
|
| runtimeOnly | Install just the dotnet runtime if true, and sdk if false. | boolean | false |
|
||||||
| dotnetRuntimeVersions | 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. | string | - |
|
| installUsingApt | If true, it installs using apt instead of the release URL | boolean | true |
|
||||||
| aspNetCoreRuntimeVersions | 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. | string | - |
|
|
||||||
|
|
||||||
## Customizations
|
## Customizations
|
||||||
|
|
||||||
|
@ -26,74 +25,7 @@ This Feature installs the latest .NET SDK, which includes the .NET CLI and the s
|
||||||
|
|
||||||
- `ms-dotnettools.csharp`
|
- `ms-dotnettools.csharp`
|
||||||
|
|
||||||
## 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
|
## OS Support
|
||||||
|
|
||||||
|
|
|
@ -1,44 +1,35 @@
|
||||||
{
|
{
|
||||||
"id": "dotnet",
|
"id": "dotnet",
|
||||||
"version": "2.0.2",
|
"version": "1.1.4",
|
||||||
"name": "Dotnet CLI",
|
"name": "Dotnet CLI",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet",
|
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/dotnet",
|
||||||
"description": "This Feature installs the latest .NET SDK, which includes the .NET CLI and the shared runtime. Options are provided to choose a different version or additional versions.",
|
"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.",
|
||||||
"options": {
|
"options": {
|
||||||
"version": {
|
"version": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"proposals": [
|
"proposals": [
|
||||||
"latest",
|
"latest",
|
||||||
"lts",
|
"7",
|
||||||
"none",
|
"6",
|
||||||
"8.0",
|
"3.1"
|
||||||
"7.0",
|
|
||||||
"6.0"
|
|
||||||
],
|
],
|
||||||
"default": "latest",
|
"default": "latest",
|
||||||
"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."
|
"description": "Select or enter a dotnet CLI version. (Available versions may vary by Linux distribution.)"
|
||||||
},
|
},
|
||||||
"additionalVersions": {
|
"runtimeOnly": {
|
||||||
"type": "string",
|
"type": "boolean",
|
||||||
"default": "",
|
"default": false,
|
||||||
"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."
|
"description": "Install just the dotnet runtime if true, and sdk if false."
|
||||||
},
|
},
|
||||||
"dotnetRuntimeVersions": {
|
"installUsingApt": {
|
||||||
"type": "string",
|
"type": "boolean",
|
||||||
"default": "",
|
"default": true,
|
||||||
"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."
|
"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": {
|
"containerEnv": {
|
||||||
"DOTNET_ROOT": "/usr/share/dotnet",
|
"DOTNET_ROOT": "/usr/local/dotnet/current",
|
||||||
"PATH": "$PATH:$DOTNET_ROOT:~/.dotnet/tools",
|
"PATH": "/usr/local/dotnet/current:${PATH}"
|
||||||
"DOTNET_RUNNING_IN_CONTAINER": "true",
|
|
||||||
"DOTNET_USE_POLLING_FILE_WATCHER": "true"
|
|
||||||
},
|
},
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
|
|
|
@ -4,21 +4,47 @@
|
||||||
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
# 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
|
# Docs: https://github.com/microsoft/vscode-dev-containers/blob/main/script-library/docs/dotnet.md
|
||||||
# Maintainer: The Dev Container spec maintainers
|
# Maintainer: The VS Code and Codespaces Teams
|
||||||
|
|
||||||
DOTNET_VERSION="${VERSION:-"latest"}"
|
DOTNET_VERSION="${VERSION:-"latest"}"
|
||||||
ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS}"
|
DOTNET_RUNTIME_ONLY="${RUNTIMEONLY:-"false"}"
|
||||||
DOTNET_RUNTIME_VERSIONS="${DOTNETRUNTIMEVERSIONS}"
|
OVERRIDE_DEFAULT_VERSION="${OVERRIDEDEFAULTVERSION:-"true"}"
|
||||||
ASPNETCORE_RUNTIME_VERSIONS="${ASPNETCORERUNTIMEVERSIONS}"
|
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"
|
||||||
|
|
||||||
|
# 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
|
||||||
|
)"
|
||||||
|
|
||||||
|
APT_PREFERENCES_FILE_ADDED="false"
|
||||||
|
APT_PREFERENCES_UPDATED="false"
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Import trim_whitespace and split_csv
|
|
||||||
source "scripts/string-helpers.sh"
|
|
||||||
|
|
||||||
# Import install_sdk and install_runtime
|
|
||||||
source "scripts/dotnet-helpers.sh"
|
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
@ -27,14 +53,72 @@ err() {
|
||||||
echo "(!) $*" >&2
|
echo "(!) $*" >&2
|
||||||
}
|
}
|
||||||
|
|
||||||
apt_get_update() {
|
# 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()
|
||||||
|
{
|
||||||
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
|
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
|
||||||
echo "Running apt-get update..."
|
echo "Running apt-get update..."
|
||||||
apt-get update -y
|
apt-get update -y
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Checks if packages are installed and installs them if not
|
# Check if packages are installed and installs them if not.
|
||||||
check_packages() {
|
check_packages() {
|
||||||
if ! dpkg -s "$@" > /dev/null 2>&1; then
|
if ! dpkg -s "$@" > /dev/null 2>&1; then
|
||||||
apt_get_update
|
apt_get_update
|
||||||
|
@ -42,77 +126,367 @@ check_packages() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ "$(id -u)" -ne 0 ]; then
|
# Get appropriate architecture name for .NET binaries for the target OS
|
||||||
err 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
|
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
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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}"
|
||||||
|
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
|
||||||
|
|
||||||
|
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."
|
||||||
|
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
|
||||||
|
|
||||||
|
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."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 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
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# For our own convenience, combine DOTNET_VERSION and ADDITIONAL_VERSIONS into a single 'versions' array
|
# Install the .NET CLI
|
||||||
versions=()
|
echo "(*) Installing .NET CLI..."
|
||||||
|
|
||||||
# The version can be set to 'none' for runtime-only installations, then the array will just remain empty
|
CHANGE_OWNERSHIP="false"
|
||||||
# Ensure there are no leading or trailing spaces that can break regex pattern matching
|
if [[ "${DOTNET_ARCHIVE_ARCHITECTURES}" = *"${architecture}"* ]] && [[ "${DOTNET_ARCHIVE_VERSION_CODENAMES}" = *"${VERSION_CODENAME}"* ]] && [[ "${INSTALL_USING_APT}" = "true" ]]; then
|
||||||
if [ "$DOTNET_VERSION" != "none" ]; then
|
echo "Detected ${VERSION_CODENAME} on ${architecture}. Attempting to install dotnet from apt"
|
||||||
versions+=("$(trim_whitespace "$DOTNET_VERSION")")
|
|
||||||
for additional_version in $(split_csv "$ADDITIONAL_VERSIONS"); do
|
|
||||||
versions+=("$additional_version")
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
dotnetRuntimeVersions=()
|
install_using_apt "${DOTNET_SDK_OR_RUNTIME}" "${DOTNET_VERSION}" false || install_using_apt "${DOTNET_SDK_OR_RUNTIME}" "${DOTNET_VERSION}" true
|
||||||
for dotnetRuntimeVersion in $(split_csv "$DOTNET_RUNTIME_VERSIONS"); do
|
if [ "$?" != 0 ]; then
|
||||||
dotnetRuntimeVersions+=("$dotnetRuntimeVersion")
|
echo "Could not install requested version from apt on current distribution."
|
||||||
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
else
|
||||||
|
if [[ "${INSTALL_USING_APT}" = "false" ]]; then
|
||||||
for version in "${dotnetRuntimeVersions[@]}"; do
|
echo "Installing dotnet from releases url"
|
||||||
if [[ "$version" =~ ^[0-9]+$ ]]; then
|
else
|
||||||
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."
|
echo "Attempting to install dotnet from releases url"
|
||||||
exit 1
|
|
||||||
fi
|
fi
|
||||||
done
|
install_using_dotnet_releases_url "${DOTNET_SDK_OR_RUNTIME}" "${DOTNET_VERSION}"
|
||||||
|
CHANGE_OWNERSHIP="true"
|
||||||
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
|
|
||||||
|
|
||||||
# Install .NET versions and dependencies
|
# Additional dotnet versions to be installed but not be set as default.
|
||||||
# icu-devtools includes dependencies for .NET
|
if [ ! -z "${ADDITIONAL_VERSIONS}" ]; then
|
||||||
check_packages wget ca-certificates icu-devtools
|
OLDIFS=$IFS
|
||||||
|
IFS=","
|
||||||
for version in "${versions[@]}"; do
|
read -a additional_versions <<< "$ADDITIONAL_VERSIONS"
|
||||||
install_sdk "$version"
|
for version in "${additional_versions[@]}"; do
|
||||||
|
OVERRIDE_DEFAULT_VERSION="false"
|
||||||
|
install_using_dotnet_releases_url "${DOTNET_SDK_OR_RUNTIME}" "${version}"
|
||||||
done
|
done
|
||||||
|
IFS=$OLDIFS
|
||||||
|
fi
|
||||||
|
|
||||||
for version in "${dotnetRuntimeVersions[@]}"; do
|
if [ "${CHANGE_OWNERSHIP}" = "true" ]; then
|
||||||
install_runtime "dotnet" "$version"
|
if ! cat /etc/group | grep -e "^dotnet:" > /dev/null 2>&1; then
|
||||||
done
|
groupadd -r dotnet
|
||||||
|
fi
|
||||||
|
usermod -a -G dotnet "${USERNAME}"
|
||||||
|
|
||||||
for version in "${aspNetCoreRuntimeVersions[@]}"; do
|
chown -R "${USERNAME}:dotnet" "${TARGET_DOTNET_ROOT}"
|
||||||
install_runtime "aspnetcore" "$version"
|
chmod -R g+r+w "${TARGET_DOTNET_ROOT}"
|
||||||
done
|
find "${TARGET_DOTNET_ROOT}" -type d -print0 | xargs -n 1 -0 chmod g+s
|
||||||
|
fi
|
||||||
|
|
||||||
# Clean up
|
# 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 /var/lib/apt/lists/*
|
||||||
rm -rf scripts
|
|
||||||
|
|
||||||
echo "Done!"
|
echo "Done!"
|
||||||
|
|
|
@ -1,119 +0,0 @@
|
||||||
#!/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 <channel> [<runtime>]
|
|
||||||
# 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 [<runtime>]
|
|
||||||
# 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 <version>
|
|
||||||
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 <runtime> <version>
|
|
||||||
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
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
#!/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"
|
|
|
@ -1,42 +0,0 @@
|
||||||
#!/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 <text>
|
|
||||||
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 <comma-separated-values>
|
|
||||||
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[@]}"
|
|
||||||
}
|
|
27
src/dotnet/scripts/vendor/README.md
vendored
27
src/dotnet/scripts/vendor/README.md
vendored
|
@ -1,27 +0,0 @@
|
||||||
### **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 <https://dot.net/v1/dotnet-install.sh>. ([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
|
|
||||||
```
|
|
1835
src/dotnet/scripts/vendor/dotnet-install.sh
vendored
1835
src/dotnet/scripts/vendor/dotnet-install.sh
vendored
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "git-lfs",
|
"id": "git-lfs",
|
||||||
"version": "1.1.1",
|
"version": "1.1.0",
|
||||||
"name": "Git Large File Support (LFS)",
|
"name": "Git Large File Support (LFS)",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/git-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.",
|
"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.",
|
||||||
|
|
|
@ -15,7 +15,6 @@ GIT_LFS_ARCHIVE_ARCHITECTURES="amd64 arm64"
|
||||||
GIT_LFS_ARCHIVE_VERSION_CODENAMES="stretch buster bullseye bionic focal jammy"
|
GIT_LFS_ARCHIVE_VERSION_CODENAMES="stretch buster bullseye bionic focal jammy"
|
||||||
GIT_LFS_CHECKSUM_GPG_KEYS="0x88ace9b29196305ba9947552f1ba225c0223b187 0x86cd3297749375bcf8206715f54fe648088335a9 0xaa3b3450295830d2de6db90caba67be5a5795889"
|
GIT_LFS_CHECKSUM_GPG_KEYS="0x88ace9b29196305ba9947552f1ba225c0223b187 0x86cd3297749375bcf8206715f54fe648088335a9 0xaa3b3450295830d2de6db90caba67be5a5795889"
|
||||||
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
||||||
keyserver hkp://keyserver.ubuntu.com:80
|
|
||||||
keyserver hkps://keys.openpgp.org
|
keyserver hkps://keys.openpgp.org
|
||||||
keyserver hkp://keyserver.pgp.com"
|
keyserver hkp://keyserver.pgp.com"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "git",
|
"id": "git",
|
||||||
"version": "1.1.6",
|
"version": "1.1.5",
|
||||||
"name": "Git (from source)",
|
"name": "Git (from source)",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/git",
|
"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.",
|
"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.",
|
||||||
|
|
|
@ -12,7 +12,6 @@ USE_PPA_IF_AVAILABLE=${PPA}
|
||||||
|
|
||||||
GIT_CORE_PPA_ARCHIVE_GPG_KEY=E1DD270288B4E6030699E45FA1715D88E1DF1F24
|
GIT_CORE_PPA_ARCHIVE_GPG_KEY=E1DD270288B4E6030699E45FA1715D88E1DF1F24
|
||||||
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
||||||
keyserver hkp://keyserver.ubuntu.com:80
|
|
||||||
keyserver hkps://keys.openpgp.org
|
keyserver hkps://keys.openpgp.org
|
||||||
keyserver hkp://keyserver.pgp.com"
|
keyserver hkp://keyserver.pgp.com"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "github-cli",
|
"id": "github-cli",
|
||||||
"version": "1.0.11",
|
"version": "1.0.10",
|
||||||
"name": "GitHub CLI",
|
"name": "GitHub CLI",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/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.",
|
"description": "Installs the GitHub CLI. Auto-detects latest version and installs needed dependencies.",
|
||||||
|
|
|
@ -12,7 +12,6 @@ INSTALL_DIRECTLY_FROM_GITHUB_RELEASE=${INSTALLDIRECTLYFROMGITHUBRELEASE:-"true"}
|
||||||
|
|
||||||
GITHUB_CLI_ARCHIVE_GPG_KEY=23F3D4EA75716059
|
GITHUB_CLI_ARCHIVE_GPG_KEY=23F3D4EA75716059
|
||||||
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
||||||
keyserver hkp://keyserver.ubuntu.com:80
|
|
||||||
keyserver hkps://keys.openpgp.org
|
keyserver hkps://keys.openpgp.org
|
||||||
keyserver hkp://keyserver.pgp.com"
|
keyserver hkp://keyserver.pgp.com"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "go",
|
"id": "go",
|
||||||
"version": "1.2.2",
|
"version": "1.2.0",
|
||||||
"name": "Go",
|
"name": "Go",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/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.",
|
"description": "Installs Go and common Go utilities. Auto-detects latest version and installs needed dependencies.",
|
||||||
|
@ -10,8 +10,8 @@
|
||||||
"proposals": [
|
"proposals": [
|
||||||
"latest",
|
"latest",
|
||||||
"none",
|
"none",
|
||||||
"1.21",
|
"1.19",
|
||||||
"1.20"
|
"1.18"
|
||||||
],
|
],
|
||||||
"default": "latest",
|
"default": "latest",
|
||||||
"description": "Select or enter a Go version to install"
|
"description": "Select or enter a Go version to install"
|
||||||
|
|
|
@ -84,6 +84,21 @@ find_version_from_git_tags() {
|
||||||
echo "${variable_name}=${!variable_name}"
|
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()
|
apt_get_update()
|
||||||
{
|
{
|
||||||
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
|
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
|
||||||
|
@ -133,6 +148,7 @@ if [[ "${TARGET_GO_VERSION}" != "none" ]] && [[ "$(go version)" != *"${TARGET_GO
|
||||||
export GNUPGHOME="/tmp/tmp-gnupg"
|
export GNUPGHOME="/tmp/tmp-gnupg"
|
||||||
mkdir -p ${GNUPGHOME}
|
mkdir -p ${GNUPGHOME}
|
||||||
chmod 700 ${GNUPGHOME}
|
chmod 700 ${GNUPGHOME}
|
||||||
|
get_common_setting GO_GPG_KEY_URI
|
||||||
curl -sSL -o /tmp/tmp-gnupg/golang_key "${GO_GPG_KEY_URI}"
|
curl -sSL -o /tmp/tmp-gnupg/golang_key "${GO_GPG_KEY_URI}"
|
||||||
gpg -q --import /tmp/tmp-gnupg/golang_key
|
gpg -q --import /tmp/tmp-gnupg/golang_key
|
||||||
echo "Downloading Go ${TARGET_GO_VERSION}..."
|
echo "Downloading Go ${TARGET_GO_VERSION}..."
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "java",
|
"id": "java",
|
||||||
"version": "1.2.2",
|
"version": "1.2.1",
|
||||||
"name": "Java (via SDKMAN!)",
|
"name": "Java (via SDKMAN!)",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/java",
|
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/java",
|
||||||
"description": "Installs Java, SDKMAN! (if not installed), and needed dependencies.",
|
"description": "Installs Java, SDKMAN! (if not installed), and needed dependencies.",
|
||||||
|
|
|
@ -111,13 +111,13 @@ sdk_install() {
|
||||||
elif echo "${requested_version}" | grep -oE "${full_version_check}" > /dev/null 2>&1; then
|
elif echo "${requested_version}" | grep -oE "${full_version_check}" > /dev/null 2>&1; then
|
||||||
echo "${requested_version}"
|
echo "${requested_version}"
|
||||||
else
|
else
|
||||||
local regex="${prefix}\\K[0-9]+\\.?[0-9]*\\.?[0-9]*${suffix}"
|
local regex="${prefix}\\K[0-9]+\\.[0-9]+\\.[0-9]+${suffix}"
|
||||||
local version_list=$(su ${USERNAME} -c ". \${SDKMAN_DIR}/bin/sdkman-init.sh && sdk list ${install_type} 2>&1 | grep -oP \"${regex}\" | tr -d ' ' | sort -rV")
|
local version_list=$(su ${USERNAME} -c ". \${SDKMAN_DIR}/bin/sdkman-init.sh && sdk list ${install_type} 2>&1 | grep -oP \"${regex}\" | tr -d ' ' | sort -rV")
|
||||||
if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ]; then
|
if [ "${requested_version}" = "latest" ] || [ "${requested_version}" = "current" ]; then
|
||||||
requested_version="$(echo "${version_list}" | head -n 1)"
|
requested_version="$(echo "${version_list}" | head -n 1)"
|
||||||
else
|
else
|
||||||
set +e
|
set +e
|
||||||
requested_version="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|-|$)")"
|
requested_version="$(echo "${version_list}" | grep -E -m 1 "^${requested_version//./\\.}([\\.\\s]|$)")"
|
||||||
set -e
|
set -e
|
||||||
fi
|
fi
|
||||||
if [ -z "${requested_version}" ] || ! echo "${version_list}" | grep "^${requested_version//./\\.}$" > /dev/null 2>&1; then
|
if [ -z "${requested_version}" ] || ! echo "${version_list}" | grep "^${requested_version//./\\.}$" > /dev/null 2>&1; then
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "kubectl-helm-minikube",
|
"id": "kubectl-helm-minikube",
|
||||||
"version": "1.1.5",
|
"version": "1.1.4",
|
||||||
"name": "Kubectl, Helm, and Minikube",
|
"name": "Kubectl, Helm, and Minikube",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/kubectl-helm-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.",
|
"description": "Installs latest version of kubectl, Helm, and optionally minikube. Auto-detects latest versions and installs needed dependencies.",
|
||||||
|
|
|
@ -23,7 +23,6 @@ USERNAME="${USERNAME:-"${_REMOTE_USER:-"automatic"}"}"
|
||||||
|
|
||||||
HELM_GPG_KEYS_URI="https://raw.githubusercontent.com/helm/helm/main/KEYS"
|
HELM_GPG_KEYS_URI="https://raw.githubusercontent.com/helm/helm/main/KEYS"
|
||||||
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
||||||
keyserver hkp://keyserver.ubuntu.com:80
|
|
||||||
keyserver hkps://keys.openpgp.org
|
keyserver hkps://keys.openpgp.org
|
||||||
keyserver hkp://keyserver.pgp.com"
|
keyserver hkp://keyserver.pgp.com"
|
||||||
|
|
||||||
|
|
|
@ -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 |
|
| version | Select or enter a Node.js version to install | string | lts |
|
||||||
| nodeGypDependencies | Install dependencies to compile native node modules (node-gyp)? | boolean | true |
|
| 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 |
|
| nvmInstallPath | The path where NVM will be installed. | string | /usr/local/share/nvm |
|
||||||
| nvmVersion | Version of NVM to install. | string | latest |
|
| nvmVersion | Version of NVM to install. | string | 0.39.2 |
|
||||||
|
|
||||||
## Customizations
|
## Customizations
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "node",
|
"id": "node",
|
||||||
"version": "1.3.1",
|
"version": "1.2.1",
|
||||||
"name": "Node.js (via nvm), yarn and pnpm",
|
"name": "Node.js (via nvm), yarn and pnpm",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/node",
|
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/node",
|
||||||
"description": "Installs Node.js, nvm, yarn, pnpm, and needed dependencies.",
|
"description": "Installs Node.js, nvm, yarn, pnpm, and needed dependencies.",
|
||||||
|
@ -30,11 +30,7 @@
|
||||||
},
|
},
|
||||||
"nvmVersion": {
|
"nvmVersion": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"proposals": [
|
"default": "0.39.2",
|
||||||
"latest",
|
|
||||||
"0.39"
|
|
||||||
],
|
|
||||||
"default": "latest",
|
|
||||||
"description": "Version of NVM to install."
|
"description": "Version of NVM to install."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
# Maintainer: The Dev Container spec maintainers
|
# Maintainer: The Dev Container spec maintainers
|
||||||
|
|
||||||
export NODE_VERSION="${VERSION:-"lts"}"
|
export NODE_VERSION="${VERSION:-"lts"}"
|
||||||
export NVM_VERSION="${NVMVERSION:-"latest"}"
|
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}"
|
INSTALL_TOOLS_FOR_NODE_GYP="${NODEGYPDEPENDENCIES:-true}"
|
||||||
|
|
||||||
|
@ -78,40 +78,6 @@ check_packages() {
|
||||||
fi
|
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
|
# Ensure apt is in non-interactive to avoid prompts
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
@ -126,10 +92,6 @@ fi
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
check_packages apt-transport-https curl ca-certificates tar gnupg2 dirmngr
|
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
|
# Install yarn
|
||||||
if type yarn > /dev/null 2>&1; then
|
if type yarn > /dev/null 2>&1; then
|
||||||
echo "Yarn already installed."
|
echo "Yarn already installed."
|
||||||
|
@ -150,8 +112,6 @@ elif [ "${NODE_VERSION}" = "latest" ]; then
|
||||||
export NODE_VERSION="node"
|
export NODE_VERSION="node"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
find_version_from_git_tags NVM_VERSION "https://github.com/nvm-sh/nvm"
|
|
||||||
|
|
||||||
# Install snipppet that we will run as the user
|
# Install snipppet that we will run as the user
|
||||||
nvm_install_snippet="$(cat << EOF
|
nvm_install_snippet="$(cat << EOF
|
||||||
set -e
|
set -e
|
||||||
|
@ -228,9 +188,6 @@ if type pnpm > /dev/null 2>&1; then
|
||||||
echo "pnpm already installed."
|
echo "pnpm already installed."
|
||||||
else
|
else
|
||||||
if type npm > /dev/null 2>&1; then
|
if type npm > /dev/null 2>&1; then
|
||||||
[ ! -z "$http_proxy" ] && npm set proxy="$http_proxy"
|
|
||||||
[ ! -z "$https_proxy" ] && npm set https-proxy="$https_proxy"
|
|
||||||
[ ! -z "$no_proxy" ] && npm set noproxy="$no_proxy"
|
|
||||||
npm install -g pnpm
|
npm install -g pnpm
|
||||||
else
|
else
|
||||||
echo "Skip installing pnpm because npm is missing"
|
echo "Skip installing pnpm because npm is missing"
|
||||||
|
|
|
@ -16,9 +16,7 @@ Installs shared libraries for NVIDIA CUDA.
|
||||||
| Options Id | Description | Type | Default Value |
|
| Options Id | Description | Type | Default Value |
|
||||||
|-----|-----|-----|-----|
|
|-----|-----|-----|-----|
|
||||||
| installCudnn | Additionally install CUDA Deep Neural Network (cuDNN) shared library | boolean | false |
|
| installCudnn | Additionally install CUDA Deep Neural Network (cuDNN) shared library | boolean | false |
|
||||||
| installCudnnDev | Additionally install CUDA Deep Neural Network (cuDNN) development libraries and headers | boolean | false |
|
|
||||||
| installNvtx | Additionally install NVIDIA Tools Extension (NVTX) | boolean | false |
|
| installNvtx | Additionally install NVIDIA Tools Extension (NVTX) | boolean | false |
|
||||||
| installToolkit | Additionally install NVIDIA CUDA Toolkit | boolean | false |
|
|
||||||
| cudaVersion | Version of CUDA to install | string | 11.8 |
|
| cudaVersion | Version of CUDA to install | string | 11.8 |
|
||||||
| cudnnVersion | Version of cuDNN to install | string | 8.6.0.163 |
|
| cudnnVersion | Version of cuDNN to install | string | 8.6.0.163 |
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "nvidia-cuda",
|
"id": "nvidia-cuda",
|
||||||
"version": "1.1.0",
|
"version": "1.0.7",
|
||||||
"name": "NVIDIA CUDA",
|
"name": "NVIDIA CUDA",
|
||||||
"description": "Installs shared libraries for NVIDIA CUDA.",
|
"description": "Installs shared libraries for NVIDIA CUDA.",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/nvidia-cuda",
|
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/nvidia-cuda",
|
||||||
|
@ -10,27 +10,14 @@
|
||||||
"default": false,
|
"default": false,
|
||||||
"description": "Additionally install CUDA Deep Neural Network (cuDNN) shared library"
|
"description": "Additionally install CUDA Deep Neural Network (cuDNN) shared library"
|
||||||
},
|
},
|
||||||
"installCudnnDev": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"description": "Additionally install CUDA Deep Neural Network (cuDNN) development libraries and headers"
|
|
||||||
},
|
|
||||||
"installNvtx": {
|
"installNvtx": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description": "Additionally install NVIDIA Tools Extension (NVTX)"
|
"description": "Additionally install NVIDIA Tools Extension (NVTX)"
|
||||||
},
|
},
|
||||||
"installToolkit": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false,
|
|
||||||
"description": "Additionally install NVIDIA CUDA Toolkit"
|
|
||||||
},
|
|
||||||
"cudaVersion": {
|
"cudaVersion": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"proposals": [
|
"proposals": [
|
||||||
"12.2",
|
|
||||||
"12.1",
|
|
||||||
"12.0",
|
|
||||||
"11.8",
|
"11.8",
|
||||||
"11.7",
|
"11.7",
|
||||||
"11.6",
|
"11.6",
|
||||||
|
@ -45,15 +32,6 @@
|
||||||
"cudnnVersion": {
|
"cudnnVersion": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"proposals": [
|
"proposals": [
|
||||||
"8.9.5.29",
|
|
||||||
"8.9.4.25",
|
|
||||||
"8.9.3.28",
|
|
||||||
"8.9.2.26",
|
|
||||||
"8.9.1.23",
|
|
||||||
"8.9.0.131",
|
|
||||||
"8.8.1.3",
|
|
||||||
"8.8.0.121",
|
|
||||||
"8.7.0.84",
|
|
||||||
"8.6.0.163",
|
"8.6.0.163",
|
||||||
"8.5.0.96",
|
"8.5.0.96",
|
||||||
"8.4.1.50",
|
"8.4.1.50",
|
||||||
|
|
|
@ -6,9 +6,7 @@ set -e
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
INSTALL_CUDNN=${INSTALLCUDNN}
|
INSTALL_CUDNN=${INSTALLCUDNN}
|
||||||
INSTALL_CUDNNDEV=${INSTALLCUDNNDEV}
|
|
||||||
INSTALL_NVTX=${INSTALLNVTX}
|
INSTALL_NVTX=${INSTALLNVTX}
|
||||||
INSTALL_TOOLKIT=${INSTALLTOOLKIT}
|
|
||||||
CUDA_VERSION=${CUDAVERSION}
|
CUDA_VERSION=${CUDAVERSION}
|
||||||
CUDNN_VERSION=${CUDNNVERSION}
|
CUDNN_VERSION=${CUDNNVERSION}
|
||||||
|
|
||||||
|
@ -49,7 +47,6 @@ apt-get update -yq
|
||||||
# Ensure that the requested version of CUDA is available
|
# Ensure that the requested version of CUDA is available
|
||||||
cuda_pkg="cuda-libraries-${CUDA_VERSION/./-}"
|
cuda_pkg="cuda-libraries-${CUDA_VERSION/./-}"
|
||||||
nvtx_pkg="cuda-nvtx-${CUDA_VERSION/./-}"
|
nvtx_pkg="cuda-nvtx-${CUDA_VERSION/./-}"
|
||||||
toolkit_pkg="cuda-toolkit-${CUDA_VERSION/./-}"
|
|
||||||
if ! apt-cache show "$cuda_pkg"; then
|
if ! apt-cache show "$cuda_pkg"; then
|
||||||
echo "The requested version of CUDA is not available: CUDA $CUDA_VERSION"
|
echo "The requested version of CUDA is not available: CUDA $CUDA_VERSION"
|
||||||
exit 1
|
exit 1
|
||||||
|
@ -70,28 +67,11 @@ if [ "$INSTALL_CUDNN" = "true" ]; then
|
||||||
apt-get install -yq "$cudnn_pkg_version"
|
apt-get install -yq "$cudnn_pkg_version"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$INSTALL_CUDNNDEV" = "true" ]; then
|
|
||||||
# Ensure that the requested version of cuDNN development package is available AND compatible
|
|
||||||
cudnn_dev_pkg_version="libcudnn8-dev=${CUDNN_VERSION}-1+cuda${CUDA_VERSION}"
|
|
||||||
if ! apt-cache show "$cudnn_dev_pkg_version"; then
|
|
||||||
echo "The requested version of cuDNN development package is not available: cuDNN $CUDNN_VERSION for CUDA $CUDA_VERSION"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Installing cuDNN dev libraries..."
|
|
||||||
apt-get install -yq "$cudnn_dev_pkg_version"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$INSTALL_NVTX" = "true" ]; then
|
if [ "$INSTALL_NVTX" = "true" ]; then
|
||||||
echo "Installing NVTX..."
|
echo "Installing NVTX..."
|
||||||
apt-get install -yq "$nvtx_pkg"
|
apt-get install -yq "$nvtx_pkg"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$INSTALL_TOOLKIT" = "true" ]; then
|
|
||||||
echo "Installing CUDA Toolkit..."
|
|
||||||
apt-get install -yq "$toolkit_pkg"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,6 @@ Installs PowerShell along with needed dependencies. Useful for base Dockerfiles
|
||||||
| version | Select or enter a version of PowerShell. | string | latest |
|
| version | Select or enter a version of PowerShell. | string | latest |
|
||||||
| modules | Optional comma separated list of PowerShell modules to install. | string | - |
|
| modules | Optional comma separated list of PowerShell modules to install. | string | - |
|
||||||
|
|
||||||
## Customizations
|
|
||||||
|
|
||||||
### VS Code Extensions
|
|
||||||
|
|
||||||
- `ms-vscode.powershell`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## OS Support
|
## OS Support
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "powershell",
|
"id": "powershell",
|
||||||
"version": "1.2.0",
|
"version": "1.1.0",
|
||||||
"name": "PowerShell",
|
"name": "PowerShell",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/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.",
|
"description": "Installs PowerShell along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.",
|
||||||
|
@ -21,13 +21,6 @@
|
||||||
"description": "Optional comma separated list of PowerShell modules to install."
|
"description": "Optional comma separated list of PowerShell modules to install."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"customizations": {
|
|
||||||
"vscode": {
|
|
||||||
"extensions": [
|
|
||||||
"ms-vscode.powershell"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"installsAfter": [
|
"installsAfter": [
|
||||||
"ghcr.io/devcontainers/features/common-utils"
|
"ghcr.io/devcontainers/features/common-utils"
|
||||||
]
|
]
|
||||||
|
|
|
@ -19,7 +19,6 @@ MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
|
||||||
POWERSHELL_ARCHIVE_ARCHITECTURES="amd64"
|
POWERSHELL_ARCHIVE_ARCHITECTURES="amd64"
|
||||||
POWERSHELL_ARCHIVE_VERSION_CODENAMES="stretch buster bionic focal bullseye jammy"
|
POWERSHELL_ARCHIVE_VERSION_CODENAMES="stretch buster bionic focal bullseye jammy"
|
||||||
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
||||||
keyserver hkp://keyserver.ubuntu.com:80
|
|
||||||
keyserver hkps://keys.openpgp.org
|
keyserver hkps://keys.openpgp.org
|
||||||
keyserver hkp://keyserver.pgp.com"
|
keyserver hkp://keyserver.pgp.com"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "python",
|
"id": "python",
|
||||||
"version": "1.3.1",
|
"version": "1.1.0",
|
||||||
"name": "Python",
|
"name": "Python",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/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.",
|
"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.",
|
||||||
|
@ -11,7 +11,6 @@
|
||||||
"latest",
|
"latest",
|
||||||
"os-provided",
|
"os-provided",
|
||||||
"none",
|
"none",
|
||||||
"3.12",
|
|
||||||
"3.11",
|
"3.11",
|
||||||
"3.10",
|
"3.10",
|
||||||
"3.9",
|
"3.9",
|
||||||
|
@ -66,7 +65,15 @@
|
||||||
"ms-python.vscode-pylance"
|
"ms-python.vscode-pylance"
|
||||||
],
|
],
|
||||||
"settings": {
|
"settings": {
|
||||||
"python.defaultInterpreterPath": "/usr/local/python/current/bin/python"
|
"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.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
|
||||||
|
"python.linting.flake8Enabled": false,
|
||||||
|
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
|
||||||
|
"python.linting.mypyEnabled": false,
|
||||||
|
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint",
|
||||||
|
"python.linting.pylintEnabled": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -27,9 +27,8 @@ CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN="${CONFIGUREJUPYTERLABALLOWORIGIN:-""}"
|
||||||
ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}"
|
ADDITIONAL_VERSIONS="${ADDITIONALVERSIONS:-""}"
|
||||||
|
|
||||||
DEFAULT_UTILS=("pylint" "flake8" "autopep8" "black" "yapf" "mypy" "pydocstyle" "pycodestyle" "bandit" "pipenv" "virtualenv" "pytest")
|
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 A821E680E5FA6305"
|
PYTHON_SOURCE_GPG_KEYS="64E628F8D684696D B26995E310250568 2D347EA6AA65421D FB9921286F5E1540 3A5CA953F73C700D 04C367C218ADD4FF 0EDDC5F26A45C816 6AF053F07D9DC8D2 C9BE28DEE6DF025C 126EB563A74B06BF D9866941EA5BBD71 ED9D77D5"
|
||||||
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
||||||
keyserver hkp://keyserver.ubuntu.com:80
|
|
||||||
keyserver hkps://keys.openpgp.org
|
keyserver hkps://keys.openpgp.org
|
||||||
keyserver hkp://keyserver.pgp.com"
|
keyserver hkp://keyserver.pgp.com"
|
||||||
|
|
||||||
|
@ -305,31 +304,25 @@ sudo_if() {
|
||||||
if [ "$(id -u)" -eq 0 ] && [ "$USERNAME" != "root" ]; then
|
if [ "$(id -u)" -eq 0 ] && [ "$USERNAME" != "root" ]; then
|
||||||
su - "$USERNAME" -c "$COMMAND"
|
su - "$USERNAME" -c "$COMMAND"
|
||||||
else
|
else
|
||||||
$COMMAND
|
"$COMMAND"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install_user_package() {
|
install_user_package() {
|
||||||
INSTALL_UNDER_ROOT="$1"
|
PACKAGE="$1"
|
||||||
PACKAGE="$2"
|
|
||||||
|
|
||||||
if [ "$INSTALL_UNDER_ROOT" = true ]; then
|
|
||||||
sudo_if "${PYTHON_SRC}" -m pip install --upgrade --no-cache-dir "$PACKAGE"
|
|
||||||
else
|
|
||||||
sudo_if "${PYTHON_SRC}" -m pip install --user --upgrade --no-cache-dir "$PACKAGE"
|
sudo_if "${PYTHON_SRC}" -m pip install --user --upgrade --no-cache-dir "$PACKAGE"
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add_user_jupyter_config() {
|
add_user_jupyter_config() {
|
||||||
CONFIG_DIR="$1"
|
CONFIG_DIR="/home/$USERNAME/.jupyter"
|
||||||
CONFIG_FILE="$2"
|
CONFIG_FILE="$CONFIG_DIR/jupyter_server_config.py"
|
||||||
|
|
||||||
# Make sure the config file exists or create it with proper permissions
|
# Make sure the config file exists or create it with proper permissions
|
||||||
test -d "$CONFIG_DIR" || sudo_if mkdir "$CONFIG_DIR"
|
test -d "$CONFIG_DIR" || sudo_if mkdir "$CONFIG_DIR"
|
||||||
test -f "$CONFIG_FILE" || sudo_if touch "$CONFIG_FILE"
|
test -f "$CONFIG_FILE" || sudo_if touch "$CONFIG_FILE"
|
||||||
|
|
||||||
# Don't write the same config more than once
|
# Don't write the same config more than once
|
||||||
grep -q "$3" "$CONFIG_FILE" || echo "$3" >> "$CONFIG_FILE"
|
grep -q "$1" "$CONFIG_FILE" || echo "$1" >> "$CONFIG_FILE"
|
||||||
}
|
}
|
||||||
|
|
||||||
install_python() {
|
install_python() {
|
||||||
|
@ -468,26 +461,13 @@ if [ "${INSTALL_JUPYTERLAB}" = "true" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
INSTALL_UNDER_ROOT=true
|
install_user_package jupyterlab
|
||||||
if [ "$(id -u)" -eq 0 ] && [ "$USERNAME" != "root" ]; then
|
install_user_package jupyterlab-git
|
||||||
INSTALL_UNDER_ROOT=false
|
|
||||||
fi
|
|
||||||
|
|
||||||
install_user_package $INSTALL_UNDER_ROOT jupyterlab
|
|
||||||
install_user_package $INSTALL_UNDER_ROOT jupyterlab-git
|
|
||||||
|
|
||||||
# Configure JupyterLab if needed
|
# Configure JupyterLab if needed
|
||||||
if [ -n "${CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN}" ]; then
|
if [ -n "${CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN}" ]; then
|
||||||
# Resolve config directory
|
add_user_jupyter_config "c.ServerApp.allow_origin = '${CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN}'"
|
||||||
CONFIG_DIR="/root/.jupyter"
|
add_user_jupyter_config "c.NotebookApp.allow_origin = '${CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN}'"
|
||||||
if [ "$INSTALL_UNDER_ROOT" = false ]; then
|
|
||||||
CONFIG_DIR="/home/$USERNAME/.jupyter"
|
|
||||||
fi
|
|
||||||
|
|
||||||
CONFIG_FILE="$CONFIG_DIR/jupyter_server_config.py"
|
|
||||||
|
|
||||||
add_user_jupyter_config $CONFIG_DIR $CONFIG_FILE "c.ServerApp.allow_origin = '${CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN}'"
|
|
||||||
add_user_jupyter_config $CONFIG_DIR $CONFIG_FILE "c.NotebookApp.allow_origin = '${CONFIGURE_JUPYTERLAB_ALLOW_ORIGIN}'"
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies.
|
||||||
|
|
||||||
### VS Code Extensions
|
### VS Code Extensions
|
||||||
|
|
||||||
|
- `rebornix.Ruby`
|
||||||
- `shopify.ruby-lsp`
|
- `shopify.ruby-lsp`
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "ruby",
|
"id": "ruby",
|
||||||
"version": "1.2.0",
|
"version": "1.1.1",
|
||||||
"name": "Ruby (via rvm)",
|
"name": "Ruby (via rvm)",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/ruby",
|
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/ruby",
|
||||||
"description": "Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies.",
|
"description": "Installs Ruby, rvm, rbenv, common Ruby utilities, and needed dependencies.",
|
||||||
|
@ -21,6 +21,7 @@
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
|
"rebornix.Ruby",
|
||||||
"shopify.ruby-lsp"
|
"shopify.ruby-lsp"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ DEFAULT_GEMS="rake"
|
||||||
|
|
||||||
RVM_GPG_KEYS="409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB"
|
RVM_GPG_KEYS="409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB"
|
||||||
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
GPG_KEY_SERVERS="keyserver hkp://keyserver.ubuntu.com
|
||||||
keyserver hkp://keyserver.ubuntu.com:80
|
|
||||||
keyserver hkps://keys.openpgp.org
|
keyserver hkps://keys.openpgp.org
|
||||||
keyserver hkp://keyserver.pgp.com"
|
keyserver hkp://keyserver.pgp.com"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "rust",
|
"id": "rust",
|
||||||
"version": "1.1.1",
|
"version": "1.1.0",
|
||||||
"name": "Rust",
|
"name": "Rust",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust",
|
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/rust",
|
||||||
"description": "Installs Rust, common Rust utilities, and their required dependencies",
|
"description": "Installs Rust, common Rust utilities, and their required dependencies",
|
||||||
|
|
|
@ -48,6 +48,21 @@ elif [ "${USERNAME}" = "none" ] || ! id -u ${USERNAME} > /dev/null 2>&1; then
|
||||||
USERNAME=root
|
USERNAME=root
|
||||||
fi
|
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
|
# Figure out correct version of a three part version number is not passed
|
||||||
find_version_from_git_tags() {
|
find_version_from_git_tags() {
|
||||||
local variable_name=$1
|
local variable_name=$1
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
|
|
||||||
|
|
||||||
## Licensing
|
|
||||||
|
|
||||||
On August 10, 2023, HashiCorp announced a change of license for its products, including Terraform. After ~9 years of Terraform being open source under the MPL v2 license, it was to move under a non-open source BSL v1.1 license, starting from the next (1.6) version. See https://github.com/hashicorp/terraform/blob/main/LICENSE
|
|
||||||
|
|
||||||
## OS Support
|
## OS Support
|
||||||
|
|
||||||
This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed.
|
This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed.
|
||||||
|
|
|
@ -32,10 +32,6 @@ Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects la
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Licensing
|
|
||||||
|
|
||||||
On August 10, 2023, HashiCorp announced a change of license for its products, including Terraform. After ~9 years of Terraform being open source under the MPL v2 license, it was to move under a non-open source BSL v1.1 license, starting from the next (1.6) version. See https://github.com/hashicorp/terraform/blob/main/LICENSE
|
|
||||||
|
|
||||||
## OS Support
|
## OS Support
|
||||||
|
|
||||||
This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed.
|
This Feature should work on recent versions of Debian/Ubuntu-based distributions with the `apt` package manager installed.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"id": "terraform",
|
"id": "terraform",
|
||||||
"version": "1.3.5",
|
"version": "1.3.4",
|
||||||
"name": "Terraform, tflint, and TFGrunt",
|
"name": "Terraform, tflint, and TFGrunt",
|
||||||
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/terraform",
|
"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.",
|
"description": "Installs the Terraform CLI and optionally TFLint and Terragrunt. Auto-detects latest version and installs needed dependencies.",
|
||||||
|
|
|
@ -77,25 +77,6 @@ receive_gpg_keys() {
|
||||||
sleep 10s
|
sleep 10s
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
# If all attempts fail, try getting the keyserver IP address and explicitly passing it to gpg
|
|
||||||
if [ "${gpg_ok}" = "false" ]; then
|
|
||||||
retry_count=0;
|
|
||||||
echo "(*) Resolving GPG keyserver IP address..."
|
|
||||||
local keyserver_ip_address=$( dig +short keyserver.ubuntu.com | head -n1 )
|
|
||||||
echo "(*) GPG keyserver IP address $keyserver_ip_address"
|
|
||||||
|
|
||||||
until [ "${gpg_ok}" = "true" ] || [ "${retry_count}" -eq "3" ];
|
|
||||||
do
|
|
||||||
echo "(*) Downloading GPG key..."
|
|
||||||
( echo "${keys}" | xargs -n 1 gpg -q ${keyring_args} --recv-keys --keyserver ${keyserver_ip_address}) 2>&1 && gpg_ok="true"
|
|
||||||
if [ "${gpg_ok}" != "true" ]; then
|
|
||||||
echo "(*) Failed getting key, retring in 10s..."
|
|
||||||
(( retry_count++ ))
|
|
||||||
sleep 10s
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
set -e
|
set -e
|
||||||
if [ "${gpg_ok}" = "false" ]; then
|
if [ "${gpg_ok}" = "false" ]; then
|
||||||
echo "(!) Failed to get gpg key."
|
echo "(!) Failed to get gpg key."
|
||||||
|
@ -202,7 +183,7 @@ ensure_cosign() {
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
# Install dependencies if missing
|
# Install dependencies if missing
|
||||||
check_packages curl ca-certificates gnupg2 dirmngr coreutils unzip dnsutils
|
check_packages curl ca-certificates gnupg2 dirmngr coreutils unzip
|
||||||
if ! type git > /dev/null 2>&1; then
|
if ! type git > /dev/null 2>&1; then
|
||||||
check_packages git
|
check_packages git
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -9,9 +9,6 @@ source dev-container-features-test-lib
|
||||||
check "default-shell-is-zsh" bash -c "getent passwd $(whoami) | awk -F: '{ print $7 }' | grep '/bin/zsh'"
|
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 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"
|
check "default-zshrc-is-dev-container-template" bash -c "cat ~/.zshrc | grep ZSH_THEME | grep devcontainers"
|
||||||
check "zsh-path-contains-local-bin" zsh -l -c "echo $PATH | grep '/home/devcontainer/.local/bin'"
|
|
||||||
|
|
||||||
check "Ensure .zprofile is owned by remoteUser" bash -c "stat -c '%U' /home/devcontainer/.zprofile | grep devcontainer"
|
|
||||||
|
|
||||||
# Report result
|
# Report result
|
||||||
reportResults
|
reportResults
|
||||||
|
|
|
@ -4,11 +4,12 @@ set -e
|
||||||
|
|
||||||
# Optional: Import test library
|
# Optional: Import test library
|
||||||
source dev-container-features-test-lib
|
source dev-container-features-test-lib
|
||||||
|
|
||||||
# Definition specific tests
|
# Definition specific tests
|
||||||
function file_not_overridden() {
|
function file_not_overridden() {
|
||||||
cat $1 | grep 'alias fnomockalias=' | grep testingmock
|
cat ~/.zshrc | grep 'alias fnomockalias=' | grep testingmock
|
||||||
}
|
}
|
||||||
check "default-zsh-with-no-zshrc" file_not_overridden /home/devcontainer/.zshrc
|
check "default-zsh-with-no-zshrc" file_not_overridden
|
||||||
|
|
||||||
# Report result
|
# Report result
|
||||||
reportResults
|
reportResults
|
|
@ -1,12 +0,0 @@
|
||||||
#!/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
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Optional: Import test library
|
|
||||||
source dev-container-features-test-lib
|
|
||||||
|
|
||||||
# Definition specific tests
|
|
||||||
check "user is customUser" grep customUser <(whoami)
|
|
||||||
check "home is /customHome" grep "/customHome" <(getent passwd customUser | cut -d: -f6)
|
|
||||||
|
|
||||||
# Report result
|
|
||||||
reportResults
|
|
|
@ -1,4 +0,0 @@
|
||||||
FROM ubuntu:focal
|
|
||||||
|
|
||||||
RUN groupadd customUser -g 30000 && \
|
|
||||||
useradd customUser -u 30000 -g 30000 --create-home --home-dir /customHome
|
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Optional: Import test library
|
|
||||||
source dev-container-features-test-lib
|
|
||||||
|
|
||||||
# Definition specific tests
|
|
||||||
check "user is customUser" grep customUser <(whoami)
|
|
||||||
check "home is /home/customUser" grep "/home/customUser" <(getent passwd customUser | cut -d: -f6)
|
|
||||||
|
|
||||||
# Report result
|
|
||||||
reportResults
|
|
|
@ -108,29 +108,17 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"configure_zsh_as_default_shell": {
|
"configure_zsh_as_default_shell": {
|
||||||
"image": "ubuntu",
|
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
||||||
"features": {
|
"features": {
|
||||||
"common-utils": {
|
"common-utils": {
|
||||||
"installZsh": true,
|
|
||||||
"configureZshAsDefaultShell": true
|
"configureZshAsDefaultShell": true
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"remoteUser": "devcontainer"
|
"configure_zsh_no_template": {
|
||||||
},
|
|
||||||
"configure_zsh_no_template_second_step": {
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
||||||
"postCreateCommand": "echo alias fnomockalias=testingmock >> /home/devcontainer/.zshrc",
|
"postCreateCommand": "echo alias fnomockalias=testingmock >> /root/.zshrc",
|
||||||
"remoteUser": "devcontainer",
|
"remoteUser": "root",
|
||||||
"features": {
|
|
||||||
"common-utils": {
|
|
||||||
"installZsh": true,
|
|
||||||
"installOhMyZshConfig": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"configure_zsh_no_template_first_step": {
|
|
||||||
"image": "debian:bullseye",
|
|
||||||
"remoteUser": "devcontainer",
|
|
||||||
"features": {
|
"features": {
|
||||||
"common-utils": {
|
"common-utils": {
|
||||||
"installZsh": true,
|
"installZsh": true,
|
||||||
|
@ -185,21 +173,5 @@
|
||||||
"configureZshAsDefaultShell": true
|
"configureZshAsDefaultShell": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"devcontainer-custom-home": {
|
|
||||||
"build": {
|
|
||||||
"dockerfile": "Dockerfile"
|
|
||||||
},
|
|
||||||
"remoteUser": "customUser",
|
|
||||||
"features": {
|
|
||||||
"common-utils": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"devcontainer-custom-user-default-home": {
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:alpine",
|
|
||||||
"remoteUser": "customUser",
|
|
||||||
"features": {
|
|
||||||
"common-utils": {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
#!/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
|
|
|
@ -67,14 +67,5 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"remoteUser": "node"
|
"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"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,10 @@ source dev-container-features-test-lib
|
||||||
# Feature specific tests
|
# Feature specific tests
|
||||||
check "version" docker --version
|
check "version" docker --version
|
||||||
check "docker-init-exists" bash -c "ls /usr/local/share/docker-init.sh"
|
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-exists" bash -c "ls /tmp/dockerd.log"
|
||||||
check "log-for-completion" bash -c "cat /tmp/dockerd.log | grep 'Daemon has completed initialization'"
|
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 "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
|
# Report result
|
||||||
reportResults
|
reportResults
|
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
export DOTNET_NOLOGO=true
|
|
||||||
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=true
|
|
||||||
export DOTNET_GENERATE_ASPNET_CERTIFICATE=false
|
|
|
@ -1,71 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Prints the latest dotnet version in the specified channel
|
|
||||||
# Usage: fetch_latest_version_in_channel <channel> [<runtime>]
|
|
||||||
# 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 [<runtime>]
|
|
||||||
# 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 <version>
|
|
||||||
# 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 <version>
|
|
||||||
# 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 <version>
|
|
||||||
# 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 $?
|
|
||||||
}
|
|
17
test/dotnet/install_additional_dotnet.sh
Normal file
17
test/dotnet/install_additional_dotnet.sh
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#!/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
|
|
@ -1,27 +0,0 @@
|
||||||
#!/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 <LABEL> <cmd> [args...]
|
|
||||||
source dotnet_env.sh
|
|
||||||
source dotnet_helpers.sh
|
|
||||||
|
|
||||||
expected=$(fetch_latest_version "aspnetcore")
|
|
||||||
|
|
||||||
check "Latest ASP.NET Core Runtime version installed" \
|
|
||||||
is_aspnetcore_runtime_version_installed "$expected"
|
|
||||||
|
|
||||||
# Expect this check to fail in November 2023 when .NET 8.0 becomes GA
|
|
||||||
check "It is a flavor of .NET 7.0" \
|
|
||||||
is_aspnetcore_runtime_version_installed "7.0"
|
|
||||||
|
|
||||||
# Report results
|
|
||||||
# If any of the checks above exited with a non-zero exit code, the test will fail.
|
|
||||||
reportResults
|
|
17
test/dotnet/install_dotnet_3.sh
Normal file
17
test/dotnet/install_dotnet_3.sh
Normal file
|
@ -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 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
|
17
test/dotnet/install_dotnet_6_bullseye.sh
Normal file
17
test/dotnet/install_dotnet_6_bullseye.sh
Normal file
|
@ -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
|
17
test/dotnet/install_dotnet_6_focal.sh
Normal file
17
test/dotnet/install_dotnet_6_focal.sh
Normal file
|
@ -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
|
17
test/dotnet/install_dotnet_6_jammy.sh
Normal file
17
test/dotnet/install_dotnet_6_jammy.sh
Normal file
|
@ -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
|
17
test/dotnet/install_dotnet_7_bullseye.sh
Normal file
17
test/dotnet/install_dotnet_7_bullseye.sh
Normal file
|
@ -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
|
17
test/dotnet/install_dotnet_7_jammy.sh
Normal file
17
test/dotnet/install_dotnet_7_jammy.sh
Normal file
|
@ -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/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
|
||||||
|
check "current link sdk" ls -l /usr/local/dotnet/current/sdk
|
||||||
|
|
||||||
|
# Report result
|
||||||
|
reportResults
|
|
@ -1,24 +0,0 @@
|
||||||
#!/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 <LABEL> <cmd> [args...]
|
|
||||||
source dotnet_env.sh
|
|
||||||
source dotnet_helpers.sh
|
|
||||||
|
|
||||||
check ".NET SDK 8.0.100-preview.6.23330.14 installed" \
|
|
||||||
is_dotnet_sdk_version_installed "8.0.100-preview.6.23330.14"
|
|
||||||
|
|
||||||
check "Build and run example project" \
|
|
||||||
dotnet run --project projects/net8.0
|
|
||||||
|
|
||||||
# Report results
|
|
||||||
# If any of the checks above exited with a non-zero exit code, the test will fail.
|
|
||||||
reportResults
|
|
|
@ -1,25 +0,0 @@
|
||||||
#!/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 <LABEL> <cmd> [args...]
|
|
||||||
source dotnet_env.sh
|
|
||||||
source dotnet_helpers.sh
|
|
||||||
|
|
||||||
# From https://learn.microsoft.com/en-us/dotnet/core/tools/global-tools
|
|
||||||
check "Install a .NET global tool" \
|
|
||||||
dotnet tool install --global dotnetsay
|
|
||||||
|
|
||||||
check "Run the tool" \
|
|
||||||
dotnetsay "$(dotnet --info)"
|
|
||||||
|
|
||||||
# Report results
|
|
||||||
# If any of the checks above exited with a non-zero exit code, the test will fail.
|
|
||||||
reportResults
|
|
17
test/dotnet/install_dotnet_latest.sh
Normal file
17
test/dotnet/install_dotnet_latest.sh
Normal file
|
@ -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/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
|
||||||
|
check "current link sdk" ls -l /usr/local/dotnet/current/sdk
|
||||||
|
|
||||||
|
# Report result
|
||||||
|
reportResults
|
|
@ -1,30 +0,0 @@
|
||||||
#!/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 <LABEL> <cmd> [args...]
|
|
||||||
source dotnet_env.sh
|
|
||||||
source dotnet_helpers.sh
|
|
||||||
|
|
||||||
expected=$(fetch_latest_version)
|
|
||||||
|
|
||||||
check "Latest .NET SDK version installed" \
|
|
||||||
is_dotnet_sdk_version_installed "$expected"
|
|
||||||
|
|
||||||
# Expect this check to fail in November 2023 when .NET 8.0 becomes GA
|
|
||||||
check "It is a flavor of .NET 7.0" \
|
|
||||||
is_dotnet_sdk_version_installed "7.0"
|
|
||||||
|
|
||||||
check "Build and run example project" \
|
|
||||||
dotnet run --project projects/net7.0
|
|
||||||
|
|
||||||
# Report results
|
|
||||||
# If any of the checks above exited with a non-zero exit code, the test will fail.
|
|
||||||
reportResults
|
|
|
@ -2,25 +2,16 @@
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Optional: Import test library bundled with the devcontainer CLI
|
# Optional: Import test library
|
||||||
# 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
|
source dev-container-features-test-lib
|
||||||
|
|
||||||
# Feature-specific tests
|
check "dotnet sdks" dotnet --list-sdks
|
||||||
# The 'check' command comes from the dev-container-features-test-lib. Syntax is...
|
check "some major version of dotnet 6 is installed" bash -c "dotnet --list-sdks | grep '6\.[0-9]*\.[0-9]*'"
|
||||||
# check <LABEL> <cmd> [args...]
|
check "dotnet version 6 installed" bash -c "ls -l /usr/share/dotnet/sdk | grep '6\.[0-9]*\.[0-9]*'"
|
||||||
source dotnet_env.sh
|
|
||||||
source dotnet_helpers.sh
|
|
||||||
|
|
||||||
expected=$(fetch_latest_version_in_channel "LTS")
|
# 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
|
||||||
|
|
||||||
check "Latest LTS version installed" \
|
# Report result
|
||||||
is_dotnet_sdk_version_installed "$expected"
|
|
||||||
|
|
||||||
check "Build and run example project" \
|
|
||||||
dotnet run --project projects/net6.0
|
|
||||||
|
|
||||||
# Report results
|
|
||||||
# If any of the checks above exited with a non-zero exit code, the test will fail.
|
|
||||||
reportResults
|
reportResults
|
|
@ -1,30 +0,0 @@
|
||||||
#!/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 <LABEL> <cmd> [args...]
|
|
||||||
source dotnet_env.sh
|
|
||||||
source dotnet_helpers.sh
|
|
||||||
|
|
||||||
check ".NET SDK 8.0 installed" \
|
|
||||||
is_dotnet_sdk_version_installed "8.0"
|
|
||||||
|
|
||||||
check ".NET SDK 7.0 installed" \
|
|
||||||
is_dotnet_sdk_version_installed "7.0"
|
|
||||||
|
|
||||||
check ".NET SDK 6.0 installed" \
|
|
||||||
is_dotnet_sdk_version_installed "6.0"
|
|
||||||
|
|
||||||
check "Build example class library" \
|
|
||||||
dotnet build projects/multitargeting
|
|
||||||
|
|
||||||
# Report results
|
|
||||||
# If any of the checks above exited with a non-zero exit code, the test will fail.
|
|
||||||
reportResults
|
|
|
@ -1,27 +0,0 @@
|
||||||
#!/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 <LABEL> <cmd> [args...]
|
|
||||||
source dotnet_env.sh
|
|
||||||
source dotnet_helpers.sh
|
|
||||||
|
|
||||||
expected=$(fetch_latest_version "dotnet")
|
|
||||||
|
|
||||||
check "Latest .NET Runtime version installed" \
|
|
||||||
is_dotnet_runtime_version_installed "$expected"
|
|
||||||
|
|
||||||
# Expect this check to fail in November 2023 when .NET 8.0 becomes GA
|
|
||||||
check "It is a flavor of .NET 7.0" \
|
|
||||||
is_dotnet_runtime_version_installed "7.0"
|
|
||||||
|
|
||||||
# Report results
|
|
||||||
# If any of the checks above exited with a non-zero exit code, the test will fail.
|
|
||||||
reportResults
|
|
|
@ -1,26 +0,0 @@
|
||||||
#!/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 <LABEL> <cmd> [args...]
|
|
||||||
source dotnet_env.sh
|
|
||||||
source dotnet_helpers.sh
|
|
||||||
|
|
||||||
expected=$(fetch_latest_version_in_channel "3.1")
|
|
||||||
|
|
||||||
check ".NET Core SDK 3.1 installed" \
|
|
||||||
is_dotnet_sdk_version_installed "$expected"
|
|
||||||
|
|
||||||
check "Build and run example project" \
|
|
||||||
dotnet run --project projects/netcoreapp3.1
|
|
||||||
|
|
||||||
# Report results
|
|
||||||
# If any of the checks above exited with a non-zero exit code, the test will fail.
|
|
||||||
reportResults
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/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 <LABEL> <cmd> [args...]
|
|
||||||
source dotnet_env.sh
|
|
||||||
source dotnet_helpers.sh
|
|
||||||
|
|
||||||
check ".NET SDK 5.0.3xx installed" \
|
|
||||||
is_dotnet_sdk_version_installed "5.0.3"
|
|
||||||
|
|
||||||
check "Build and run example project" \
|
|
||||||
dotnet run --project projects/net5.0
|
|
||||||
|
|
||||||
# Report results
|
|
||||||
# If any of the checks above exited with a non-zero exit code, the test will fail.
|
|
||||||
reportResults
|
|
17
test/dotnet/install_wo_apt.sh
Normal file
17
test/dotnet/install_wo_apt.sh
Normal file
|
@ -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
|
2
test/dotnet/projects/.gitignore
vendored
2
test/dotnet/projects/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
||||||
bin
|
|
||||||
obj
|
|
|
@ -1,4 +0,0 @@
|
||||||
public class Class1
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFrameworks>net8.0;net7.0;net6.0</TargetFrameworks>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,32 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
string json = @"{
|
|
||||||
""Name"": ""Inception"",
|
|
||||||
""ReleaseDate"": ""2010-07-08T00:00:00"",
|
|
||||||
""Genres"": [
|
|
||||||
""Action"",
|
|
||||||
""Thriller""
|
|
||||||
]
|
|
||||||
}";
|
|
||||||
|
|
||||||
Movie? m = JsonConvert.DeserializeObject<Movie>(json);
|
|
||||||
|
|
||||||
if (m == default)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Decoding failed!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Movie name: {m.Name}");
|
|
||||||
Console.WriteLine($"Release Date: {m.ReleaseDate}");
|
|
||||||
Console.WriteLine($"Genres: {string.Join(", ", m.Genres)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
class Movie
|
|
||||||
{
|
|
||||||
public string Name { get; set; } = "Default Name";
|
|
||||||
public DateTime ReleaseDate { get; set; }
|
|
||||||
public List<string> Genres { get; set; } = new List<string>();
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,30 +0,0 @@
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
string json = @"{
|
|
||||||
""Name"": ""Inception"",
|
|
||||||
""ReleaseDate"": ""2010-07-08T00:00:00"",
|
|
||||||
""Genres"": [
|
|
||||||
""Action"",
|
|
||||||
""Thriller""
|
|
||||||
]
|
|
||||||
}";
|
|
||||||
|
|
||||||
Movie? m = JsonConvert.DeserializeObject<Movie>(json);
|
|
||||||
|
|
||||||
if (m == default)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Decoding failed!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Movie name: {m.Name}");
|
|
||||||
Console.WriteLine($"Release Date: {m.ReleaseDate}");
|
|
||||||
Console.WriteLine($"Genres: {string.Join(", ", m.Genres)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
class Movie
|
|
||||||
{
|
|
||||||
public string Name { get; set; } = "Default Name";
|
|
||||||
public DateTime ReleaseDate { get; set; }
|
|
||||||
public List<string> Genres { get; set; } = new List<string>();
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,30 +0,0 @@
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
string json = @"{
|
|
||||||
""Name"": ""Inception"",
|
|
||||||
""ReleaseDate"": ""2010-07-08T00:00:00"",
|
|
||||||
""Genres"": [
|
|
||||||
""Action"",
|
|
||||||
""Thriller""
|
|
||||||
]
|
|
||||||
}";
|
|
||||||
|
|
||||||
Movie? m = JsonConvert.DeserializeObject<Movie>(json);
|
|
||||||
|
|
||||||
if (m == default)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Decoding failed!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Movie name: {m.Name}");
|
|
||||||
Console.WriteLine($"Release Date: {m.ReleaseDate}");
|
|
||||||
Console.WriteLine($"Genres: {string.Join(", ", m.Genres)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
class Movie
|
|
||||||
{
|
|
||||||
public string Name { get; set; } = "Default Name";
|
|
||||||
public DateTime ReleaseDate { get; set; }
|
|
||||||
public List<string> Genres { get; set; } = new List<string>();
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,32 +0,0 @@
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
string json = """
|
|
||||||
{
|
|
||||||
"Name": "Inception",
|
|
||||||
"ReleaseDate": "2010-07-08T00:00:00",
|
|
||||||
"Genres": [
|
|
||||||
"Action",
|
|
||||||
"Thriller"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
""";
|
|
||||||
|
|
||||||
Movie? m = JsonConvert.DeserializeObject<Movie>(json);
|
|
||||||
|
|
||||||
if (m == default)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Decoding failed!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Movie name: {m.Name}");
|
|
||||||
Console.WriteLine($"Release Date: {m.ReleaseDate}");
|
|
||||||
Console.WriteLine($"Genres: {string.Join(", ", m.Genres)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
class Movie
|
|
||||||
{
|
|
||||||
public string Name { get; set; } = "Default Name";
|
|
||||||
public DateTime ReleaseDate { get; set; }
|
|
||||||
public List<string> Genres { get; set; } = new List<string>();
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,39 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
class Program
|
|
||||||
{
|
|
||||||
public static void Main()
|
|
||||||
{
|
|
||||||
string json = @"{
|
|
||||||
""Name"": ""Inception"",
|
|
||||||
""ReleaseDate"": ""2010-07-08T00:00:00"",
|
|
||||||
""Genres"": [
|
|
||||||
""Action"",
|
|
||||||
""Thriller""
|
|
||||||
]
|
|
||||||
}";
|
|
||||||
|
|
||||||
Movie? m = JsonConvert.DeserializeObject<Movie>(json);
|
|
||||||
|
|
||||||
if (m == default)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Decoding failed!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine($"Movie name: {m.Name}");
|
|
||||||
Console.WriteLine($"Release Date: {m.ReleaseDate}");
|
|
||||||
Console.WriteLine($"Genres: {string.Join(", ", m.Genres)}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Movie
|
|
||||||
{
|
|
||||||
public string Name { get; set; } = "Default Name";
|
|
||||||
public DateTime ReleaseDate { get; set; }
|
|
||||||
public List<string> Genres { get; set; } = new List<string>();
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
|
@ -1,84 +1,83 @@
|
||||||
{
|
{
|
||||||
|
"install_additional_dotnet": {
|
||||||
|
"image": "ubuntu:focal",
|
||||||
|
"features": {
|
||||||
|
"dotnet": {
|
||||||
|
"version": "6.0.301",
|
||||||
|
"additionalVersions": "5.0,3.1.420"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"install_dotnet_3": {
|
||||||
|
"image": "ubuntu:focal",
|
||||||
|
"features": {
|
||||||
|
"dotnet": {
|
||||||
|
"version": "3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"install_dotnet_6_bullseye": {
|
||||||
|
"image": "debian:bullseye",
|
||||||
|
"features": {
|
||||||
|
"dotnet": {
|
||||||
|
"version": "6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"install_dotnet_6_focal": {
|
||||||
|
"image": "ubuntu:focal",
|
||||||
|
"features": {
|
||||||
|
"dotnet": {
|
||||||
|
"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_6_jammy": {
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/base:jammy",
|
||||||
|
"features": {
|
||||||
|
"dotnet": {
|
||||||
|
"version": "6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"install_dotnet_latest": {
|
||||||
|
"image": "ubuntu:jammy",
|
||||||
|
"features": {
|
||||||
|
"dotnet": {
|
||||||
|
"version": "latest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"install_dotnet_lts": {
|
"install_dotnet_lts": {
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
"image": "ubuntu:focal",
|
||||||
"remoteUser": "vscode",
|
|
||||||
"features": {
|
"features": {
|
||||||
"dotnet": {
|
"dotnet": {
|
||||||
"version": "lts"
|
"version": "lts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"install_dotnet_specific_release": {
|
"install_wo_apt": {
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04",
|
"image": "ubuntu:jammy",
|
||||||
"remoteUser": "vscode",
|
|
||||||
"features": {
|
"features": {
|
||||||
"dotnet": {
|
"dotnet": {
|
||||||
"version": "3.1"
|
"version": "7",
|
||||||
}
|
"installUsingApt": false
|
||||||
}
|
|
||||||
},
|
|
||||||
"install_dotnet_specific_release_and_feature_band": {
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-20.04",
|
|
||||||
"remoteUser": "vscode",
|
|
||||||
"features": {
|
|
||||||
"dotnet": {
|
|
||||||
"version": "5.0.3xx"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"install_dotnet_exact_version": {
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
|
||||||
"remoteUser": "vscode",
|
|
||||||
"features": {
|
|
||||||
"dotnet": {
|
|
||||||
"version": "8.0.100-preview.6.23330.14"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"install_dotnet_multiple_versions": {
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
|
||||||
"remoteUser": "vscode",
|
|
||||||
"features": {
|
|
||||||
"dotnet": {
|
|
||||||
"version": "8.0.100-preview.6.23330.14",
|
|
||||||
"additionalVersions": [
|
|
||||||
"7.0",
|
|
||||||
"6.0"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"install_dotnet_global_tool": {
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
|
||||||
"remoteUser": "vscode",
|
|
||||||
"features": {
|
|
||||||
"dotnet": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"install_dotnet_latest_when_version_is_empty": {
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
|
||||||
"remoteUser": "vscode",
|
|
||||||
"features": {
|
|
||||||
"dotnet": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"install_dotnet_runtime_only": {
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
|
||||||
"remoteUser": "vscode",
|
|
||||||
"features": {
|
|
||||||
"dotnet": {
|
|
||||||
"version": "none",
|
|
||||||
"dotnetRuntimeVersions": "latest"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"install_aspnetcore_runtime_only": {
|
|
||||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
|
||||||
"remoteUser": "vscode",
|
|
||||||
"features": {
|
|
||||||
"dotnet": {
|
|
||||||
"version": "none",
|
|
||||||
"aspnetcoreRuntimeVersions": "latest"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue