Handle upgrade from binary to loose files

As best we can, anyway.
This commit is contained in:
Asher 2020-02-21 12:32:58 -06:00
parent 9b7a203fe5
commit cf0f11105b
No known key found for this signature in database
GPG Key ID: D63C1EF81242354A

View File

@ -1,5 +1,7 @@
import { logger, field } from "@coder/logger" import { logger, field } from "@coder/logger"
import * as cp from "child_process" import * as cp from "child_process"
import * as fs from "fs-extra"
import * as path from "path"
import { Emitter } from "../common/emitter" import { Emitter } from "../common/emitter"
interface HandshakeMessage { interface HandshakeMessage {
@ -175,40 +177,53 @@ export class WrapperProcess {
public start(): Promise<void> { public start(): Promise<void> {
if (!this.started) { if (!this.started) {
const child = this.spawn() this.started = this.spawn().then((child) => {
logger.debug(`spawned inner process ${child.pid}`) logger.debug(`spawned inner process ${child.pid}`)
this.started = ipcMain() ipcMain()
.handshake(child) .handshake(child)
.then(() => { .then(() => {
child.once("exit", (code) => { child.once("exit", (code) => {
logger.debug(`inner process ${child.pid} exited unexpectedly`) logger.debug(`inner process ${child.pid} exited unexpectedly`)
ipcMain().exit(code || 0) ipcMain().exit(code || 0)
})
}) })
}) this.process = child
this.process = child })
} }
return this.started return this.started
} }
private spawn(): cp.ChildProcess { private async spawn(): Promise<cp.ChildProcess> {
// Flags to pass along to the Node binary. // Flags to pass along to the Node binary.
let nodeOptions = `${process.env.NODE_OPTIONS || ""} ${(this.options && this.options.nodeOptions) || ""}` let nodeOptions = `${process.env.NODE_OPTIONS || ""} ${(this.options && this.options.nodeOptions) || ""}`
if (!/max_old_space_size=(\d+)/g.exec(nodeOptions)) { if (!/max_old_space_size=(\d+)/g.exec(nodeOptions)) {
nodeOptions += ` --max_old_space_size=${(this.options && this.options.maxMemory) || 2048}` nodeOptions += ` --max_old_space_size=${(this.options && this.options.maxMemory) || 2048}`
} }
return cp.fork(process.argv[1], process.argv.slice(2), { // This is to handle the upgrade from binary release to loose release. This
// will only work for users that restart code-server entirely between
// upgrading to this version and the loose file version since this is the
// wrapper code that does not get updated. The hope is that it'll be likely
// for that to happen to most users in that timeframe to minimize disruption
// when loose files are release. This can be removed with that release.
const bundledNodePath = path.join(process.argv[0], "node")
const binary = (await fs.pathExists(bundledNodePath)) ? bundledNodePath : process.argv[0]
// Use spawn (instead of fork) to use the new binary in case it was updated.
return cp.spawn(binary, process.argv.slice(1), {
env: { env: {
...process.env, ...process.env,
CODE_SERVER_PARENT_PID: process.pid.toString(), CODE_SERVER_PARENT_PID: process.pid.toString(),
NODE_OPTIONS: nodeOptions, NODE_OPTIONS: nodeOptions,
NBIN_BYPASS: undefined,
}, },
stdio: ["inherit", "inherit", "inherit", "ipc"],
}) })
} }
} }
// // It's possible that the pipe has closed (for example if you run code-server // It's possible that the pipe has closed (for example if you run code-server
// // --version | head -1). Assume that means we're done. // --version | head -1). Assume that means we're done.
if (!process.stdout.isTTY) { if (!process.stdout.isTTY) {
process.stdout.on("error", () => ipcMain().exit()) process.stdout.on("error", () => ipcMain().exit())
} }