5c19962930
* Avoid spawning code-server with --reuse-window and --new-window These flags mean the user explicitly wants to open in an existing instance so if the socket is down it should error rather than try to spawn code-server normally. * Set session socket into environment variable While I was at it I added a CLI flag to override the default. I also swapped the default to --user-data-dir. The value is set on an environment variable so it can be used by the extension host similar to VSCODE_IPC_HOOK_CLI. * Add e2e test for opening files externally
130 lines
4.9 KiB
Diff
130 lines
4.9 KiB
Diff
Store the IPC socket with workspace metadata.
|
|
|
|
This lets us use it to open files inside code-server from outside of
|
|
code-server.
|
|
|
|
To test this:
|
|
1. run code-server
|
|
2. open file outside of code-server i.e. `code-server <path-to-file`
|
|
|
|
It should open in your existing code-server instance.
|
|
|
|
When the extension host is terminated, the socket is unregistered.
|
|
|
|
Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
|
|
+++ code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
|
|
@@ -2,7 +2,7 @@
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
-
|
|
+import * as _http from 'http';
|
|
import * as performance from 'vs/base/common/performance';
|
|
import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl';
|
|
import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterceptor';
|
|
@@ -17,6 +17,7 @@ import { ExtensionRuntime } from 'vs/wor
|
|
import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer';
|
|
import { realpathSync } from 'vs/base/node/extpath';
|
|
import { ExtHostConsoleForwarder } from 'vs/workbench/api/node/extHostConsoleForwarder';
|
|
+import { IExtHostWorkspace } from '../common/extHostWorkspace';
|
|
import { ExtHostDiskFileSystemProvider } from 'vs/workbench/api/node/extHostDiskFileSystemProvider';
|
|
|
|
class NodeModuleRequireInterceptor extends RequireInterceptor {
|
|
@@ -83,6 +84,52 @@ export class ExtHostExtensionService ext
|
|
await interceptor.install();
|
|
performance.mark('code/extHost/didInitAPI');
|
|
|
|
+ (async () => {
|
|
+ const socketPath = process.env['VSCODE_IPC_HOOK_CLI'];
|
|
+ const codeServerSocketPath = process.env['CODE_SERVER_SESSION_SOCKET']
|
|
+ if (!socketPath || !codeServerSocketPath) {
|
|
+ return;
|
|
+ }
|
|
+ const workspace = this._instaService.invokeFunction((accessor) => {
|
|
+ const workspaceService = accessor.get(IExtHostWorkspace);
|
|
+ return workspaceService.workspace;
|
|
+ });
|
|
+ const entry = {
|
|
+ workspace,
|
|
+ socketPath
|
|
+ };
|
|
+ const message = JSON.stringify({entry});
|
|
+ await new Promise<void>((resolve, reject) => {
|
|
+ const opts: _http.RequestOptions = {
|
|
+ path: '/add-session',
|
|
+ socketPath: codeServerSocketPath,
|
|
+ method: 'POST',
|
|
+ headers: {
|
|
+ 'content-type': 'application/json',
|
|
+ }
|
|
+ };
|
|
+ const req = _http.request(opts, (res) => {
|
|
+ res.on('error', reject);
|
|
+ res.on('end', () => {
|
|
+ try {
|
|
+ if (res.statusCode === 200) {
|
|
+ resolve();
|
|
+ } else {
|
|
+ reject(new Error('Unexpected status code: ' + res.statusCode));
|
|
+ }
|
|
+ } catch (e: unknown) {
|
|
+ reject(e);
|
|
+ }
|
|
+ });
|
|
+ });
|
|
+ req.on('error', reject);
|
|
+ req.write(message);
|
|
+ req.end();
|
|
+ });
|
|
+ })().catch(error => {
|
|
+ this._logService.error(error);
|
|
+ });
|
|
+
|
|
// Do this when extension service exists, but extensions are not being activated yet.
|
|
const configProvider = await this._extHostConfiguration.getConfigProvider();
|
|
await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._logService, this._mainThreadTelemetryProxy, this._initData);
|
|
Index: code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
|
|
===================================================================
|
|
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
|
|
+++ code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
|
|
@@ -3,6 +3,7 @@
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
+import * as _http from 'http';
|
|
import * as nativeWatchdog from 'native-watchdog';
|
|
import * as net from 'net';
|
|
import * as minimist from 'minimist';
|
|
@@ -400,7 +401,28 @@ async function startExtensionHostProcess
|
|
);
|
|
|
|
// rewrite onTerminate-function to be a proper shutdown
|
|
- onTerminate = (reason: string) => extensionHostMain.terminate(reason);
|
|
+ onTerminate = (reason: string) => {
|
|
+ extensionHostMain.terminate(reason);
|
|
+
|
|
+ const socketPath = process.env['VSCODE_IPC_HOOK_CLI'];
|
|
+ const codeServerSocketPath = process.env['CODE_SERVER_SESSION_SOCKET']
|
|
+ if (!socketPath || !codeServerSocketPath) {
|
|
+ return;
|
|
+ }
|
|
+ const message = JSON.stringify({socketPath});
|
|
+ const opts: _http.RequestOptions = {
|
|
+ path: '/delete-session',
|
|
+ socketPath: codeServerSocketPath,
|
|
+ method: 'POST',
|
|
+ headers: {
|
|
+ 'content-type': 'application/json',
|
|
+ 'accept': 'application/json'
|
|
+ }
|
|
+ };
|
|
+ const req = _http.request(opts);
|
|
+ req.write(message);
|
|
+ req.end();
|
|
+ };
|
|
}
|
|
|
|
startExtensionHostProcess().catch((err) => console.log(err));
|