Archived
1
0

Update node to 10.15.1 (#472)

* Update Node to 10.15.1

* Remove string replace that was used for oclif

* Update nbin

* Package node-pty and spdlog with nbin

* Label stderr/stdout from shared process

* Remove fork override

* Prevent "already disposed" errors when trying to kill disposed proxies

* Include spdlog dependencies

* Shim /node_modules

* Add node_modules to Docker ignore

It keeps using my already-built .node files which results in a
mismatching GLIBC version error.

* Update nbin
This commit is contained in:
Asher
2019-04-15 19:48:12 -05:00
committed by GitHub
parent dfabc070b9
commit aabb2ecda7
22 changed files with 95 additions and 647 deletions

View File

@ -9,7 +9,7 @@
"build:binary": "ts-node scripts/nbin.ts"
},
"dependencies": {
"@coder/nbin": "^1.0.7",
"@coder/nbin": "^1.1.1",
"commander": "^2.19.0",
"express": "^4.16.4",
"express-static-gzip": "^1.1.3",

View File

@ -10,6 +10,16 @@ const bin = new Binary({
});
bin.writeFiles(path.join(rootDir, "build", "**"));
bin.writeFiles(path.join(rootDir, "out", "**"));
[
// Native modules. These are marked as externals in the webpack config.
"spdlog",
"node-pty",
// These are spdlog's dependencies.
"mkdirp", "bindings",
].forEach((name) => {
bin.writeModule(path.join(__dirname, "../../../node_modules", name));
});
bin.build().then((binaryData) => {
const outputPath = path.join(__dirname, "..", `cli-${target}`);
fs.writeFileSync(outputPath, binaryData);

View File

@ -8,9 +8,8 @@ import * as os from "os";
import * as path from "path";
import * as WebSocket from "ws";
import { buildDir, cacheHome, dataHome, isCli, serveStatic } from "./constants";
import { setup as setupNativeModules } from "./modules";
import { createApp } from "./server";
import { forkModule, requireFork, requireModule } from "./vscode/bootstrapFork";
import { forkModule, requireModule } from "./vscode/bootstrapFork";
import { SharedProcess, SharedProcessState } from "./vscode/sharedProcess";
import opn = require("opn");
@ -31,7 +30,6 @@ commander.version(process.env.VERSION || "development")
.option("-H, --allow-http", "Allow http connections.", false)
.option("-P, --password <value>", "Specify a password for authentication.")
.option("--bootstrap-fork <name>", "Used for development. Never set.")
.option("--fork <name>", "Used for development. Never set.")
.option("--extra-args <args>", "Used for development. Never set.")
.arguments("Specify working directory.")
.parse(process.argv);
@ -39,6 +37,7 @@ commander.version(process.env.VERSION || "development")
Error.stackTraceLimit = Infinity;
if (isCli) {
require("nbin").shimNativeFs(buildDir);
require("nbin").shimNativeFs("/node_modules");
}
// Makes strings or numbers bold in stdout
const bold = (text: string | number): string | number => {
@ -63,7 +62,6 @@ const bold = (text: string | number): string | number => {
readonly certKey?: string;
readonly bootstrapFork?: string;
readonly fork?: string;
readonly extraArgs?: string;
};
@ -75,6 +73,7 @@ const bold = (text: string | number): string | number => {
const dataDir = path.resolve(options.userDataDir || options.dataDir || path.join(dataHome, "code-server"));
const extensionsDir = options.extensionsDir ? path.resolve(options.extensionsDir) : path.resolve(dataDir, "extensions");
const workingDir = path.resolve(args[0] || process.cwd());
const dependenciesDir = path.join(os.tmpdir(), "code-server/dependencies");
if (!fs.existsSync(dataDir)) {
const oldDataDir = path.resolve(path.join(os.homedir(), ".code-server"));
@ -89,9 +88,22 @@ const bold = (text: string | number): string | number => {
fse.mkdirp(dataDir),
fse.mkdirp(extensionsDir),
fse.mkdirp(workingDir),
fse.mkdirp(dependenciesDir),
]);
setupNativeModules(dataDir);
const unpackExecutable = (binaryName: string): void => {
const memFile = path.join(isCli ? buildDir! : path.join(__dirname, ".."), "build/dependencies", binaryName);
const diskFile = path.join(dependenciesDir, binaryName);
if (!fse.existsSync(diskFile)) {
fse.writeFileSync(diskFile, fse.readFileSync(memFile));
}
fse.chmodSync(diskFile, "755");
};
unpackExecutable("rg");
// tslint:disable-next-line no-any
(<any>global).RIPGREP_LOCATION = path.join(dependenciesDir, "rg");
const builtInExtensionsDir = path.resolve(buildDir || path.join(__dirname, ".."), "build/extensions");
if (options.bootstrapFork) {
const modulePath = options.bootstrapFork;
@ -106,13 +118,7 @@ const bold = (text: string | number): string | number => {
process.argv[i + 2] = arg;
});
return requireModule(modulePath, dataDir, builtInExtensionsDir);
}
if (options.fork) {
const modulePath = options.fork;
return requireFork(modulePath, JSON.parse(options.extraArgs!), builtInExtensionsDir);
return requireModule(modulePath, builtInExtensionsDir);
}
const logDir = path.join(cacheHome, "code-server/logs", new Date().toISOString().replace(/[-:.TZ]/g, ""));
@ -224,14 +230,7 @@ const bold = (text: string | number): string | number => {
return forkModule(options.env.AMD_ENTRYPOINT, args, options, dataDir);
}
if (isCli) {
return spawn(process.execPath, [path.join(buildDir, "out", "cli.js"), "--fork", modulePath, "--extra-args", JSON.stringify(args), "--data-dir", dataDir], {
...options,
stdio: [null, null, null, "ipc"],
});
} else {
return fork(modulePath, args, options);
}
return fork(modulePath, args, options);
},
},
password,

View File

@ -1,53 +0,0 @@
import * as fs from "fs";
import * as path from "path";
import * as os from "os";
import { isCli, buildDir } from "./constants";
/**
* Handling of native modules within the CLI
*/
export const setup = (dataDirectory: string): void => {
path.resolve(dataDirectory, "dependencies").split(path.sep).reduce((parentDir, childDir) => {
const currentDir = path.join(parentDir, childDir);
try {
fs.mkdirSync(currentDir);
} catch (ex) {
if (ex.code !== "EEXIST" && ex.code !== "EISDIR" && ex.code !== "ENOENT") {
throw ex;
}
}
return currentDir;
}, os.platform() === "win32" ? undefined! : path.sep); // Might need path.sep here for linux. Having it for windows causes an error because \C:\Users ...
const unpackModule = (moduleName: string, markExecutable: boolean = false): void => {
const memFile = path.join(isCli ? buildDir! : path.join(__dirname, ".."), "build/dependencies", moduleName);
const diskFile = path.join(dataDirectory, "dependencies", moduleName);
if (!fs.existsSync(diskFile)) {
fs.writeFileSync(diskFile, fs.readFileSync(memFile));
}
if (markExecutable) {
fs.chmodSync(diskFile, "755");
}
};
/**
* We need to unpack node-pty and patch its `loadNative` function to require our unpacked pty.node
* If pty.node isn't unpacked a SIGSEGV is thrown and the application exits. The exact reasoning
* for this is unknown ATM, but this patch works around it.
*/
unpackModule("pty.node");
unpackModule("spdlog.node");
unpackModule("rg", true);
// const nodePtyUtils = require("../../protocol/node_modules/node-pty-prebuilt/lib/utils") as typeof import("../../protocol/node_modules/node-pty-prebuilt/src/utils");
// tslint:disable-next-line:no-any
// nodePtyUtils.loadNative = (modName: string): any => {
// return (typeof __non_webpack_require__ !== "undefined" ? __non_webpack_require__ : require)(path.join(dataDirectory, "dependencies", modName + ".node"));
// };
(<any>global).RIPGREP_LOCATION = path.join(dataDirectory, "dependencies", "rg");
(<any>global).NODEPTY_LOCATION = path.join(dataDirectory, "dependencies", "pty.node");
// tslint:disable-next-line:no-any
(<any>global).SPDLOG_LOCATION = path.join(dataDirectory, "dependencies", "spdlog.node");
// tslint:disable-next-line:no-unused-expression
require("../../protocol/node_modules/node-pty-prebuilt/lib/index") as typeof import("../../protocol/node_modules/node-pty-prebuilt/src/index");
};

View File

@ -42,54 +42,13 @@ const requireFilesystemModule = (id: string, builtInExtensionsDir: string): any
return customMod.require(id);
};
/**
* Called from forking a module
*/
export const requireFork = (modulePath: string, args: string[], builtInExtensionsDir: string): void => {
const Module = require("module") as typeof import("module");
const oldRequire = Module.prototype.require;
// tslint:disable-next-line:no-any
const oldLoad = (Module as any)._findPath;
// @ts-ignore
(Module as any)._findPath = function (request, parent, isMain): any {
const lookupPaths = oldLoad.call(this, request, parent, isMain);
return lookupPaths;
};
// tslint:disable-next-line:no-any
Module.prototype.require = function (id: string): any {
if (id === "typescript") {
return require("typescript");
}
// tslint:disable-next-line:no-any
return oldRequire.call(this, id as any);
};
if (!process.send) {
throw new Error("No IPC messaging initialized");
}
process.argv = ["", "", ...args];
requireFilesystemModule(modulePath, builtInExtensionsDir);
if (ipcMsgBuffer && ipcMsgListener) {
process.removeListener("message", ipcMsgListener);
// tslint:disable-next-line:no-any
ipcMsgBuffer.forEach((i) => process.emit("message" as any, i as any));
ipcMsgBuffer = undefined;
ipcMsgListener = undefined;
}
};
export const requireModule = (modulePath: string, dataDir: string, builtInExtensionsDir: string): void => {
export const requireModule = (modulePath: string, builtInExtensionsDir: string): void => {
process.env.AMD_ENTRYPOINT = modulePath;
const xml = require("xhr2");
xml.XMLHttpRequest.prototype._restrictedHeaders["user-agent"] = false;
// tslint:disable-next-line no-any this makes installing extensions work.
(global as any).XMLHttpRequest = xml.XMLHttpRequest;
const mod = require("module") as typeof import("module");
const promiseFinally = require("promise.prototype.finally") as { shim: () => void };
promiseFinally.shim();
/**
@ -102,16 +61,7 @@ export const requireModule = (modulePath: string, dataDir: string, builtInExtens
};
if (isCli) {
/**
* Needed for properly forking external modules within the CLI
*/
// tslint:disable-next-line:no-any
(<any>cp).fork = (modulePath: string, args: ReadonlyArray<string> = [], options?: cp.ForkOptions): cp.ChildProcess => {
return cp.spawn(process.execPath, [path.join(buildDir, "out", "cli.js"), "--fork", modulePath, "--extra-args", JSON.stringify(args), "--data-dir", dataDir], {
...options,
stdio: [null, null, null, "ipc"],
});
};
process.env.NBIN_BYPASS = "true";
}
const baseDir = path.join(buildDir, "build");

View File

@ -8,7 +8,7 @@ import { StdioIpcHandler } from "../ipc";
import { ParsedArgs } from "vs/platform/environment/common/environment";
import { Emitter } from "@coder/events/src";
import { retry } from "@coder/ide/src/retry";
import { logger, Level } from "@coder/logger";
import { logger, field, Level } from "@coder/logger";
export enum SharedProcessState {
Stopped,
@ -127,13 +127,13 @@ export class SharedProcess {
activeProcess.on("exit", doReject);
activeProcess.stdout.on("data", (data) => {
logger.trace(data.toString());
logger.trace("stdout", field("data", data.toString()));
});
activeProcess.stderr.on("data", (data) => {
// Warn instead of error to prevent panic. It's unlikely stderr here is
// about anything critical to the functioning of the editor.
logger.warn(data.toString());
logger.warn("stderr", field("data", data.toString()));
});
this.ipcHandler = new StdioIpcHandler(activeProcess);

View File

@ -13,7 +13,6 @@ module.exports = merge(
path: path.join(__dirname, "out"),
libraryTarget: "commonjs",
},
mode: "production",
node: {
console: false,
global: false,
@ -23,14 +22,8 @@ module.exports = merge(
__dirname: false,
setImmediate: false
},
resolve: {
alias: {
"node-pty": "node-pty-prebuilt",
},
},
externals: {
"nbin": "commonjs nbin",
"fsevents": "fsevents",
},
entry: "./packages/server/src/cli.ts",
plugins: [

View File

@ -7,10 +7,10 @@
resolved "https://registry.yarnpkg.com/@coder/logger/-/logger-1.0.3.tgz#e0e1ae5496fde5a3c6ef3d748fdfb26a55add8b8"
integrity sha512-1o5qDZX2VZUNnzgz5KfAdMnaqaX6FNeTs0dUdg73MRHfQW94tFTIryFC1xTTCuzxGDjVHOHkaUAI4uHA2bheOA==
"@coder/nbin@^1.0.7":
version "1.0.7"
resolved "https://registry.yarnpkg.com/@coder/nbin/-/nbin-1.0.7.tgz#fc6adeb8366bf9d7dc7c301ce0be9e741eccf14b"
integrity sha512-HkCFJnYyFuPaAjk6O8IcafEEBYlHG63SqxgwB0QSyUGwjq/hUekgB23BnKmywbcxNIuX26b9j2AGWt/DBdJlXA==
"@coder/nbin@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@coder/nbin/-/nbin-1.1.1.tgz#0690928fb1306ee2a84120c8ae8ba221c338b190"
integrity sha512-SDlW0dNw6N5Ge3XlI6nbQV7G7dvTYqxzhN0douJlD56upaU4C130g0FCrhLPU/H4gT3SdZVfWoWc4AGv2fhZZw==
dependencies:
"@coder/logger" "^1.0.3"
fs-extra "^7.0.1"