mirror of
https://github.com/jeanp413/open-remote-ssh.git
synced 2026-07-16 19:17:11 +02:00
refactor: extract install scripts from serverSetup.ts into script files (#287)
This commit is contained in:
@@ -7,3 +7,4 @@
|
||||
!README.md
|
||||
!lib/extension.js
|
||||
!resources/icon.png
|
||||
!src/scripts/**
|
||||
|
||||
+2
-1
@@ -261,7 +261,8 @@ export class RemoteSSHResolver implements vscode.RemoteAuthorityResolver, vscode
|
||||
remotePlatformMap[sshDest.hostname],
|
||||
remoteServerListenOnSocket,
|
||||
customInstallPath,
|
||||
this.logger
|
||||
this.logger,
|
||||
this.context.extensionPath
|
||||
);
|
||||
|
||||
for (const key of Object.keys(envVariables)) {
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
# Server installation script
|
||||
|
||||
$TMP_DIR="$env:TEMP\$([System.IO.Path]::GetRandomFileName())"
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
$DISTRO_VERSION="%%DISTRO_VERSION%%"
|
||||
$DISTRO_COMMIT="%%DISTRO_COMMIT%%"
|
||||
$DISTRO_QUALITY="%%DISTRO_QUALITY%%"
|
||||
$DISTRO_VSCODIUM_RELEASE="%%DISTRO_VSCODIUM_RELEASE%%"
|
||||
|
||||
$SERVER_APP_NAME="%%SERVER_APP_NAME%%"
|
||||
$SERVER_INITIAL_EXTENSIONS="%%SERVER_INITIAL_EXTENSIONS%%"
|
||||
$SERVER_LISTEN_FLAG="%%SERVER_LISTEN_FLAG%%"
|
||||
$SERVER_DATA_DIR="%%SERVER_DATA_DIR%%"
|
||||
$SERVER_DATA_DIR_FLAG="%%SERVER_DATA_DIR_FLAG%%"
|
||||
$SERVER_DIR="$SERVER_DATA_DIR\bin\$DISTRO_COMMIT"
|
||||
$SERVER_SCRIPT="$SERVER_DIR\bin\$SERVER_APP_NAME.cmd"
|
||||
$SERVER_LOGFILE="$SERVER_DATA_DIR\.$DISTRO_COMMIT.log"
|
||||
$SERVER_PIDFILE="$SERVER_DATA_DIR\.$DISTRO_COMMIT.pid"
|
||||
$SERVER_TOKENFILE="$SERVER_DATA_DIR\.$DISTRO_COMMIT.token"
|
||||
$SERVER_ARCH=
|
||||
$SERVER_CONNECTION_TOKEN=
|
||||
$SERVER_DOWNLOAD_URL="%%SERVER_DOWNLOAD_URL%%"
|
||||
$SERVER_VALIDATION_FLAG="%%SERVER_VALIDATION_FLAG%%"
|
||||
|
||||
$LISTENING_ON=
|
||||
$OS_RELEASE_ID=
|
||||
$ARCH=
|
||||
$PLATFORM="win32"
|
||||
|
||||
function printInstallResults($code) {
|
||||
"%%SCRIPT_ID%%: start"
|
||||
"exitCode==$code=="
|
||||
"listeningOn==$LISTENING_ON=="
|
||||
"connectionToken==$SERVER_CONNECTION_TOKEN=="
|
||||
"logFile==$SERVER_LOGFILE=="
|
||||
"osReleaseId==$OS_RELEASE_ID=="
|
||||
"arch==$ARCH=="
|
||||
"platform==$PLATFORM=="
|
||||
"tmpDir==$TMP_DIR=="
|
||||
%%ENV_VAR_LINES%%
|
||||
"%%SCRIPT_ID%%: end"
|
||||
}
|
||||
|
||||
# Check machine architecture
|
||||
$ARCH=$env:PROCESSOR_ARCHITECTURE
|
||||
# Use x64 version for ARM64, as it's not yet available.
|
||||
if(($ARCH -eq "AMD64") -or ($ARCH -eq "IA64") -or ($ARCH -eq "ARM64")) {
|
||||
$SERVER_ARCH="x64"
|
||||
}
|
||||
else {
|
||||
"Error architecture not supported: $ARCH"
|
||||
printInstallResults 1
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Create installation folder
|
||||
if(!(Test-Path $SERVER_DIR)) {
|
||||
try {
|
||||
ni -it d $SERVER_DIR -f -ea si
|
||||
} catch {
|
||||
"Error creating server install directory - $($_.ToString())"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if(!(Test-Path $SERVER_DIR)) {
|
||||
"Error creating server install directory"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
cd $SERVER_DIR
|
||||
|
||||
# Check if server script is already installed
|
||||
if(!(Test-Path $SERVER_SCRIPT)) {
|
||||
del vscode-server.tar.gz
|
||||
|
||||
$REQUEST_ARGUMENTS = @{
|
||||
Uri="$SERVER_DOWNLOAD_URL"
|
||||
TimeoutSec=20
|
||||
OutFile="vscode-server.tar.gz"
|
||||
UseBasicParsing=$True
|
||||
}
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
Invoke-RestMethod @REQUEST_ARGUMENTS
|
||||
|
||||
if(Test-Path "vscode-server.tar.gz") {
|
||||
tar -xf vscode-server.tar.gz --strip-components 1
|
||||
|
||||
del vscode-server.tar.gz
|
||||
}
|
||||
|
||||
if(!(Test-Path $SERVER_SCRIPT)) {
|
||||
"Error while installing the server binary"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
else {
|
||||
"Server script already installed in $SERVER_SCRIPT"
|
||||
}
|
||||
|
||||
# Modify the commit in the remote server to match the local value
|
||||
if(%%MODIFY_PRODUCT_JSON%%) {
|
||||
echo "Will modify product.json on remote to match the commit value"
|
||||
(Get-Content -Raw "$SERVER_DIR\product.json") -replace '"commit": "[0-9a-f]+",', ('"commit": "' + $DISTRO_COMMIT + '",') |
|
||||
Set-Content -NoNewLine "$SERVER_DIR\product.json"
|
||||
}
|
||||
|
||||
# Try to find if server is already running
|
||||
if(Get-Process node -ErrorAction SilentlyContinue | Where-Object Path -Like "$SERVER_DIR\*") {
|
||||
echo "Server script is already running $SERVER_SCRIPT"
|
||||
}
|
||||
else {
|
||||
if(Test-Path $SERVER_LOGFILE) {
|
||||
del $SERVER_LOGFILE
|
||||
}
|
||||
if(Test-Path $SERVER_PIDFILE) {
|
||||
del $SERVER_PIDFILE
|
||||
}
|
||||
if(Test-Path $SERVER_TOKENFILE) {
|
||||
del $SERVER_TOKENFILE
|
||||
}
|
||||
|
||||
$SERVER_CONNECTION_TOKEN="%%SERVER_CONNECTION_TOKEN%%"
|
||||
[System.IO.File]::WriteAllLines($SERVER_TOKENFILE, $SERVER_CONNECTION_TOKEN)
|
||||
|
||||
$SCRIPT_ARGUMENTS="--start-server --host=127.0.0.1 $SERVER_LISTEN_FLAG $SERVER_DATA_DIR_FLAG $SERVER_VALIDATION_FLAG $SERVER_INITIAL_EXTENSIONS --connection-token-file $SERVER_TOKENFILE --telemetry-level off --enable-remote-auto-shutdown --accept-server-license-terms *> '$SERVER_LOGFILE'"
|
||||
|
||||
$START_ARGUMENTS = @{
|
||||
FilePath = "powershell.exe"
|
||||
WindowStyle = "hidden"
|
||||
ArgumentList = @(
|
||||
"-ExecutionPolicy", "Unrestricted", "-NoLogo", "-NoProfile", "-NonInteractive", "-c", "$SERVER_SCRIPT $SCRIPT_ARGUMENTS"
|
||||
)
|
||||
PassThru = $True
|
||||
}
|
||||
|
||||
$SERVER_ID = (start @START_ARGUMENTS).ID
|
||||
|
||||
if($SERVER_ID) {
|
||||
[System.IO.File]::WriteAllLines($SERVER_PIDFILE, $SERVER_ID)
|
||||
}
|
||||
}
|
||||
|
||||
if(Test-Path $SERVER_TOKENFILE) {
|
||||
$SERVER_CONNECTION_TOKEN="$(cat $SERVER_TOKENFILE)"
|
||||
}
|
||||
else {
|
||||
"Error server token file not found $SERVER_TOKENFILE"
|
||||
printInstallResults 1
|
||||
exit 0
|
||||
}
|
||||
|
||||
sleep -Milliseconds 500
|
||||
|
||||
$SELECT_ARGUMENTS = @{
|
||||
Path = $SERVER_LOGFILE
|
||||
Pattern = "Extension host agent listening on (\d+)"
|
||||
}
|
||||
|
||||
for($I = 1; $I -le 5; $I++) {
|
||||
if(Test-Path $SERVER_LOGFILE) {
|
||||
$GROUPS = (Select-String @SELECT_ARGUMENTS).Matches.Groups
|
||||
|
||||
if($GROUPS) {
|
||||
$LISTENING_ON = $GROUPS[1].Value
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
sleep -Milliseconds 500
|
||||
}
|
||||
|
||||
if(!(Test-Path $SERVER_LOGFILE)) {
|
||||
"Error server log file not found $SERVER_LOGFILE"
|
||||
printInstallResults 1
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Finish server setup
|
||||
printInstallResults 0
|
||||
|
||||
if($SERVER_ID) {
|
||||
while($True) {
|
||||
if(!(gps -Id $SERVER_ID)) {
|
||||
"server died, exit"
|
||||
exit 0
|
||||
}
|
||||
|
||||
sleep 30
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
# Server installation script
|
||||
|
||||
TMP_DIR="${XDG_RUNTIME_DIR:-"/tmp"}"
|
||||
|
||||
DISTRO_VERSION="%%DISTRO_VERSION%%"
|
||||
DISTRO_COMMIT="%%DISTRO_COMMIT%%"
|
||||
DISTRO_QUALITY="%%DISTRO_QUALITY%%"
|
||||
DISTRO_VSCODIUM_RELEASE="%%DISTRO_VSCODIUM_RELEASE%%"
|
||||
|
||||
SERVER_APP_NAME="%%SERVER_APP_NAME%%"
|
||||
SERVER_INITIAL_EXTENSIONS="%%SERVER_INITIAL_EXTENSIONS%%"
|
||||
SERVER_LISTEN_FLAG="%%SERVER_LISTEN_FLAG%%"
|
||||
SERVER_DATA_DIR="%%SERVER_DATA_DIR%%"
|
||||
SERVER_DATA_DIR_FLAG="%%SERVER_DATA_DIR_FLAG%%"
|
||||
SERVER_DIR="$SERVER_DATA_DIR/bin/$DISTRO_COMMIT"
|
||||
SERVER_SCRIPT="$SERVER_DIR/bin/$SERVER_APP_NAME"
|
||||
SERVER_LOGFILE="$SERVER_DATA_DIR/.$DISTRO_COMMIT.log"
|
||||
SERVER_PIDFILE="$SERVER_DATA_DIR/.$DISTRO_COMMIT.pid"
|
||||
SERVER_TOKENFILE="$SERVER_DATA_DIR/.$DISTRO_COMMIT.token"
|
||||
SERVER_ARCH=
|
||||
SERVER_CONNECTION_TOKEN=
|
||||
SERVER_DOWNLOAD_URL=
|
||||
SERVER_VALIDATION_FLAG="%%SERVER_VALIDATION_FLAG%%"
|
||||
|
||||
LISTENING_ON=
|
||||
OS_RELEASE_ID=
|
||||
ARCH=
|
||||
PLATFORM=
|
||||
|
||||
# Mimic output from logs of remote-ssh extension
|
||||
print_install_results_and_exit() {
|
||||
echo "%%SCRIPT_ID%%: start"
|
||||
echo "exitCode==$1=="
|
||||
echo "listeningOn==$LISTENING_ON=="
|
||||
echo "connectionToken==$SERVER_CONNECTION_TOKEN=="
|
||||
echo "logFile==$SERVER_LOGFILE=="
|
||||
echo "osReleaseId==$OS_RELEASE_ID=="
|
||||
echo "arch==$ARCH=="
|
||||
echo "platform==$PLATFORM=="
|
||||
echo "tmpDir==$TMP_DIR=="
|
||||
%%ENV_VAR_LINES%%
|
||||
echo "%%SCRIPT_ID%%: end"
|
||||
exit 0
|
||||
}
|
||||
|
||||
LOCKFILE="$TMP_DIR/server_install.lock"
|
||||
|
||||
if command -v flock >/dev/null 2>&1; then
|
||||
exec {FD}<>"$LOCKFILE"
|
||||
# wait 30s to acquire lock, otherwise fail
|
||||
flock -x -w 30 $FD || print_install_results_and_exit 1
|
||||
trap "flock -u $FD; trap - EXIT INT HUP; exit" EXIT INT HUP
|
||||
else
|
||||
echo "Warning: flock not available, skipping install lock" >&2
|
||||
fi
|
||||
|
||||
# Check if platform is supported
|
||||
if ! command -v uname; then
|
||||
echo "Error 'uname' command not found, could not get platform/arch data."
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
KERNEL="$(uname -s)"
|
||||
case $KERNEL in
|
||||
Darwin)
|
||||
PLATFORM="darwin"
|
||||
;;
|
||||
Linux)
|
||||
PLATFORM="linux"
|
||||
;;
|
||||
FreeBSD)
|
||||
PLATFORM="freebsd"
|
||||
;;
|
||||
DragonFly)
|
||||
PLATFORM="dragonfly"
|
||||
;;
|
||||
"")
|
||||
echo "Error uname -s yields empty result"
|
||||
print_install_results_and_exit 1
|
||||
;;
|
||||
*)
|
||||
echo "Error platform not supported: $KERNEL"
|
||||
print_install_results_and_exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check machine architecture
|
||||
ARCH="$(uname -m)"
|
||||
case $ARCH in
|
||||
x86_64 | amd64)
|
||||
SERVER_ARCH="x64"
|
||||
;;
|
||||
armv7l | armv8l)
|
||||
SERVER_ARCH="armhf"
|
||||
;;
|
||||
arm64 | aarch64)
|
||||
SERVER_ARCH="arm64"
|
||||
;;
|
||||
ppc64le)
|
||||
SERVER_ARCH="ppc64le"
|
||||
;;
|
||||
riscv64)
|
||||
SERVER_ARCH="riscv64"
|
||||
;;
|
||||
loongarch64)
|
||||
SERVER_ARCH="loong64"
|
||||
;;
|
||||
s390x)
|
||||
SERVER_ARCH="s390x"
|
||||
;;
|
||||
*)
|
||||
echo "Error architecture not supported: $ARCH"
|
||||
print_install_results_and_exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||
OS_RELEASE_ID="$(grep -i '^ID=' /etc/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
|
||||
if [[ -z $OS_RELEASE_ID ]]; then
|
||||
OS_RELEASE_ID="$(grep -i '^ID=' /usr/lib/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
|
||||
if [[ -z $OS_RELEASE_ID ]]; then
|
||||
OS_RELEASE_ID="unknown"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create installation folder
|
||||
if [[ ! -d $SERVER_DIR ]]; then
|
||||
mkdir -p $SERVER_DIR
|
||||
if (( $? > 0 )); then
|
||||
echo "Error creating server install directory"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# adjust platform for vscodium download, if needed
|
||||
if [[ $OS_RELEASE_ID = alpine ]]; then
|
||||
PLATFORM=$OS_RELEASE_ID
|
||||
fi
|
||||
|
||||
SERVER_DOWNLOAD_URL="$(echo "%%SERVER_DOWNLOAD_URL_TEMPLATE%%" | sed "s/\${quality}/$DISTRO_QUALITY/g" | sed "s/\${version}/$DISTRO_VERSION/g" | sed "s/\${commit}/$DISTRO_COMMIT/g" | sed "s/\${os}/$PLATFORM/g" | sed "s/\${arch}/$SERVER_ARCH/g" | sed "s/\${release}/$DISTRO_VSCODIUM_RELEASE/g")"
|
||||
|
||||
# Check if server script is already installed
|
||||
if [[ ! -f $SERVER_SCRIPT ]]; then
|
||||
case "$PLATFORM" in
|
||||
darwin | linux | alpine | freebsd )
|
||||
;;
|
||||
*)
|
||||
echo "Error '$PLATFORM' needs manual installation of remote extension host"
|
||||
print_install_results_and_exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
pushd $SERVER_DIR > /dev/null
|
||||
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
wget --tries=3 --timeout=10 --continue --no-verbose -O vscode-server.tar.gz $SERVER_DOWNLOAD_URL
|
||||
elif command -v curl >/dev/null 2>&1; then
|
||||
curl --retry 3 --connect-timeout 10 --location --show-error --silent --output vscode-server.tar.gz $SERVER_DOWNLOAD_URL
|
||||
elif command -v fetch >/dev/null 2>&1; then
|
||||
fetch --retry --timeout=10 --quiet --output=vscode-server.tar.gz $SERVER_DOWNLOAD_URL
|
||||
else
|
||||
echo "Error no tool to download server binary"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
if (( $? > 0 )); then
|
||||
echo "Error downloading server from $SERVER_DOWNLOAD_URL"
|
||||
rm -rf vscode-server.tar.gz
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
tar -xf vscode-server.tar.gz --strip-components 1
|
||||
if (( $? > 0 )); then
|
||||
echo "Error while extracting server contents"
|
||||
rm -rf vscode-server.tar.gz
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f $SERVER_SCRIPT ]]; then
|
||||
rm -rf $SERVER_DIR/*
|
||||
echo "Error server contents are corrupted"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
rm -f vscode-server.tar.gz
|
||||
|
||||
popd > /dev/null
|
||||
else
|
||||
echo "Server script already installed in $SERVER_SCRIPT"
|
||||
fi
|
||||
|
||||
# Modify the commit in the remote server to match the local value
|
||||
if %%MODIFY_PRODUCT_JSON%%; then
|
||||
if command -v sed >/dev/null 2>&1; then
|
||||
echo "Will modify product.json on remote to match the commit value"
|
||||
sed -i -E 's/"commit": "[0-9a-f]+",/"commit": "'"$DISTRO_COMMIT"'",/' "$SERVER_DIR/product.json";
|
||||
else
|
||||
echo "Cannot find the 'sed' command, make sure it is installed to modify product.json with the matching commit."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Try to find if server is already running
|
||||
if [[ -f $SERVER_PIDFILE ]]; then
|
||||
SERVER_PID="$(cat $SERVER_PIDFILE)"
|
||||
SERVER_RUNNING_PROCESS="$(ps -o pid,args -p $SERVER_PID | grep $SERVER_SCRIPT)"
|
||||
else
|
||||
SERVER_RUNNING_PROCESS="$(ps -o pid,args -A | grep $SERVER_SCRIPT | grep -v grep)"
|
||||
fi
|
||||
|
||||
if [[ -z $SERVER_RUNNING_PROCESS ]]; then
|
||||
if [[ -f $SERVER_LOGFILE ]]; then
|
||||
rm $SERVER_LOGFILE
|
||||
fi
|
||||
if [[ -f $SERVER_TOKENFILE ]]; then
|
||||
rm $SERVER_TOKENFILE
|
||||
fi
|
||||
|
||||
touch $SERVER_TOKENFILE
|
||||
chmod 600 $SERVER_TOKENFILE
|
||||
SERVER_CONNECTION_TOKEN="%%SERVER_CONNECTION_TOKEN%%"
|
||||
echo $SERVER_CONNECTION_TOKEN > $SERVER_TOKENFILE
|
||||
|
||||
$SERVER_SCRIPT --start-server --host=127.0.0.1 $SERVER_LISTEN_FLAG $SERVER_DATA_DIR_FLAG $SERVER_VALIDATION_FLAG $SERVER_INITIAL_EXTENSIONS --connection-token-file $SERVER_TOKENFILE --telemetry-level off --enable-remote-auto-shutdown --accept-server-license-terms &> $SERVER_LOGFILE &
|
||||
echo $! > $SERVER_PIDFILE
|
||||
else
|
||||
echo "Server script is already running $SERVER_SCRIPT"
|
||||
fi
|
||||
|
||||
if [[ -f $SERVER_TOKENFILE ]]; then
|
||||
SERVER_CONNECTION_TOKEN="$(cat $SERVER_TOKENFILE)"
|
||||
else
|
||||
echo "Error server token file not found $SERVER_TOKENFILE"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
if [[ -f $SERVER_LOGFILE ]]; then
|
||||
for i in {1..35}; do
|
||||
LISTENING_ON="$(cat $SERVER_LOGFILE | grep -E 'Extension host agent listening on .+' | sed 's/Extension host agent listening on //')"
|
||||
if [[ -n $LISTENING_ON ]]; then
|
||||
break
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
|
||||
if [[ -z $LISTENING_ON ]]; then
|
||||
echo "Error server did not start successfully"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
else
|
||||
echo "Error server log file not found $SERVER_LOGFILE"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
# Finish server setup
|
||||
print_install_results_and_exit 0
|
||||
+65
-459
@@ -1,9 +1,24 @@
|
||||
import * as crypto from 'crypto';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import Log from './common/logger';
|
||||
import { getVSCodeServerConfig, ServerVersion, ServerValidation } from './serverConfig';
|
||||
import SSHConnection from './ssh/sshConnection';
|
||||
import { fetchRelease, IRelease } from './fetchRelease';
|
||||
|
||||
/**
|
||||
* Reads a script template from <extensionPath>/scripts/<templateName> and
|
||||
* replaces every %%KEY%% occurrence with the matching value from `variables`.
|
||||
*/
|
||||
function compileTemplate(templateName: string, variables: Record<string, string>, extensionPath: string): string {
|
||||
const templatePath = path.join(extensionPath, 'src', 'scripts', templateName);
|
||||
let content = fs.readFileSync(templatePath, 'utf8');
|
||||
for (const [key, value] of Object.entries(variables)) {
|
||||
content = content.replace(new RegExp(`%%${key}%%`, 'g'), value);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches a hostname against a pattern that may contain wildcards.
|
||||
* Returns a specificity score: higher scores indicate more specific matches.
|
||||
@@ -103,7 +118,8 @@ export async function installCodeServer(
|
||||
platform: string | undefined,
|
||||
useSocketPath: boolean,
|
||||
customInstallPath: string | undefined,
|
||||
logger: Log
|
||||
logger: Log,
|
||||
extensionPath: string
|
||||
): Promise<ServerInstallResult> {
|
||||
let shell = 'powershell';
|
||||
|
||||
@@ -160,7 +176,7 @@ export async function installCodeServer(
|
||||
|
||||
let commandOutput: { stdout: string; stderr: string };
|
||||
if (platform === 'windows') {
|
||||
const installServerScript = generatePowerShellInstallScript(installOptions);
|
||||
const installServerScript = generatePowerShellInstallScript(installOptions, extensionPath);
|
||||
|
||||
logger.trace('Server install command:', installServerScript);
|
||||
|
||||
@@ -207,7 +223,7 @@ export async function installCodeServer(
|
||||
|
||||
commandOutput = await conn.execPartial(command, (stdout: string) => endRegex.test(stdout));
|
||||
} else {
|
||||
const installServerScript = generateBashInstallScript(installOptions);
|
||||
const installServerScript = generateBashInstallScript(installOptions, extensionPath);
|
||||
|
||||
logger.trace('Server install command:', installServerScript);
|
||||
// Fish shell does not support heredoc so let's workaround it using -c option,
|
||||
@@ -275,272 +291,37 @@ function parseServerInstallOutput(str: string, scriptId: string): { [k: string]:
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
function generateBashInstallScript({ id, quality, version, commit, release, extensionIds, envVariables, useSocketPath, serverApplicationName, serverDataFolderName, serverDownloadUrlTemplate, customInstallPath, serverValidation }: ServerInstallOptions) {
|
||||
const extensions = extensionIds.map(id => '--install-extension ' + id).join(' ');
|
||||
function generateBashInstallScript({ id, quality, version, commit, release, extensionIds, envVariables, useSocketPath, serverApplicationName, serverDataFolderName, serverDownloadUrlTemplate, customInstallPath, serverValidation }: ServerInstallOptions, extensionPath: string): string {
|
||||
const extensions = extensionIds.map(extId => '--install-extension ' + extId).join(' ');
|
||||
const serverDataDir = customInstallPath
|
||||
? customInstallPath.replace(/^~(?=\/|$)/, '$HOME')
|
||||
: `$HOME/${serverDataFolderName}`;
|
||||
return `
|
||||
# Server installation script
|
||||
const listenFlag = useSocketPath
|
||||
? `--socket-path="$TMP_DIR/vscode-server-sock-${crypto.randomUUID()}"`
|
||||
: '--port=0';
|
||||
const envVarLines = envVariables.map(envVar => ` echo "${envVar}==$${envVar}=="`).join('\n');
|
||||
|
||||
TMP_DIR="\${XDG_RUNTIME_DIR:-"/tmp"}"
|
||||
|
||||
DISTRO_VERSION="${version}"
|
||||
DISTRO_COMMIT="${commit}"
|
||||
DISTRO_QUALITY="${quality}"
|
||||
DISTRO_VSCODIUM_RELEASE="${release ?? ''}"
|
||||
|
||||
SERVER_APP_NAME="${serverApplicationName}"
|
||||
SERVER_INITIAL_EXTENSIONS="${extensions}"
|
||||
SERVER_LISTEN_FLAG="${useSocketPath ? `--socket-path="$TMP_DIR/vscode-server-sock-${crypto.randomUUID()}"` : '--port=0'}"
|
||||
SERVER_DATA_DIR="${serverDataDir}"
|
||||
SERVER_DATA_DIR_FLAG="${customInstallPath ? '--server-data-dir="$SERVER_DATA_DIR"' : ''}"
|
||||
SERVER_DIR="$SERVER_DATA_DIR/bin/$DISTRO_COMMIT"
|
||||
SERVER_SCRIPT="$SERVER_DIR/bin/$SERVER_APP_NAME"
|
||||
SERVER_LOGFILE="$SERVER_DATA_DIR/.$DISTRO_COMMIT.log"
|
||||
SERVER_PIDFILE="$SERVER_DATA_DIR/.$DISTRO_COMMIT.pid"
|
||||
SERVER_TOKENFILE="$SERVER_DATA_DIR/.$DISTRO_COMMIT.token"
|
||||
SERVER_ARCH=
|
||||
SERVER_CONNECTION_TOKEN=
|
||||
SERVER_DOWNLOAD_URL=
|
||||
SERVER_VALIDATION_FLAG="${serverValidation === 'skip' ? '--disable-client-validation' : ''}"
|
||||
|
||||
LISTENING_ON=
|
||||
OS_RELEASE_ID=
|
||||
ARCH=
|
||||
PLATFORM=
|
||||
|
||||
# Mimic output from logs of remote-ssh extension
|
||||
print_install_results_and_exit() {
|
||||
echo "${id}: start"
|
||||
echo "exitCode==$1=="
|
||||
echo "listeningOn==$LISTENING_ON=="
|
||||
echo "connectionToken==$SERVER_CONNECTION_TOKEN=="
|
||||
echo "logFile==$SERVER_LOGFILE=="
|
||||
echo "osReleaseId==$OS_RELEASE_ID=="
|
||||
echo "arch==$ARCH=="
|
||||
echo "platform==$PLATFORM=="
|
||||
echo "tmpDir==$TMP_DIR=="
|
||||
${envVariables.map(envVar => `echo "${envVar}==$${envVar}=="`).join('\n')}
|
||||
echo "${id}: end"
|
||||
exit 0
|
||||
return compileTemplate('server-setup.sh', {
|
||||
DISTRO_VERSION: version,
|
||||
DISTRO_COMMIT: commit,
|
||||
DISTRO_QUALITY: quality,
|
||||
DISTRO_VSCODIUM_RELEASE: release ?? '',
|
||||
SERVER_APP_NAME: serverApplicationName,
|
||||
SERVER_INITIAL_EXTENSIONS: extensions,
|
||||
SERVER_LISTEN_FLAG: listenFlag,
|
||||
SERVER_DATA_DIR: serverDataDir,
|
||||
SERVER_DATA_DIR_FLAG: customInstallPath ? '--server-data-dir="$SERVER_DATA_DIR"' : '',
|
||||
SERVER_VALIDATION_FLAG: serverValidation === 'skip' ? '--disable-client-validation' : '',
|
||||
SERVER_DOWNLOAD_URL_TEMPLATE: serverDownloadUrlTemplate.replace(/\$\{/g, '\\${'),
|
||||
SCRIPT_ID: id,
|
||||
ENV_VAR_LINES: envVarLines,
|
||||
MODIFY_PRODUCT_JSON: serverValidation === 'force' ? 'true' : 'false',
|
||||
SERVER_CONNECTION_TOKEN: crypto.randomUUID(),
|
||||
}, extensionPath);
|
||||
}
|
||||
|
||||
LOCKFILE="$TMP_DIR/server_install.lock"
|
||||
|
||||
if command -v flock >/dev/null 2>&1; then
|
||||
exec {FD}<>"$LOCKFILE"
|
||||
# wait 30s to acquire lock, otherwise fail
|
||||
flock -x -w 30 $FD || print_install_results_and_exit 1
|
||||
trap "flock -u $FD; trap - EXIT INT HUP; exit" EXIT INT HUP
|
||||
else
|
||||
echo "Warning: flock not available, skipping install lock" >&2
|
||||
fi
|
||||
|
||||
# Check if platform is supported
|
||||
if ! command -v uname; then
|
||||
echo "Error 'uname' command not found, could not get platform/arch data."
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
KERNEL="$(uname -s)"
|
||||
case $KERNEL in
|
||||
Darwin)
|
||||
PLATFORM="darwin"
|
||||
;;
|
||||
Linux)
|
||||
PLATFORM="linux"
|
||||
;;
|
||||
FreeBSD)
|
||||
PLATFORM="freebsd"
|
||||
;;
|
||||
DragonFly)
|
||||
PLATFORM="dragonfly"
|
||||
;;
|
||||
"")
|
||||
echo "Error uname -s yields empty result"
|
||||
print_install_results_and_exit 1
|
||||
;;
|
||||
*)
|
||||
echo "Error platform not supported: $KERNEL"
|
||||
print_install_results_and_exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check machine architecture
|
||||
ARCH="$(uname -m)"
|
||||
case $ARCH in
|
||||
x86_64 | amd64)
|
||||
SERVER_ARCH="x64"
|
||||
;;
|
||||
armv7l | armv8l)
|
||||
SERVER_ARCH="armhf"
|
||||
;;
|
||||
arm64 | aarch64)
|
||||
SERVER_ARCH="arm64"
|
||||
;;
|
||||
ppc64le)
|
||||
SERVER_ARCH="ppc64le"
|
||||
;;
|
||||
riscv64)
|
||||
SERVER_ARCH="riscv64"
|
||||
;;
|
||||
loongarch64)
|
||||
SERVER_ARCH="loong64"
|
||||
;;
|
||||
s390x)
|
||||
SERVER_ARCH="s390x"
|
||||
;;
|
||||
*)
|
||||
echo "Error architecture not supported: $ARCH"
|
||||
print_install_results_and_exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||
OS_RELEASE_ID="$(grep -i '^ID=' /etc/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
|
||||
if [[ -z $OS_RELEASE_ID ]]; then
|
||||
OS_RELEASE_ID="$(grep -i '^ID=' /usr/lib/os-release 2>/dev/null | sed 's/^ID=//gi' | sed 's/"//g')"
|
||||
if [[ -z $OS_RELEASE_ID ]]; then
|
||||
OS_RELEASE_ID="unknown"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create installation folder
|
||||
if [[ ! -d $SERVER_DIR ]]; then
|
||||
mkdir -p $SERVER_DIR
|
||||
if (( $? > 0 )); then
|
||||
echo "Error creating server install directory"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# adjust platform for vscodium download, if needed
|
||||
if [[ $OS_RELEASE_ID = alpine ]]; then
|
||||
PLATFORM=$OS_RELEASE_ID
|
||||
fi
|
||||
|
||||
SERVER_DOWNLOAD_URL="$(echo "${serverDownloadUrlTemplate.replace(/\$\{/g, '\\${')}" | sed "s/\\\${quality}/$DISTRO_QUALITY/g" | sed "s/\\\${version}/$DISTRO_VERSION/g" | sed "s/\\\${commit}/$DISTRO_COMMIT/g" | sed "s/\\\${os}/$PLATFORM/g" | sed "s/\\\${arch}/$SERVER_ARCH/g" | sed "s/\\\${release}/$DISTRO_VSCODIUM_RELEASE/g")"
|
||||
|
||||
# Check if server script is already installed
|
||||
if [[ ! -f $SERVER_SCRIPT ]]; then
|
||||
case "$PLATFORM" in
|
||||
darwin | linux | alpine | freebsd )
|
||||
;;
|
||||
*)
|
||||
echo "Error '$PLATFORM' needs manual installation of remote extension host"
|
||||
print_install_results_and_exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
pushd $SERVER_DIR > /dev/null
|
||||
|
||||
if command -v wget >/dev/null 2>&1; then
|
||||
wget --tries=3 --timeout=10 --continue --no-verbose -O vscode-server.tar.gz $SERVER_DOWNLOAD_URL
|
||||
elif command -v curl >/dev/null 2>&1; then
|
||||
curl --retry 3 --connect-timeout 10 --location --show-error --silent --output vscode-server.tar.gz $SERVER_DOWNLOAD_URL
|
||||
elif command -v fetch >/dev/null 2>&1; then
|
||||
fetch --retry --timeout=10 --quiet --output=vscode-server.tar.gz $SERVER_DOWNLOAD_URL
|
||||
else
|
||||
echo "Error no tool to download server binary"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
if (( $? > 0 )); then
|
||||
echo "Error downloading server from $SERVER_DOWNLOAD_URL"
|
||||
rm -rf vscode-server.tar.gz
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
tar -xf vscode-server.tar.gz --strip-components 1
|
||||
if (( $? > 0 )); then
|
||||
echo "Error while extracting server contents"
|
||||
rm -rf vscode-server.tar.gz
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f $SERVER_SCRIPT ]]; then
|
||||
rm -rf $SERVER_DIR/*
|
||||
echo "Error server contents are corrupted"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
rm -f vscode-server.tar.gz
|
||||
|
||||
popd > /dev/null
|
||||
else
|
||||
echo "Server script already installed in $SERVER_SCRIPT"
|
||||
fi
|
||||
|
||||
# Modify the commit in the remote server to match the local value
|
||||
if ${serverValidation === 'force' ? 'true' : 'false'}; then
|
||||
if command -v sed >/dev/null 2>&1; then
|
||||
echo "Will modify product.json on remote to match the commit value"
|
||||
sed -i -E 's/"commit": "[0-9a-f]+",/"commit": "'"$DISTRO_COMMIT"'",/' "$SERVER_DIR/product.json";
|
||||
else
|
||||
echo "Cannot find the 'sed' command, make sure it is installed to modify product.json with the matching commit."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Try to find if server is already running
|
||||
if [[ -f $SERVER_PIDFILE ]]; then
|
||||
SERVER_PID="$(cat $SERVER_PIDFILE)"
|
||||
SERVER_RUNNING_PROCESS="$(ps -o pid,args -p $SERVER_PID | grep $SERVER_SCRIPT)"
|
||||
else
|
||||
SERVER_RUNNING_PROCESS="$(ps -o pid,args -A | grep $SERVER_SCRIPT | grep -v grep)"
|
||||
fi
|
||||
|
||||
if [[ -z $SERVER_RUNNING_PROCESS ]]; then
|
||||
if [[ -f $SERVER_LOGFILE ]]; then
|
||||
rm $SERVER_LOGFILE
|
||||
fi
|
||||
if [[ -f $SERVER_TOKENFILE ]]; then
|
||||
rm $SERVER_TOKENFILE
|
||||
fi
|
||||
|
||||
touch $SERVER_TOKENFILE
|
||||
chmod 600 $SERVER_TOKENFILE
|
||||
SERVER_CONNECTION_TOKEN="${crypto.randomUUID()}"
|
||||
echo $SERVER_CONNECTION_TOKEN > $SERVER_TOKENFILE
|
||||
|
||||
$SERVER_SCRIPT --start-server --host=127.0.0.1 $SERVER_LISTEN_FLAG $SERVER_DATA_DIR_FLAG $SERVER_VALIDATION_FLAG $SERVER_INITIAL_EXTENSIONS --connection-token-file $SERVER_TOKENFILE --telemetry-level off --enable-remote-auto-shutdown --accept-server-license-terms &> $SERVER_LOGFILE &
|
||||
echo $! > $SERVER_PIDFILE
|
||||
else
|
||||
echo "Server script is already running $SERVER_SCRIPT"
|
||||
fi
|
||||
|
||||
if [[ -f $SERVER_TOKENFILE ]]; then
|
||||
SERVER_CONNECTION_TOKEN="$(cat $SERVER_TOKENFILE)"
|
||||
else
|
||||
echo "Error server token file not found $SERVER_TOKENFILE"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
if [[ -f $SERVER_LOGFILE ]]; then
|
||||
for i in {1..35}; do
|
||||
LISTENING_ON="$(cat $SERVER_LOGFILE | grep -E 'Extension host agent listening on .+' | sed 's/Extension host agent listening on //')"
|
||||
if [[ -n $LISTENING_ON ]]; then
|
||||
break
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
|
||||
if [[ -z $LISTENING_ON ]]; then
|
||||
echo "Error server did not start successfully"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
else
|
||||
echo "Error server log file not found $SERVER_LOGFILE"
|
||||
print_install_results_and_exit 1
|
||||
fi
|
||||
|
||||
# Finish server setup
|
||||
print_install_results_and_exit 0
|
||||
`;
|
||||
}
|
||||
|
||||
function generatePowerShellInstallScript({ id, quality, version, commit, release, extensionIds, envVariables, useSocketPath, serverApplicationName, serverDataFolderName, serverDownloadUrlTemplate, customInstallPath, serverValidation }: ServerInstallOptions) {
|
||||
const extensions = extensionIds.map(id => '--install-extension ' + id).join(' ');
|
||||
function generatePowerShellInstallScript({ id, quality, version, commit, release, extensionIds, envVariables, useSocketPath, serverApplicationName, serverDataFolderName, serverDownloadUrlTemplate, customInstallPath, serverValidation }: ServerInstallOptions, extensionPath: string): string {
|
||||
const extensions = extensionIds.map(extId => '--install-extension ' + extId).join(' ');
|
||||
const downloadUrl = serverDownloadUrlTemplate
|
||||
.replace(/\$\{quality\}/g, quality)
|
||||
.replace(/\$\{version\}/g, version)
|
||||
@@ -551,201 +332,26 @@ function generatePowerShellInstallScript({ id, quality, version, commit, release
|
||||
const serverDataDir = customInstallPath
|
||||
? customInstallPath.replace(/^~(?=[\\/]|$)/, '$(Resolve-Path ~)')
|
||||
: `$(Resolve-Path ~)\\${serverDataFolderName}`;
|
||||
const listenFlag = useSocketPath
|
||||
? `--socket-path="$TMP_DIR/vscode-server-sock-${crypto.randomUUID()}"`
|
||||
: '--port=0';
|
||||
const envVarLines = envVariables.map(envVar => ` "$${envVar}==$${envVar}=="`).join('\n');
|
||||
|
||||
return `
|
||||
# Server installation script
|
||||
|
||||
$TMP_DIR="$env:TEMP\\$([System.IO.Path]::GetRandomFileName())"
|
||||
$ProgressPreference = "SilentlyContinue"
|
||||
|
||||
$DISTRO_VERSION="${version}"
|
||||
$DISTRO_COMMIT="${commit}"
|
||||
$DISTRO_QUALITY="${quality}"
|
||||
$DISTRO_VSCODIUM_RELEASE="${release ?? ''}"
|
||||
|
||||
$SERVER_APP_NAME="${serverApplicationName}"
|
||||
$SERVER_INITIAL_EXTENSIONS="${extensions}"
|
||||
$SERVER_LISTEN_FLAG="${useSocketPath ? `--socket-path="$TMP_DIR/vscode-server-sock-${crypto.randomUUID()}"` : '--port=0'}"
|
||||
$SERVER_DATA_DIR="${serverDataDir}"
|
||||
$SERVER_DATA_DIR_FLAG="${customInstallPath ? '--server-data-dir=""$SERVER_DATA_DIR""' : ''}"
|
||||
$SERVER_DIR="$SERVER_DATA_DIR\\bin\\$DISTRO_COMMIT"
|
||||
$SERVER_SCRIPT="$SERVER_DIR\\bin\\$SERVER_APP_NAME.cmd"
|
||||
$SERVER_LOGFILE="$SERVER_DATA_DIR\\.$DISTRO_COMMIT.log"
|
||||
$SERVER_PIDFILE="$SERVER_DATA_DIR\\.$DISTRO_COMMIT.pid"
|
||||
$SERVER_TOKENFILE="$SERVER_DATA_DIR\\.$DISTRO_COMMIT.token"
|
||||
$SERVER_ARCH=
|
||||
$SERVER_CONNECTION_TOKEN=
|
||||
$SERVER_DOWNLOAD_URL=
|
||||
$SERVER_VALIDATION_FLAG="${serverValidation === 'skip' ? '--disable-client-validation' : ''}"
|
||||
|
||||
$LISTENING_ON=
|
||||
$OS_RELEASE_ID=
|
||||
$ARCH=
|
||||
$PLATFORM="win32"
|
||||
|
||||
function printInstallResults($code) {
|
||||
"${id}: start"
|
||||
"exitCode==$code=="
|
||||
"listeningOn==$LISTENING_ON=="
|
||||
"connectionToken==$SERVER_CONNECTION_TOKEN=="
|
||||
"logFile==$SERVER_LOGFILE=="
|
||||
"osReleaseId==$OS_RELEASE_ID=="
|
||||
"arch==$ARCH=="
|
||||
"platform==$PLATFORM=="
|
||||
"tmpDir==$TMP_DIR=="
|
||||
${envVariables.map(envVar => `"${envVar}==$${envVar}=="`).join('\n')}
|
||||
"${id}: end"
|
||||
}
|
||||
|
||||
# Check machine architecture
|
||||
$ARCH=$env:PROCESSOR_ARCHITECTURE
|
||||
# Use x64 version for ARM64, as it's not yet available.
|
||||
if(($ARCH -eq "AMD64") -or ($ARCH -eq "IA64") -or ($ARCH -eq "ARM64")) {
|
||||
$SERVER_ARCH="x64"
|
||||
}
|
||||
else {
|
||||
"Error architecture not supported: $ARCH"
|
||||
printInstallResults 1
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Create installation folder
|
||||
if(!(Test-Path $SERVER_DIR)) {
|
||||
try {
|
||||
ni -it d $SERVER_DIR -f -ea si
|
||||
} catch {
|
||||
"Error creating server install directory - $($_.ToString())"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if(!(Test-Path $SERVER_DIR)) {
|
||||
"Error creating server install directory"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
cd $SERVER_DIR
|
||||
|
||||
# Check if server script is already installed
|
||||
if(!(Test-Path $SERVER_SCRIPT)) {
|
||||
del vscode-server.tar.gz
|
||||
|
||||
$REQUEST_ARGUMENTS = @{
|
||||
Uri="${downloadUrl}"
|
||||
TimeoutSec=20
|
||||
OutFile="vscode-server.tar.gz"
|
||||
UseBasicParsing=$True
|
||||
}
|
||||
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
Invoke-RestMethod @REQUEST_ARGUMENTS
|
||||
|
||||
if(Test-Path "vscode-server.tar.gz") {
|
||||
tar -xf vscode-server.tar.gz --strip-components 1
|
||||
|
||||
del vscode-server.tar.gz
|
||||
}
|
||||
|
||||
if(!(Test-Path $SERVER_SCRIPT)) {
|
||||
"Error while installing the server binary"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
else {
|
||||
"Server script already installed in $SERVER_SCRIPT"
|
||||
}
|
||||
|
||||
# Modify the commit in the remote server to match the local value
|
||||
if(${serverValidation === 'force' ? '$true' : '$false'}) {
|
||||
echo "Will modify product.json on remote to match the commit value"
|
||||
(Get-Content -Raw "$SERVER_DIR\\product.json") -replace '"commit": "[0-9a-f]+",', ('"commit": "' + $DISTRO_COMMIT + '",') |
|
||||
Set-Content -NoNewLine "$SERVER_DIR\\product.json"
|
||||
}
|
||||
|
||||
# Try to find if server is already running
|
||||
if(Get-Process node -ErrorAction SilentlyContinue | Where-Object Path -Like "$SERVER_DIR\\*") {
|
||||
echo "Server script is already running $SERVER_SCRIPT"
|
||||
}
|
||||
else {
|
||||
if(Test-Path $SERVER_LOGFILE) {
|
||||
del $SERVER_LOGFILE
|
||||
}
|
||||
if(Test-Path $SERVER_PIDFILE) {
|
||||
del $SERVER_PIDFILE
|
||||
}
|
||||
if(Test-Path $SERVER_TOKENFILE) {
|
||||
del $SERVER_TOKENFILE
|
||||
}
|
||||
|
||||
$SERVER_CONNECTION_TOKEN="${crypto.randomUUID()}"
|
||||
[System.IO.File]::WriteAllLines($SERVER_TOKENFILE, $SERVER_CONNECTION_TOKEN)
|
||||
|
||||
$SCRIPT_ARGUMENTS="--start-server --host=127.0.0.1 $SERVER_LISTEN_FLAG $SERVER_DATA_DIR_FLAG $SERVER_VALIDATION_FLAG $SERVER_INITIAL_EXTENSIONS --connection-token-file $SERVER_TOKENFILE --telemetry-level off --enable-remote-auto-shutdown --accept-server-license-terms *> '$SERVER_LOGFILE'"
|
||||
|
||||
$START_ARGUMENTS = @{
|
||||
FilePath = "powershell.exe"
|
||||
WindowStyle = "hidden"
|
||||
ArgumentList = @(
|
||||
"-ExecutionPolicy", "Unrestricted", "-NoLogo", "-NoProfile", "-NonInteractive", "-c", "$SERVER_SCRIPT $SCRIPT_ARGUMENTS"
|
||||
)
|
||||
PassThru = $True
|
||||
}
|
||||
|
||||
$SERVER_ID = (start @START_ARGUMENTS).ID
|
||||
|
||||
if($SERVER_ID) {
|
||||
[System.IO.File]::WriteAllLines($SERVER_PIDFILE, $SERVER_ID)
|
||||
}
|
||||
}
|
||||
|
||||
if(Test-Path $SERVER_TOKENFILE) {
|
||||
$SERVER_CONNECTION_TOKEN="$(cat $SERVER_TOKENFILE)"
|
||||
}
|
||||
else {
|
||||
"Error server token file not found $SERVER_TOKENFILE"
|
||||
printInstallResults 1
|
||||
exit 0
|
||||
}
|
||||
|
||||
sleep -Milliseconds 500
|
||||
|
||||
$SELECT_ARGUMENTS = @{
|
||||
Path = $SERVER_LOGFILE
|
||||
Pattern = "Extension host agent listening on (\\d+)"
|
||||
}
|
||||
|
||||
for($I = 1; $I -le 5; $I++) {
|
||||
if(Test-Path $SERVER_LOGFILE) {
|
||||
$GROUPS = (Select-String @SELECT_ARGUMENTS).Matches.Groups
|
||||
|
||||
if($GROUPS) {
|
||||
$LISTENING_ON = $GROUPS[1].Value
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
sleep -Milliseconds 500
|
||||
}
|
||||
|
||||
if(!(Test-Path $SERVER_LOGFILE)) {
|
||||
"Error server log file not found $SERVER_LOGFILE"
|
||||
printInstallResults 1
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Finish server setup
|
||||
printInstallResults 0
|
||||
|
||||
if($SERVER_ID) {
|
||||
while($True) {
|
||||
if(!(gps -Id $SERVER_ID)) {
|
||||
"server died, exit"
|
||||
exit 0
|
||||
}
|
||||
|
||||
sleep 30
|
||||
}
|
||||
}
|
||||
`;
|
||||
return compileTemplate('server-setup.ps1', {
|
||||
DISTRO_VERSION: version,
|
||||
DISTRO_COMMIT: commit,
|
||||
DISTRO_QUALITY: quality,
|
||||
DISTRO_VSCODIUM_RELEASE: release ?? '',
|
||||
SERVER_APP_NAME: serverApplicationName,
|
||||
SERVER_INITIAL_EXTENSIONS: extensions,
|
||||
SERVER_LISTEN_FLAG: listenFlag,
|
||||
SERVER_DATA_DIR: serverDataDir,
|
||||
SERVER_DATA_DIR_FLAG: customInstallPath ? '--server-data-dir=""$SERVER_DATA_DIR""' : '',
|
||||
SERVER_VALIDATION_FLAG: serverValidation === 'skip' ? '--disable-client-validation' : '',
|
||||
SERVER_DOWNLOAD_URL: downloadUrl,
|
||||
SCRIPT_ID: id,
|
||||
ENV_VAR_LINES: envVarLines,
|
||||
MODIFY_PRODUCT_JSON: serverValidation === 'force' ? '$true' : '$false',
|
||||
SERVER_CONNECTION_TOKEN: crypto.randomUUID(),
|
||||
}, extensionPath);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user