diff --git a/src/node/cli.ts b/src/node/cli.ts index c4d0d9dd4edad6b5102dc3b9d8583959d4445388..8546866858f63b3fbcd3fa5cdbefed814194d8f4 100644 --- a/src/node/cli.ts +++ b/src/node/cli.ts @@ -48,7 +48,7 @@ export interface Args extends VsArgs { readonly "reuse-window"?: boolean readonly "new-window"?: boolean - readonly expose?: OptionalString + readonly "coder-link"?: OptionalString } interface Option { @@ -159,10 +159,10 @@ const options: Options> = { log: { type: LogLevel }, verbose: { type: "boolean", short: "vvv", description: "Enable verbose logging." }, - expose: { + "coder-link": { type: OptionalString, description: ` - Securely expose code-server via Coder Cloud with the passed name. You'll get a URL like + Securely link code-server via Coder Cloud with the passed name. You'll get a URL like https://myname.coder-cloud.com at which you can easily access your code-server instance. Authorization is done via GitHub. Only the first code-server spawned with the current configuration will be accessible.`, diff --git a/src/node/coder-cloud.ts b/src/node/coder-cloud.ts index b621b08cdda6d30573635f942b331f0a6bbb5511..c8782812b7102fc72b46d404926992a3877c184f 100644 --- a/src/node/coder-cloud.ts +++ b/src/node/coder-cloud.ts @@ -9,7 +9,7 @@ import xdgBasedir from "xdg-basedir" const coderCloudAgent = path.resolve(__dirname, "../../lib/coder-cloud-agent") -export async function coderCloudExpose(serverName: string): Promise { +export async function coderCloudLink(serverName: string): Promise { const agent = spawn(coderCloudAgent, ["link", serverName], { stdio: ["inherit", "inherit", "pipe"], }) diff --git a/src/node/entry.ts b/src/node/entry.ts index 539b3bccdc4be7c54dbcc2230f3d961ee96ab495..42abbc2debb8b4c9f4213e696e306d7a12d943d2 100644 --- a/src/node/entry.ts +++ b/src/node/entry.ts @@ -12,7 +12,7 @@ import { StaticHttpProvider } from "./app/static" import { UpdateHttpProvider } from "./app/update" import { VscodeHttpProvider } from "./app/vscode" import { Args, bindAddrFromAllSources, optionDescriptions, parse, readConfigFile, setDefaults } from "./cli" -import { coderCloudExpose, coderCloudProxy } from "./coder-cloud" +import { coderCloudLink, coderCloudProxy } from "./coder-cloud" import { AuthType, HttpServer, HttpServerOptions } from "./http" import { loadPlugins } from "./plugin" import { generateCertificate, hash, humanPath, open } from "./util" @@ -36,6 +36,15 @@ const version = pkg.version || "development" const commit = pkg.commit || "development" const main = async (args: Args, cliArgs: Args, configArgs: Args): Promise => { + if (args["coder-link"]) { + // If we're being exposed to the cloud, we listen on a random address. + args = { + ...args, + host: "localhost", + port: 0, + } + } + if (!args.auth) { args = { ...args, @@ -131,6 +140,22 @@ const main = async (args: Args, cliArgs: Args, configArgs: Args): Promise await open(openAddress).catch(console.error) logger.info(`Opened ${openAddress}`) } + + if (args["coder-link"]) { + if (!args["coder-link"].value) { + logger.error("You must pass a name to link with coder cloud. See --help") + process.exit(1) + } + + logger.info(`linking code-server to the cloud with name ${args["coder-link"].value}`) + + try { + await coderCloudLink(args["coder-link"].value) + } catch (err) { + logger.error(err.message) + process.exit(1) + } + } } async function entry(): Promise { @@ -191,20 +216,6 @@ async function entry(): Promise { process.exit(1) }) vscode.on("exit", (code) => process.exit(code || 0)) - } else if (args["expose"]) { - logger.debug("exposing code-server via the coder-cloud agent") - - if (!args["expose"].value) { - logger.error("You must pass a name to expose with coder cloud. See --help") - process.exit(1) - } - - try { - await coderCloudExpose(args["expose"].value) - } catch (err) { - logger.error(err.message) - process.exit(1) - } } else if (process.env.VSCODE_IPC_HOOK_CLI) { const pipeArgs: OpenCommandPipeArgs = { type: "open",