Dev/hshami/new dev containers (#604)
* Introducing dev containers * user choses if they wish to use a dev container * new version
This commit is contained in:
Родитель
3f8ef23805
Коммит
e675bd4022
|
@ -1,4 +1,10 @@
|
|||
# Change Log
|
||||
## 1.25.0- 2021-10-05
|
||||
### Changed
|
||||
* Added Dev Container definitions for all supported languages
|
||||
* Incorporate Dev Container definition with every new EdgeSolution
|
||||
* Added a new command to add Dev Container definition to existing solutions
|
||||
|
||||
## 1.24.4 - 2021-10-01
|
||||
### Changed
|
||||
* Maximum version number for edgeHub/properties.desired.schemaVersion is capped to 1.1
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/dotnet/.devcontainer/base.Dockerfile
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/dotnet:0-3.1
|
||||
|
||||
# Install Docker CE
|
||||
COPY library-scripts/*.sh /tmp/library-scripts/
|
||||
RUN \
|
||||
apt-get update -y \
|
||||
# Use Docker script from script library to set things up - enable non-root docker, user vscode, using moby
|
||||
&& /bin/bash /tmp/library-scripts/docker-in-docker-debian.sh "true" "vscode" "true" \
|
||||
# install iotedgehubdev
|
||||
&& apt-get install -y python3-pip && pip3 install iotedgehubdev \
|
||||
# Clean up
|
||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts/
|
||||
|
||||
# launch docker-ce
|
||||
ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
|
||||
CMD [ "sleep", "infinity" ]
|
|
@ -0,0 +1,61 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/dotnet
|
||||
{
|
||||
"name": "Azure IoTEdge C# (.NET)",
|
||||
"build": { "dockerfile": "Dockerfile" },
|
||||
"runArgs": ["--init", "--privileged"],
|
||||
"mounts": [
|
||||
// Keep command history
|
||||
"source=ostf-bashhistory,target=/commandhistory,type=volume",
|
||||
// Use docker-in-docker socket
|
||||
"source=dind-var-lib-docker,target=/var/lib/docker,type=volume"
|
||||
],
|
||||
"overrideCommand": false,
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.profiles.linux": {
|
||||
"bash": {
|
||||
"path": "/bin/bash"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-dotnettools.csharp",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"vsciot-vscode.azure-iot-tools"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [5000, 5001],
|
||||
|
||||
// [Optional] To reuse of your local HTTPS dev cert:
|
||||
//
|
||||
// 1. Export it locally using this command:
|
||||
// * Windows PowerShell:
|
||||
// dotnet dev-certs https --trust; dotnet dev-certs https -ep "$env:USERPROFILE/.aspnet/https/aspnetapp.pfx" -p "SecurePwdGoesHere"
|
||||
// * macOS/Linux terminal:
|
||||
// dotnet dev-certs https --trust; dotnet dev-certs https -ep "${HOME}/.aspnet/https/aspnetapp.pfx" -p "SecurePwdGoesHere"
|
||||
//
|
||||
// 2. Uncomment these 'remoteEnv' lines:
|
||||
// "remoteEnv": {
|
||||
// "ASPNETCORE_Kestrel__Certificates__Default__Password": "SecurePwdGoesHere",
|
||||
// "ASPNETCORE_Kestrel__Certificates__Default__Path": "/home/vscode/.aspnet/https/aspnetapp.pfx",
|
||||
// },
|
||||
//
|
||||
// 3. Do one of the following depending on your scenario:
|
||||
// * When using GitHub Codespaces and/or Remote - Containers:
|
||||
// 1. Start the container
|
||||
// 2. Drag ~/.aspnet/https/aspnetapp.pfx into the root of the file explorer
|
||||
// 3. Open a terminal in VS Code and run "mkdir -p /home/vscode/.aspnet/https && mv aspnetapp.pfx /home/vscode/.aspnet/https"
|
||||
//
|
||||
// * If only using Remote - Containers with a local container, uncomment this line instead:
|
||||
// "mounts": [ "source=${env:HOME}${env:USERPROFILE}/.aspnet/https,target=/home/vscode/.aspnet/https,type=bind" ],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "dotnet restore",
|
||||
|
||||
"remoteUser": "vscode"
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/debian/.devcontainer/base.Dockerfile
|
||||
|
||||
# [Choice] Debian version: bullseye, buster, stretch
|
||||
ARG VARIANT="buster"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT}
|
||||
|
||||
# Install Docker CE
|
||||
COPY library-scripts/*.sh /tmp/library-scripts/
|
||||
RUN \
|
||||
apt-get update -y \
|
||||
# Use Docker script from script library to set things up - enable non-root docker, user vscode, using moby
|
||||
&& /bin/bash /tmp/library-scripts/docker-in-docker-debian.sh "true" "automatic" "true" \
|
||||
# install iotedgehubdev
|
||||
&& apt-get install -y python3-pip && pip3 install --upgrade pip && pip install iotedgehubdev \
|
||||
# Clean up
|
||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts/
|
||||
|
||||
# launch docker-ce
|
||||
ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
|
||||
CMD [ "sleep", "infinity" ]
|
|
@ -0,0 +1,39 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/debian
|
||||
{
|
||||
"name": "Azure IoT Edge C/C++",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
// Update 'VARIANT' to pick an Debian version: bullseye, buster, stretch
|
||||
"args": { "VARIANT": "buster" }
|
||||
},
|
||||
"runArgs": ["--init", "--privileged"],
|
||||
"mounts": [
|
||||
// Keep command history
|
||||
"source=ostf-bashhistory,target=/commandhistory,type=volume",
|
||||
// Use docker-in-docker socket
|
||||
"source=dind-var-lib-docker,target=/var/lib/docker,type=volume"
|
||||
],
|
||||
"overrideCommand": false,
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": { "terminal.integrated.defaultProfile.linux": "/bin/bash" },
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-vscode.cpptools",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"vsciot-vscode.azure-iot-tools"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Uncomment to use the Docker CLI from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker.
|
||||
// "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ],
|
||||
|
||||
// Uncomment when using a ptrace-based debugger like C++, Go, and Rust
|
||||
// "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ],
|
||||
|
||||
"remoteUser": "vscode"
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/java/.devcontainer/base.Dockerfile
|
||||
|
||||
# [Choice] Java version: 11, 16
|
||||
ARG VARIANT="16"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/java:0-${VARIANT}
|
||||
|
||||
# [Option] Install Maven
|
||||
ARG INSTALL_MAVEN="false"
|
||||
ARG MAVEN_VERSION=""
|
||||
RUN if [ "${INSTALL_MAVEN}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install maven \"${MAVEN_VERSION}\""; fi
|
||||
|
||||
# Install Docker CE
|
||||
COPY library-scripts/*.sh /tmp/library-scripts/
|
||||
RUN \
|
||||
apt-get update -y \
|
||||
# Use Docker script from script library to set things up - enable non-root docker, user vscode, using moby
|
||||
&& /bin/bash /tmp/library-scripts/docker-in-docker-debian.sh "true" "automatic" "true" \
|
||||
# install iotedgehubdev
|
||||
&& apt-get install -y python3-pip && pip3 install --upgrade pip && pip install iotedgehubdev \
|
||||
# Clean up
|
||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts/
|
||||
|
||||
# launch docker-ce
|
||||
ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
|
||||
CMD [ "sleep", "infinity" ]
|
|
@ -0,0 +1,49 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/java
|
||||
{
|
||||
"name": "Azure IoTEdge Java",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
"args": {
|
||||
// Update the VARIANT arg to pick a Java version: 11, 16
|
||||
"VARIANT": "11",
|
||||
// Options
|
||||
"INSTALL_MAVEN": "true",
|
||||
"INSTALL_GRADLE": "false",
|
||||
"NODE_VERSION": "none"
|
||||
}
|
||||
},
|
||||
"runArgs": ["--init", "--privileged"],
|
||||
"mounts": [
|
||||
// Keep command history
|
||||
"source=ostf-bashhistory,target=/commandhistory,type=volume",
|
||||
// Use docker-in-docker socket
|
||||
"source=dind-var-lib-docker,target=/var/lib/docker,type=volume"
|
||||
],
|
||||
"overrideCommand": false,
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"java.home": "/docker-java-home",
|
||||
"terminal.integrated.profiles.linux": {
|
||||
"bash": {
|
||||
"path": "/bin/bash"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"vscjava.vscode-java-pack",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"vsciot-vscode.azure-iot-tools"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "java -version",
|
||||
|
||||
"remoteUser": "vscode"
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/javascript-node/.devcontainer/base.Dockerfile
|
||||
|
||||
# [Choice] Node.js version: 16, 14, 12
|
||||
ARG VARIANT="16-buster"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/javascript-node:0-${VARIANT}
|
||||
|
||||
# Install Docker CE
|
||||
COPY library-scripts/*.sh /tmp/library-scripts/
|
||||
RUN \
|
||||
apt-get update -y \
|
||||
# Use Docker script from script library to set things up - enable non-root docker, user vscode, using moby
|
||||
&& /bin/bash /tmp/library-scripts/docker-in-docker-debian.sh "true" "automatic" "true" \
|
||||
# install iotedgehubdev
|
||||
&& apt-get install -y python3-pip && pip3 install --upgrade pip && pip install iotedgehubdev \
|
||||
# Clean up
|
||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts/
|
||||
|
||||
# [Optional] Uncomment this line to install global node packages.
|
||||
# ARG EXTRA_NODE_VERSION=10
|
||||
# RUN su node -c "source /usr/local/share/nvm/nvm.sh && nvm install ${EXTRA_NODE_VERSION}"
|
||||
|
||||
RUN npm install -g yo@latest generator-azure-iot-edge-module
|
||||
|
||||
# launch docker-ce
|
||||
ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
|
||||
CMD [ "sleep", "infinity" ]
|
|
@ -0,0 +1,38 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/javascript-node
|
||||
{
|
||||
"name": "Azure IoTEdge Node.js",
|
||||
"build": { "dockerfile": "Dockerfile" },
|
||||
"runArgs": ["--init", "--privileged"],
|
||||
"mounts": [
|
||||
// Keep command history
|
||||
"source=ostf-bashhistory,target=/commandhistory,type=volume",
|
||||
// Use docker-in-docker socket
|
||||
"source=dind-var-lib-docker,target=/var/lib/docker,type=volume"
|
||||
],
|
||||
"overrideCommand": false,
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.profiles.linux": {
|
||||
"bash": {
|
||||
"path": "/bin/bash"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"vsciot-vscode.azure-iot-tools"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "yarn install"
|
||||
|
||||
"remoteUser": "node"
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/python-3/.devcontainer/base.Dockerfile
|
||||
|
||||
# [Choice] Python version: 3, 3.9, 3.8, 3.7, 3.6
|
||||
ARG VARIANT="3.7"
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}
|
||||
|
||||
# Install Docker CE
|
||||
COPY library-scripts/*.sh /tmp/library-scripts/
|
||||
RUN \
|
||||
apt-get update -y \
|
||||
# Use Docker script from script library to set things up - enable non-root docker, user vscode, using moby
|
||||
&& /bin/bash /tmp/library-scripts/docker-in-docker-debian.sh "true" "automatic" "true" \
|
||||
# install iotedgehubdev
|
||||
# && apt-get install -y python3-pip && pip3 install --upgrade pip && pip install iotedgehubdev \
|
||||
&& apt-get install -y python3-pip && pip install iotedgehubdev \
|
||||
# Clean up
|
||||
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* /tmp/library-scripts/
|
||||
|
||||
# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.
|
||||
# COPY requirements.txt /tmp/pip-tmp/
|
||||
# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
|
||||
# && rm -rf /tmp/pip-tmp
|
||||
|
||||
# launch docker-ce
|
||||
ENTRYPOINT [ "/usr/local/share/docker-init.sh" ]
|
||||
CMD [ "sleep", "infinity" ]
|
|
@ -0,0 +1,59 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
|
||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.0/containers/python-3
|
||||
{
|
||||
"name": "Azure IoT Edge Python 3.7",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile",
|
||||
"args": {
|
||||
// Update 'VARIANT' to pick a Python version: 3, 3.6, 3.7, 3.8, 3.9
|
||||
"VARIANT": "3.7"
|
||||
}
|
||||
},
|
||||
"runArgs": ["--init", "--privileged"],
|
||||
"mounts": [
|
||||
// Keep command history
|
||||
"source=ostf-bashhistory,target=/commandhistory,type=volume",
|
||||
// Use docker-in-docker socket
|
||||
"source=dind-var-lib-docker,target=/var/lib/docker,type=volume"
|
||||
],
|
||||
"overrideCommand": false,
|
||||
|
||||
// Set *default* container specific settings.json values on container create.
|
||||
"settings": {
|
||||
"terminal.integrated.profiles.linux": {
|
||||
"bash": {
|
||||
"path": "/bin/bash"
|
||||
}
|
||||
},
|
||||
"terminal.integrated.defaultProfile.linux": "bash",
|
||||
"python.pythonPath": "/usr/local/bin/python",
|
||||
"python.languageServer": "Pylance",
|
||||
"python.linting.enabled": true,
|
||||
"python.linting.pylintEnabled": true,
|
||||
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
|
||||
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
|
||||
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
|
||||
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
|
||||
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
|
||||
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
|
||||
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
|
||||
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
|
||||
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint"
|
||||
},
|
||||
|
||||
// Add the IDs of extensions you want installed when the container is created.
|
||||
"extensions": [
|
||||
"ms-python.python",
|
||||
"ms-python.vscode-pylance",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"vsciot-vscode.azure-iot-tools"
|
||||
],
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// "forwardPorts": [],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
// "postCreateCommand": "pip3 install --user -r requirements.txt",
|
||||
|
||||
"remoteUser": "vscode"
|
||||
}
|
|
@ -0,0 +1,236 @@
|
|||
#!/usr/bin/env 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/microsoft/vscode-dev-containers/blob/main/script-library/docs/docker-in-docker.md
|
||||
# Maintainer: The VS Code and Codespaces Teams
|
||||
#
|
||||
# Syntax: ./docker-in-docker-debian.sh [enable non-root docker access flag] [non-root user] [use moby]
|
||||
|
||||
ENABLE_NONROOT_DOCKER=${1:-"true"}
|
||||
USERNAME=${2:-"automatic"}
|
||||
USE_MOBY=${3:-"true"}
|
||||
MICROSOFT_GPG_KEYS_URI="https://packages.microsoft.com/keys/microsoft.asc"
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo -e 'Script must be run as root. Use sudo, su, or add "USER root" to your Dockerfile before running this script.'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 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
|
||||
|
||||
# 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}"
|
||||
}
|
||||
|
||||
# Function to run apt-get if needed
|
||||
apt_get_update_if_needed()
|
||||
{
|
||||
if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then
|
||||
echo "Running apt-get update..."
|
||||
apt-get update
|
||||
else
|
||||
echo "Skipping apt-get update."
|
||||
fi
|
||||
}
|
||||
|
||||
# Checks if packages are installed and installs them if not
|
||||
check_packages() {
|
||||
if ! dpkg -s "$@" > /dev/null 2>&1; then
|
||||
apt_get_update_if_needed
|
||||
apt-get -y install --no-install-recommends "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# Ensure apt is in non-interactive to avoid prompts
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install dependencies
|
||||
check_packages apt-transport-https curl ca-certificates lxc pigz iptables gnupg2 dirmngr
|
||||
|
||||
# Swap to legacy iptables for compatibility
|
||||
if type iptables-legacy > /dev/null 2>&1; then
|
||||
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
||||
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
|
||||
fi
|
||||
|
||||
# Install Docker / Moby CLI if not already installed
|
||||
architecture="$(dpkg --print-architecture)"
|
||||
if type docker > /dev/null 2>&1 && type dockerd > /dev/null 2>&1; then
|
||||
echo "Docker / Moby CLI and Engine already installed."
|
||||
else
|
||||
# Source /etc/os-release to get OS info
|
||||
. /etc/os-release
|
||||
if [ "${USE_MOBY}" = "true" ]; then
|
||||
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
|
||||
get_common_setting MICROSOFT_GPG_KEYS_URI
|
||||
curl -sSL ${MICROSOFT_GPG_KEYS_URI} | gpg --dearmor > /usr/share/keyrings/microsoft-archive-keyring.gpg
|
||||
echo "deb [arch=${architecture} signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] https://packages.microsoft.com/repos/microsoft-${ID}-${VERSION_CODENAME}-prod ${VERSION_CODENAME} main" > /etc/apt/sources.list.d/microsoft.list
|
||||
apt-get update
|
||||
apt-get -y install --no-install-recommends moby-cli moby-buildx moby-engine
|
||||
apt-get -y install --no-install-recommends moby-compose || echo "(*) Package moby-compose (Docker Compose v2) not available for ${VERSION_CODENAME} ${architecture}. Skipping."
|
||||
else
|
||||
# Import key safely (new 'signed-by' method rather than deprecated apt-key approach) and install
|
||||
curl -fsSL https://download.docker.com/linux/${ID}/gpg | gpg --dearmor > /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list
|
||||
apt-get update
|
||||
apt-get -y install --no-install-recommends docker-ce-cli docker-ce
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Finished installing docker / moby"
|
||||
|
||||
# Install Docker Compose if not already installed and is on a supported architecture
|
||||
if type docker-compose > /dev/null 2>&1; then
|
||||
echo "Docker Compose already installed."
|
||||
else
|
||||
target_compose_arch="${architecture}"
|
||||
if [ "${target_compose_arch}" != "x86_64" ]; then
|
||||
# Use pip to get a version that runns on this architecture
|
||||
if ! dpkg -s python3-minimal python3-pip libffi-dev python3-venv > /dev/null 2>&1; then
|
||||
apt_get_update_if_needed
|
||||
apt-get -y install python3-minimal python3-pip libffi-dev python3-venv
|
||||
fi
|
||||
export PIPX_HOME=/usr/local/pipx
|
||||
mkdir -p ${PIPX_HOME}
|
||||
export PIPX_BIN_DIR=/usr/local/bin
|
||||
export PYTHONUSERBASE=/tmp/pip-tmp
|
||||
export PIP_CACHE_DIR=/tmp/pip-tmp/cache
|
||||
pipx_bin=pipx
|
||||
if ! type pipx > /dev/null 2>&1; then
|
||||
pip3 install --disable-pip-version-check --no-warn-script-location --no-cache-dir --user pipx
|
||||
pipx_bin=/tmp/pip-tmp/bin/pipx
|
||||
fi
|
||||
${pipx_bin} install --system-site-packages --pip-args '--no-cache-dir --force-reinstall' docker-compose
|
||||
rm -rf /tmp/pip-tmp
|
||||
else
|
||||
latest_compose_version=$(basename "$(curl -fsSL -o /dev/null -w "%{url_effective}" https://github.com/docker/compose/releases/latest)")
|
||||
curl -fsSL "https://github.com/docker/compose/releases/download/${latest_compose_version}/docker-compose-$(uname -s)-${target_compose_arch}" -o /usr/local/bin/docker-compose
|
||||
chmod +x /usr/local/bin/docker-compose
|
||||
fi
|
||||
fi
|
||||
|
||||
# If init file already exists, exit
|
||||
if [ -f "/usr/local/share/docker-init.sh" ]; then
|
||||
echo "/usr/local/share/docker-init.sh already exists, so exiting."
|
||||
exit 0
|
||||
fi
|
||||
echo "docker-init doesnt exist..."
|
||||
|
||||
# Add user to the docker group
|
||||
if [ "${ENABLE_NONROOT_DOCKER}" = "true" ]; then
|
||||
if ! getent group docker > /dev/null 2>&1; then
|
||||
groupadd docker
|
||||
fi
|
||||
|
||||
usermod -aG docker ${USERNAME}
|
||||
fi
|
||||
|
||||
tee /usr/local/share/docker-init.sh > /dev/null \
|
||||
<< 'EOF'
|
||||
#!/usr/bin/env bash
|
||||
#-------------------------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
||||
#-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
sudoIf()
|
||||
{
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
sudo "$@"
|
||||
else
|
||||
"$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# explicitly remove dockerd and containerd PID file to ensure that it can start properly if it was stopped uncleanly
|
||||
# ie: docker kill <ID>
|
||||
sudoIf find /run /var/run -iname 'docker*.pid' -delete || :
|
||||
sudoIf find /run /var/run -iname 'container*.pid' -delete || :
|
||||
|
||||
set -e
|
||||
|
||||
## Dind wrapper script from docker team
|
||||
# Maintained: https://github.com/moby/moby/blob/master/hack/dind
|
||||
|
||||
export container=docker
|
||||
|
||||
if [ -d /sys/kernel/security ] && ! sudoIf mountpoint -q /sys/kernel/security; then
|
||||
sudoIf mount -t securityfs none /sys/kernel/security || {
|
||||
echo >&2 'Could not mount /sys/kernel/security.'
|
||||
echo >&2 'AppArmor detection and --privileged mode might break.'
|
||||
}
|
||||
fi
|
||||
|
||||
# Mount /tmp (conditionally)
|
||||
if ! sudoIf mountpoint -q /tmp; then
|
||||
sudoIf mount -t tmpfs none /tmp
|
||||
fi
|
||||
|
||||
# cgroup v2: enable nesting
|
||||
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
|
||||
# move the init process (PID 1) from the root group to the /init group,
|
||||
# otherwise writing subtree_control fails with EBUSY.
|
||||
sudoIf mkdir -p /sys/fs/cgroup/init
|
||||
sudoIf echo 1 > /sys/fs/cgroup/init/cgroup.procs
|
||||
# enable controllers
|
||||
sudoIf sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
|
||||
> /sys/fs/cgroup/cgroup.subtree_control
|
||||
fi
|
||||
## Dind wrapper over.
|
||||
|
||||
# Handle DNS
|
||||
set +e
|
||||
cat /etc/resolv.conf | grep -i 'internal.cloudapp.net'
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
echo "Setting dockerd Azure DNS."
|
||||
CUSTOMDNS="--dns 168.63.129.16"
|
||||
else
|
||||
echo "Not setting dockerd DNS manually."
|
||||
CUSTOMDNS=""
|
||||
fi
|
||||
set -e
|
||||
|
||||
# Start docker/moby engine
|
||||
( sudoIf dockerd $CUSTOMDNS > /tmp/dockerd.log 2>&1 ) &
|
||||
|
||||
set +e
|
||||
|
||||
# Execute whatever commands were passed in (if any). This allows us
|
||||
# to set this script to ENTRYPOINT while still executing the default CMD.
|
||||
exec "$@"
|
||||
EOF
|
||||
|
||||
chmod +x /usr/local/share/docker-init.sh
|
||||
chown ${USERNAME}:root /usr/local/share/docker-init.sh
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "azure-iot-edge",
|
||||
"version": "1.24.4",
|
||||
"version": "1.25.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
12
package.json
12
package.json
|
@ -2,7 +2,7 @@
|
|||
"name": "azure-iot-edge",
|
||||
"displayName": "Azure IoT Edge",
|
||||
"description": "This extension is now a part of Azure IoT Tools extension pack. We highly recommend installing Azure IoT Tools to get full capabilities for Azure IoT development. Develop, deploy, debug, and manage your IoT Edge solution.",
|
||||
"version": "1.24.4",
|
||||
"version": "1.25.0",
|
||||
"publisher": "vsciot-vscode",
|
||||
"aiKey": "95b20d64-f54f-4de3-8ad5-165a75a6c6fe",
|
||||
"icon": "logo.png",
|
||||
|
@ -48,6 +48,7 @@
|
|||
"onCommand:azure-iot-edge.setModuleCred",
|
||||
"onCommand:azure-iot-edge.setDefaultPlatform",
|
||||
"onCommand:azure-iot-edge.showGallery",
|
||||
"onCommand:azure-iot-edge.addDevContainer",
|
||||
"workspaceContains:**/deployment.template.json"
|
||||
],
|
||||
"main": "./dist/extension",
|
||||
|
@ -101,6 +102,10 @@
|
|||
{
|
||||
"when": "explorerResourceIsFolder && resourceFilename == modules",
|
||||
"command": "azure-iot-edge.addModule"
|
||||
},
|
||||
{
|
||||
"when": "explorerResourceIsFolder",
|
||||
"command": "azure-iot-edge.addDevContainer"
|
||||
}
|
||||
],
|
||||
"view/item/context": [
|
||||
|
@ -191,6 +196,11 @@
|
|||
"command": "azure-iot-edge.showGallery",
|
||||
"title": "Show Sample Gallery",
|
||||
"category": "Azure IoT Edge"
|
||||
},
|
||||
{
|
||||
"command": "azure-iot-edge.addDevContainer",
|
||||
"title": "Add Dev Container definition files",
|
||||
"category": "Azure IoT Edge"
|
||||
}
|
||||
],
|
||||
"configuration": {
|
||||
|
|
|
@ -33,6 +33,23 @@ export class Constants {
|
|||
public static versionPlaceholderPattern: RegExp = new RegExp(/\${VERSION\..+}/g);
|
||||
public static assetsFolder = "assets";
|
||||
public static solutionFolder = "solution";
|
||||
public static containersFolder = "containers";
|
||||
public static libraryScriptsFolder = "library-scripts";
|
||||
public static dotDevContainer = ".devcontainer";
|
||||
public static CONTAINER_C = "Cpp";
|
||||
public static CONTAINER_CSHARP = "CSharp";
|
||||
public static CONTAINER_JAVA = "Java";
|
||||
public static CONTAINER_NODE = "Node";
|
||||
public static CONTAINER_PYTHON = "Python";
|
||||
public static CONTAINER_C_DESCRIPTION = "Use C/C++ Dev Container";
|
||||
public static CONTAINER_CSHARP_DESCRIPTION = "Use C# .Net Dev Container";
|
||||
public static CONTAINER_JAVA_DESCRIPTION = "Use Java Dev Container";
|
||||
public static CONTAINER_NODE_DESCRIPTION = "Use Node.js Dev Container";
|
||||
public static CONTAINER_PYTHON_DESCRIPTION = "Use Python Dev Container";
|
||||
public static CHOICE_REPLACE = "Replace";
|
||||
public static CHOICE_REPLACE_DECRIPTION = "Replace existing Dev Container definitions";
|
||||
public static CHOICE_KEEP = "Keep";
|
||||
public static CHOICE_KEEP_DECRIPTION = "Keep existing Dev Container definitions";
|
||||
public static LANGUAGE_CSHARP = "C# Module";
|
||||
public static LANGUAGE_NODE = "Node.js Module";
|
||||
public static LANGUAGE_PYTHON = "Python Module";
|
||||
|
@ -98,6 +115,7 @@ export class Constants {
|
|||
public static imagePattern = `${Constants.registryPlaceholder}/${Constants.repoNamePlaceholder}:${Constants.tagPlaceholder}`;
|
||||
public static imagePrompt = "Provide Docker Image for the Module";
|
||||
public static selectTemplate = "Select Module Template";
|
||||
public static selectDevContainer = "Select Dev Container Type";
|
||||
public static parentFolderLabel = "Select Folder";
|
||||
public static moduleManifest = "module.json";
|
||||
public static outputConfig = "config";
|
||||
|
@ -110,6 +128,7 @@ export class Constants {
|
|||
public static generateDeploymentEvent = "generateDeployment";
|
||||
public static addModuleEvent = "addModule";
|
||||
public static selectEdgeRuntimeVerEvent = "selectEdgeVer";
|
||||
public static selectDevContainerEvent = "selectDevContainer";
|
||||
public static launchCSharp = "launch_csharp.json";
|
||||
public static launchNode = "launch_node.json";
|
||||
public static launchC = "launch_c.json";
|
||||
|
@ -220,6 +239,9 @@ export class Constants {
|
|||
public static noWorkspaceSetDefaultPlatformMsg = "No workspace is opened for setting default platform. Please open a workspace and try again.";
|
||||
public static noWorkspaceMsg = "This extension only works when folders are opened.";
|
||||
|
||||
public static canOnlyUseWithEdgeSolution = "This option is only available when an Azure IoT EdgeSolution is open.";
|
||||
public static containerDefinitionIsPresent = "This solution currently uses a Dev Container";
|
||||
|
||||
public static openSampleEvent = "openSample";
|
||||
public static openSampleUrlEvent = "openSampleUrl";
|
||||
|
||||
|
|
|
@ -295,6 +295,7 @@ export class EdgeManager {
|
|||
await this.writeRegistryCredEnv(address, envFilePath, usernameEnv, passwordEnv, debugTemplateEnv.usernameEnv, debugTemplateEnv.passwordEnv);
|
||||
|
||||
if (isNewSolution) {
|
||||
await this.generateDevContainerDirectory(template, slnPath);
|
||||
await vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(slnPath), false);
|
||||
}
|
||||
}
|
||||
|
@ -304,6 +305,43 @@ export class EdgeManager {
|
|||
await saManager.checkAndUpdateASAJob(templateFile, moduleName);
|
||||
}
|
||||
|
||||
public async addDevContainerDefinition() {
|
||||
if (!Utility.checkWorkspace(Constants.canOnlyUseWithEdgeSolution)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const workspaceFolders = vscode.workspace.workspaceFolders;
|
||||
const defaultFolder: vscode.Uri | undefined = workspaceFolders && workspaceFolders.length > 0 ? workspaceFolders[0].uri : undefined;
|
||||
const workspaceFolder = defaultFolder.fsPath;
|
||||
const dotDevContainer = path.join(workspaceFolder, Constants.dotDevContainer);
|
||||
if (await fse.pathExists(dotDevContainer)) {
|
||||
const templatePicks: vscode.QuickPickItem[] = [
|
||||
{
|
||||
label: Constants.CHOICE_REPLACE,
|
||||
description: Constants.CHOICE_REPLACE_DECRIPTION,
|
||||
},
|
||||
{
|
||||
label: Constants.CHOICE_KEEP,
|
||||
description: Constants.CHOICE_KEEP_DECRIPTION,
|
||||
},
|
||||
];
|
||||
const doYouWishToOverride = await vscode.window.showQuickPick(templatePicks, { placeHolder: Constants.containerDefinitionIsPresent, ignoreFocusOut: true });
|
||||
if (!doYouWishToOverride) {
|
||||
throw new UserCancelledError();
|
||||
}
|
||||
|
||||
if (doYouWishToOverride.label === Constants.CHOICE_KEEP) {
|
||||
throw new UserCancelledError();
|
||||
}
|
||||
}
|
||||
|
||||
const selection = await this.selectDevContainerKind();
|
||||
if (selection) {
|
||||
await this.generateDevContainerDirectory(selection, workspaceFolder);
|
||||
await vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(workspaceFolder), false);
|
||||
}
|
||||
}
|
||||
|
||||
private async generateDebugCreateOptions(moduleName: string, template: string): Promise<{ debugImageName: string, debugCreateOptions: any }> {
|
||||
let debugCreateOptions = {};
|
||||
switch (template) {
|
||||
|
@ -916,4 +954,75 @@ export class EdgeManager {
|
|||
const templates = this.get3rdPartyModuleTemplates();
|
||||
return templates ? templates.find((template) => template.name === name) : undefined;
|
||||
}
|
||||
|
||||
private async generateDevContainerDirectory(template: string, slnPath: string) {
|
||||
const sourceContainersPath = this.context.asAbsolutePath(path.join(Constants.assetsFolder, Constants.containersFolder));
|
||||
const sourceLibrayScriptsPath = this.context.asAbsolutePath(path.join(Constants.assetsFolder, Constants.libraryScriptsFolder));
|
||||
let containerSource = "";
|
||||
switch (template) {
|
||||
// we get here from two different paths:
|
||||
// 1- when creating a new edge solution and the first add module is called
|
||||
// 2- when working with an existing solution and the use wishes to use a dev container
|
||||
case Constants.LANGUAGE_C:
|
||||
case Constants.CONTAINER_C:
|
||||
containerSource = path.join(sourceContainersPath, Constants.CONTAINER_C);
|
||||
break;
|
||||
case Constants.LANGUAGE_CSHARP:
|
||||
case Constants.CONTAINER_CSHARP:
|
||||
containerSource = path.join(sourceContainersPath, Constants.CONTAINER_CSHARP);
|
||||
break;
|
||||
case Constants.LANGUAGE_JAVA:
|
||||
case Constants.CONTAINER_JAVA:
|
||||
containerSource = path.join(sourceContainersPath, Constants.CONTAINER_JAVA);
|
||||
break;
|
||||
case Constants.LANGUAGE_NODE:
|
||||
case Constants.CONTAINER_NODE:
|
||||
containerSource = path.join(sourceContainersPath, Constants.CONTAINER_NODE);
|
||||
break;
|
||||
case Constants.LANGUAGE_PYTHON:
|
||||
case Constants.CONTAINER_PYTHON:
|
||||
containerSource = path.join(sourceContainersPath, Constants.CONTAINER_PYTHON);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Language '" + template + "' is not supported.");
|
||||
}
|
||||
await fse.copy(containerSource, slnPath, { overwrite : true });
|
||||
await fse.copy(sourceLibrayScriptsPath, path.join(slnPath, Constants.dotDevContainer, Constants.libraryScriptsFolder));
|
||||
}
|
||||
|
||||
private async selectDevContainerKind(label?: string, isNewSolution: boolean = false): Promise<string> {
|
||||
const templatePicks: vscode.QuickPickItem[] = [
|
||||
{
|
||||
label: Constants.CONTAINER_C,
|
||||
description: Constants.CONTAINER_C_DESCRIPTION,
|
||||
},
|
||||
{
|
||||
label: Constants.CONTAINER_CSHARP,
|
||||
description: Constants.CONTAINER_CSHARP_DESCRIPTION,
|
||||
},
|
||||
{
|
||||
label: Constants.CONTAINER_JAVA,
|
||||
description: Constants.CONTAINER_JAVA_DESCRIPTION,
|
||||
},
|
||||
{
|
||||
label: Constants.CONTAINER_NODE,
|
||||
description: Constants.CONTAINER_NODE_DESCRIPTION,
|
||||
},
|
||||
{
|
||||
label: Constants.CONTAINER_PYTHON,
|
||||
description: Constants.CONTAINER_PYTHON_DESCRIPTION,
|
||||
},
|
||||
];
|
||||
if (label === undefined) {
|
||||
label = Constants.selectDevContainer;
|
||||
}
|
||||
const templatePick = await vscode.window.showQuickPick(templatePicks, { placeHolder: label, ignoreFocusOut: true });
|
||||
if (!templatePick) {
|
||||
throw new UserCancelledError();
|
||||
}
|
||||
TelemetryClient.sendEvent(`${Constants.selectDevContainerEvent}.selectDevContainer`, {
|
||||
template: templatePick.label,
|
||||
});
|
||||
return templatePick.label;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,6 +190,12 @@ export function activate(context: vscode.ExtensionContext) {
|
|||
return gallery.loadWebView();
|
||||
});
|
||||
|
||||
initCommandAsync(context, outputChannel,
|
||||
"azure-iot-edge.addDevContainer",
|
||||
async (): Promise<void> => {
|
||||
return edgeManager.addDevContainerDefinition();
|
||||
});
|
||||
|
||||
initCommandAsync(context, outputChannel,
|
||||
"azure-iot-edge.initializeSample",
|
||||
async (name: string, url: string, platform: string): Promise<void> => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче