From 16fa7309c41109c4f54c8687f5de9369e6aece6b Mon Sep 17 00:00:00 2001 From: Mitch Denny Date: Mon, 19 Oct 2020 13:46:18 +1100 Subject: [PATCH] Add back updated Codespaces configuration. --- .devcontainer/Dockerfile | 75 ++------ .devcontainer/devcontainer.json | 76 ++++---- .../library-scripts/docker-debian.sh | 172 ++++++++++++++++++ .../library-scripts/git-lfs-debian.sh | 34 ++++ 4 files changed, 259 insertions(+), 98 deletions(-) create mode 100644 .devcontainer/library-scripts/docker-debian.sh create mode 100644 .devcontainer/library-scripts/git-lfs-debian.sh diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index fd7040be36db9..9628a309e345f 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,64 +1,21 @@ -#------------------------------------------------------------------------------------------------------------- -# Copyright (c) Microsoft Corporation. All rights reserved. -# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. -#------------------------------------------------------------------------------------------------------------- -ARG VARIANT="3.1-bionic" -FROM mcr.microsoft.com/dotnet/core/sdk:${VARIANT} +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.145.0/containers/codespaces-linux/.devcontainer/base.Dockerfile -# This Dockerfile adds a non-root user with sudo access. Use the "remoteUser" -# property in devcontainer.json to use it. On Linux, the container user's GID/UIDs -# will be updated to match your local UID/GID (when using the dockerFile property). -# See https://aka.ms/vscode-remote/containers/non-root-user for details. -ARG USERNAME=vscode -ARG USER_UID=1000 -ARG USER_GID=$USER_UID +FROM mcr.microsoft.com/vscode/devcontainers/universal:0-linux -# Options for common package install script -ARG INSTALL_ZSH="true" -ARG UPGRADE_PACKAGES="true" -ARG COMMON_SCRIPT_SOURCE="https://raw.githubusercontent.com/microsoft/vscode-dev-containers/v0.128.0/script-library/common-debian.sh" -ARG COMMON_SCRIPT_SHA="a6bfacc5c9c6c3706adc8788bf70182729767955b7a5509598ac205ce6847e1e" +USER root -# [Optional] Settings for installing Node.js. -ARG INSTALL_NODE="true" -ARG NODE_SCRIPT_SOURCE="https://raw.githubusercontent.com/microsoft/vscode-dev-containers/master/script-library/node-debian.sh" -ARG NODE_SCRIPT_SHA="dev-mode" -ARG NODE_VERSION="lts/*" -ENV NVM_DIR=/usr/local/share/nvm -# Have nvm create a "current" symlink and add to path to work around https://github.com/microsoft/vscode-remote-release/issues/3224 -ENV NVM_SYMLINK_CURRENT=true -ENV PATH=${NVM_DIR}/current/bin:${PATH} +# [Option] Install Docker CLI +ARG INSTALL_DOCKER="false" +COPY library-scripts/docker-debian.sh /tmp/library-scripts/ +RUN if [ "${INSTALL_DOCKER}" = "true" ]; then \ + rm -f /usr/local/share/docker-init.sh \ + && bash /tmp/library-scripts/docker-debian.sh "true" "/var/run/docker-host.sock" "/var/run/docker.sock" "codespace"; \ + fi \ + && rm -rf /var/lib/apt/lists/* /tmp/library-scripts/ -# [Optional] Install the Azure CLI -ARG INSTALL_AZURE_CLI="false" +USER codespace + +# ** [Optional] Uncomment this section to install additional packages. ** +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends -# Configure apt and install packages -RUN apt-get update \ - && export DEBIAN_FRONTEND=noninteractive \ - # - # Verify git, common tools / libs installed, add/modify non-root user, optionally install zsh - && apt-get -y install --no-install-recommends curl ca-certificates 2>&1 \ - && curl -sSL ${COMMON_SCRIPT_SOURCE} -o /tmp/common-setup.sh \ - && ([ "${COMMON_SCRIPT_SHA}" = "dev-mode" ] || (echo "${COMMON_SCRIPT_SHA} */tmp/common-setup.sh" | sha256sum -c -)) \ - && /bin/bash /tmp/common-setup.sh "${INSTALL_ZSH}" "${USERNAME}" "${USER_UID}" "${USER_GID}" "${UPGRADE_PACKAGES}" \ - # - # [Optional] Install Node.js for ASP.NET Core Web Applications - && if [ "$INSTALL_NODE" = "true" ]; then \ - curl -sSL ${NODE_SCRIPT_SOURCE} -o /tmp/node-setup.sh \ - && ([ "${NODE_SCRIPT_SHA}" = "dev-mode" ] || (echo "${COMMON_SCRIPT_SHA} */tmp/node-setup.sh" | sha256sum -c -)) \ - && /bin/bash /tmp/node-setup.sh "${NVM_DIR}" "${NODE_VERSION}" "${USERNAME}"; \ - fi \ - # - # [Optional] Install the Azure CLI - && if [ "$INSTALL_AZURE_CLI" = "true" ]; then \ - echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $(lsb_release -cs) main" > /etc/apt/sources.list.d/azure-cli.list \ - && curl -sL https://packages.microsoft.com/keys/microsoft.asc | apt-key add - 2>/dev/null \ - && apt-get update \ - && apt-get install -y azure-cli; \ - fi \ - # - # Clean up - && apt-get autoremove -y \ - && apt-get clean -y \ - && rm -f /tmp/common-setup.sh /tmp/node-setup.sh \ - && rm -rf /var/lib/apt/lists/* diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c495b9223952a..80712a781c15d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,54 +1,52 @@ -// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.128.0/containers/dotnetcore { - "name": "Azure SDK for .NET", + "name": "GitHub Codespaces (Default)", "build": { "dockerfile": "Dockerfile", - "args": { - // Update 'VARIANT' to pick a .NET Core version. Rebuild the container if - // it already exists to update. Example variants: 2.1-bionic, 3.1-bionic - "VARIANT": "3.1-bionic", - // Options - "INSTALL_NODE": "true", - "NODE_VERSION": "lts/*", - "INSTALL_AZURE_CLI": "true", - "UPGRADE_PACKAGES": "false" + "args": { + "INSTALL_DOCKER": "true" } }, - - // Set *default* container specific settings.json values on container create. "settings": { - "terminal.integrated.shell.linux": "/bin/bash" + "terminal.integrated.shell.linux": "/bin/bash", + "go.useGoProxyToCheckForToolUpdates": false, + "go.useLanguageServer": true, + "go.gopath": "/go", + "go.goroot": "/usr/local/go", + "go.toolsGopath": "/go/bin", + "python.pythonPath": "/opt/python/latest/bin/python", + "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", + "lldb.executable": "/usr/bin/lldb", + "files.watcherExclude": { + "**/target/**": true + } }, + "remoteUser": "codespace", + "overrideCommand": false, + "workspaceMount": "source=${localWorkspaceFolder},target=/home/codespace/workspace,type=bind,consistency=cached", + "workspaceFolder": "/home/codespace/workspace", + "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker-host.sock,type=bind" ], + "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ], // Add the IDs of extensions you want installed when the container is created. "extensions": [ - "ms-dotnettools.csharp" - ], + "GitHub.vscode-pull-request-github", + "MS-vsliveshare.vsliveshare", + "VisualStudioExptTeam.vscodeintellicode" + ] // 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, first 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" - // - // Next, after running the command above, uncomment lines in the 'mounts' and 'remoteEnv' lines below, - // and open / rebuild the container so the settings take effect. - // - "mounts": [ - // "source=${env:HOME}${env:USERPROFILE}/.aspnet/https,target=/home/vscode/.aspnet/https,type=bind" - ], - "remoteEnv": { - // "ASPNETCORE_Kestrel__Certificates__Default__Password": "SecurePwdGoesHere", - // "ASPNETCORE_Kestrel__Certificates__Default__Path": "/home/vscode/.aspnet/https/aspnetapp.pfx", - } + // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. - // "postCreateCommand": "dotnet restore", - - // Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. - // "remoteUser": "vscode" + // "postCreateCommand": "uname -a" } diff --git a/.devcontainer/library-scripts/docker-debian.sh b/.devcontainer/library-scripts/docker-debian.sh new file mode 100644 index 0000000000000..42ee7d6cd3826 --- /dev/null +++ b/.devcontainer/library-scripts/docker-debian.sh @@ -0,0 +1,172 @@ +#!/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/master/script-library/docs/docker.md +# +# Syntax: ./docker-debian.sh [enable non-root docker socket access flag] [source socket] [target socket] [non-root user] + +ENABLE_NONROOT_DOCKER=${1:-"true"} +SOURCE_SOCKET=${2:-"/var/run/docker-host.sock"} +TARGET_SOCKET=${3:-"/var/run/docker.sock"} +USERNAME=${4:-"automatic"} + +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 + +# 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 +} + +# Ensure apt is in non-interactive to avoid prompts +export DEBIAN_FRONTEND=noninteractive + +# Install apt-transport-https, curl, lsb-release, gpg if missing +if ! dpkg -s apt-transport-https curl ca-certificates lsb-release > /dev/null 2>&1 || ! type gpg > /dev/null 2>&1; then + apt-get-update-if-needed + apt-get -y install --no-install-recommends apt-transport-https curl ca-certificates lsb-release gnupg2 +fi + +# Install Docker CLI if not already installed +if type docker > /dev/null 2>&1; then + echo "Docker CLI already installed." +else + curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | (OUT=$(apt-key add - 2>&1) || echo $OUT) + echo "deb [arch=amd64] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list + apt-get update + apt-get -y install --no-install-recommends docker-ce-cli +fi + +# Install Docker Compose if not already installed +if type docker-compose > /dev/null 2>&1; then + echo "Docker Compose already installed." +else + + LATEST_COMPOSE_VERSION=$(curl -sSL "https://api.github.com/repos/docker/compose/releases/latest" | grep -o -P '(?<="tag_name": ").+(?=")') + curl -sSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + chmod +x /usr/local/bin/docker-compose +fi + +# If init file already exists, exit +if [ -f "/usr/local/share/docker-init.sh" ]; then + exit 0 +fi + +# By default, make the source and target sockets the same +if [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ]; then + touch "${SOURCE_SOCKET}" + ln -s "${SOURCE_SOCKET}" "${TARGET_SOCKET}" +fi + +# Add a stub if not adding non-root user access, user is root +if [ "${ENABLE_NONROOT_DOCKER}" = "false" ] || [ "${USERNAME}" = "root" ]; then + echo '/usr/bin/env bash -c "\$@"' > /usr/local/share/docker-init.sh + chmod +x /usr/local/share/docker-init.sh + exit 0 +fi + +# If enabling non-root access and specified user is found, setup socat and add script +chown -h "${USERNAME}":root "${TARGET_SOCKET}" +if ! dpkg -s socat > /dev/null 2>&1; then + apt-get-update-if-needed + apt-get -y install socat +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. +#------------------------------------------------------------------------------------------------------------- + +set -e + +SOCAT_PATH_BASE=/tmp/vscr-dind-socat +SOCAT_LOG=\${SOCAT_PATH_BASE}.log +SOCAT_PID=\${SOCAT_PATH_BASE}.pid + +# Wrapper function to only use sudo if not already root +sudoIf() +{ + if [ "\$(id -u)" -ne 0 ]; then + sudo "\$@" + else + "\$@" + fi +} + +# Log messages +log() +{ + echo -e "[\$(date)] \$@" | sudoIf tee -a \${SOCAT_LOG} > /dev/null +} + +echo -e "\n** \$(date) **" | sudoIf tee -a \${SOCAT_LOG} > /dev/null +log "Ensuring ${USERNAME} has access to ${SOURCE_SOCKET} via ${TARGET_SOCKET}" + +# If enabled, try to add a docker group with the right GID. If the group is root, +# fall back on using socat to forward the docker socket to another unix socket so +# that we can set permissions on it without affecting the host. +if [ "${ENABLE_NONROOT_DOCKER}" = "true" ] && [ "${SOURCE_SOCKET}" != "${TARGET_SOCKET}" ] && [ "${USERNAME}" != "root" ] && [ "${USERNAME}" != "0" ]; then + SOCKET_GID=\$(stat -c '%g' ${SOURCE_SOCKET}) + if [ "\${SOCKET_GID}" != "0" ]; then + log "Adding user to group with GID \${SOCKET_GID}." + if [ "\$(cat /etc/group | grep :\${SOCKET_GID}:)" = "" ]; then + sudoIf groupadd --gid \${SOCKET_GID} docker-host + fi + # Add user to group if not already in it + if [ "\$(id ${USERNAME} | grep -E 'groups=.+\${SOCKET_GID}\(')" = "" ]; then + sudoIf usermod -aG \${SOCKET_GID} ${USERNAME} + fi + else + # Enable proxy if not already running + if [ ! -f "\${SOCAT_PID}" ] || ! ps -p \$(cat \${SOCAT_PID}) > /dev/null; then + log "Enabling socket proxy." + log "Proxying ${SOURCE_SOCKET} to ${TARGET_SOCKET} for vscode" + sudoIf rm -rf ${TARGET_SOCKET} + (sudoIf socat UNIX-LISTEN:${TARGET_SOCKET},fork,mode=660,user=${USERNAME} UNIX-CONNECT:${SOURCE_SOCKET} 2>&1 | sudoIf tee -a \${SOCAT_LOG} > /dev/null & echo "\$!" | sudoIf tee \${SOCAT_PID} > /dev/null) + else + log "Socket proxy already running." + fi + fi + log "Success" +fi + +# Execute whatever commands were passed in (if any). This allows us +# to set this script to ENTRYPOINT while still executing the default CMD. +set +e +exec "\$@" +EOF +chmod +x /usr/local/share/docker-init.sh +chown ${USERNAME}:root /usr/local/share/docker-init.sh +echo "Done!" \ No newline at end of file diff --git a/.devcontainer/library-scripts/git-lfs-debian.sh b/.devcontainer/library-scripts/git-lfs-debian.sh new file mode 100644 index 0000000000000..1f5647475aaa7 --- /dev/null +++ b/.devcontainer/library-scripts/git-lfs-debian.sh @@ -0,0 +1,34 @@ +#!/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/master/script-library/docs/git-lfs.md +# +# Syntax: ./git-lfs-debian.sh + +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 + +export DEBIAN_FRONTEND=noninteractive + +# Install git and curl if missing +if ! dpkg -s git curl ca-certificates > /dev/null 2>&1; then + if [ ! -d "/var/lib/apt/lists" ] || [ "$(ls /var/lib/apt/lists/ | wc -l)" = "0" ]; then + apt-get update + fi + apt-get -y install --no-install-recommends git curl ca-certificates +fi + +# Install Git LFS +echo "Downloading Git LFS..." +curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | bash +echo "Installing Git LFS..." +apt-get install -yq git-lfs +git lfs install +echo "Done!" \ No newline at end of file