From 6ab27c4d8cbe77aca7ddde706c69ec59fd6255e0 Mon Sep 17 00:00:00 2001 From: Chuck Lantz Date: Mon, 1 Jun 2020 20:46:08 -0700 Subject: [PATCH] Development container for VS Code --- .devcontainer/Dockerfile | 117 ++++++++++++++++++++++++ .devcontainer/README.md | 80 ++++++++++++++++ .devcontainer/bin/init-dev-container.sh | 90 ++++++++++++++++++ .devcontainer/bin/set-resolution | 25 +++++ .devcontainer/devcontainer.json | 41 +++++++++ .devcontainer/fluxbox/apps | 9 ++ .devcontainer/fluxbox/init | 9 ++ .devcontainer/fluxbox/menu | 16 ++++ .vscode/launch.json | 26 ++++-- README.md | 4 + 10 files changed, 411 insertions(+), 6 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/README.md create mode 100644 .devcontainer/bin/init-dev-container.sh create mode 100644 .devcontainer/bin/set-resolution create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/fluxbox/apps create mode 100644 .devcontainer/fluxbox/init create mode 100644 .devcontainer/fluxbox/menu diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000000..002da59ac5e --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,117 @@ +#------------------------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information. +#------------------------------------------------------------------------------------------------------------- + +FROM mcr.microsoft.com/vscode/devcontainers/typescript-node:0-10 + +ARG TARGET_DISPLAY=":1" + +# VNC options +ARG MAX_VNC_RESOLUTION=1920x1080x16 +ARG TARGET_VNC_RESOLUTION=1920x1080 +ARG TARGET_VNC_DPI=72 +ARG TARGET_VNC_PORT=5901 + +# noVNC (VNC web client) options +ARG INSTALL_NOVNC="true" +ARG NOVNC_VERSION=1.1.0 +ARG TARGET_NOVNC_PORT=6080 +ARG WEBSOCKETIFY_VERSION=0.9.0 + +# Firefox is useful for testing things like browser launch events, but optional +ARG INSTALL_FIREFOX="false" + +# Expected non-root username from base image +ARG USERNAME=node + +# Core environment variables for X11, VNC, and fluxbox +ENV DBUS_SESSION_BUS_ADDRESS="autolaunch:" \ + MAX_VNC_RESOLUTION="${MAX_VNC_RESOLUTION}" \ + VNC_RESOLUTION="${TARGET_VNC_RESOLUTION}" \ + VNC_DPI="${TARGET_VNC_DPI}" \ + VNC_PORT="${TARGET_VNC_PORT}" \ + NOVNC_PORT="${TARGET_NOVNC_PORT}" \ + DISPLAY="${TARGET_DISPLAY}" \ + LANG="en_US.UTF-8" \ + LANGUAGE="en_US.UTF-8" \ + VISUAL="nano" \ + EDITOR="nano" + +COPY bin/init-dev-container.sh /usr/local/share/ +COPY bin/set-resolution /usr/local/bin/ +COPY fluxbox/* /root/.fluxbox/ +COPY fluxbox/* /home/${USERNAME}/.fluxbox/ + +# Configure apt and install packages +RUN apt-get update \ + && export DEBIAN_FRONTEND=noninteractive \ + # + # Install the Cascadia Code fonts - https://github.com/microsoft/cascadia-code + && curl -sSL https://github.com/microsoft/cascadia-code/releases/download/v2004.30/CascadiaCode_2004.30.zip -o /tmp/cascadia-fonts.zip \ + && unzip /tmp/cascadia-fonts.zip -d /tmp/cascadia-fonts \ + && mkdir -p /usr/share/fonts/truetype/cascadia \ + && mv /tmp/cascadia-fonts/ttf/* /usr/share/fonts/truetype/cascadia/ \ + && rm -rf /tmp/cascadia-fonts.zip /tmp/cascadia-fonts \ + # + # Install X11, fluxbox and VS Code dependencies + && apt-get -y install --no-install-recommends \ + xvfb \ + x11vnc \ + fluxbox \ + dbus-x11 \ + x11-utils \ + x11-xserver-utils \ + xdg-utils \ + fbautostart \ + xterm \ + eterm \ + gnome-terminal \ + gnome-keyring \ + seahorse \ + nautilus \ + libx11-dev \ + libxkbfile-dev \ + libsecret-1-dev \ + libnotify4 \ + libnss3 \ + libxss1 \ + libasound2 \ + xfonts-base \ + xfonts-terminus \ + fonts-noto \ + fonts-wqy-microhei \ + fonts-droid-fallback \ + vim-tiny \ + nano \ + && mkdir -p /var/run/dbus \ + && touch /root/.Xmodmap /home/${USERNAME}/.Xmodmap \ + && chown -R ${USERNAME}:${USERNAME} /home/${USERNAME}/.Xmodmap /home/${USERNAME}/.fluxbox \ + && chmod +x /usr/local/share/init-dev-container.sh /usr/local/bin/set-resolution \ + # + # [Optional] Install noVNC + && if [ "${INSTALL_NOVNC}" = "true" ]; then \ + mkdir -p /usr/local/novnc \ + && curl -sSL https://github.com/novnc/noVNC/archive/v${NOVNC_VERSION}.zip -o /tmp/novnc-install.zip \ + && unzip /tmp/novnc-install.zip -d /usr/local/novnc \ + && cp /usr/local/novnc/noVNC-${NOVNC_VERSION}/vnc_lite.html /usr/local/novnc/noVNC-${NOVNC_VERSION}/index.html \ + && rm /tmp/novnc-install.zip \ + && curl -sSL https://github.com/novnc/websockify/archive/v${WEBSOCKETIFY_VERSION}.zip -o /tmp/websockify-install.zip \ + && unzip /tmp/websockify-install.zip -d /usr/local/novnc \ + && apt-get -y install --no-install-recommends python-numpy \ + && ln -s /usr/local/novnc/websockify-${WEBSOCKETIFY_VERSION} /usr/local/novnc/noVNC-${NOVNC_VERSION}/utils/websockify \ + && rm /tmp/websockify-install.zip; \ + fi \ + # + # [Optional] Install Firefox + && if [ "${INSTALL_FIREFOX}" = "true" ]; then \ + apt-get -y install --no-install-recommends firefox-esr; \ + fi \ + # + # Clean up + && apt-get autoremove -y \ + && apt-get clean -y \ + && rm -rf /var/lib/apt/lists/* + +ENTRYPOINT ["/usr/local/share/init-dev-container.sh"] +CMD ["sleep", "infinity"] diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 00000000000..1823baf1c4f --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,80 @@ +# Code - OSS Development Container + +This repository includes configuration for a development container for working with Code - OSS in an isolated local container or using [Visual Studio Codespaces](https://aka.ms/vso). + +## Quick start - local + +1. Install Docker Desktop or Docker on your local machine. (See [docs](https://aka.ms/vscode-remote/containers/getting-started) for additional details.) + +2. [Docker Desktop] If you are not using the new WSL2 Docker Desktop engine, increase the resources allocated to Docker Desktop to at least **4 Cores and 4 GB of RAM (8 GB recommended)**. Right-click on the Docker status bar item, go to **Preferences/Settings > Resources > Advanced** to do so. + +3. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Remote - Containers](https://aka.ms/vscode-remote/download/containers) extension. + + ![Image of Remote - Containers extension](https://microsoft.github.io/vscode-remote-release/images/remote-containers-extn.png) + + > Note that the Remote - Containers extension requires the Visual Studio Code distribution of Code - OSS. See the [FAQ](https://aka.ms/vscode-remote/faq/license) for details. + +4. Press Ctrl/Cmd + Shift + P and select **Remote - Containers: Open Repository in Container...**. + + > Tip: While you can use your local source tree from the container, operations like `yarn install` can be slow on macOS or using the Hyper-V engine on Windows. We recommend this approach instead since it uses "named volume" rather than the local filesystem. + +5. Type `https://github.com/microsoft/vscode` (or a branch or PR URL) in the input box and press Enter. + +6. After the container is running, open a web browser and go to [http://localhost:6080](http://localhost:6080). + +Anything you start in VS Code or the integrated terminal will appear here. + +This container uses the [Fluxbox desktop](http://fluxbox.org/) to keep things lean. **Right-click on the desktop** to see menu options. It works with GNOME and GTK applications, so other tools can be installed if needed. + +You can also set the resolution of the desktop from the command line by typing `set-resolution`. + +## Quick start - Codespaces + +Note that the Codspaces browser-based editor cannot currently access the desktop environment in this containe (due to a [missing feature](https://github.com/MicrosoftDocs/vsonline/issues/117)). We recommend using Visual Studio Code from the desktop to connect instead in the near term. + +1. Install [Visual Studio Code Stable](https://code.visualstudio.com/) or [Insiders](https://code.visualstudio.com/insiders/) and the [Visual Studio Codespaces](https://aka.ms/vscs-ext-vscode) extension. + + ![Image of VS Codespaces extension](https://microsoft.github.io/vscode-remote-release/images/codespaces-extn.png) + + > Note that the Visual Studio Codespaces extension requires the Visual Studio Code distribution of Code - OSS. + +2. Sign in by pressing Ctrl/Cmd + Shift + P and selecting **Codespaces: Sign In**. You may also need to use the **Codespaces: Create Plan** if you do not have a plan. See the [Codespaces docs](https://aka.ms/vso-docs/vscode) for details. + +3. Press Ctrl/Cmd + Shift + P and select **Codespaes: Create New Codespace**. + +4. Use default settings, select a plan, and then enter the repository URL `https://github.com/microsoft/vscode` (or a branch or PR URL) in the input box when prompted. + +5. After the Codespace is running, open a web browser and go to [http://localhost:6080](http://localhost:6080). + +6. Anything you start in VS Code or the integrated terminal will appear here. + +This container uses the [Fluxbox desktop](http://fluxbox.org/) to keep things lean. **Right-click on the desktop** to see menu options. It works with GNOME and GTK applications, so other tools can be installed if needed. + +You can also set the resolution of the desktop from the command line by typing `set-resolution`. + +## Try it! + +Follow these steps: + +1. In your local VS Code, open a terminal (Ctrl/Cmd + Shift + \`) and type the following commands: + + ```bash + yarn install + scripts/code.sh + ``` + +2. After the build is complete, use a local browser to open [http://localhost:6080](http://localhost:6080) or use a VNC client to connect to localhost:5901. + +3. You should now see Code - OSS! + +Next, let's try debugging. + +1. Shut down Code - OSS by clicking the box in the upper right corner using your browser or VNC client. + +2. Go to your local VS Code client, and use Run / Debug view to launch the **VS Code** configuration. (Typically the default, so you can likely just press F5). + + > **Note:** If launching times out, you can increase the value of `timeout` in the VS Code, Attach Main Process, Attach Extension Host, and Attach to Shared Process configurations. + +3. After a bit, Code - OSS will appear with the debugger attached! + +Enjoy! diff --git a/.devcontainer/bin/init-dev-container.sh b/.devcontainer/bin/init-dev-container.sh new file mode 100644 index 00000000000..43acc5fe543 --- /dev/null +++ b/.devcontainer/bin/init-dev-container.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +NONROOT_USER=node +LOG=/tmp/container-init.log + +# Execute the command it not already running +startInBackgroundIfNotRunning() +{ + log "Starting $1." + echo -e "\n** $(date) **" | sudoIf tee -a /tmp/$1.log > /dev/null + if [ ! -f "/tmp/$1.pid" ] || ! ps -p $(cat /tmp/$1.pid) > /dev/null; then + ($2 sh -c "while :; do echo [\$(date)] Process started.; $3; echo [\$(date)] Process exited!; sleep 5; done 2>&1" | sudoIf tee -a /tmp/$1.log > /dev/null & echo "$!" | sudoIf tee /tmp/$1.pid > /dev/null) + log "$1 started." + else + echo "$1 is already running." | sudoIf tee -a /tmp/$1.log > /dev/null + log "$1 is already running." + fi +} + +# Use sudo to run as root when required +sudoIf() +{ + if [ "$(id -u)" -ne 0 ]; then + sudo "$@" + else + "$@" + fi +} + +# Use sudo to run as non-root user if not already running +sudoUserIf() +{ + if [ "$(id -u)" -eq 0 ]; then + sudo -u ${NONROOT_USER} "$@" + else + "$@" + fi +} + +# Log messages +log() +{ + echo -e "[$(date)] $@" | sudoIf tee -a $LOG > /dev/null +} + +log "** SCRIPT START **" + +# Start dbus. +log 'Running "/etc/init.d/dbus start".' +if [ -f "/var/run/dbus/pid" ] && ! ps -p $(cat /var/run/dbus/pid) > /dev/null; then + sudoIf rm -f /var/run/dbus/pid +fi +sudoIf /etc/init.d/dbus start 2>&1 | sudoIf tee -a /tmp/dbus-daemon-system.log > /dev/null +while ! pidof dbus-daemon > /dev/null; do + sleep 1 +done + +# Set up Xvfb. +startInBackgroundIfNotRunning "Xvfb" sudoIf "Xvfb ${DISPLAY:-:1} +extension RANDR -screen 0 ${MAX_VNC_RESOLUTION:-1920x1080x16}" +while ! pidof Xvfb > /dev/null; do + sleep 1 +done + +# Start fluxbox as a light weight window manager. +startInBackgroundIfNotRunning "fluxbox" sudoUserIf "dbus-launch startfluxbox" +while ! pidof fluxbox > /dev/null; do + sleep 1 +done + +# Set resolution +/usr/local/bin/set-resolution ${VNC_RESOLUTION:-1280x720} ${VNC_DPI:-72} + +# Start x11vnc if installed. +if type x11vnc 2>&1 > /dev/null; then + startInBackgroundIfNotRunning "x11vnc" sudoIf "x11vnc -display ${DISPLAY:-:1} -rfbport ${VNC_PORT:-5901} -listen localhost -rfbportv6 ${VNC_PORT:-5901} -listenv6 localhost -xkb -shared -forever -nopw" +else + log "Skipping x11vnc - not installed." +fi + +# Spin up noVNC if installed. +if [ -d "/usr/local/novnc" ]; then + startInBackgroundIfNotRunning "noVNC" sudoIf "/usr/local/novnc/noVNC*/utils/launch.sh --listen ${NOVNC_PORT:-6080} --vnc localhost:${VNC_PORT:-5901}" +else + log "Skipping noVNC - not installed." +fi + +# Run whatever was passed in +log "Executing \"$@\"." +"$@" +log "** SCRIPT EXIT **" diff --git a/.devcontainer/bin/set-resolution b/.devcontainer/bin/set-resolution new file mode 100644 index 00000000000..5b4ca79f518 --- /dev/null +++ b/.devcontainer/bin/set-resolution @@ -0,0 +1,25 @@ +#!/bin/bash +RESOLUTION=${1:-${VNC_RESOLUTION:-1920x1080}} +DPI=${2:-${VNC_DPI:-72}} +if [ -z "$1" ]; then + echo -e "**Current Settings **\n" + xrandr + echo -n -e "\nEnter new resolution (WIDTHxHEIGHT, blank for ${RESOLUTION}, Ctrl+C to abort).\n> " + read NEW_RES + if [ "${NEW_RES}" != "" ]; then + RESOLUTION=${NEW_RES} + fi + if [ -z "$2" ]; then + echo -n -e "\nEnter new DPI (blank for ${DPI}, Ctrl+C to abort).\n> " + read NEW_DPI + if [ "${NEW_DPI}" != "" ]; then + DPI=${NEW_DPI} + fi + fi +fi + +xrandr --fb ${RESOLUTION} --dpi ${DPI} > /dev/null 2>&1 + +echo -e "\n**New Settings **\n" +xrandr +echo diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000000..b27b92534be --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,41 @@ +{ + "name": "Code - OSS", + "build": { + "dockerfile": "Dockerfile", + "args": { + "MAX_VNC_RESOLUTION": "1920x1080x16", + "TARGET_VNC_RESOLUTION": "1280x768", + "TARGET_VNC_PORT": "5901", + "TARGET_NOVNC_PORT": "6080", + "INSTALL_FIREFOX": "true" + } + }, + "overrideCommand": false, + "runArgs": ["--init"], + + "settings": { + // zsh is also available + "terminal.integrated.shell.linux": "/bin/bash", + "resmon.show.battery": false, + "resmon.show.cpufreq": false, + "remote.extensionKind": { + "ms-vscode.js-debug-nightly": "workspace" + }, + "debug.chrome.useV3": true + }, + + // noVNC, VNC ports + "forwardPorts": [6080, 5901], + + "extensions": [ + "ms-vscode.vscode-typescript-tslint-plugin", + "dbaeumer.vscode-eslint", + "EditorConfig.EditorConfig", + "ms-vscode.js-debug-nightly", + "eamodio.gitlens", + "GitHub.vscode-pull-request-github", + "mutantdino.resourcemonitor" + ], + + "remoteUser": "node" +} diff --git a/.devcontainer/fluxbox/apps b/.devcontainer/fluxbox/apps new file mode 100644 index 00000000000..d43f05e9e20 --- /dev/null +++ b/.devcontainer/fluxbox/apps @@ -0,0 +1,9 @@ +[app] (name=code-oss-dev) + [Position] (CENTER) {0 0} + [Maximized] {yes} + [Dimensions] {100% 100%} +[end] +[transient] (role=GtkFileChooserDialog) + [Position] (CENTER) {0 0} + [Dimensions] {70% 70%} +[end] diff --git a/.devcontainer/fluxbox/init b/.devcontainer/fluxbox/init new file mode 100644 index 00000000000..a6b8d73fa73 --- /dev/null +++ b/.devcontainer/fluxbox/init @@ -0,0 +1,9 @@ +session.menuFile: ~/.fluxbox/menu +session.keyFile: ~/.fluxbox/keys +session.styleFile: /usr/share/fluxbox/styles//Squared_for_Debian +session.configVersion: 13 +session.screen0.workspaces: 1 +session.screen0.workspacewarping: false +session.screen0.toolbar.widthPercent: 100 +session.screen0.strftimeFormat: %d %b, %a %02k:%M:%S +session.screen0.toolbar.tools: prevworkspace, workspacename, nextworkspace, clock, prevwindow, nextwindow, iconbar, systemtray diff --git a/.devcontainer/fluxbox/menu b/.devcontainer/fluxbox/menu new file mode 100644 index 00000000000..f00e0f7967e --- /dev/null +++ b/.devcontainer/fluxbox/menu @@ -0,0 +1,16 @@ +[begin] ( Code - OSS Development Container ) + [exec] (File Manager) { nautilus ~ } <> + [exec] (Terminal) {/usr/bin/gnome-terminal --working-directory=~ } <> + [exec] (Start Code - OSS) { x-terminal-emulator -T "Code - OSS Build" -e /workspaces/vscode*/scripts/code.sh } <> + [submenu] (System >) {} + [exec] (Set Resolution) { x-terminal-emulator -T "Set Resolution" -e bash /usr/local/bin/set-resolution } <> + [exec] (Passwords and Keys) { seahorse } <> + [exec] (Top) { x-terminal-emulator -T "Top" -e /usr/bin/top } <> + [exec] (Editres) {editres} <> + [exec] (Xfontsel) {xfontsel} <> + [exec] (Xkill) {xkill} <> + [exec] (Xrefresh) {xrefresh} <> + [end] + [config] (Configuration >) + [workspaces] (Workspaces >) +[end] diff --git a/.vscode/launch.json b/.vscode/launch.json index 3fe3be010e9..6a423332b10 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -26,6 +26,7 @@ "type": "pwa-chrome", "request": "attach", "name": "Attach to Shared Process", + "timeout": 30000, "port": 9222, "urlFilter": "*sharedProcess.html*", "presentation": { @@ -57,6 +58,7 @@ "type": "node", "request": "attach", "name": "Attach to Main Process", + "timeout": 30000, "port": 5875, "outFiles": [ "${workspaceFolder}/out/**/*.js" @@ -170,7 +172,7 @@ "${workspaceFolder}/out/**/*.js" ], "presentation": { - "group": "6_tests", + "group": "5_tests", "order": 6 } }, @@ -217,10 +219,7 @@ "type": "node", "request": "launch", "name": "VS Code (Web)", - "runtimeExecutable": "yarn", - "runtimeArgs": [ - "web" - ], + "program": "${workspaceFolder}/scripts/code-web.js", "presentation": { "group": "0_vscode", "order": 2 @@ -274,7 +273,7 @@ { "type": "node", "request": "launch", - "name": "HTML Unit Tests", + "name": "HTML Server Unit Tests", "program": "${workspaceFolder}/extensions/html-language-features/server/test/index.js", "stopOnEntry": false, "cwd": "${workspaceFolder}/extensions/html-language-features/server", @@ -286,6 +285,21 @@ "order": 10 } }, + { + "type": "node", + "request": "launch", + "name": "CSS Server Unit Tests", + "program": "${workspaceFolder}/extensions/css-language-features/server/test/index.js", + "stopOnEntry": false, + "cwd": "${workspaceFolder}/extensions/css-language-features/server", + "outFiles": [ + "${workspaceFolder}/extensions/css-language-features/server/out/**/*.js" + ], + "presentation": { + "group": "5_tests", + "order": 10 + } + }, { "type": "extensionHost", "request": "launch", diff --git a/README.md b/README.md index 1d3bc28f9bb..b7b0eecbc07 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,10 @@ Many of the core components and extensions to VS Code live in their own reposito VS Code includes a set of built-in extensions located in the [extensions](extensions) folder, including grammars and snippets for many languages. Extensions that provide rich language support (code completion, Go to Definition) for a language have the suffix `language-features`. For example, the `json` extension provides coloring for `JSON` and the `json-language-features` provides rich language support for `JSON`. +## Development Container + +This repository includes a Visual Studio Code Remote - Containers / Codespaces development container. You can open it using the **Remote-Containers: Open Repository in Container...** from the [Remote - Containers](https://aka.ms/vscode-remote/download/containers) extension or by referencing the repository Git URL when creating a cloud-based environment using the [Visual Studio Codespaces](https://aka.ms/vscs-ext-vscode) extension. See the [development container README](.devcontainer/README.md) for more details on its use. + ## Code of Conduct This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.