Archived
1
0

Set session socket into environment variable (#6282)

* 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
This commit is contained in:
Asher
2023-06-21 22:47:01 -08:00
committed by GitHub
parent 56d10d82bf
commit 5c19962930
11 changed files with 168 additions and 98 deletions

View File

@ -9,7 +9,7 @@ import * as util from "../common/util"
import { DefaultedArgs } from "./cli"
import { disposer } from "./http"
import { isNodeJSErrnoException } from "./util"
import { DEFAULT_SOCKET_PATH, EditorSessionManager, makeEditorSessionManagerServer } from "./vscodeSocket"
import { EditorSessionManager, makeEditorSessionManagerServer } from "./vscodeSocket"
import { handleUpgrade } from "./wsRouter"
type SocketOptions = { socket: string; "socket-mode"?: string }
@ -88,7 +88,7 @@ export const createApp = async (args: DefaultedArgs): Promise<App> => {
handleUpgrade(wsRouter, server)
const editorSessionManager = new EditorSessionManager()
const editorSessionManagerServer = await makeEditorSessionManagerServer(DEFAULT_SOCKET_PATH, editorSessionManager)
const editorSessionManagerServer = await makeEditorSessionManagerServer(args["session-socket"], editorSessionManager)
const disposeEditorSessionManagerServer = disposer(editorSessionManagerServer)
const dispose = async () => {

View File

@ -4,7 +4,7 @@ import { load } from "js-yaml"
import * as os from "os"
import * as path from "path"
import { generateCertificate, generatePassword, humanPath, paths, splitOnFirstEquals } from "./util"
import { DEFAULT_SOCKET_PATH, EditorSessionManagerClient } from "./vscodeSocket"
import { EditorSessionManagerClient } from "./vscodeSocket"
export enum Feature {
// No current experimental features!
@ -51,6 +51,7 @@ export interface UserProvidedCodeArgs {
"disable-file-downloads"?: boolean
"disable-workspace-trust"?: boolean
"disable-getting-started-override"?: boolean
"session-socket"?: string
}
/**
@ -160,6 +161,9 @@ export const options: Options<Required<UserProvidedArgs>> = {
"Disable update check. Without this flag, code-server checks every 6 hours against the latest github release and \n" +
"then notifies you once every week that a new release is available.",
},
"session-socket": {
type: "string",
},
"disable-file-downloads": {
type: "boolean",
description:
@ -459,6 +463,7 @@ export interface DefaultedArgs extends ConfigArgs {
usingEnvHashedPassword: boolean
"extensions-dir": string
"user-data-dir": string
"session-socket": string
/* Positional arguments. */
_: string[]
}
@ -479,6 +484,11 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args["extensions-dir"] = path.join(args["user-data-dir"], "extensions")
}
if (!args["session-socket"]) {
args["session-socket"] = path.join(args["user-data-dir"], "code-server-ipc.sock")
}
process.env.CODE_SERVER_SESSION_SOCKET = args["session-socket"]
// --verbose takes priority over --log and --log takes priority over the
// environment variable.
if (args.verbose) {
@ -739,7 +749,10 @@ function bindAddrFromAllSources(...argsConfig: UserProvidedArgs[]): Addr {
* existing instance. The arguments here should be the arguments the user
* explicitly passed on the command line, *NOT DEFAULTS* or the configuration.
*/
export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Promise<string | undefined> => {
export const shouldOpenInExistingInstance = async (
args: UserProvidedArgs,
sessionSocket: string,
): Promise<string | undefined> => {
// Always use the existing instance if we're running from VS Code's terminal.
if (process.env.VSCODE_IPC_HOOK_CLI) {
logger.debug("Found VSCODE_IPC_HOOK_CLI")
@ -747,21 +760,22 @@ export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Prom
}
const paths = getResolvedPathsFromArgs(args)
const client = new EditorSessionManagerClient(DEFAULT_SOCKET_PATH)
// If we can't connect to the socket then there's no existing instance.
if (!(await client.canConnect())) {
return undefined
}
const client = new EditorSessionManagerClient(sessionSocket)
// If these flags are set then assume the user is trying to open in an
// existing instance since these flags have no effect otherwise.
// existing instance since these flags have no effect otherwise. That means
// if there is no existing instance we should error rather than falling back
// to spawning code-server normally.
const openInFlagCount = ["reuse-window", "new-window"].reduce((prev, cur) => {
return args[cur as keyof UserProvidedArgs] ? prev + 1 : prev
}, 0)
if (openInFlagCount > 0) {
logger.debug("Found --reuse-window or --new-window")
return await client.getConnectedSocketPath(paths[0])
const socketPath = await client.getConnectedSocketPath(paths[0])
if (!socketPath) {
throw new Error(`No opened code-server instances found to handle ${paths[0]}`)
}
return socketPath
}
// It's possible the user is trying to spawn another instance of code-server.
@ -769,7 +783,11 @@ export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Prom
// code-server is invoked exactly like this: `code-server my-file`).
// 2. That a file or directory was passed.
// 3. That the socket is active.
// 4. That an instance exists to handle the path (implied by #3).
if (Object.keys(args).length === 1 && typeof args._ !== "undefined" && args._.length > 0) {
if (!(await client.canConnect())) {
return undefined
}
const socketPath = await client.getConnectedSocketPath(paths[0])
if (socketPath) {
logger.debug("Found existing code-server socket")

View File

@ -51,7 +51,7 @@ async function entry(): Promise<void> {
return runCodeCli(args)
}
const socketPath = await shouldOpenInExistingInstance(cliArgs)
const socketPath = await shouldOpenInExistingInstance(cliArgs, args["session-socket"])
if (socketPath) {
logger.debug("Trying to open in existing instance")
return openInExistingInstance(args, socketPath)

View File

@ -4,10 +4,7 @@ import * as http from "http"
import * as path from "path"
import { HttpCode } from "../common/http"
import { listen } from "./app"
import { canConnect, paths } from "./util"
// Socket path of the daemonized code-server instance.
export const DEFAULT_SOCKET_PATH = path.join(paths.data, `code-server-ipc.sock`)
import { canConnect } from "./util"
export interface EditorSessionEntry {
workspace: {