Add linkup command to enable linking

The linkup command is the successor to coder-cloud. It enables port-forwarding via URL, uses WebRTC internally, and will enable greater linking functionality longer-term. A Link extension will be published once this is merged. We are not removing the old link functionality yet... we eventually will, but want to ensure a smooth transition.
This commit is contained in:
Kyle Carberry 2021-09-09 16:24:04 -05:00
parent c7a5263b38
commit d39a141d42
6 changed files with 55 additions and 0 deletions

1
.gitignore vendored
View File

@ -12,6 +12,7 @@ node_modules
node-* node-*
/plugins /plugins
/lib/coder-cloud-agent /lib/coder-cloud-agent
/lib/linkup
.home .home
coverage coverage
**/.DS_Store **/.DS_Store

View File

@ -29,6 +29,20 @@ main() {
set -e set -e
fi fi
if ! [ -f ./lib/linkup ]; then
echo "Downloading Link 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://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/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/login.js -o out/browser/pages/login.browserified.js
yarn browserify out/browser/pages/vscode.js -o out/browser/pages/vscode.browserified.js yarn browserify out/browser/pages/vscode.js -o out/browser/pages/vscode.browserified.js

View File

@ -60,6 +60,7 @@ EOF
rsync node_modules/ "$RELEASE_PATH/node_modules" rsync node_modules/ "$RELEASE_PATH/node_modules"
mkdir -p "$RELEASE_PATH/lib" mkdir -p "$RELEASE_PATH/lib"
rsync ./lib/coder-cloud-agent "$RELEASE_PATH/lib" rsync ./lib/coder-cloud-agent "$RELEASE_PATH/lib"
rsync ./lib/linkup "$RELEASE_PATH/lib"
fi fi
} }

View File

@ -63,6 +63,12 @@ main() {
echo "Failed to download cloud agent; --link will not work" echo "Failed to download cloud agent; --link will not work"
fi 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 if ! vscode_yarn; then
echo "You may not have the required dependencies to build the native modules." 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" echo "Please see https://github.com/cdr/code-server/blob/master/docs/npm.md"

23
src/node/link.ts Normal file
View File

@ -0,0 +1,23 @@
import { logger } from "@coder/logger"
import { spawn } from "child_process"
import path from "path"
export function startLink(port: number): Promise<void> {
logger.debug(`running link targetting ${port}`)
const agent = spawn(path.resolve(__dirname, "../../lib/linkup"), ["--devurl", `code:${port}:code-server`], {
stdio: "ignore",
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()
})
})
}

View File

@ -8,6 +8,7 @@ import { createApp, ensureAddress } from "./app"
import { AuthType, DefaultedArgs, Feature } from "./cli" import { AuthType, DefaultedArgs, Feature } from "./cli"
import { coderCloudBind } from "./coder_cloud" import { coderCloudBind } from "./coder_cloud"
import { commit, version } from "./constants" import { commit, version } from "./constants"
import { startLink } from "./link"
import { register } from "./routes" import { register } from "./routes"
import { humanPath, isFile, open } from "./util" import { humanPath, isFile, open } from "./util"
@ -129,6 +130,15 @@ export const runCodeServer = async (args: DefaultedArgs): Promise<http.Server> =
logger.info(" - Connected to cloud agent") 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) { if (args.enable && args.enable.length > 0) {
logger.info("Enabling the following experimental features:") logger.info("Enabling the following experimental features:")
args.enable.forEach((feature) => { args.enable.forEach((feature) => {