mirror of https://github.com/coder/code-server.git
Add flags for customizing user data dir and extensions dir (#420)
* Add flags for customizing extensions directory * Update @coder/nbin
This commit is contained in:
parent
c607015a26
commit
4af84fcaf6
|
@ -271,6 +271,7 @@ export class Client {
|
||||||
workingDirectory: init.getWorkingDirectory(),
|
workingDirectory: init.getWorkingDirectory(),
|
||||||
os: protoToOperatingSystem(init.getOperatingSystem()),
|
os: protoToOperatingSystem(init.getOperatingSystem()),
|
||||||
shell: init.getShell(),
|
shell: init.getShell(),
|
||||||
|
extensionsDirectory: init.getExtensionsDirectory(),
|
||||||
builtInExtensionsDirectory: init.getBuiltinExtensionsDir(),
|
builtInExtensionsDirectory: init.getBuiltinExtensionsDir(),
|
||||||
};
|
};
|
||||||
this.initDataEmitter.emit(this._initData);
|
this.initDataEmitter.emit(this._initData);
|
||||||
|
|
|
@ -23,6 +23,7 @@ export interface InitData {
|
||||||
readonly homeDirectory: string;
|
readonly homeDirectory: string;
|
||||||
readonly tmpDirectory: string;
|
readonly tmpDirectory: string;
|
||||||
readonly shell: string;
|
readonly shell: string;
|
||||||
|
readonly extensionsDirectory: string;
|
||||||
readonly builtInExtensionsDirectory: string;
|
readonly builtInExtensionsDirectory: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ export interface ServerOptions {
|
||||||
readonly dataDirectory: string;
|
readonly dataDirectory: string;
|
||||||
readonly cacheDirectory: string;
|
readonly cacheDirectory: string;
|
||||||
readonly builtInExtensionsDirectory: string;
|
readonly builtInExtensionsDirectory: string;
|
||||||
|
readonly extensionsDirectory: string;
|
||||||
readonly fork?: ForkProvider;
|
readonly fork?: ForkProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +94,7 @@ export class Server {
|
||||||
initMsg.setDataDirectory(this.options.dataDirectory);
|
initMsg.setDataDirectory(this.options.dataDirectory);
|
||||||
initMsg.setWorkingDirectory(this.options.workingDirectory);
|
initMsg.setWorkingDirectory(this.options.workingDirectory);
|
||||||
initMsg.setBuiltinExtensionsDir(this.options.builtInExtensionsDirectory);
|
initMsg.setBuiltinExtensionsDir(this.options.builtInExtensionsDirectory);
|
||||||
|
initMsg.setExtensionsDirectory(this.options.extensionsDirectory);
|
||||||
initMsg.setHomeDirectory(os.homedir());
|
initMsg.setHomeDirectory(os.homedir());
|
||||||
initMsg.setTmpDirectory(os.tmpdir());
|
initMsg.setTmpDirectory(os.tmpdir());
|
||||||
initMsg.setOperatingSystem(platformToProto(os.platform()));
|
initMsg.setOperatingSystem(platformToProto(os.platform()));
|
||||||
|
|
|
@ -41,4 +41,5 @@ message WorkingInit {
|
||||||
OperatingSystem operating_system = 5;
|
OperatingSystem operating_system = 5;
|
||||||
string shell = 6;
|
string shell = 6;
|
||||||
string builtin_extensions_dir = 7;
|
string builtin_extensions_dir = 7;
|
||||||
|
string extensions_directory = 8;
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,9 @@ export class WorkingInit extends jspb.Message {
|
||||||
getBuiltinExtensionsDir(): string;
|
getBuiltinExtensionsDir(): string;
|
||||||
setBuiltinExtensionsDir(value: string): void;
|
setBuiltinExtensionsDir(value: string): void;
|
||||||
|
|
||||||
|
getExtensionsDirectory(): string;
|
||||||
|
setExtensionsDirectory(value: string): void;
|
||||||
|
|
||||||
serializeBinary(): Uint8Array;
|
serializeBinary(): Uint8Array;
|
||||||
toObject(includeInstance?: boolean): WorkingInit.AsObject;
|
toObject(includeInstance?: boolean): WorkingInit.AsObject;
|
||||||
static toObject(includeInstance: boolean, msg: WorkingInit): WorkingInit.AsObject;
|
static toObject(includeInstance: boolean, msg: WorkingInit): WorkingInit.AsObject;
|
||||||
|
@ -151,6 +154,7 @@ export namespace WorkingInit {
|
||||||
operatingSystem: WorkingInit.OperatingSystem,
|
operatingSystem: WorkingInit.OperatingSystem,
|
||||||
shell: string,
|
shell: string,
|
||||||
builtinExtensionsDir: string,
|
builtinExtensionsDir: string,
|
||||||
|
extensionsDirectory: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum OperatingSystem {
|
export enum OperatingSystem {
|
||||||
|
|
|
@ -794,7 +794,8 @@ proto.WorkingInit.toObject = function(includeInstance, msg) {
|
||||||
workingDirectory: jspb.Message.getFieldWithDefault(msg, 4, ""),
|
workingDirectory: jspb.Message.getFieldWithDefault(msg, 4, ""),
|
||||||
operatingSystem: jspb.Message.getFieldWithDefault(msg, 5, 0),
|
operatingSystem: jspb.Message.getFieldWithDefault(msg, 5, 0),
|
||||||
shell: jspb.Message.getFieldWithDefault(msg, 6, ""),
|
shell: jspb.Message.getFieldWithDefault(msg, 6, ""),
|
||||||
builtinExtensionsDir: jspb.Message.getFieldWithDefault(msg, 7, "")
|
builtinExtensionsDir: jspb.Message.getFieldWithDefault(msg, 7, ""),
|
||||||
|
extensionsDirectory: jspb.Message.getFieldWithDefault(msg, 8, "")
|
||||||
};
|
};
|
||||||
|
|
||||||
if (includeInstance) {
|
if (includeInstance) {
|
||||||
|
@ -859,6 +860,10 @@ proto.WorkingInit.deserializeBinaryFromReader = function(msg, reader) {
|
||||||
var value = /** @type {string} */ (reader.readString());
|
var value = /** @type {string} */ (reader.readString());
|
||||||
msg.setBuiltinExtensionsDir(value);
|
msg.setBuiltinExtensionsDir(value);
|
||||||
break;
|
break;
|
||||||
|
case 8:
|
||||||
|
var value = /** @type {string} */ (reader.readString());
|
||||||
|
msg.setExtensionsDirectory(value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
reader.skipField();
|
reader.skipField();
|
||||||
break;
|
break;
|
||||||
|
@ -937,6 +942,13 @@ proto.WorkingInit.serializeBinaryToWriter = function(message, writer) {
|
||||||
f
|
f
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
f = message.getExtensionsDirectory();
|
||||||
|
if (f.length > 0) {
|
||||||
|
writer.writeString(
|
||||||
|
8,
|
||||||
|
f
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1054,4 +1066,19 @@ proto.WorkingInit.prototype.setBuiltinExtensionsDir = function(value) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* optional string extensions_directory = 8;
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
proto.WorkingInit.prototype.getExtensionsDirectory = function() {
|
||||||
|
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** @param {string} value */
|
||||||
|
proto.WorkingInit.prototype.setExtensionsDirectory = function(value) {
|
||||||
|
jspb.Message.setProto3StringField(this, 8, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
goog.object.extend(exports, proto);
|
goog.object.extend(exports, proto);
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"build:binary": "ts-node scripts/nbin.ts"
|
"build:binary": "ts-node scripts/nbin.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@coder/nbin": "^1.0.4",
|
"@coder/nbin": "^1.0.5",
|
||||||
"commander": "^2.19.0",
|
"commander": "^2.19.0",
|
||||||
"express": "^4.16.4",
|
"express": "^4.16.4",
|
||||||
"express-static-gzip": "^1.1.3",
|
"express-static-gzip": "^1.1.3",
|
||||||
|
|
|
@ -21,7 +21,9 @@ commander.version(process.env.VERSION || "development")
|
||||||
.description("Run VS Code on a remote server.")
|
.description("Run VS Code on a remote server.")
|
||||||
.option("--cert <value>")
|
.option("--cert <value>")
|
||||||
.option("--cert-key <value>")
|
.option("--cert-key <value>")
|
||||||
.option("-d, --data-dir <value>", "Customize where user-data is stored.")
|
.option("-e, --extensions-dir <dir>", "Set the root path for extensions.")
|
||||||
|
.option("-d --user-data-dir <dir>", " Specifies the directory that user data is kept in, useful when running as root.")
|
||||||
|
.option("--data-dir <value>", "DEPRECATED: Use '--user-data-dir' instead. Customize where user-data is stored.")
|
||||||
.option("-h, --host <value>", "Customize the hostname.", "0.0.0.0")
|
.option("-h, --host <value>", "Customize the hostname.", "0.0.0.0")
|
||||||
.option("-o, --open", "Open in the browser on startup.", false)
|
.option("-o, --open", "Open in the browser on startup.", false)
|
||||||
.option("-p, --port <number>", "Port to bind on.", 8443)
|
.option("-p, --port <number>", "Port to bind on.", 8443)
|
||||||
|
@ -51,6 +53,9 @@ const bold = (text: string | number): string | number => {
|
||||||
readonly host: string;
|
readonly host: string;
|
||||||
readonly port: number;
|
readonly port: number;
|
||||||
|
|
||||||
|
readonly userDataDir?: string;
|
||||||
|
readonly extensionsDir?: string;
|
||||||
|
|
||||||
readonly dataDir?: string;
|
readonly dataDir?: string;
|
||||||
readonly password?: string;
|
readonly password?: string;
|
||||||
readonly open?: boolean;
|
readonly open?: boolean;
|
||||||
|
@ -67,7 +72,8 @@ const bold = (text: string | number): string | number => {
|
||||||
const noAuthValue = (commander as any).auth;
|
const noAuthValue = (commander as any).auth;
|
||||||
options.noAuth = !noAuthValue;
|
options.noAuth = !noAuthValue;
|
||||||
|
|
||||||
const dataDir = path.resolve(options.dataDir || path.join(dataHome, "code-server"));
|
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 workingDir = path.resolve(args[0] || process.cwd());
|
||||||
|
|
||||||
if (!fs.existsSync(dataDir)) {
|
if (!fs.existsSync(dataDir)) {
|
||||||
|
@ -81,6 +87,7 @@ const bold = (text: string | number): string | number => {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
fse.mkdirp(cacheHome),
|
fse.mkdirp(cacheHome),
|
||||||
fse.mkdirp(dataDir),
|
fse.mkdirp(dataDir),
|
||||||
|
fse.mkdirp(extensionsDir),
|
||||||
fse.mkdirp(workingDir),
|
fse.mkdirp(workingDir),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -144,10 +151,15 @@ const bold = (text: string | number): string | number => {
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`\u001B[1mcode-server ${process.env.VERSION ? `v${process.env.VERSION}` : "development"}`);
|
logger.info(`\u001B[1mcode-server ${process.env.VERSION ? `v${process.env.VERSION}` : "development"}`);
|
||||||
|
|
||||||
|
if (options.dataDir) {
|
||||||
|
logger.warn('"--data-dir" is deprecated. Use "--user-data-dir" instead.');
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: fill in appropriate doc url
|
// TODO: fill in appropriate doc url
|
||||||
logger.info("Additional documentation: http://github.com/codercom/code-server");
|
logger.info("Additional documentation: http://github.com/codercom/code-server");
|
||||||
logger.info("Initializing", field("data-dir", dataDir), field("working-dir", workingDir), field("log-dir", logDir));
|
logger.info("Initializing", field("data-dir", dataDir), field("extensions-dir", extensionsDir), field("working-dir", workingDir), field("log-dir", logDir));
|
||||||
const sharedProcess = new SharedProcess(dataDir, builtInExtensionsDir);
|
const sharedProcess = new SharedProcess(dataDir, extensionsDir, builtInExtensionsDir);
|
||||||
const sendSharedProcessReady = (socket: WebSocket): void => {
|
const sendSharedProcessReady = (socket: WebSocket): void => {
|
||||||
const active = new SharedProcessActive();
|
const active = new SharedProcessActive();
|
||||||
active.setSocketPath(sharedProcess.socketPath);
|
active.setSocketPath(sharedProcess.socketPath);
|
||||||
|
@ -196,6 +208,7 @@ const bold = (text: string | number): string | number => {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
serverOptions: {
|
serverOptions: {
|
||||||
|
extensionsDirectory: extensionsDir,
|
||||||
builtInExtensionsDirectory: builtInExtensionsDir,
|
builtInExtensionsDirectory: builtInExtensionsDir,
|
||||||
dataDirectory: dataDir,
|
dataDirectory: dataDir,
|
||||||
workingDirectory: workingDir,
|
workingDirectory: workingDir,
|
||||||
|
|
|
@ -38,6 +38,7 @@ export class SharedProcess {
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly userDataDir: string,
|
private readonly userDataDir: string,
|
||||||
|
private readonly extensionsDir: string,
|
||||||
private readonly builtInExtensionsDir: string,
|
private readonly builtInExtensionsDir: string,
|
||||||
) {
|
) {
|
||||||
this.retry.run();
|
this.retry.run();
|
||||||
|
@ -95,10 +96,8 @@ export class SharedProcess {
|
||||||
this.activeProcess.kill();
|
this.activeProcess.kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
const extensionsDir = path.join(this.userDataDir, "extensions");
|
|
||||||
const backupsDir = path.join(this.userDataDir, "Backups");
|
const backupsDir = path.join(this.userDataDir, "Backups");
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
fse.mkdirp(extensionsDir),
|
|
||||||
fse.mkdirp(backupsDir),
|
fse.mkdirp(backupsDir),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -141,7 +140,7 @@ export class SharedProcess {
|
||||||
args: {
|
args: {
|
||||||
"builtin-extensions-dir": this.builtInExtensionsDir,
|
"builtin-extensions-dir": this.builtInExtensionsDir,
|
||||||
"user-data-dir": this.userDataDir,
|
"user-data-dir": this.userDataDir,
|
||||||
"extensions-dir": extensionsDir,
|
"extensions-dir": this.extensionsDir,
|
||||||
},
|
},
|
||||||
logLevel: this.logger.level,
|
logLevel: this.logger.level,
|
||||||
sharedIPCHandle: this.socketPath,
|
sharedIPCHandle: this.socketPath,
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
resolved "https://registry.yarnpkg.com/@coder/logger/-/logger-1.0.3.tgz#e0e1ae5496fde5a3c6ef3d748fdfb26a55add8b8"
|
resolved "https://registry.yarnpkg.com/@coder/logger/-/logger-1.0.3.tgz#e0e1ae5496fde5a3c6ef3d748fdfb26a55add8b8"
|
||||||
integrity sha512-1o5qDZX2VZUNnzgz5KfAdMnaqaX6FNeTs0dUdg73MRHfQW94tFTIryFC1xTTCuzxGDjVHOHkaUAI4uHA2bheOA==
|
integrity sha512-1o5qDZX2VZUNnzgz5KfAdMnaqaX6FNeTs0dUdg73MRHfQW94tFTIryFC1xTTCuzxGDjVHOHkaUAI4uHA2bheOA==
|
||||||
|
|
||||||
"@coder/nbin@^1.0.4":
|
"@coder/nbin@^1.0.5":
|
||||||
version "1.0.4"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/@coder/nbin/-/nbin-1.0.4.tgz#13a3d110fe116ed5d5fdbd1384f0335745dfd859"
|
resolved "https://registry.yarnpkg.com/@coder/nbin/-/nbin-1.0.5.tgz#6a9e9982eb179d6bcc9c2e7dfebb608b7c4605d9"
|
||||||
integrity sha512-mtd5hzPHWBwKpTCYdJdLdiY4CFCEb8HUtv3NgH8SSLFiPDwY7H1UlpqeamIty27NZ+9NLnrBd/DfaE3aVo7rxQ==
|
integrity sha512-rai1/WgvH2j8SlRweOSk0JmrAzBx8bc22P+pThnPHj5terd0GScshqNR3EIoL/cdC2Ii4wjfOYodYbl/QynYGg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@coder/logger" "^1.0.3"
|
"@coder/logger" "^1.0.3"
|
||||||
fs-extra "^7.0.1"
|
fs-extra "^7.0.1"
|
||||||
|
|
|
@ -8,7 +8,7 @@ export class EnvironmentService extends environment.EnvironmentService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public get extensionsPath(): string {
|
public get extensionsPath(): string {
|
||||||
return path.join(paths.getAppDataPath(), "extensions");
|
return paths.getExtensionsDirectory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ class Paths {
|
||||||
private _appData: string | undefined;
|
private _appData: string | undefined;
|
||||||
private _defaultUserData: string | undefined;
|
private _defaultUserData: string | undefined;
|
||||||
private _socketPath: string | undefined;
|
private _socketPath: string | undefined;
|
||||||
|
private _extensionsDirectory: string | undefined;
|
||||||
private _builtInExtensionsDirectory: string | undefined;
|
private _builtInExtensionsDirectory: string | undefined;
|
||||||
private _workingDirectory: string | undefined;
|
private _workingDirectory: string | undefined;
|
||||||
|
|
||||||
|
@ -31,6 +32,14 @@ class Paths {
|
||||||
return this._socketPath;
|
return this._socketPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get extensionsDirectory(): string {
|
||||||
|
if (!this._extensionsDirectory) {
|
||||||
|
throw new Error("trying to access extensions directory before it has been set");
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._extensionsDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
public get builtInExtensionsDirectory(): string {
|
public get builtInExtensionsDirectory(): string {
|
||||||
if (!this._builtInExtensionsDirectory) {
|
if (!this._builtInExtensionsDirectory) {
|
||||||
throw new Error("trying to access builtin extensions directory before it has been set");
|
throw new Error("trying to access builtin extensions directory before it has been set");
|
||||||
|
@ -52,6 +61,7 @@ class Paths {
|
||||||
this._appData = data.dataDirectory;
|
this._appData = data.dataDirectory;
|
||||||
this._defaultUserData = data.dataDirectory;
|
this._defaultUserData = data.dataDirectory;
|
||||||
this._socketPath = sharedData.socketPath;
|
this._socketPath = sharedData.socketPath;
|
||||||
|
this._extensionsDirectory = data.extensionsDirectory;
|
||||||
this._builtInExtensionsDirectory = data.builtInExtensionsDirectory;
|
this._builtInExtensionsDirectory = data.builtInExtensionsDirectory;
|
||||||
this._workingDirectory = data.workingDirectory;
|
this._workingDirectory = data.workingDirectory;
|
||||||
}
|
}
|
||||||
|
@ -61,5 +71,6 @@ export const _paths = new Paths();
|
||||||
export const getAppDataPath = (): string => _paths.appData;
|
export const getAppDataPath = (): string => _paths.appData;
|
||||||
export const getDefaultUserDataPath = (): string => _paths.defaultUserData;
|
export const getDefaultUserDataPath = (): string => _paths.defaultUserData;
|
||||||
export const getWorkingDirectory = (): string => _paths.workingDirectory;
|
export const getWorkingDirectory = (): string => _paths.workingDirectory;
|
||||||
|
export const getExtensionsDirectory = (): string => _paths.extensionsDirectory;
|
||||||
export const getBuiltInExtensionsDirectory = (): string => _paths.builtInExtensionsDirectory;
|
export const getBuiltInExtensionsDirectory = (): string => _paths.builtInExtensionsDirectory;
|
||||||
export const getSocketPath = (): string => _paths.socketPath;
|
export const getSocketPath = (): string => _paths.socketPath;
|
||||||
|
|
Loading…
Reference in New Issue