From ad7da73c80fc2055099cfcd0a8e951bf127226ff Mon Sep 17 00:00:00 2001 From: Teffen Ellis Date: Thu, 11 Nov 2021 18:02:45 -0500 Subject: [PATCH 1/4] Refactor vscode router to load async. --- src/node/routes/index.ts | 26 +++------ src/node/routes/vscode.ts | 112 ++++++++++++++++++++++++++------------ 2 files changed, 85 insertions(+), 53 deletions(-) diff --git a/src/node/routes/index.ts b/src/node/routes/index.ts index 7ca79fa7c486..0328ce22929a 100644 --- a/src/node/routes/index.ts +++ b/src/node/routes/index.ts @@ -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 { @@ -164,6 +156,6 @@ export const register = async (app: App, args: DefaultedArgs): Promise { heart.dispose() pluginApi?.dispose() - vscode?.codeServerMain.dispose() + vsServerRouteHandler.dispose() } } diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index 76efb93402ed..55fb308ec2b9 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -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 const createVSServerRouter = async (args: DefaultedArgs): Promise => { - // See ../../../vendor/modules/code-oss-dev/src/vs/server/main.js. - const createVSServer = await loadAMDModule( - "vs/server/remoteExtensionHostAgent", - "createServer", - ) +export class CodeServerRouteWrapper { + /** Assigned in `ensureCodeServerLoaded` */ + private _codeServerMain!: CodeServerLib.IServerAPI + private _wsRouterWrapper = WsRouter() + public router = express.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, - }) + public get wsRouter() { + return this._wsRouterWrapper.router + } - const router = express.Router() - const wsRouter = WsRouter() + //#region Route Handlers - 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) => { + 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) - }) + } + + req.once("error", requestErrorHandler) - codeServerMain.handleRequest(req, res) - }) + this._codeServerMain.handleRequest(req, res) + } - wsRouter.ws("/", ensureAuthenticated, (req) => { - codeServerMain.handleUpgrade(req, req.socket) + private $proxyWebsocket = async (req: WebsocketRequest) => { + this._codeServerMain.handleUpgrade(req, req.socket) req.socket.resume() - }) + } + + //#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( + "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) + } - return { - router, - wsRouter, - codeServerMain, + dispose() { + this._codeServerMain?.dispose() } } From e56d970c43976fdac3e7ae5a7943f4f0ee8ae714 Mon Sep 17 00:00:00 2001 From: Teffen Ellis Date: Thu, 11 Nov 2021 18:03:07 -0500 Subject: [PATCH 2/4] Bump vscode. --- vendor/package.json | 2 +- vendor/yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vendor/package.json b/vendor/package.json index bdf69c89768f..e98b3e3a1a12 100644 --- a/vendor/package.json +++ b/vendor/package.json @@ -7,6 +7,6 @@ "postinstall": "./postinstall.sh" }, "devDependencies": { - "code-oss-dev": "cdr/vscode#d62e8db202f80db7a42233cd56d04e6806109fb1" + "code-oss-dev": "cdr/vscode#8db6c9bb0bc065bdb905dc076f4d4234f126aff7" } } diff --git a/vendor/yarn.lock b/vendor/yarn.lock index 10acfc6576a8..17f03ea4d865 100644 --- a/vendor/yarn.lock +++ b/vendor/yarn.lock @@ -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" From 22231f4dbd0a740f4f914175ef90976d08467c40 Mon Sep 17 00:00:00 2001 From: Jinu Date: Sat, 13 Nov 2021 02:10:47 +0900 Subject: [PATCH 3/4] fix volumes (#4497) --- ci/helm-chart/templates/deployment.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ci/helm-chart/templates/deployment.yaml b/ci/helm-chart/templates/deployment.yaml index 201e3e6cb8c6..3f0d11d5c600 100644 --- a/ci/helm-chart/templates/deployment.yaml +++ b/ci/helm-chart/templates/deployment.yaml @@ -142,6 +142,12 @@ spec: secretName: {{ .secretName }} defaultMode: {{ .defaultMode }} {{- end }} + {{- range .Values.extraConfigmapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} + defaultMode: {{ .defaultMode }} + {{- end }} {{- range .Values.extraVolumeMounts }} - name: {{ .name }} {{- if .existingClaim }} From 0de57fe09d6293da98767f8cceacdb1576a1dc9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Han=20Seung=20Min=20-=20=ED=95=9C=EC=8A=B9=EB=AF=BC?= Date: Sat, 13 Nov 2021 06:25:48 +0900 Subject: [PATCH 4/4] 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 --- docs/termux.md | 153 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 115 insertions(+), 38 deletions(-) diff --git a/docs/termux.md b/docs/termux.md index db50adf3c8d0..8a9b7a87034d 100644 --- a/docs/termux.md +++ b/docs/termux.md @@ -5,67 +5,144 @@ - [Install](#install) - [Upgrade](#upgrade) - [Known Issues](#known-issues) - - [Search doesn't work](#search-doesnt-work) - - [Backspace doesn't work](#backspace-doesnt-work) + - [Git won't work in `/sdcard`](#git-wont-work-in-sdcard) +- [Extra](#extra) + - [Create a new user](#create-a-new-user) + - [Install Go](#install-go) + - [Install Python](#install-python) -Termux is a terminal application and Linux environment that you can also use to -run code-server from your Android phone. - ## Install -1. Install Termux from [F-Droid](https://f-droid.org/en/packages/com.termux/). -1. Make sure it's up-to-date: `apt update && apt upgrade` -1. Install required packages: `apt install build-essential python git nodejs-lts yarn` -1. Install code-server: `yarn global add code-server` -1. Run code-server: `code-server` and navigate to localhost:8080 in your browser +1. Get [Termux](https://f-droid.org/en/packages/com.termux/) from **F-Droid**. +2. Install Debian by running the following. + - Run `termux-setup-storage` to allow storage access, or else code-server won't be able to read from `/sdcard`.\ + If you used the Andronix command then you may have to edit the `start-debian.sh` script to mount `/sdcard` just as simple as uncommenting the `command+=" -b /sdcard"` line. + > The following command was extracted from [Andronix](https://andronix.app/) you can also use [proot-distro](https://github.com/termux/proot-distro). + > After Debian is installed the `~ $` will change to `root@localhost`. + +```bash +pkg update -y && pkg install wget curl proot tar -y && wget https://raw.githubusercontent.com/AndronixApp/AndronixOrigin/master/Installer/Debian/debian.sh -O debian.sh && chmod +x debian.sh && bash debian.sh +``` + +3. Run the following commands to setup Debian. + +```bash +apt update +apt upgrade -y +apt-get install nano vim sudo curl wget git -y +``` + +4. Install [NVM](https://github.com/nvm-sh/nvm) by following the install guide in the README, just a curl/wget command. +5. Set up NVM for multi-user. After installing NVM it automatically adds the necessary commands for it to work, but it will only work if you are logged in as root; + + - Copy the lines NVM asks you to run after running the install script. + - Run `nano /root/.bashrc` and comment out those lines by adding a `#` at the start. + - Run `nano /etc/profile` and paste those lines at the end and make sure to replace `$HOME` with `/root` + - Now run `exit` and start Debain again. + +6. After following the instructions and setting up NVM you can now install the [required node version](https://coder.com/docs/code-server/latest/npm#nodejs-version) using `nvm install version_here`. +7. To install `code-server` run the following. + > To check the install process (Will not actually install code-server) + > If it all looks good, you can install code-server by running the second command + +```bash +curl -fsSL https://code-server.dev/install.sh | sh -s -- --dry-run +``` + +```bash +curl -fsSL https://code-server.dev/install.sh | sh +``` + +8. You can now start code server by simply running `code-server`. + +> Consider using a new user instead of root, read [here](https://www.howtogeek.com/124950/htg-explains-why-you-shouldnt-log-into-your-linux-system-as-root/) why using root is not recommended.\ +> Learn how to add a user [here](#create-a-new-user). ## Upgrade -To upgrade run: `yarn global upgrade code-server --latest` +1. Remove all previous installs `rm -rf ~/.local/lib/code-server-*` +2. Run the install script again `curl -fsSL https://code-server.dev/install.sh | sh` ## Known Issues -The following details known issues and suggested workarounds for using -code-server with Termux. +### Git won't work in `/sdcard` + +Issue : Using git in the `/sdcard` directory will fail during cloning/commit/staging/etc...\ +Fix : None\ +Potential Workaround : + +1. Create a soft-link from the debian-fs to your folder in `/sdcard` +2. Use git from termux (preferred) + +## Extra + +### Create a new user + +To create a new user follow these simple steps - + +1. Create a new user by running `useradd username -m`. +2. Change the password by running `passwd username`. +3. Give your new user sudo access by runnning `visudo`, scroll down to `User privilege specification` and add the following line after root `username ALL=(ALL:ALL) ALL`. +4. Now edit the `/etc/passwd` file with your commadline editor of choice and at the end of the line that specifies your user change `/bin/sh` to `/bin/bash`. +5. Now switch users, by running `su - username` + +- Remember the `-` betweeen `su` and username is required to execute `/etc/profile`,\ + since `/etc/profile` may have some necessary things to be executed you should always add a `-`. + +### Install Go -### Search doesn't work +> From https://golang.org/doc/install -There is a known issue with search not working on Android because it's missing -`bin/rg` ([context](https://github.com/cdr/code-server/issues/1730#issuecomment-721515979)). To fix this: +1. Go to https://golang.org/dl/ and copy the download link for `linux arm` and run the following. -1. Install `ripgrep` with `pkg` +```bash +wget download_link +``` - ```sh - pkg install ripgrep - ``` +2. Extract the downloaded archive. (This step will erase all previous GO installs, make sure to create a backup if you have previously installed GO) -1. Make a soft link using `ln -s` +```bash +rm -rf /usr/local/go && tar -C /usr/local -xzf archive_name +``` - ```sh - # run this command inside the code-server directory - ln -s $PREFIX/bin/rg ./vendor/modules/code-oss-dev/vscode-ripgrep/bin/rg - ``` +3. Run `nano /etc/profile` and add the following line `export PATH=$PATH:/usr/local/go/bin`. +4. Now run `exit` (depending on if you have switched users or not, you may have to run `exit` multiple times to get to normal termux shell) and start Debian again. +5. Check if your install was successful by running `go version` -### Backspace doesn't work +### Install Python -When using Android's on-screen keyboard, the backspace key doesn't work -properly. This is a known upstream issue: +> Run these commands as root -- [Issues with backspace in Codespaces on Android (Surface Duo)](https://github.com/microsoft/vscode/issues/107602) -- [Support mobile platforms](https://github.com/xtermjs/xterm.js/issues/1101) +1. Run the following command to install required packages to build python. -There are two workarounds. +```bash +sudo apt-get update +sudo apt-get install make build-essential libssl-dev zlib1g-dev \ + libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \ + libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev +``` -**Option 1:** Modify keyboard dispatch settings +2. Install [pyenv](https://github.com/pyenv/pyenv/) from [pyenv-installer](https://github.com/pyenv/pyenv-installer) by running. -1. Open the Command Palette -2. Search for **Preferences: Open Settings (JSON)** -3. Add `"keyboard.dispatch": "keyCode"` +```bash +curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash +``` -The backspace button should work at this point. +3. Run `nano /etc/profile` and add the following -_Thanks to @Nefomemes for the [suggestion](https://github.com/cdr/code-server/issues/1141#issuecomment-789463707)!_ +```bash +export PYENV_ROOT="/root/.pyenv" +export PATH="/root/.pyenv/bin:$PATH" +eval "$(pyenv init --path)" +eval "$(pyenv virtualenv-init -)" +``` -**Option 2:** Use a Bluetooth keyboard. +4. Exit start Debian again. +5. Run `pyenv versions` to list all installable versions. +6. Run `pyenv install version` to install the desired python version. + > The build process may take some time (an hour or 2 depending on your device). +7. Run `touch /root/.pyenv/version && echo "your_version_here" > /root/.pyenv/version` +8. (You may have to start Debian again) Run `python3 -V` to verify if PATH works or not. + > If `python3` doesn't work but pyenv says that the install was successful in step 6 then try running `$PYENV_ROOT/versions/your_version/bin/python3`.