Use unique socket per user for managing editor sessions (#6278)

Also warn if editor session manager socket cannot be created rather than failing.
This commit is contained in:
Sean Lee 2023-06-21 14:39:25 -04:00 committed by GitHub
parent 5d3c9edce4
commit b5a9ef80e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 7 deletions

View File

@ -126,7 +126,9 @@ export const runCodeServer = async (
logger.info(`Using config file ${humanPath(os.homedir(), args.config)}`) logger.info(`Using config file ${humanPath(os.homedir(), args.config)}`)
logger.info(`${protocol.toUpperCase()} server listening on ${serverAddress.toString()}`) logger.info(`${protocol.toUpperCase()} server listening on ${serverAddress.toString()}`)
logger.info(`Session server listening on ${sessionServerAddress?.toString()}`) if (sessionServerAddress) {
logger.info(`Session server listening on ${sessionServerAddress.toString()}`)
}
if (args.auth === AuthType.Password) { if (args.auth === AuthType.Password) {
logger.info(" - Authentication is enabled") logger.info(" - Authentication is enabled")

View File

@ -1,14 +1,13 @@
import { logger } from "@coder/logger" import { logger } from "@coder/logger"
import express from "express" import express from "express"
import * as http from "http" import * as http from "http"
import * as os from "os"
import * as path from "path" import * as path from "path"
import { HttpCode } from "../common/http" import { HttpCode } from "../common/http"
import { listen } from "./app" import { listen } from "./app"
import { canConnect } from "./util" import { canConnect, paths } from "./util"
// Socket path of the daemonized code-server instance. // Socket path of the daemonized code-server instance.
export const DEFAULT_SOCKET_PATH = path.join(os.tmpdir(), "code-server-ipc.sock") export const DEFAULT_SOCKET_PATH = path.join(paths.data, `code-server-ipc.sock`)
export interface EditorSessionEntry { export interface EditorSessionEntry {
workspace: { workspace: {
@ -78,7 +77,11 @@ export async function makeEditorSessionManagerServer(
}) })
const server = http.createServer(router) const server = http.createServer(router)
await listen(server, { socket: codeServerSocketPath }) try {
await listen(server, { socket: codeServerSocketPath })
} catch (e) {
logger.warn(`Could not create socket at ${codeServerSocketPath}`)
}
return server return server
} }

View File

@ -1,5 +1,50 @@
import { EditorSessionManager } from "../../../src/node/vscodeSocket" import { logger } from "@coder/logger"
import { clean, tmpdir, listenOn } from "../../utils/helpers" import * as app from "../../../src/node/app"
import { paths } from "../../../src/node/util"
import {
DEFAULT_SOCKET_PATH,
EditorSessionManager,
makeEditorSessionManagerServer,
} from "../../../src/node/vscodeSocket"
import { clean, tmpdir, listenOn, mockLogger } from "../../utils/helpers"
describe("DEFAULT_SOCKET_PATH", () => {
it("should be a unique path per user", () => {
expect(DEFAULT_SOCKET_PATH.startsWith(paths.data)).toBe(true)
})
})
describe("makeEditorSessionManagerServer", () => {
let tmpDirPath: string
const testName = "mesms"
beforeAll(async () => {
jest.clearAllMocks()
mockLogger()
await clean(testName)
})
afterAll(() => {
jest.resetModules()
})
beforeEach(async () => {
tmpDirPath = await tmpdir(testName)
})
it("warns if socket cannot be created", async () => {
jest.spyOn(app, "listen").mockImplementation(() => {
throw new Error()
})
const server = await makeEditorSessionManagerServer(
`${tmpDirPath}/code-server-ipc.sock`,
new EditorSessionManager(),
)
expect(logger.warn).toHaveBeenCalledWith(`Could not create socket at ${tmpDirPath}/code-server-ipc.sock`)
server.close()
})
})
describe("EditorSessionManager", () => { describe("EditorSessionManager", () => {
let tmpDirPath: string let tmpDirPath: string