microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
164.9k stars 29.52k forks source link

Remote SSH extension does not recognize existing server installation #231537

Open ofek opened 1 month ago

ofek commented 1 month ago

Steps to Reproduce:

FROM ubuntu:14.04

RUN apt-get update \
 && apt-get install -y autoconf build-essential ca-certificates curl jq libssl-dev libz-dev pkg-config tar tree

COPY <<-"EOF" /set-up-ssh.sh
IFS=$'\n\t'
set -euxo pipefail

VERSION="V_9_3_P2"
url="https://github.com/openssh/openssh-portable/archive/refs/tags/${VERSION}.tar.gz"

archive_name=$(basename "${url}")
workdir="/tmp/setup-${archive_name}"
mkdir -p "${workdir}"
curl "${url}" -Lo "${workdir}/${archive_name}"
tar -xf "${workdir}/${archive_name}" -C "${workdir}" --strip-components 1

sudo useradd -r -s /sbin/nologin sshd

pushd "${workdir}"
autoreconf
./configure
make -j "$(nproc)"
make install
popd
rm -rf "${workdir}"

passwd -d root
cat <<'EOL' >> /usr/local/etc/sshd_config
PermitRootLogin yes
PermitEmptyPasswords yes
EOL
EOF
RUN bash /set-up-ssh.sh

COPY <<-"EOF" /set-up-vscode.sh
IFS=$'\n\t'
set -euxo pipefail

VERSION="1.85.2"

arch=$(uname -m)
if [[ $arch == "aarch64" ]]; then
  arch="arm64"
else
  arch="x64"
fi
metadata_url="https://update.code.visualstudio.com/api/versions/${VERSION}/linux-${arch}/stable"

commit=$(curl -s "${metadata_url}" | jq -r .version)
server_download_url="https://update.code.visualstudio.com/commit:${commit}/server-linux-${arch}/stable"
cli_download_url="https://update.code.visualstudio.com/${VERSION}/cli-linux-x64/stable"

vscode_root_dir="${HOME}/.vscode-server"
vscode_binary="${vscode_root_dir}/code-${commit}"
vscode_install_dir="${vscode_root_dir}/cli/servers/Stable-${commit}"
vscode_unpack_dir="${vscode_install_dir}/server"

curl "${server_download_url}" -Lo "vscode-server-linux-${arch}.tar.gz"
mkdir -p "${vscode_unpack_dir}"
tar --no-same-owner -xf "vscode-server-linux-${arch}.tar.gz" -C "${vscode_unpack_dir}" --strip-components 1
rm "vscode-server-linux-${arch}.tar.gz"

curl "${cli_download_url}" -Lo "vscode_cli_alpine_${arch}_cli.tar.gz"
tar --no-same-owner -xf "vscode_cli_alpine_${arch}_cli.tar.gz" -C "${vscode_root_dir}"
mv "${vscode_root_dir}/code" "${vscode_binary}"
rm "vscode_cli_alpine_${arch}_cli.tar.gz"

ln -s "${vscode_root_dir}/cli/servers/Stable-${commit}/server/bin/code-server" /usr/local/bin/code-server
EOF
RUN bash /set-up-vscode.sh

EXPOSE 22
ENTRYPOINT ["/usr/local/sbin/sshd", "-D", "-e"]
❯ docker build . --tag vsc-test
❯ docker run --rm -d --name vsc-test -p 22:22 vsc-test
1c425b20ea8ce4e290a6e384e8513355fb6d9bddbffb1baf4fea229fac98a0c0
❯ docker exec vsc-test tree -L 5 /root/.vscode-server
/root/.vscode-server
|-- cli
|   `-- servers
|       `-- Stable-8b3775030ed1a69b13e4f4c628c612102e30a681
|           `-- server
|               |-- LICENSE
|               |-- bin
|               |-- extensions
|               |-- node
|               |-- node_modules
|               |-- out
|               |-- package.json
|               `-- product.json
`-- code-8b3775030ed1a69b13e4f4c628c612102e30a681

Finally open in VS Code and notice that the server is still downloaded, appearing to always look for the commit from what you run locally:

code --remote ssh-remote+root@localhost /root/

Here is the output:

[17:48:16.209] Log Level: 2 [17:48:16.233] VS Code version: 1.94.1 [17:48:16.233] Remote-SSH version: remote-ssh@0.115.0 [17:48:16.234] win32 x64 [17:48:16.240] SSH Resolver called for "ssh-remote+root@localhost", attempt 1 [17:48:16.241] "remote.SSH.useLocalServer": false [17:48:16.241] "remote.SSH.useExecServer": true [17:48:16.241] "remote.SSH.showLoginTerminal": false [17:48:16.242] "remote.SSH.remotePlatform": {"192.168.86.52":"linux","localhost":"linux"} [17:48:16.242] "remote.SSH.path": undefined [17:48:16.242] "remote.SSH.configFile": undefined [17:48:16.242] "remote.SSH.useFlock": true [17:48:16.242] "remote.SSH.lockfilesInTmp": false [17:48:16.242] "remote.SSH.localServerDownload": off [17:48:16.242] "remote.SSH.remoteServerListenOnSocket": false [17:48:16.242] "remote.SSH.showLoginTerminal": false [17:48:16.242] "remote.SSH.defaultExtensions": [] [17:48:16.242] "remote.SSH.loglevel": 2 [17:48:16.243] "remote.SSH.enableDynamicForwarding": true [17:48:16.243] "remote.SSH.enableRemoteCommand": false [17:48:16.243] "remote.SSH.serverPickPortsFromRange": {} [17:48:16.243] "remote.SSH.serverInstallPath": {} [17:48:16.243] "remote.SSH.permitPtyAllocation": false [17:48:16.243] "remote.SSH.preferredLocalPortRange: undefined [17:48:16.243] "remote.SSH.useCurlAndWgetConfigurationFiles: false [17:48:16.253] SSH Resolver called for host: root@localhost [17:48:16.253] Setting up SSH remote "localhost" [17:48:16.265] Using commit id "e10f2369d0d9614a452462f2e01cdc4aa9486296" and quality "stable" for server [17:48:16.267] Script variables: { "InstallExitCode.24": "AlreadyInProgress", "InstallExitCode.25": "ServerDownloadFailed", "InstallExitCode.26": "NoDownloaderAvailable", "InstallExitCode.27": "UnsupportedArch", "InstallExitCode.28": "StatusCheckFailed", "InstallExitCode.29": "NeedInsidersArch", "InstallExitCode.30": "NoDownloaderAvailableForStatusCheck", "InstallExitCode.31": "ServerTransferFailed", "InstallExitCode.32": "ServerFailedToStart", "InstallExitCode.33": "NeedInsidersWindows", "InstallExitCode.34": "CreateInstallDirFailed", "InstallExitCode.35": "UnsupportedPlatform", "InstallExitCode.36": "ServerTerminatedCVE20201416", "InstallExitCode.37": "UnpackFailed", "InstallExitCode.38": "ChangeDirFailed", "InstallExitCode.AlreadyInProgress": "24", "InstallExitCode.ServerDownloadFailed": "25", "InstallExitCode.NoDownloaderAvailable": "26", "InstallExitCode.NoDownloaderAvailableForStatusCheck": "30", "InstallExitCode.UnsupportedArch": "27", "InstallExitCode.StatusCheckFailed": "28", "InstallExitCode.NeedInsidersArch": "29", "InstallExitCode.ServerTransferFailed": "31", "InstallExitCode.ServerFailedToStart": "32", "InstallExitCode.NeedInsidersWindows": "33", "InstallExitCode.CreateInstallDirFailed": "34", "InstallExitCode.UnsupportedPlatform": "35", "InstallExitCode.ServerTerminatedCVE20201416": "36", "InstallExitCode.UnpackFailed": "37", "InstallExitCode.ChangeDirFailed": "38", "InstallUnpackCode.Success": "success", "InstallUnpackCode.Error": "error", "InstallUnpackCode.MissingFiles": "missingFiles", "uuid": "97d1968c8abd", "startMarker": "97d1968c8abd: running", "commitId": "e10f2369d0d9614a452462f2e01cdc4aa9486296", "quality": "stable", "token": "1a111a1a-aa1a-1a11-a111-aaa111a11aaa", "vscodeAgentFolder": "$HOME/.vscode-server", "allowClientDownload": "0", "forceClientDownload": "0", "cliNameInArchive": "code", "ignoreWgetConfigFlag": " --no-config ", "ignoreCurlConfigFlag": " --disable ", "wgetTriesSegment": "", "listenArgs": "--on-host=127.0.0.1 --on-port", "getDownloadServerStartTrigger": "97d1968c8abd:trigger_server_download", "getDownloadServerEndTrigger": "97d1968c8abd:trigger_server_download_end", "getProgressDownloading": "97d1968c8abd%%1%%", "getProgressInstalling": "97d1968c8abd%%2%%" } [17:48:16.271] Install and start server if needed [17:48:16.274] Checking ssh with "C:\Program Files\OpenSSH\ssh.exe -V" [17:48:16.315] > OpenSSH_for_Windows_9.8p1 Win32-OpenSSH-GitHub, LibreSSL 3.9.2 [17:48:16.320] Running script with connection command: "C:\Program Files\OpenSSH\ssh.exe" -T -D 61518 "root@localhost" sh [17:48:16.322] Generated SSH command: 'type "C:\Users\ofek\AppData\Local\Temp\vscode-linux-multi-line-command-localhost-445716631.sh" | "C:\Program Files\OpenSSH\ssh.exe" -T -D 61518 "root@localhost" sh' [17:48:16.322] Using connect timeout of 17 seconds [17:48:16.323] Terminal shell path: C:\WINDOWS\System32\cmd.exe [17:48:16.819] > Warning: Permanently added 'localhost' (ED25519) to the list of known hosts. > ]0;C:\WINDOWS\System32\cmd.exe [17:48:16.819] Got some output, clearing connection timeout [17:48:16.923] > 97d1968c8abd: running > Script executing under PID: 21 > Installing to /root/.vscode-server... > 97d1968c8abd%%1%% > Downloading with curl > % Total % Received % Xferd Average Speed Time Time Time Current > Dload Upload Total Spent Left Speed > 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 [17:48:17.418] > 100 162 100 162 0 0 337 0 --:--:-- --:--:-- --:--:-- 337 [17:48:17.874] > 100 8834k 100 8834k 0 0 9447k 0 --:--:-- --:--:-- --:--:-- 9447k > Download complete > 97d1968c8abd%%2%% > tar --version: tar (GNU tar) 1.27.1 > Copyright (C) 2013 Free Software Foundation, Inc. > License GPLv3+: GNU GPL version 3 or later . > This is free software: you are free to change and redistribute it. > There is NO WARRANTY, to the extent permitted by law.Written by John Gilmore and Jay Fenlason. > [17:48:18.017] > code 1.94.1 (commit e10f2369d0d9614a452462f2e01cdc4aa9486296) > Starting VS Code CLI... > printenv: > MAIL=/var/mail/root > SSH_CLIENT=172.17.0.1 35732 22 > USER=root > SHLVL=1 > HOME=/root > OLDPWD=/root/.vscode-server > LOGNAME=root > _=/bin/sh > PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin > SSH_AUTH_SOCK=/tmp/ssh-XXXXRFyGym/agent.19 > SHELL=/bin/bash > PWD=/root > SSH_CONNECTION=172.17.0.1 35732 172.17.0.2 22 > Spawned remote CLI: 77 > Waiting for server log... [17:48:18.031] > [17:48:18.048] > 97d1968c8abd: start > listeningOn==127.0.0.1:37307== > osReleaseId==ubuntu== > arch==x86_64== > vscodeArch==x64== > bitness==64== > tmpDir==/tmp== > platform==linux== > unpackResult==success== > didLocalDownload==0== > downloadTime==945== > installTime==151== > serverStartTime==35== > execServerToken==1a111a1a-aa1a-1a11-a111-aaa111a11aaa== > platformDownloadPath==cli-alpine-x64== > 97d1968c8abd: end [17:48:18.048] Received install output: listeningOn==127.0.0.1:37307== osReleaseId==ubuntu== arch==x86_64== vscodeArch==x64== bitness==64== tmpDir==/tmp== platform==linux== unpackResult==success== didLocalDownload==0== downloadTime==945== installTime==151== serverStartTime==35== execServerToken==1a111a1a-aa1a-1a11-a111-aaa111a11aaa== platformDownloadPath==cli-alpine-x64== [17:48:18.049] Remote server is listening on port 37307 [17:48:18.049] Parsed server configuration: {"serverConfiguration":{"remoteListeningOn":{"port":37307},"osReleaseId":"ubuntu","arch":"x86_64","tmpDir":"/tmp","platform":"linux","execServerToken":"1a111a1a-aa1a-1a11-a111-aaa111a11aaa"},"downloadTime":945,"installTime":151,"serverStartTime":35,"installUnpackCode":"success"} [17:48:18.053] Starting forwarding server. local port 61527 -> socksPort 61518 -> remotePort 37307 [17:48:18.054] Forwarding server listening on port 61527 [17:48:18.054] Waiting for ssh tunnel to be ready [17:48:18.055] [Forwarding server port 61527] Got connection 0 [17:48:18.057] Tunneled port 37307 to local port 61527 [17:48:18.057] Resolved "ssh-remote+root@localhost" to "port 61527" [17:48:18.069] Initizing new exec server for ssh-remote+root@localhost [17:48:18.069] Resolving exec server at port 61527 [17:48:18.073] [Forwarding server port 61527] Got connection 1 [17:48:18.093] > [17:48:18.161] Exec server for ssh-remote+root@localhost created and cached [17:48:18.167] ------ [17:48:18.189] [server] Checking /root/.vscode-server/cli/servers/Stable-e10f2369d0d9614a452462f2e01cdc4aa9486296/log.txt and /root/.vscode-server/cli/servers/Stable-e10f2369d0d9614a452462f2e01cdc4aa9486296/pid.txt for a running server... [17:48:18.230] [server] Installing and setting up Visual Studio Code Server... [17:48:19.122] [server] Downloading Visual Studio Code server -> /tmp/.tmpKEJ6xF/vscode-server-linux-legacy-x64.tar.gz [17:48:19.123] [server] server download progress: 0/59645501 (0%) [17:48:19.254] [server] server download progress: 2105265/59645501 (4%) [17:48:19.297] [server] server download progress: 4204769/59645501 (7%) [17:48:19.345] [server] server download progress: 6307840/59645501 (11%) [17:48:19.395] [server] server download progress: 8412694/59645501 (14%) [17:48:19.438] [server] server download progress: 10515925/59645501 (18%) [17:48:19.481] [server] server download progress: 12615680/59645501 (21%) [17:48:19.524] [server] server download progress: 14717259/59645501 (25%) [17:48:19.567] [server] server download progress: 16822279/59645501 (28%) [17:48:19.610] [server] server download progress: 18921732/59645501 (32%) [17:48:19.653] [server] server download progress: 21020672/59645501 (35%) [17:48:19.696] [server] server download progress: 23123157/59645501 (39%) [17:48:19.742] [server] server download progress: 25222824/59645501 (42%) [17:48:19.790] [server] server download progress: 27327226/59645501 (46%) [17:48:19.835] [server] server download progress: 29430395/59645501 (49%) [17:48:19.881] [server] server download progress: 31529447/59645501 (53%) [17:48:19.932] [server] server download progress: 33634279/59645501 (56%) [17:48:19.979] [server] server download progress: 35737664/59645501 (60%) [17:48:20.025] [server] server download progress: 37836142/59645501 (63%) [17:48:20.077] [server] server download progress: 39933424/59645501 (67%) [17:48:20.126] [server] server download progress: 42033152/59645501 (70%) [17:48:20.169] [server] server download progress: 44136441/59645501 (74%) [17:48:20.215] [server] server download progress: 46235565/59645501 (78%) [17:48:20.261] [server] server download progress: 48337485/59645501 (81%) [17:48:20.303] [server] server download progress: 50435094/59645501 (85%) [17:48:20.347] [server] server download progress: 52534396/59645501 (88%) [17:48:20.395] [server] server download progress: 54637735/59645501 (92%) [17:48:20.440] [server] server download progress: 56742529/59645501 (95%) [17:48:20.483] [server] server download progress: 58839811/59645501 (99%) [17:48:20.500] [server] server download progress: 59645501/59645501 (100%) [17:48:21.001] [server] server inflate progress: 89/1763 (5%) [17:48:21.011] [server] server inflate progress: 179/1763 (10%) [17:48:21.117] [server] server inflate progress: 269/1763 (15%) [17:48:21.146] [server] server inflate progress: 359/1763 (20%) [17:48:21.153] [server] server inflate progress: 449/1763 (25%) [17:48:21.168] [server] server inflate progress: 539/1763 (31%) [17:48:21.179] [server] server inflate progress: 629/1763 (36%) [17:48:21.189] [server] server inflate progress: 719/1763 (41%) [17:48:21.195] [server] server inflate progress: 809/1763 (46%) [17:48:21.203] [server] server inflate progress: 899/1763 (51%) [17:48:21.209] [server] server inflate progress: 989/1763 (56%) [17:48:21.219] [server] server inflate progress: 1079/1763 (61%) [17:48:21.609] [server] server inflate progress: 1169/1763 (66%) [17:48:21.652] [server] server inflate progress: 1259/1763 (71%) [17:48:21.674] [server] server inflate progress: 1349/1763 (77%) [17:48:21.689] [server] server inflate progress: 1439/1763 (82%) [17:48:21.699] [server] server inflate progress: 1529/1763 (87%) [17:48:21.726] [server] server inflate progress: 1619/1763 (92%) [17:48:21.739] [server] server inflate progress: 1709/1763 (97%) [17:48:21.758] [server] server inflate progress: 1763/1763 (100%) [17:48:21.896] [server] Server integrity verified, version: 1.94.1 / e10f2369d0d9614a452462f2e01cdc4aa9486296 / x64 / [17:48:21.903] [server] Server setup complete [17:48:21.903] [server] Starting server... [17:48:21.904] [server] Starting server with command... Command { std: "/root/.vscode-server/cli/servers/Stable-e10f2369d0d9614a452462f2e01cdc4aa9486296/server/bin/code-server" "--connection-token=remotessh" "--accept-server-license-terms" "--start-server" "--enable-remote-auto-shutdown" "--socket-path=/tmp/code-13976418-08d6-46ee-b1b0-5d0169551c32", kill_on_drop: false } [17:48:21.949] [server] * [17:48:21.949] [server] * Visual Studio Code Server [17:48:21.949] [server] * [17:48:21.949] [server] * By using the software, you agree to [17:48:21.949] [server] * the Visual Studio Code Server License Terms (https://aka.ms/vscode-server-license) and [17:48:21.949] [server] * the Microsoft Privacy Statement (https://privacy.microsoft.com/en-US/privacystatement). [17:48:21.952] [server] Server bound to /tmp/code-13976418-08d6-46ee-b1b0-5d0169551c32 [17:48:21.952] [server] Extension host agent listening on /tmp/code-13976418-08d6-46ee-b1b0-5d0169551c32 [17:48:21.952] [server] parsed location: "/tmp/code-13976418-08d6-46ee-b1b0-5d0169551c32" [17:48:21.952] [server] [17:48:21.953] [server] Server started [17:48:22.079] [server] [21:48:22] [17:48:22.130] [server] [17:48:22.130] [server] [17:48:22.130] [server] [17:48:22.132] [server] [21:48:22] Extension host agent started. [17:48:22.176] [server] [21:48:22] Started initializing default profile extensions in extensions installation folder. file:///root/.vscode-server/extensions [17:48:22.181] [server] [21:48:22] [][b4b4de40][ExtensionHostConnection] New connection established. [17:48:22.240] [server] [21:48:22] [][33a7367a][ManagementConnection] New connection established. [17:48:22.240] [server] [21:48:22] Completed initializing default profile extensions in extensions installation folder. file:///root/.vscode-server/extensions [17:48:22.241] [server] [21:48:22] [][b4b4de40][ExtensionHostConnection] <161> Launched Extension Host Process. [17:48:23.821] Opening exec server for ssh-remote+root@localhost [17:48:23.865] Opening exec server for ssh-remote+root@localhost [17:48:23.927] Verified and reusing cached exec server for ssh-remote+root@localhost [17:48:23.930] Verified and reusing cached exec server for ssh-remote+root@localhost [17:48:23.990] Opening exec server for ssh-remote+root@localhost [17:48:24.060] Verified and reusing cached exec server for ssh-remote+root@localhost [17:53:22.133] [server] New EH opened, aborting shutdown [17:53:22.134] [server] [21:53:22] New EH opened, aborting shutdown
ofek commented 1 month ago

I noticed it sends a shell script that is temporarily saved so I captured it:

import shutil
from pathlib import Path
from tempfile import gettempdir
from time import sleep

def main():
    temp_dir = Path(gettempdir())
    while True:
        for entry in temp_dir.iterdir():
            if entry.stem.startswith('vscode-linux-multi-line-command-localhost-'):
                shutil.copy2(entry, Path.home() / 'Desktop')
                return

        sleep(0.1)

Here are the contents:

```sh # shellcheck shell=sh echo "88eae011963a: running" echo "Script executing under PID: $$" VSC_TMP="${XDG_RUNTIME_DIR:-/tmp}" # Configuration # set -u ## TODO: Audit that none of these values can intentionally be empty UUID="88eae011963a" COMMIT_ID="e10f2369d0d9614a452462f2e01cdc4aa9486296" QUALITY="stable" TOKEN="" VSCODE_AGENT_FOLDER="$HOME/.vscode-server" ALLOW_CLIENT_DOWNLOAD="0" FORCE_CLIENT_DOWNLOAD="0" CLI_NAME_IN_ARCHIVE="code" IGNORE_WGET_CONFIG_FLAG=" --no-config " IGNORE_CURL_CONFIG_FLAG=" --disable " WGET_TRIES_SEGMENT="" LISTEN_ARGS="--on-host=127.0.0.1 --on-port" CLI_NAME_ON_DISK="${CLI_NAME_IN_ARCHIVE}-${COMMIT_ID}" CLI_PATH="${VSCODE_AGENT_FOLDER}/${CLI_NAME_ON_DISK}" CLI_LOG_FILE="${VSCODE_AGENT_FOLDER}/.cli.${COMMIT_ID}.log" # Marker strings GET_DOWNLOAD_SERVER_START_TRIGGER="88eae011963a:trigger_server_download" GET_DOWNLOAD_SERVER_END_TRIGGER="88eae011963a:trigger_server_download_end" GET_PROGRESS_DOWNLOADING="88eae011963a%%1%%" GET_PROGRESS_INSTALLING="88eae011963a%%2%%" # set +u ## TODO: See above UNPACK_RESULT= DID_LOCAL_DOWNLOAD=0 DOWNLOAD_TIME= INSTALL_TIME= SERVER_START_TIME= fail_with_exitcode() { echo "${UUID}: start" echo "exitCode==$1==" echo_common_results echo "${UUID}: end" exit 0 } echo_common_results() { echo "listeningOn==$LISTENING_ON==" echo "osReleaseId==$OSRELEASEID==" echo "arch==$ARCH==" echo "vscodeArch==$VSCODE_ARCH==" echo "bitness==$BITNESS==" echo "tmpDir==$VSC_TMP==" echo "platform==$PLATFORM==" echo "unpackResult==$UNPACK_RESULT==" echo "didLocalDownload==$DID_LOCAL_DOWNLOAD==" echo "downloadTime==$DOWNLOAD_TIME==" echo "installTime==$INSTALL_TIME==" echo "serverStartTime==$SERVER_START_TIME==" echo "execServerToken==${TOKEN}==" echo "platformDownloadPath==$PLATFORM_DOWNLOAD_PATH==" } millis() { d=$(date +%s%N) # Test if 'd' contains any non-digit characters if [ -z "${d##*[!0-9]*}" ] || [ "$PLATFORM" != "linux" ]; then # Fallback for MacOS or any date binary that doesn't handle '%N' echo $(($(date +%s)*1000)) return fi echo $((d/1000000)) } elapsed() { echo $(($(millis) - $1)) } if [ ! -d "$VSCODE_AGENT_FOLDER" ]; then mkdir -p "$VSCODE_AGENT_FOLDER" error_code=$? if [ "${error_code}" -gt 0 ]; then echo "Creating the server install dir failed..." fail_with_exitcode 34 fi fi printenv_indent() { echo "printenv:" printenv | sed 's/^/ /' } # # Get OS name # OSRELEASEID=$(cat /etc/os-release 2>/dev/null | grep -a -E '^ID=' | sed 's/^[Ii][Dd]=//g' | sed 's/"//g') if [ -z "$OSRELEASEID" ] then OSRELEASEID=$(cat /usr/lib/os-release 2>/dev/null | grep -a -E '^ID=' | sed 's/^[Ii][Dd]=//g' | sed 's/"//g') if [ -z "$OSRELEASEID" ] then OSRELEASEID=$(uname -s) fi fi # # Get host platform/architecture # UNAME=$(uname -s) case $UNAME in Linux) PLATFORM=linux;; Darwin) PLATFORM=macOS;; *) echo "Unsupported platform: $UNAME" fail_with_exitcode 35 ;; esac BITNESS=$(getconf LONG_BIT) ARCH=$(uname -m) case $ARCH in x86_64) VSCODE_ARCH="x64";; armv7l | armv8l) VSCODE_ARCH="armhf" ;; arm64 | aarch64) if [ "$BITNESS" = 32 ]; then # Can have 32-bit userland on 64-bit kernel VSCODE_ARCH="armhf" else VSCODE_ARCH="arm64" fi ;; *) OSRELEASE=$(uname -r) case $OSRELEASE in *x86_64*) VSCODE_ARCH="x64";; *) echo "Unsupported architecture: $ARCH" fail_with_exitcode 27 ;; esac ;; esac if [ "$PLATFORM" = linux ]; then if [ "$VSCODE_ARCH" = armhf ]; then PLATFORM_DOWNLOAD_PATH=cli-linux-armhf else PLATFORM_DOWNLOAD_PATH=cli-alpine-$VSCODE_ARCH fi elif [ "$VSCODE_ARCH" = "arm64" ]; then PLATFORM_DOWNLOAD_PATH=cli-darwin-arm64 else PLATFORM_DOWNLOAD_PATH=cli-darwin-x64 fi # # Delete old CLIs if needed # # shellcheck disable=SC2010 TO_DELETE=$(ls -1 -t "$VSCODE_AGENT_FOLDER" | grep -E "code(-insiders)?-[a-fA-F0-9]{40}" | tail -n +6) for CLI_TO_DELETE in $TO_DELETE; do target_dir="$VSCODE_AGENT_FOLDER/$CLI_TO_DELETE" echo "Deleting old install $target_dir" rm -rf "$target_dir" done do_client_download() { DID_LOCAL_DOWNLOAD=1 echo "Trigger local server download" echo "${GET_DOWNLOAD_SERVER_START_TRIGGER}" echo artifact==$PLATFORM_DOWNLOAD_PATH== echo destFolder==$VSCODE_AGENT_FOLDER== echo destFolder2==/vscode-cli-$COMMIT_ID.tar.gz== echo "${GET_DOWNLOAD_SERVER_END_TRIGGER}" echo "Waiting for client to transfer server archive..." echo "Waiting for $VSCODE_AGENT_FOLDER/vscode-cli-$COMMIT_ID.tar.gz.done and vscode-server.tar.gz to exist" while true; do if [ -f "$VSCODE_AGENT_FOLDER/vscode-cli-$COMMIT_ID.tar.gz.done" ]; then if [ ! -f "$VSCODE_AGENT_FOLDER/vscode-cli-$COMMIT_ID.tar.gz" ]; then echo "Found flag but not server tar - server transfer failed" fail_with_exitcode 31 fi echo "Found flag and server on host" rm "$VSCODE_AGENT_FOLDER/vscode-cli-$COMMIT_ID.tar.gz.done" break else printf ' ' sleep 3 fi done } do_client_download_or_fail() { error_code="${1:-"1"}" if [ "$DID_LOCAL_DOWNLOAD" = "1" ]; then echo "Already attempted local download, failing" fail_with_exitcode "$error_code" elif [ $ALLOW_CLIENT_DOWNLOAD = "1" ]; then do_client_download else fail_with_exitcode "$error_code" fi } is_program_from_busybox() { program=$1 if command -v busybox > /dev/null 2>&1 then # Check symlink from program to busybox if [ -L "$(command -v "$program")" ] && [ "$(readlink -f "$(command -v "$program")")" = "$(command -v busybox)" ] then echo "Program '$program' is provided by busybox" >&2 echo 'yes' return fi fi echo 'no' } supports_flag() { program="$1" flag="$2" if command -v "$program" > /dev/null 2>&1; then if "$program" --help 2>&1 | grep -q -- "$flag" then echo "Program '$program' appears to support flag '$flag'" >&2 echo 'yes' return fi fi echo "Program '$program' is not available or does not appear to support flag '$flag'" >&2 echo 'no' } do_host_download() { start=$(millis) echo "${GET_PROGRESS_DOWNLOADING}" DOWNLOAD_URL=https://update.code.visualstudio.com/commit:$COMMIT_ID/$PLATFORM_DOWNLOAD_PATH/${QUALITY} if command -v wget > /dev/null 2>&1 then echo "Downloading with wget" IS_WGET_BUSYBOX=$(is_program_from_busybox wget) echo "wget is from busybox: $IS_WGET_BUSYBOX" if [ "$IS_WGET_BUSYBOX" = 'no' ] then # Not busybox. # Assuming its GNU wget or similar if [ -n "$IGNORE_WGET_CONFIG_FLAG" ] && [ "$(supports_flag 'wget' '--no-config')" = "no" ]; then echo "Detected that this version of wget does not support '--no-config'. Will not ignore wget default configuration files." IGNORE_WGET_CONFIG_FLAG="" fi WGET_ERRORS=$(2>&1 wget ${IGNORE_WGET_CONFIG_FLAG} ${WGET_TRIES_SEGMENT} --connect-timeout=7 --dns-timeout=7 -nv -O vscode-cli-$COMMIT_ID.tar.gz ${DOWNLOAD_URL}) else # Is busybox. # Remove flags for the sake of compatibility WGET_ERRORS=$(2>&1 wget -O vscode-cli-$COMMIT_ID.tar.gz ${DOWNLOAD_URL}) fi error_code=$? if [ $error_code -ne 0 ] then echo "wget download failed" echo "$WGET_ERRORS" printenv_indent do_client_download_or_fail 25 else echo "Download complete" DOWNLOAD_TIME=$(elapsed $start) fi else command -v curl > /dev/null 2>&1 error_code=$? if [ $error_code -eq 0 ] then echo "Downloading with curl" CURL_STATUS_CODE_RESULT=$(curl ${IGNORE_CURL_CONFIG_FLAG} --connect-timeout 7 -L $DOWNLOAD_URL --output vscode-cli-$COMMIT_ID.tar.gz -w "%{http_code}") error_code=$? curl_status_code_if_2xx=$(echo "$CURL_STATUS_CODE_RESULT" | grep -E "^2[0-9]{2}$") if [ $error_code -ne 0 ] || [ -z "$curl_status_code_if_2xx" ] then echo "curl download failed" echo "HTTP status code: $CURL_STATUS_CODE_RESULT" printenv_indent do_client_download_or_fail 25 else echo "Download complete" DOWNLOAD_TIME=$(elapsed $start) fi else printenv_indent echo "Neither wget nor curl is installed" do_client_download_or_fail 26 fi fi } do_install() { start=$(millis) echo "${GET_PROGRESS_INSTALLING}" UNPACK_RESULT="success" echo "tar --version: $(tar --version)" tar -xf vscode-cli-$COMMIT_ID.tar.gz --no-same-owner TAR_EXIT=$? INSTALL_TIME=$(elapsed $start) if [ $TAR_EXIT -ne 0 ] then echo "ERROR: tar exited with a non-zero exit code: $TAR_EXIT" UNPACK_RESULT="error" do_client_download_or_fail "37" do_install return fi mv "$CLI_NAME_IN_ARCHIVE" "$CLI_PATH" # cheap sanity check if ! eval "$CLI_PATH --version" then UNPACK_RESULT="missingFiles" echo "ERROR: $CLI_PATH don't exist" do_client_download_or_fail "37" do_install return fi # Delete the leftover folder which might have -web prefix, and the .tar.gz rm -rf vscode-cli* } # # Install if needed # if [ ! -f "$CLI_PATH" ] then echo "Installing to $VSCODE_AGENT_FOLDER..." STASHED_WORKING_DIR="$(pwd)" cd "$VSCODE_AGENT_FOLDER" || fail_with_exitcode 38 if [ $FORCE_CLIENT_DOWNLOAD = "1" ]; then do_client_download else do_host_download fi do_install cd "$STASHED_WORKING_DIR" || fail_with_exitcode 38 else echo "Found existing installation at $VSCODE_AGENT_FOLDER..." fi # # Start the server # start_server() { echo "Starting VS Code CLI..." printenv_indent start=$(millis) if [ -f $CLI_LOG_FILE ]; then echo "Removing old logfile at $CLI_LOG_FILE" rm "$CLI_LOG_FILE" # See #6265 fi # Stop exporting VSCODE_AGENT_FOLDER once https://github.com/microsoft/vscode/pull/228287 is available and replace with: # --extensions-dir "$VSCODE_AGENT_FOLDER/extensions" --user-data-dir "$VSCODE_AGENT_FOLDER/data" # See https://github.com/microsoft/vscode-internalbacklog/issues/2604, https://github.com/microsoft/vscode-remote-release/issues/10255 export VSCODE_AGENT_FOLDER VSCODE_CLI_REQUIRE_TOKEN=${TOKEN} "$CLI_PATH" command-shell --cli-data-dir "$VSCODE_AGENT_FOLDER/cli" --parent-process-id $$ ${LISTEN_ARGS} > "$CLI_LOG_FILE" 2>&1 < /dev/null & CLI_PID=$! echo "Spawned remote CLI: $!" count=0 max_retries=15 while [ $count -lt $max_retries ]; do count=$((count + 1)) LISTENING_ON=$(cat "$CLI_LOG_FILE" | grep -a -E 'Listening on .+' | grep -v grep | sed 's/Listening on //') if [ "$LISTENING_ON" != '' ] then break fi # "If sig is 0 (the null signal), error checking is performed but no signal is actually sent. # The null signal can be used to check the validity of pid."" # Source: https://pubs.opengroup.org/onlinepubs/007908799/xsh/kill.html if ! kill -0 $CLI_PID > /dev/null; then echo "Exec server process not found" cat $CLI_LOG_FILE break fi echo "Waiting for server log..." sleep .03 done SERVER_START_TIME=$(elapsed $start) } start_server # What we echo below cannot be wider than 80 characters echo "${UUID}: start" echo_common_results echo "${UUID}: end" while true; do sleep 180; printf ' '; done ```

Indeed, there is an explicit check for the exact commit (and therefore directory structure) of the VS Code instance running on the host. Is there a way to install ahead of time? I was under the assumption that this was supported.

ofek commented 1 month ago

@hediet Do you have any idea why this might be happening?

ofek commented 1 month ago

I still can't get this to work.

mmirate commented 3 weeks ago
while true; do sleep 180; printf ' '; done

Aha, that's what's been polluting my servers with leftover do-nothing shell processes! Any way to turn that off?