mirror of https://github.com/coder/code-server.git
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 { plural } from "../../common/util"
|
||||||
import { App } from "../app"
|
import { App } from "../app"
|
||||||
import { AuthType, DefaultedArgs } from "../cli"
|
import { AuthType, DefaultedArgs } from "../cli"
|
||||||
import { commit, isDevMode, rootPath } from "../constants"
|
import { commit, rootPath } from "../constants"
|
||||||
import { Heart } from "../heart"
|
import { Heart } from "../heart"
|
||||||
import { ensureAuthenticated, redirect } from "../http"
|
import { ensureAuthenticated, redirect } from "../http"
|
||||||
import { PluginAPI } from "../plugin"
|
import { PluginAPI } from "../plugin"
|
||||||
|
@ -23,7 +23,7 @@ import * as login from "./login"
|
||||||
import * as logout from "./logout"
|
import * as logout from "./logout"
|
||||||
import * as pathProxy from "./pathProxy"
|
import * as pathProxy from "./pathProxy"
|
||||||
import * as update from "./update"
|
import * as update from "./update"
|
||||||
import { createVSServerRouter, VSServerResult } from "./vscode"
|
import { CodeServerRouteWrapper } from "./vscode"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register all routes and middleware.
|
* 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)
|
app.router.use("/update", update.router)
|
||||||
|
|
||||||
let vscode: VSServerResult
|
const vsServerRouteHandler = new CodeServerRouteWrapper()
|
||||||
try {
|
|
||||||
vscode = await createVSServerRouter(args)
|
// Note that the root route is replaced in Coder Enterprise by the plugin API.
|
||||||
app.router.use("/", vscode.router)
|
for (const routePrefix of ["/", "/vscode"]) {
|
||||||
app.wsRouter.use("/", vscode.wsRouter.router)
|
app.router.use(routePrefix, vsServerRouteHandler.router)
|
||||||
app.router.use("/vscode", vscode.router)
|
app.wsRouter.use(routePrefix, vsServerRouteHandler.wsRouter)
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
app.router.use(() => {
|
app.router.use(() => {
|
||||||
|
@ -164,6 +156,6 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
|
||||||
return () => {
|
return () => {
|
||||||
heart.dispose()
|
heart.dispose()
|
||||||
pluginApi?.dispose()
|
pluginApi?.dispose()
|
||||||
vscode?.codeServerMain.dispose()
|
vsServerRouteHandler.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,65 +1,105 @@
|
||||||
|
import { logger } from "@coder/logger"
|
||||||
import * as express from "express"
|
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 { ensureAuthenticated, authenticated, redirect } from "../http"
|
||||||
import { loadAMDModule } from "../util"
|
import { loadAMDModule } from "../util"
|
||||||
import { Router as WsRouter, WebsocketRouter } from "../wsRouter"
|
import { Router as WsRouter } from "../wsRouter"
|
||||||
import { errorHandler } from "./errors"
|
import { errorHandler } from "./errors"
|
||||||
|
|
||||||
export interface VSServerResult {
|
export class CodeServerRouteWrapper {
|
||||||
router: express.Router
|
/** Assigned in `ensureCodeServerLoaded` */
|
||||||
wsRouter: WebsocketRouter
|
private _codeServerMain!: CodeServerLib.IServerAPI
|
||||||
codeServerMain: CodeServerLib.IServerAPI
|
private _wsRouterWrapper = WsRouter()
|
||||||
|
public router = express.Router()
|
||||||
|
|
||||||
|
public get wsRouter() {
|
||||||
|
return this._wsRouterWrapper.router
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createVSServerRouter = async (args: DefaultedArgs): Promise<VSServerResult> => {
|
//#region Route Handlers
|
||||||
// See ../../../vendor/modules/code-oss-dev/src/vs/server/main.js.
|
|
||||||
const createVSServer = await loadAMDModule<CodeServerLib.CreateServer>(
|
|
||||||
"vs/server/remoteExtensionHostAgent",
|
|
||||||
"createServer",
|
|
||||||
)
|
|
||||||
|
|
||||||
const codeServerMain = await createVSServer(null, {
|
private $root: express.Handler = async (req, res, next) => {
|
||||||
connectionToken: "0000",
|
|
||||||
...args,
|
|
||||||
// For some reason VS Code takes the port as a string.
|
|
||||||
port: typeof args.port !== "undefined" ? args.port.toString() : undefined,
|
|
||||||
})
|
|
||||||
|
|
||||||
const router = express.Router()
|
|
||||||
const wsRouter = WsRouter()
|
|
||||||
|
|
||||||
router.get("/", async (req, res, next) => {
|
|
||||||
const isAuthenticated = await authenticated(req)
|
const isAuthenticated = await authenticated(req)
|
||||||
|
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
return redirect(req, res, "login", {
|
return redirect(req, res, "login", {
|
||||||
// req.baseUrl can be blank if already at the root.
|
// req.baseUrl can be blank if already at the root.
|
||||||
to: req.baseUrl && req.baseUrl !== "/" ? req.baseUrl : undefined,
|
to: req.baseUrl && req.baseUrl !== "/" ? req.baseUrl : undefined,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
next()
|
|
||||||
})
|
|
||||||
|
|
||||||
router.all("*", ensureAuthenticated, (req, res, next) => {
|
next()
|
||||||
req.on("error", (error: any) => {
|
}
|
||||||
|
|
||||||
|
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)) {
|
if (error instanceof Error && ["EntryNotFound", "FileNotFound", "HttpError"].includes(error.message)) {
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
|
||||||
errorHandler(error, req, res, next)
|
errorHandler(error, req, res, next)
|
||||||
})
|
}
|
||||||
|
|
||||||
codeServerMain.handleRequest(req, res)
|
req.once("error", requestErrorHandler)
|
||||||
})
|
|
||||||
|
|
||||||
wsRouter.ws("/", ensureAuthenticated, (req) => {
|
this._codeServerMain.handleRequest(req, res)
|
||||||
codeServerMain.handleUpgrade(req, req.socket)
|
}
|
||||||
|
|
||||||
|
private $proxyWebsocket = async (req: WebsocketRequest) => {
|
||||||
|
this._codeServerMain.handleUpgrade(req, req.socket)
|
||||||
|
|
||||||
req.socket.resume()
|
req.socket.resume()
|
||||||
})
|
}
|
||||||
|
|
||||||
return {
|
//#endregion
|
||||||
router,
|
|
||||||
wsRouter,
|
/**
|
||||||
codeServerMain,
|
* 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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,6 @@
|
||||||
"postinstall": "./postinstall.sh"
|
"postinstall": "./postinstall.sh"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"code-oss-dev": "cdr/vscode#d62e8db202f80db7a42233cd56d04e6806109fb1"
|
"code-oss-dev": "cdr/vscode#8db6c9bb0bc065bdb905dc076f4d4234f126aff7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,9 +296,9 @@ clone-response@^1.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
mimic-response "^1.0.0"
|
mimic-response "^1.0.0"
|
||||||
|
|
||||||
code-oss-dev@cdr/vscode#d62e8db202f80db7a42233cd56d04e6806109fb1:
|
code-oss-dev@cdr/vscode#8db6c9bb0bc065bdb905dc076f4d4234f126aff7:
|
||||||
version "1.61.1"
|
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:
|
dependencies:
|
||||||
"@microsoft/applicationinsights-web" "^2.6.4"
|
"@microsoft/applicationinsights-web" "^2.6.4"
|
||||||
"@vscode/sqlite3" "4.0.12"
|
"@vscode/sqlite3" "4.0.12"
|
||||||
|
|
Loading…
Reference in New Issue