diff --git a/.gitignore b/.gitignore index 3cc6e31d..8f02ff03 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ vendor/modules node-* /plugins /lib/coder-cloud-agent +/lib/linkup .home coverage **/.DS_Store diff --git a/ci/build/build-code-server.sh b/ci/build/build-code-server.sh index c1772539..e61264c3 100755 --- a/ci/build/build-code-server.sh +++ b/ci/build/build-code-server.sh @@ -15,20 +15,29 @@ main() { chmod +x out/node/entry.js fi + # for arch; we do not use OS from lib.sh and get our own. + # lib.sh normalizes macos to darwin - but cloud-agent's binaries do not + source ./ci/lib.sh + OS="$(uname | tr '[:upper:]' '[:lower:]')" + if ! [ -f ./lib/coder-cloud-agent ]; then echo "Downloading the cloud agent..." - # for arch; we do not use OS from lib.sh and get our own. - # lib.sh normalizes macos to darwin - but cloud-agent's binaries do not - source ./ci/lib.sh - OS="$(uname | tr '[:upper:]' '[:lower:]')" - set +e curl -fsSL "https://github.com/cdr/cloud-agent/releases/latest/download/cloud-agent-$OS-$ARCH" -o ./lib/coder-cloud-agent chmod +x ./lib/coder-cloud-agent set -e fi + if ! [ -f ./lib/linkup ]; then + echo "Downloading Link agent..." + + set +e + curl -fsSL "https://storage.googleapis.com/coder-link-releases/latest/linkup-$OS-$ARCH" -o ./lib/linkup + chmod +x ./lib/linkup + set -e + fi + yarn browserify out/browser/register.js -o out/browser/register.browserified.js yarn browserify out/browser/pages/login.js -o out/browser/pages/login.browserified.js yarn browserify out/browser/pages/vscode.js -o out/browser/pages/vscode.browserified.js diff --git a/ci/build/build-release.sh b/ci/build/build-release.sh index ba319351..09d59aed 100755 --- a/ci/build/build-release.sh +++ b/ci/build/build-release.sh @@ -61,6 +61,7 @@ EOF rsync node_modules/ "$RELEASE_PATH/node_modules" mkdir -p "$RELEASE_PATH/lib" rsync ./lib/coder-cloud-agent "$RELEASE_PATH/lib" + rsync ./lib/linkup "$RELEASE_PATH/lib" fi } diff --git a/ci/build/npm-postinstall.sh b/ci/build/npm-postinstall.sh index 76c558d1..38412ee7 100755 --- a/ci/build/npm-postinstall.sh +++ b/ci/build/npm-postinstall.sh @@ -63,6 +63,12 @@ main() { echo "Failed to download cloud agent; --link will not work" fi + if curl -fsSL "https://storage.googleapis.com/coder-link-releases/latest/linkup-$OS-$ARCH" -o ./lib/linkup; then + chmod +x ./lib/linkup + else + echo "Failed to download Link agent; the Link extension will not work" + fi + if ! vscode_yarn; then echo "You may not have the required dependencies to build the native modules." echo "Please see https://github.com/cdr/code-server/blob/master/docs/npm.md" diff --git a/src/node/link.ts b/src/node/link.ts new file mode 100644 index 00000000..5dfe7952 --- /dev/null +++ b/src/node/link.ts @@ -0,0 +1,22 @@ +import { logger } from "@coder/logger" +import { spawn } from "child_process" +import path from "path" + +export function startLink(port: number): Promise { + logger.debug(`running link targetting ${port}`) + + const agent = spawn(path.resolve(__dirname, "../../lib/linkup"), ["--devurl", `code:${port}:code-server`], { + shell: false, + }) + return new Promise((res, rej) => { + agent.on("error", rej) + agent.on("close", (code) => { + if (code !== 0) { + return rej({ + message: `Link exited with ${code}`, + }) + } + res() + }) + }) +} diff --git a/src/node/main.ts b/src/node/main.ts index 1e9569fa..d351ffb2 100644 --- a/src/node/main.ts +++ b/src/node/main.ts @@ -8,6 +8,7 @@ import { createApp, ensureAddress } from "./app" import { AuthType, DefaultedArgs, Feature } from "./cli" import { coderCloudBind } from "./coder_cloud" import { commit, version } from "./constants" +import { startLink } from "./link" import { register } from "./routes" import { humanPath, isFile, open } from "./util" @@ -129,6 +130,15 @@ export const runCodeServer = async (args: DefaultedArgs): Promise = logger.info(" - Connected to cloud agent") } + try { + const port = parseInt(serverAddress.split(":").pop() as string, 10) + startLink(port).catch((ex) => { + logger.debug("Link daemon exited!", field("error", ex)) + }) + } catch (ex) { + logger.debug("Failed to start link daemon!", ex) + } + if (args.enable && args.enable.length > 0) { logger.info("Enabling the following experimental features:") args.enable.forEach((feature) => {