Spawn vscode on demand (#4499)
* Refactor vscode router to load async. * Bump vscode. * fix volumes (#4497) * Fix : recreate the termux guide to adapt the recent changes (#4472) * Fix : recreate the termux guide to adapt the recent changes Termux nodejs-lts changed from v14 to v16 and there are many issues people are facing such as with argon2. Hence I recommend changing it to this install process which is comparably better and has one less issue :^) I've also added some extra things such as installing GO and Python, idk about the TOC tree but this is pretty much it. * yarn-fmt and minor typos https://github.com/cdr/code-server/pull/4472#issuecomment-964752180 * Fix : replace unnecessary steps to be linked to a guide * Change from private gist to a section in Extra * Remove reference to non-existent step * ready to merge! Co-authored-by: Joe Previte <jjprevite@gmail.com> Co-authored-by: Jinu <jlandowner8@gmail.com> Co-authored-by: Han Seung Min - 한승민 <hanseungmin.ar@gmail.com> Co-authored-by: Joe Previte <jjprevite@gmail.com>
This commit is contained in:
parent
6606040835
commit
e705948ef3
@ -10,7 +10,7 @@ import { HttpCode, HttpError } from "../../common/http"
|
||||
import { plural } from "../../common/util"
|
||||
import { App } from "../app"
|
||||
import { AuthType, DefaultedArgs } from "../cli"
|
||||
import { commit, isDevMode, rootPath } from "../constants"
|
||||
import { commit, rootPath } from "../constants"
|
||||
import { Heart } from "../heart"
|
||||
import { ensureAuthenticated, redirect } from "../http"
|
||||
import { PluginAPI } from "../plugin"
|
||||
@ -23,7 +23,7 @@ import * as login from "./login"
|
||||
import * as logout from "./logout"
|
||||
import * as pathProxy from "./pathProxy"
|
||||
import * as update from "./update"
|
||||
import { createVSServerRouter, VSServerResult } from "./vscode"
|
||||
import { CodeServerRouteWrapper } from "./vscode"
|
||||
|
||||
/**
|
||||
* Register all routes and middleware.
|
||||
@ -138,20 +138,12 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
|
||||
|
||||
app.router.use("/update", update.router)
|
||||
|
||||
let vscode: VSServerResult
|
||||
try {
|
||||
vscode = await createVSServerRouter(args)
|
||||
app.router.use("/", vscode.router)
|
||||
app.wsRouter.use("/", vscode.wsRouter.router)
|
||||
app.router.use("/vscode", vscode.router)
|
||||
app.wsRouter.use("/vscode", vscode.wsRouter.router)
|
||||
} catch (error: any) {
|
||||
if (isDevMode) {
|
||||
logger.warn(error)
|
||||
logger.warn("VS Server router may still be compiling.")
|
||||
} else {
|
||||
throw error
|
||||
}
|
||||
const vsServerRouteHandler = new CodeServerRouteWrapper()
|
||||
|
||||
// Note that the root route is replaced in Coder Enterprise by the plugin API.
|
||||
for (const routePrefix of ["/", "/vscode"]) {
|
||||
app.router.use(routePrefix, vsServerRouteHandler.router)
|
||||
app.wsRouter.use(routePrefix, vsServerRouteHandler.wsRouter)
|
||||
}
|
||||
|
||||
app.router.use(() => {
|
||||
@ -164,6 +156,6 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
|
||||
return () => {
|
||||
heart.dispose()
|
||||
pluginApi?.dispose()
|
||||
vscode?.codeServerMain.dispose()
|
||||
vsServerRouteHandler.dispose()
|
||||
}
|
||||
}
|
||||
|
@ -1,65 +1,105 @@
|
||||
import { logger } from "@coder/logger"
|
||||
import * as express from "express"
|
||||
import { DefaultedArgs } from "../cli"
|
||||
import { WebsocketRequest } from "../../../typings/pluginapi"
|
||||
import { logError } from "../../common/util"
|
||||
import { isDevMode } from "../constants"
|
||||
import { ensureAuthenticated, authenticated, redirect } from "../http"
|
||||
import { loadAMDModule } from "../util"
|
||||
import { Router as WsRouter, WebsocketRouter } from "../wsRouter"
|
||||
import { Router as WsRouter } from "../wsRouter"
|
||||
import { errorHandler } from "./errors"
|
||||
|
||||
export interface VSServerResult {
|
||||
router: express.Router
|
||||
wsRouter: WebsocketRouter
|
||||
codeServerMain: CodeServerLib.IServerAPI
|
||||
}
|
||||
export class CodeServerRouteWrapper {
|
||||
/** Assigned in `ensureCodeServerLoaded` */
|
||||
private _codeServerMain!: CodeServerLib.IServerAPI
|
||||
private _wsRouterWrapper = WsRouter()
|
||||
public router = express.Router()
|
||||
|
||||
export const createVSServerRouter = async (args: DefaultedArgs): Promise<VSServerResult> => {
|
||||
// See ../../../vendor/modules/code-oss-dev/src/vs/server/main.js.
|
||||
const createVSServer = await loadAMDModule<CodeServerLib.CreateServer>(
|
||||
"vs/server/remoteExtensionHostAgent",
|
||||
"createServer",
|
||||
)
|
||||
public get wsRouter() {
|
||||
return this._wsRouterWrapper.router
|
||||
}
|
||||
|
||||
const codeServerMain = await createVSServer(null, {
|
||||
connectionToken: "0000",
|
||||
...args,
|
||||
// For some reason VS Code takes the port as a string.
|
||||
port: typeof args.port !== "undefined" ? args.port.toString() : undefined,
|
||||
})
|
||||
//#region Route Handlers
|
||||
|
||||
const router = express.Router()
|
||||
const wsRouter = WsRouter()
|
||||
|
||||
router.get("/", async (req, res, next) => {
|
||||
private $root: express.Handler = async (req, res, next) => {
|
||||
const isAuthenticated = await authenticated(req)
|
||||
|
||||
if (!isAuthenticated) {
|
||||
return redirect(req, res, "login", {
|
||||
// req.baseUrl can be blank if already at the root.
|
||||
to: req.baseUrl && req.baseUrl !== "/" ? req.baseUrl : undefined,
|
||||
})
|
||||
}
|
||||
next()
|
||||
})
|
||||
|
||||
router.all("*", ensureAuthenticated, (req, res, next) => {
|
||||
req.on("error", (error: any) => {
|
||||
next()
|
||||
}
|
||||
|
||||
private $proxyRequest: express.Handler = async (req, res, next) => {
|
||||
// We allow certain errors to propagate so that other routers may handle requests
|
||||
// outside VS Code
|
||||
const requestErrorHandler = (error: any) => {
|
||||
if (error instanceof Error && ["EntryNotFound", "FileNotFound", "HttpError"].includes(error.message)) {
|
||||
next()
|
||||
}
|
||||
|
||||
errorHandler(error, req, res, next)
|
||||
})
|
||||
}
|
||||
|
||||
codeServerMain.handleRequest(req, res)
|
||||
})
|
||||
req.once("error", requestErrorHandler)
|
||||
|
||||
wsRouter.ws("/", ensureAuthenticated, (req) => {
|
||||
codeServerMain.handleUpgrade(req, req.socket)
|
||||
this._codeServerMain.handleRequest(req, res)
|
||||
}
|
||||
|
||||
private $proxyWebsocket = async (req: WebsocketRequest) => {
|
||||
this._codeServerMain.handleUpgrade(req, req.socket)
|
||||
|
||||
req.socket.resume()
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
router,
|
||||
wsRouter,
|
||||
codeServerMain,
|
||||
//#endregion
|
||||
|
||||
/**
|
||||
* Fetches a code server instance asynchronously to avoid an initial memory overhead.
|
||||
*/
|
||||
private ensureCodeServerLoaded: express.Handler = async (req, _res, next) => {
|
||||
if (this._codeServerMain) {
|
||||
return next()
|
||||
}
|
||||
|
||||
const { args } = req
|
||||
|
||||
/**
|
||||
* @file ../../../vendor/modules/code-oss-dev/src/vs/server/main.js
|
||||
*/
|
||||
const createVSServer = await loadAMDModule<CodeServerLib.CreateServer>(
|
||||
"vs/server/remoteExtensionHostAgent",
|
||||
"createServer",
|
||||
)
|
||||
|
||||
try {
|
||||
this._codeServerMain = await createVSServer(null, {
|
||||
connectionToken: "0000",
|
||||
...args,
|
||||
// For some reason VS Code takes the port as a string.
|
||||
port: args.port?.toString(),
|
||||
})
|
||||
} catch (createServerError) {
|
||||
logError(logger, "CodeServerRouteWrapper", createServerError)
|
||||
|
||||
const loggedError = isDevMode ? new Error("VS Code may still be compiling...") : createServerError
|
||||
|
||||
return next(loggedError)
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
constructor() {
|
||||
this.router.get("/", this.ensureCodeServerLoaded, this.$root)
|
||||
this.router.all("*", ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyRequest)
|
||||
this._wsRouterWrapper.ws("/", ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyWebsocket)
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._codeServerMain?.dispose()
|
||||
}
|
||||
}
|
||||
|
2
vendor/package.json
vendored
2
vendor/package.json
vendored
@ -7,6 +7,6 @@
|
||||
"postinstall": "./postinstall.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
"code-oss-dev": "cdr/vscode#d62e8db202f80db7a42233cd56d04e6806109fb1"
|
||||
"code-oss-dev": "cdr/vscode#8db6c9bb0bc065bdb905dc076f4d4234f126aff7"
|
||||
}
|
||||
}
|
||||
|
4
vendor/yarn.lock
vendored
4
vendor/yarn.lock
vendored
@ -296,9 +296,9 @@ clone-response@^1.0.2:
|
||||
dependencies:
|
||||
mimic-response "^1.0.0"
|
||||
|
||||
code-oss-dev@cdr/vscode#d62e8db202f80db7a42233cd56d04e6806109fb1:
|
||||
code-oss-dev@cdr/vscode#8db6c9bb0bc065bdb905dc076f4d4234f126aff7:
|
||||
version "1.61.1"
|
||||
resolved "https://codeload.github.com/cdr/vscode/tar.gz/d62e8db202f80db7a42233cd56d04e6806109fb1"
|
||||
resolved "https://codeload.github.com/cdr/vscode/tar.gz/8db6c9bb0bc065bdb905dc076f4d4234f126aff7"
|
||||
dependencies:
|
||||
"@microsoft/applicationinsights-web" "^2.6.4"
|
||||
"@vscode/sqlite3" "4.0.12"
|
||||
|
Reference in New Issue
Block a user