Skip to content

Use upstream server #4414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 29 commits into from
Nov 10, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3c10163
Flesh out fixes to align with upstream.
GirlBossRush Oct 28, 2021
0e7eb7e
Update route handlers to better reflect fallback behavior.
GirlBossRush Oct 29, 2021
ad787bb
Bump vendor.
GirlBossRush Oct 29, 2021
19c9c23
Touch up build, tests.
GirlBossRush Oct 29, 2021
062ce32
bump vscode.
GirlBossRush Nov 4, 2021
2481711
Add platform to vscode-reh-web task
code-asher Nov 4, 2021
dde9a08
Fix issue where workspace args are not parsed.
GirlBossRush Nov 4, 2021
26733fd
Update CLI test.
GirlBossRush Nov 4, 2021
059893f
Update CLI tests.
GirlBossRush Nov 4, 2021
9945428
Fix issues surrounding opening files within code-server's terminal.
GirlBossRush Nov 4, 2021
93adec7
Bump vendor.
GirlBossRush Nov 4, 2021
28e0d78
Update VS Code
code-asher Nov 5, 2021
4cf13f4
Merge remote-tracking branch 'origin/main' into upstream-server-fixes
code-asher Nov 5, 2021
76e6ccc
Readd parent wrapper for hot reload.
GirlBossRush Nov 5, 2021
efada23
Allow more errors.
GirlBossRush Nov 5, 2021
1f7e8a1
Bump vscode.
GirlBossRush Nov 5, 2021
914aad2
Fix issues surrounding Coder link.
GirlBossRush Nov 5, 2021
a413abf
Add dir creation and fix cli
code-asher Nov 5, 2021
55d878e
Remove hardcoded VSCODE_DEV=1
code-asher Nov 8, 2021
d03c9f5
Fix mismatching commit between client and server
code-asher Nov 8, 2021
8244463
Mostly restore command-line parity
code-asher Nov 8, 2021
d5ed30f
Fix static endpoint not emitting 404s
code-asher Nov 8, 2021
30b9923
Update VS Code
code-asher Nov 8, 2021
a281ccd
Import missing logError
code-asher Nov 9, 2021
7d48b82
Fix 403 errors
code-asher Nov 9, 2021
fc94ac9
Add code-server version to about dialog
code-asher Nov 9, 2021
89cc5a9
Use user settings to disable welcome page
code-asher Nov 10, 2021
e022788
Update VS Code cache step with new build directories
code-asher Nov 10, 2021
c8f2b12
Merge branch 'main' into upstream-server-fixes
code-asher Nov 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Readd parent wrapper for hot reload.
  • Loading branch information
GirlBossRush committed Nov 5, 2021
commit 76e6cccca4263bf19d6e9c39c01e3e8711924c92
27 changes: 17 additions & 10 deletions src/node/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,13 @@ import { commit, pkgName, version } from "./constants"
import { openInExistingInstance, runCodeServer, runVsCodeCli, shouldSpawnCliProcess } from "./main"
import { monkeyPatchProxyProtocols } from "./proxy_agent"
import { loadAMDModule } from "./util"
import { wrapper } from "./wrapper"
import { isChild, wrapper } from "./wrapper"

const cliPipe = process.env["VSCODE_IPC_HOOK_CLI"] as string
const cliCommand = process.env["VSCODE_CLIENT_COMMAND"] as string

async function entry(): Promise<void> {
monkeyPatchProxyProtocols()
const cliArgs = await parse(process.argv.slice(2))

// There's no need to check flags like --help or to spawn in an existing
// instance for the child process because these would have already happened in
// the parent and the child wouldn't have been spawned. We also get the
// arguments from the parent so we don't have to parse twice and to account
// for environment manipulation (like how PASSWORD gets removed to avoid
// leaking to child processes).

if (cliPipe || cliCommand) {
const remoteAgentMain = await loadAMDModule<CodeServerLib.RemoteCLIMain>("vs/server/remoteCli", "main")
Expand All @@ -35,6 +27,21 @@ async function entry(): Promise<void> {
return
}

// There's no need to check flags like --help or to spawn in an existing
// instance for the child process because these would have already happened in
// the parent and the child wouldn't have been spawned. We also get the
// arguments from the parent so we don't have to parse twice and to account
// for environment manipulation (like how PASSWORD gets removed to avoid
// leaking to child processes).
if (isChild(wrapper)) {
const args = await wrapper.handshake()
wrapper.preventExit()
const server = await runCodeServer(args)
wrapper.onDispose(() => server.dispose())
return
}

const cliArgs = await parse(process.argv.slice(2))
const configArgs = await readConfigFile(cliArgs.config)
const args = await setDefaults(cliArgs, configArgs)

Expand Down Expand Up @@ -76,7 +83,7 @@ async function entry(): Promise<void> {
return openInExistingInstance(args, socketPath)
}

runCodeServer(args)
return wrapper.start(args)
}

entry().catch((error) => {
Expand Down
67 changes: 66 additions & 1 deletion src/node/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,64 @@ abstract class Process {
}
}

/**
* Child process that will clean up after itself if the parent goes away and can
* perform a handshake with the parent and ask it to relaunch.
*/
class ChildProcess extends Process {
public logger = logger.named(`child:${process.pid}`)

public constructor(private readonly parentPid: number) {
super()

// Kill the inner process if the parent dies. This is for the case where the
// parent process is forcefully terminated and cannot clean up.
setInterval(() => {
try {
// process.kill throws an exception if the process doesn't exist.
process.kill(this.parentPid, 0)
} catch (_) {
// Consider this an error since it should have been able to clean up
// the child process unless it was forcefully killed.
this.logger.error(`parent process ${parentPid} died`)
this._onDispose.emit(undefined)
}
}, 5000)
}

/**
* Initiate the handshake and wait for a response from the parent.
*/
public async handshake(): Promise<DefaultedArgs> {
this.send({ type: "handshake" })
const message = await onMessage<ParentMessage, ParentHandshakeMessage>(
process,
(message): message is ParentHandshakeMessage => {
return message.type === "handshake"
},
this.logger,
)
return message.args
}

/**
* Notify the parent process that it should relaunch the child.
*/
public relaunch(version: string): void {
this.send({ type: "relaunch", version })
}

/**
* Send a message to the parent.
*/
private send(message: ChildMessage): void {
if (!process.send) {
throw new Error("not spawned with IPC")
}
process.send(message)
}
}

/**
* Parent process wrapper that spawns the child process and performs a handshake
* with it. Will relaunch the child if it receives a SIGUSR1 or is asked to by
Expand Down Expand Up @@ -288,7 +346,14 @@ export class ParentProcess extends Process {
/**
* Process wrapper.
*/
export const wrapper = new ParentProcess(require("../../package.json").version)
export const wrapper =
typeof process.env.CODE_SERVER_PARENT_PID !== "undefined"
? new ChildProcess(parseInt(process.env.CODE_SERVER_PARENT_PID))
: new ParentProcess(require("../../package.json").version)

export function isChild(proc: ChildProcess | ParentProcess): proc is ChildProcess {
return proc instanceof ChildProcess
}

// It's possible that the pipe has closed (for example if you run code-server
// --version | head -1). Assume that means we're done.
Expand Down