diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 612902f..9458e46 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -26,6 +26,9 @@ jobs: continue-on-error: true strategy: matrix: + # vscode-web is intentionally absent: it requires acceptLicenseTerms=true + # and autogenerated tests cannot set options, so it is covered by + # scenario tests only (including non-default base images). features: - code-server baseImage: @@ -49,6 +52,7 @@ jobs: matrix: features: - code-server + - vscode-web steps: - uses: actions/checkout@v4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 314d209..a6fbc65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,6 +7,7 @@ This guide contains information about how to contribute to this collection of de This repository currently contains the following features: - `code-server` - Adds VS Code in the browser functionality to your dev container +- `vscode-web` - Adds VS Code in the browser via Microsoft's official VS Code web server ## Adding a New Feature diff --git a/Makefile b/Makefile index 24d023d..009b4ce 100644 --- a/Makefile +++ b/Makefile @@ -3,5 +3,5 @@ test: devcontainer features test --filter "$$DEVCONTAINER_FEATURE_TEST_FILTER" .PHONY: docs -docs: src/code-server/README.md +docs: src/code-server/README.md src/vscode-web/README.md cd src && devcontainer features generate-docs -n coder/devcontainer-features diff --git a/README.md b/README.md index 5ac8a39..23b3f8a 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ This repository contains a collection of [dev container Features](https://contai ## Available Features - [code-server](./src/code-server/README.md) - VS Code in the browser +- [vscode-web](./src/vscode-web/README.md) - VS Code in the browser (Microsoft's official VS Code web server) ## Contributing diff --git a/src/code-server/README.md b/src/code-server/README.md index fa00ac0..177f289 100644 --- a/src/code-server/README.md +++ b/src/code-server/README.md @@ -53,4 +53,4 @@ VS Code in the browser ([code-server](https://github.com/coder/code-server)) --- -_Note: This file was auto-generated from the [devcontainer-feature.json](https://github.com/coder/devcontainer-features/blob/main/src/code-server/devcontainer-feature.json). Add additional notes to a `NOTES.md`._ +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/vscode-web/NOTES.md b/src/vscode-web/NOTES.md new file mode 100644 index 0000000..7fd667a --- /dev/null +++ b/src/vscode-web/NOTES.md @@ -0,0 +1,53 @@ +## vscode-web vs code-server + +This feature installs Microsoft's official VS Code web server (the same +`vscode-server-linux-*-web` build used by `code serve-web`), not +[coder/code-server](https://github.com/coder/code-server). The main practical +difference is the extension marketplace: the official server uses the +Microsoft Marketplace, so Microsoft-exclusive extensions such as Pylance and +GitHub Copilot can be installed. If you do not need those, consider the +[code-server feature](../code-server) instead. + +## License + +Installing this feature requires explicitly accepting the +[Microsoft VS Code Server license](https://aka.ms/vscode-server-license), +which limits usage to your own development purposes. Set the +`acceptLicenseTerms` option to `true`; installation fails otherwise: + +```json +"features": { + "ghcr.io/coder/devcontainer-features/vscode-web:1": { + "acceptLicenseTerms": true + } +} +``` + +The server is then started with `--accept-server-license-terms`. + +## Extensions + +Extensions must be listed in this feature's `extensions` option. The +`customizations.vscode.extensions` property of `devcontainer.json` is consumed +by VS Code clients (e.g. the Dev Containers extension), not by the standalone +web server, so extensions listed only there will not show up in VS Code Web. + +## Authentication + +By default the server binds to `127.0.0.1` and starts without a connection +token. This assumes an authenticating reverse proxy (such as Coder) in front +of it. If you expose the port directly, set `connectionTokenFile` to require a +token. + +## Opening a folder + +Use the `defaultFolder` option to control which folder opens by default, or +append `?folder=/path/to/folder` to the URL. + +## Coder integration + +When used inside a [Coder workspace with dev container support](https://coder.com/docs/admin/templates/extending-templates/devcontainers), +the feature registers a `vscode-web` app on the workspace dashboard via +`customizations.coder.apps`. Its health check probes the `/version` endpoint +(the standalone web server exposes no `/healthz`). The `app*` options +only affect this Coder app metadata, not the server itself. diff --git a/src/vscode-web/README.md b/src/vscode-web/README.md new file mode 100644 index 0000000..c2d0acd --- /dev/null +++ b/src/vscode-web/README.md @@ -0,0 +1,95 @@ + +# vscode-web (vscode-web) + +VS Code in the browser (Microsoft's official [VS Code web server](https://code.visualstudio.com/docs/remote/vscode-server), with access to the Microsoft Marketplace) + +## Example Usage + +```json +"features": { + "ghcr.io/coder/devcontainer-features/vscode-web:1": {} +} +``` + +## Options + +| Options Id | Description | Type | Default Value | +|-----|-----|-----|-----| +| acceptLicenseTerms | REQUIRED: set to true to accept the Microsoft VS Code Server license terms (https://aka.ms/vscode-server-license). The feature fails to install when the terms are not accepted. | boolean | false | +| connectionTokenFile | Path to a file containing the connection token used for authentication. When empty, the server starts without a connection token (intended to be used behind an authenticating reverse proxy such as Coder). | string | - | +| defaultFolder | The folder to open by default when no folder is specified in the URL. Can also be passed per-request via the '?folder=' query parameter. | string | - | +| disableWorkspaceTrust | Disable Workspace Trust feature. This only affects the current session. | boolean | false | +| extensions | Comma-separated list of VS Code extensions to install from the Microsoft Marketplace. Format: 'publisher.extension[@version]' (e.g., 'ms-python.python,ms-python.vscode-pylance'). | string | - | +| extensionsDir | Path where extensions are installed. Defaults to a directory under the server data dir. | string | - | +| host | The address to bind to for the VS Code web server. Use '0.0.0.0' to listen on all interfaces. | string | 127.0.0.1 | +| logFile | Path to a file to send stdout and stderr logs to from the VS Code web server. | string | /tmp/vscode-web.log | +| logLevel | Log level of the VS Code web server. One of 'trace', 'debug', 'info', 'warn', 'error', 'critical', 'off'. Defaults to the server's built-in default ('info'). | string | - | +| port | The port to bind to for the VS Code web server. | string | 13338 | +| serverBasePath | Path under which the server is served (e.g. when running behind a path-routing reverse proxy). | string | - | +| serverDataDir | Directory where the server stores its data. Defaults to '~/.vscode-server'. | string | - | +| socketPath | Path to a socket to listen on instead of host:port. | string | - | +| telemetryLevel | Telemetry level of the VS Code web server. | string | off | +| userDataDir | Directory where user data (settings, state) is kept. Defaults to a directory under the server data dir. | string | - | +| version | The version of VS Code to install (e.g. '1.101.0'). If empty, installs the latest stable version. | string | - | +| appOpenIn | The way to open the app in Coder. Defaults to 'slim-window'. | string | slim-window | +| appShare | The sharing level to use for the app in Coder. Defaults to 'owner'. | string | owner | +| appGroup | The group to use for the app in Coder. Defaults to 'Web Editors'. | string | Web Editors | + +## vscode-web vs code-server + +This feature installs Microsoft's official VS Code web server (the same +`vscode-server-linux-*-web` build used by `code serve-web`), not +[coder/code-server](https://github.com/coder/code-server). The main practical +difference is the extension marketplace: the official server uses the +Microsoft Marketplace, so Microsoft-exclusive extensions such as Pylance and +GitHub Copilot can be installed. If you do not need those, consider the +[code-server feature](../code-server) instead. + +## License + +Installing this feature requires explicitly accepting the +[Microsoft VS Code Server license](https://aka.ms/vscode-server-license), +which limits usage to your own development purposes. Set the +`acceptLicenseTerms` option to `true`; installation fails otherwise: + +```json +"features": { + "ghcr.io/coder/devcontainer-features/vscode-web:1": { + "acceptLicenseTerms": true + } +} +``` + +The server is then started with `--accept-server-license-terms`. + +## Extensions + +Extensions must be listed in this feature's `extensions` option. The +`customizations.vscode.extensions` property of `devcontainer.json` is consumed +by VS Code clients (e.g. the Dev Containers extension), not by the standalone +web server, so extensions listed only there will not show up in VS Code Web. + +## Authentication + +By default the server binds to `127.0.0.1` and starts without a connection +token. This assumes an authenticating reverse proxy (such as Coder) in front +of it. If you expose the port directly, set `connectionTokenFile` to require a +token. + +## Opening a folder + +Use the `defaultFolder` option to control which folder opens by default, or +append `?folder=/path/to/folder` to the URL. + +## Coder integration + +When used inside a [Coder workspace with dev container support](https://coder.com/docs/admin/templates/extending-templates/devcontainers), +the feature registers a `vscode-web` app on the workspace dashboard via +`customizations.coder.apps`. Its health check probes the `/version` endpoint +(the standalone web server exposes no `/healthz`). The `app*` options +only affect this Coder app metadata, not the server itself. + + +--- + +_Note: This file was auto-generated from the [devcontainer-feature.json](devcontainer-feature.json). Add additional notes to a `NOTES.md`._ diff --git a/src/vscode-web/devcontainer-feature.json b/src/vscode-web/devcontainer-feature.json new file mode 100644 index 0000000..140347a --- /dev/null +++ b/src/vscode-web/devcontainer-feature.json @@ -0,0 +1,128 @@ +{ + "name": "vscode-web", + "id": "vscode-web", + "version": "1.0.0", + "description": "VS Code in the browser (Microsoft's official [VS Code web server](https://code.visualstudio.com/docs/remote/vscode-server), with access to the Microsoft Marketplace)", + "options": { + "acceptLicenseTerms": { + "type": "boolean", + "default": false, + "description": "REQUIRED: set to true to accept the Microsoft VS Code Server license terms (https://aka.ms/vscode-server-license). The feature fails to install when the terms are not accepted." + }, + "connectionTokenFile": { + "type": "string", + "default": "", + "description": "Path to a file containing the connection token used for authentication. When empty, the server starts without a connection token (intended to be used behind an authenticating reverse proxy such as Coder)." + }, + "defaultFolder": { + "type": "string", + "default": "", + "description": "The folder to open by default when no folder is specified in the URL. Can also be passed per-request via the '?folder=' query parameter." + }, + "disableWorkspaceTrust": { + "type": "boolean", + "default": false, + "description": "Disable Workspace Trust feature. This only affects the current session." + }, + "extensions": { + "type": "string", + "default": "", + "description": "Comma-separated list of VS Code extensions to install from the Microsoft Marketplace. Format: 'publisher.extension[@version]' (e.g., 'ms-python.python,ms-python.vscode-pylance')." + }, + "extensionsDir": { + "type": "string", + "default": "", + "description": "Path where extensions are installed. Defaults to a directory under the server data dir." + }, + "host": { + "type": "string", + "default": "127.0.0.1", + "description": "The address to bind to for the VS Code web server. Use '0.0.0.0' to listen on all interfaces." + }, + "logFile": { + "type": "string", + "default": "/tmp/vscode-web.log", + "description": "Path to a file to send stdout and stderr logs to from the VS Code web server." + }, + "logLevel": { + "type": "string", + "default": "", + "description": "Log level of the VS Code web server. One of 'trace', 'debug', 'info', 'warn', 'error', 'critical', 'off'. Defaults to the server's built-in default ('info')." + }, + "port": { + "type": "string", + "default": "13338", + "description": "The port to bind to for the VS Code web server." + }, + "serverBasePath": { + "type": "string", + "default": "", + "description": "Path under which the server is served (e.g. when running behind a path-routing reverse proxy)." + }, + "serverDataDir": { + "type": "string", + "default": "", + "description": "Directory where the server stores its data. Defaults to '~/.vscode-server'." + }, + "socketPath": { + "type": "string", + "default": "", + "description": "Path to a socket to listen on instead of host:port." + }, + "telemetryLevel": { + "type": "string", + "enum": ["off", "crash", "error", "all"], + "default": "off", + "description": "Telemetry level of the VS Code web server." + }, + "userDataDir": { + "type": "string", + "default": "", + "description": "Directory where user data (settings, state) is kept. Defaults to a directory under the server data dir." + }, + "version": { + "type": "string", + "default": "", + "description": "The version of VS Code to install (e.g. '1.101.0'). If empty, installs the latest stable version." + }, + "appOpenIn": { + "type": "string", + "default": "slim-window", + "description": "The way to open the app in Coder. Defaults to 'slim-window'." + }, + "appShare": { + "type": "string", + "default": "owner", + "description": "The sharing level to use for the app in Coder. Defaults to 'owner'." + }, + "appGroup": { + "type": "string", + "default": "Web Editors", + "description": "The group to use for the app in Coder. Defaults to 'Web Editors'." + } + }, + "customizations": { + "coder": { + "apps": [ + { + "slug": "vscode-web", + "displayName": "VS Code Web", + "url": "http://${localEnv:FEATURE_VSCODE_WEB_OPTION_HOST:127.0.0.1}:${localEnv:FEATURE_VSCODE_WEB_OPTION_PORT:13338}/", + "openIn": "${localEnv:FEATURE_VSCODE_WEB_OPTION_APPOPENIN:slim-window}", + "share": "${localEnv:FEATURE_VSCODE_WEB_OPTION_APPSHARE:owner}", + "icon": "/icon/code.svg", + "group": "${localEnv:FEATURE_VSCODE_WEB_OPTION_APPGROUP:Web Editors}", + "healthCheck": { + "url": "http://127.0.0.1:${localEnv:FEATURE_VSCODE_WEB_OPTION_PORT:13338}/version", + "interval": 3, + "threshold": 10 + } + } + ] + } + }, + "entrypoint": "/usr/local/bin/vscode-web-entrypoint", + "dependsOn": { + "ghcr.io/devcontainers/features/common-utils:2": {} + } +} diff --git a/src/vscode-web/install.sh b/src/vscode-web/install.sh new file mode 100644 index 0000000..ef72022 --- /dev/null +++ b/src/vscode-web/install.sh @@ -0,0 +1,123 @@ +#!/usr/bin/env bash +set -e + +if [[ "$ACCEPTLICENSETERMS" != "true" ]]; then + echo "ERROR: The Microsoft VS Code Server license terms (https://aka.ms/vscode-server-license) must be accepted to install this feature." >&2 + echo "Set the 'acceptLicenseTerms' option to true to accept them:" >&2 + echo ' "vscode-web": { "acceptLicenseTerms": true }' >&2 + exit 1 +fi + +ARCH=$(uname -m) +case "$ARCH" in + x86_64) ARCH="x64" ;; + aarch64 | arm64) ARCH="arm64" ;; + *) + echo "ERROR: unsupported architecture: $ARCH" >&2 + exit 1 + ;; +esac + +INSTALL_PREFIX=/usr/local/lib/vscode-web + +if [[ -n $VERSION ]]; then + DOWNLOAD_URL=$(curl -fsSL "https://update.code.visualstudio.com/api/versions/$VERSION/server-linux-$ARCH-web/stable" \ + | grep -o '"url":"[^"]*"' | head -n 1 | cut -d '"' -f 4) + + if [[ -z $DOWNLOAD_URL ]]; then + echo "ERROR: could not resolve a download URL for VS Code version '$VERSION'" >&2 + exit 1 + fi +else + COMMIT=$(curl -fsSL "https://update.code.visualstudio.com/api/commits/stable/server-linux-$ARCH-web" | cut -d '"' -f 2) + DOWNLOAD_URL="https://vscode.download.prss.microsoft.com/dbazure/download/stable/$COMMIT/vscode-server-linux-$ARCH-web.tar.gz" +fi + +echo "Downloading VS Code web server from $DOWNLOAD_URL" +mkdir -p "$INSTALL_PREFIX" +curl -fsSL "$DOWNLOAD_URL" | tar -xz -C "$INSTALL_PREFIX" --strip-components 1 + +# The CLI inside the tarball is named code-server for historical reasons. +# Expose it as vscode-web so it cannot clash with coder/code-server. +ln -sf "$INSTALL_PREFIX/bin/code-server" /usr/local/bin/vscode-web + +EXTENSION_INSTALL_ARGS="" + +if [[ -n $EXTENSIONSDIR ]]; then + EXTENSION_INSTALL_ARGS="$EXTENSION_INSTALL_ARGS --extensions-dir '$EXTENSIONSDIR'" +fi + +if [[ -n $SERVERDATADIR ]]; then + EXTENSION_INSTALL_ARGS="$EXTENSION_INSTALL_ARGS --server-data-dir '$SERVERDATADIR'" +fi + +if [[ -n "$EXTENSIONS" ]]; then + IFS=',' read -ra extensions <<<"$EXTENSIONS" + + for extension in "${extensions[@]}" + do + if ! su "$_REMOTE_USER" -c "vscode-web --install-extension '$extension' --force$EXTENSION_INSTALL_ARGS"; then + echo "ERROR: Failed to install extension '$extension' as user '$_REMOTE_USER'" >&2 + exit 1 + fi + done +fi + +FLAGS=(serve-local) +FLAGS+=(--accept-server-license-terms) +FLAGS+=(--host "$HOST") +FLAGS+=(--port "$PORT") +FLAGS+=(--telemetry-level "$TELEMETRYLEVEL") + +if [[ -n "$CONNECTIONTOKENFILE" ]]; then + FLAGS+=(--connection-token-file "$CONNECTIONTOKENFILE") +else + FLAGS+=(--without-connection-token) +fi + +if [[ -n "$SOCKETPATH" ]]; then + FLAGS+=(--socket-path "$SOCKETPATH") +fi + +if [[ -n "$SERVERBASEPATH" ]]; then + FLAGS+=(--server-base-path "$SERVERBASEPATH") +fi + +if [[ -n "$SERVERDATADIR" ]]; then + FLAGS+=(--server-data-dir "$SERVERDATADIR") +fi + +if [[ -n "$USERDATADIR" ]]; then + FLAGS+=(--user-data-dir "$USERDATADIR") +fi + +if [[ -n "$EXTENSIONSDIR" ]]; then + FLAGS+=(--extensions-dir "$EXTENSIONSDIR") +fi + +if [[ -n "$DEFAULTFOLDER" ]]; then + FLAGS+=(--default-folder "$DEFAULTFOLDER") +fi + +if [[ "$DISABLEWORKSPACETRUST" == "true" ]]; then + FLAGS+=(--disable-workspace-trust) +fi + +if [[ -n "$LOGLEVEL" ]]; then + FLAGS+=(--log "$LOGLEVEL") +fi + +cat > /usr/local/bin/vscode-web-entrypoint <"$LOGFILE" 2>&1 +EOF + +chmod +x /usr/local/bin/vscode-web-entrypoint diff --git a/test/vscode-web/scenarios.json b/test/vscode-web/scenarios.json new file mode 100644 index 0000000..593a8f7 --- /dev/null +++ b/test/vscode-web/scenarios.json @@ -0,0 +1,72 @@ +{ + "vscode-web-defaults": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "vscode-web": { + "acceptLicenseTerms": true + } + } + }, + "vscode-web-debian": { + "image": "debian:latest", + "features": { + "vscode-web": { + "acceptLicenseTerms": true + } + } + }, + "vscode-web-modified-port": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "vscode-web": { + "acceptLicenseTerms": true, + "port": "4321" + } + } + }, + "vscode-web-modified-host": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "vscode-web": { + "acceptLicenseTerms": true, + "host": "0.0.0.0" + } + } + }, + "vscode-web-extensions": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "vscode-web": { + "acceptLicenseTerms": true, + "extensions": "tamasfe.even-better-toml,redhat.vscode-yaml" + } + } + }, + "vscode-web-install-version": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "vscode-web": { + "acceptLicenseTerms": true, + "version": "1.101.0" + } + } + }, + "vscode-web-default-folder": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "vscode-web": { + "acceptLicenseTerms": true, + "defaultFolder": "/home/vscode" + } + } + }, + "vscode-web-log-level": { + "image": "mcr.microsoft.com/devcontainers/base:ubuntu", + "features": { + "vscode-web": { + "acceptLicenseTerms": true, + "logLevel": "debug" + } + } + } +} diff --git a/test/vscode-web/vscode-web-debian.sh b/test/vscode-web/vscode-web-debian.sh new file mode 100644 index 0000000..c597910 --- /dev/null +++ b/test/vscode-web/vscode-web-debian.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +# The server is started by the entrypoint and needs a moment to come up. +wait_for_server() { + for _ in $(seq 30); do + if curl -fsS "http://127.0.0.1:$1/version" >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + return 1 +} + +# Feature-specific tests +check "vscode-web version" vscode-web --version +check "vscode-web running" pgrep -f 'vscode-web/out/server-main.js' +check "vscode-web responding" wait_for_server 13338 + +check "vscode-web log-file" test -f /tmp/vscode-web.log + +# Report results +reportResults diff --git a/test/vscode-web/vscode-web-default-folder.sh b/test/vscode-web/vscode-web-default-folder.sh new file mode 100644 index 0000000..a818b45 --- /dev/null +++ b/test/vscode-web/vscode-web-default-folder.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +wait_for_server() { + for _ in $(seq 30); do + if curl -fsS "http://127.0.0.1:$1/version" >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + return 1 +} + +# Feature-specific tests +check "vscode-web version" vscode-web --version +check "vscode-web running" pgrep -f 'vscode-web/out/server-main.js' +check "vscode-web responding" wait_for_server 13338 + +# The workbench redirects to the default folder when none is given in the URL. +check "vscode-web default folder flag" grep -e '--default-folder' /usr/local/bin/vscode-web-entrypoint + +# Report results +reportResults diff --git a/test/vscode-web/vscode-web-defaults.sh b/test/vscode-web/vscode-web-defaults.sh new file mode 100644 index 0000000..3131279 --- /dev/null +++ b/test/vscode-web/vscode-web-defaults.sh @@ -0,0 +1,27 @@ +#!/bin/bash +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +# The server is started by the entrypoint and needs a moment to come up. +wait_for_server() { + for _ in $(seq 30); do + if curl -fsS "http://127.0.0.1:$1/version" >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + return 1 +} + +# Feature-specific tests +check "vscode-web version" vscode-web --version +check "vscode-web running" pgrep -f 'vscode-web/out/server-main.js' +check "vscode-web responding" wait_for_server 13338 +check "vscode-web listening" lsof -i "@127.0.0.1:13338" + +check "vscode-web log-file" test -f /tmp/vscode-web.log + +# Report results +reportResults diff --git a/test/vscode-web/vscode-web-extensions.sh b/test/vscode-web/vscode-web-extensions.sh new file mode 100644 index 0000000..550a578 --- /dev/null +++ b/test/vscode-web/vscode-web-extensions.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +wait_for_server() { + for _ in $(seq 30); do + if curl -fsS "http://127.0.0.1:$1/version" >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + return 1 +} + +# Feature-specific tests +check "vscode-web version" vscode-web --version +check "vscode-web running" pgrep -f 'vscode-web/out/server-main.js' +check "vscode-web responding" wait_for_server 13338 + +# Verify extensions are installed under the remoteUser's home, not root's. +# See: https://github.com/coder/devcontainer-features/issues/18 +extensions_dir=/home/vscode/.vscode-server/extensions + +check "even-better-toml installed under remoteUser" ls "$extensions_dir"/tamasfe.even-better-toml-* +check "vscode-yaml installed under remoteUser" ls "$extensions_dir"/redhat.vscode-yaml-* +check "extensions not installed under root" test ! -d /root/.vscode-server/extensions + +# Report results +reportResults diff --git a/test/vscode-web/vscode-web-install-version.sh b/test/vscode-web/vscode-web-install-version.sh new file mode 100644 index 0000000..8d3efb8 --- /dev/null +++ b/test/vscode-web/vscode-web-install-version.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +wait_for_server() { + for _ in $(seq 30); do + if curl -fsS "http://127.0.0.1:$1/version" >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + return 1 +} + +# Feature-specific tests +check "vscode-web version" vscode-web --version +check "vscode-web running" pgrep -f 'vscode-web/out/server-main.js' +check "vscode-web responding" wait_for_server 13338 + +version=$(vscode-web --version) +check "vscode-web is correct version" grep '1.101.0\>' <<<"$version" + +# Report results +reportResults diff --git a/test/vscode-web/vscode-web-log-level.sh b/test/vscode-web/vscode-web-log-level.sh new file mode 100644 index 0000000..d63aece --- /dev/null +++ b/test/vscode-web/vscode-web-log-level.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +wait_for_server() { + for _ in $(seq 30); do + if curl -fsS "http://127.0.0.1:$1/version" >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + return 1 +} + +# Feature-specific tests +check "vscode-web version" vscode-web --version +check "vscode-web running" pgrep -f 'vscode-web/out/server-main.js' +check "vscode-web responding" wait_for_server 13338 + +check "vscode-web log flag" grep -e '--log' /usr/local/bin/vscode-web-entrypoint + +# Report results +reportResults diff --git a/test/vscode-web/vscode-web-modified-host.sh b/test/vscode-web/vscode-web-modified-host.sh new file mode 100644 index 0000000..8d5194d --- /dev/null +++ b/test/vscode-web/vscode-web-modified-host.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +wait_for_server() { + for _ in $(seq 30); do + if curl -fsS "http://127.0.0.1:$1/version" >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + return 1 +} + +# Feature-specific tests +check "vscode-web version" vscode-web --version +check "vscode-web running" pgrep -f 'vscode-web/out/server-main.js' +check "vscode-web responding" wait_for_server 13338 +check "vscode-web listening" lsof -i "@0.0.0.0:13338" + +# Report results +reportResults diff --git a/test/vscode-web/vscode-web-modified-port.sh b/test/vscode-web/vscode-web-modified-port.sh new file mode 100644 index 0000000..1c7a344 --- /dev/null +++ b/test/vscode-web/vscode-web-modified-port.sh @@ -0,0 +1,24 @@ +#!/bin/bash +set -e + +# Optional: Import test library bundled with the devcontainer CLI +source dev-container-features-test-lib + +wait_for_server() { + for _ in $(seq 30); do + if curl -fsS "http://127.0.0.1:$1/version" >/dev/null 2>&1; then + return 0 + fi + sleep 1 + done + return 1 +} + +# Feature-specific tests +check "vscode-web version" vscode-web --version +check "vscode-web running" pgrep -f 'vscode-web/out/server-main.js' +check "vscode-web responding" wait_for_server 4321 +check "vscode-web listening" lsof -i "@127.0.0.1:4321" + +# Report results +reportResults