Files
dotfiles/.vscode/extensions/ms-vscode-remote.remote-ssh-0.122.0/out/install-script/scripts/linux-exec-server-installer.sh
2025-12-15 12:50:23 -05:00

453 lines
12 KiB
Bash

# shellcheck shell=sh
echo "#<<startMarker>>"
echo "Script executing under PID: $$"
VSC_TMP="${XDG_RUNTIME_DIR:-/tmp}"
# Configuration
UUID="#<<uuid>>"
COMMIT_ID="#<<commitId>>"
QUALITY="#<<quality>>"
TOKEN="#<<token>>"
VSCODE_AGENT_FOLDER="#<<vscodeAgentFolder>>"
ALLOW_CLIENT_DOWNLOAD="#<<allowClientDownload>>"
FORCE_CLIENT_DOWNLOAD="#<<forceClientDownload>>"
CLI_NAME_IN_ARCHIVE="#<<cliNameInArchive>>"
IGNORE_WGET_CONFIG_FLAG="#<<ignoreWgetConfigFlag>>"
IGNORE_CURL_CONFIG_FLAG="#<<ignoreCurlConfigFlag>>"
WGET_TRIES_SEGMENT="#<<wgetTriesSegment>>"
LISTEN_ARGS="#<<listenArgs>>"
VERBOSE="#<<verbose>>"
HTTP_PROXY_INPUT="#<<httpProxy>>"
HTTPS_PROXY_INPUT="#<<httpsProxy>>"
RECONNECTION_GRACE_TIME="#<<reconnectionGraceTime>>"
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="#<<getDownloadServerStartTrigger>>"
GET_DOWNLOAD_SERVER_END_TRIGGER="#<<getDownloadServerEndTrigger>>"
GET_PROGRESS_DOWNLOADING="#<<getProgressDownloading>>"
GET_PROGRESS_INSTALLING="#<<getProgressInstalling>>"
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=="
#<<printVars>>
}
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))
}
printenv_indent() {
if [ "$VERBOSE" = "1" ]; then
echo "printenv:"
printenv | sed 's/^/ /'
fi
}
[ -z "${http_proxy}" ] && [ "${HTTP_PROXY_INPUT}" != "" ] && export http_proxy="$HTTP_PROXY_INPUT"
[ -z "${https_proxy}" ] && [ "${HTTPS_PROXY_INPUT}" != "" ] && export https_proxy="$HTTPS_PROXY_INPUT"
#
# 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 #<<ExitCode.UnsupportedPlatform>>
;;
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 #<<ExitCode.UnsupportedArch>>
;;
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
if [ ! -d "$VSCODE_AGENT_FOLDER" ]; then
mkdir -p "$VSCODE_AGENT_FOLDER"
chmod 750 "$VSCODE_AGENT_FOLDER"
error_code=$?
if [ "${error_code}" -gt 0 ]; then
echo "Creating the server install dir failed..."
fail_with_exitcode #<<ExitCode.CreateInstallDirFailed>>
fi
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 #<<ExitCode.ServerTransferFailed>>
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}"
UPDATE_URL="#<<updateUrl>>"
DOWNLOAD_URL=$UPDATE_URL/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 #<<ExitCode.ServerDownloadFailed>>
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 #<<ExitCode.ServerDownloadFailed>>
else
echo "Download complete"
DOWNLOAD_TIME=$(elapsed $start)
fi
else
printenv_indent
echo "Neither wget nor curl is installed"
do_client_download_or_fail #<<ExitCode.NoDownloaderAvailable>>
fi
fi
}
do_install() {
start=$(millis)
echo "${GET_PROGRESS_INSTALLING}"
UNPACK_RESULT="#<<InstallUnpackCode.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="#<<InstallUnpackCode.Error>>"
do_client_download_or_fail "#<<ExitCode.UnpackFailed>>"
do_install
return
fi
mv "$CLI_NAME_IN_ARCHIVE" "$CLI_PATH"
# cheap sanity check
if ! eval "$CLI_PATH --version"
then
UNPACK_RESULT="#<<InstallUnpackCode.MissingFiles>>"
echo "ERROR: $CLI_PATH don't exist"
do_client_download_or_fail "#<<ExitCode.UnpackFailed>>"
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 #<<ExitCode.ChangeDirFailed>>
if [ $FORCE_CLIENT_DOWNLOAD = "1" ]; then
do_client_download
else
do_host_download
fi
do_install
cd "$STASHED_WORKING_DIR" || fail_with_exitcode #<<ExitCode.ChangeDirFailed>>
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
touch $CLI_LOG_FILE
chmod 600 $CLI_LOG_FILE
LOG_LEVEL_FLAG=""
if [ "$VERBOSE" = "1" ]; then
echo "Setting '--log trace' on CLI"
LOG_LEVEL_FLAG="--log trace"
fi
RECONNECTION_FLAG=""
if [ -n "$RECONNECTION_GRACE_TIME" ]; then
RECONNECTION_FLAG="--reconnection-grace-time $RECONNECTION_GRACE_TIME"
fi
VSCODE_CLI_REQUIRE_TOKEN=${TOKEN} "$CLI_PATH" command-shell ${LOG_LEVEL_FLAG} ${RECONNECTION_FLAG} --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
if grep -q "This machine does not meet .* prerequisites, expected either..." "$CLI_LOG_FILE"; then
fail_with_exitcode #<<ExitCode.LinuxPrereqs>>
fi
break
fi
echo "Waiting for server log..."
sleep .03 || sleep 1
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