Skip to content

Commit ef3759d

Browse files
committed
Use VS Code Remote SSH instead of custom installer
Fixes #15, #12, #5, #2, and #1.
1 parent 639911b commit ef3759d

12 files changed

+579
-5733
lines changed

package.json

+8-5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
"Other"
2222
],
2323
"activationEvents": [
24-
"onResolveRemoteAuthority:coder",
24+
"onResolveRemoteAuthority:ssh-remote",
2525
"onCommand:coder.connect",
2626
"onCommand:coder.open",
2727
"onCommand:coder.login",
28-
"onView:coderWorkspaces",
28+
"onView:coderRemote",
2929
"onUri"
3030
],
3131
"extensionDependencies": [
@@ -45,7 +45,7 @@
4545
"views": {
4646
"coder": [
4747
{
48-
"id": "coderWorkspaces",
48+
"id": "coderRemote",
4949
"name": "",
5050
"visibility": "visible",
5151
"icon": "media/logo.svg",
@@ -55,12 +55,12 @@
5555
},
5656
"viewsWelcome": [
5757
{
58-
"view": "coderWorkspaces",
58+
"view": "coderRemote",
5959
"contents": "Coder is a platform that provisions remote development environments. \n[Login](command:coder.login)",
6060
"when": "!coder.authenticated && coder.loaded"
6161
},
6262
{
63-
"view": "coderWorkspaces",
63+
"view": "coderRemote",
6464
"contents": "You're logged in! \n[Open Workspace](command:coder.open)",
6565
"when": "coder.authenticated && coder.loaded"
6666
}
@@ -132,8 +132,11 @@
132132
"dependencies": {
133133
"axios": "0.26.1",
134134
"eventsource": "^2.0.2",
135+
"find-process": "^1.4.7",
136+
"jsonc-parser": "^3.2.0",
135137
"ndjson": "^2.0.0",
136138
"pretty-bytes": "^6.0.0",
139+
"ssh-config": "4.1.6",
137140
"tar-fs": "^2.1.1",
138141
"which": "^2.0.2",
139142
"ws": "^8.11.0",

src/commands.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import axios from "axios"
22
import { getUser, getWorkspaces } from "coder/site/src/api/api"
33
import { Workspace } from "coder/site/src/api/typesGenerated"
44
import * as vscode from "vscode"
5+
import { Remote } from "./remote"
56
import { Storage } from "./storage"
67

78
export class Commands {
@@ -33,7 +34,7 @@ export class Commands {
3334
title: "Coder API Key",
3435
password: true,
3536
placeHolder: "Copy your API key from the opened browser page.",
36-
value: this.storage.getSessionToken(),
37+
value: await this.storage.getSessionToken(),
3738
ignoreFocusOut: true,
3839
validateInput: (value) => {
3940
return axios
@@ -151,7 +152,7 @@ export class Commands {
151152

152153
// A workspace can have multiple agents, but that's handled
153154
// when opening a workspace unless explicitly specified.
154-
let uri = vscode.Uri.parse(`vscode-remote://coder+${workspaceOwner}.${workspaceName}/`)
155+
let uri = vscode.Uri.parse(`vscode-remote://ssh-remote+${Remote.Prefix}${workspaceOwner}--${workspaceName}/`)
155156

156157
const output: {
157158
workspaces: { folderUri: vscode.Uri; remoteAuthority: string }[]

src/extension.ts

+21-13
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
"use strict"
22

33
import { getUser } from "coder/site/src/api/api"
4-
import { readFileSync } from "fs"
54
import * as module from "module"
6-
import path from "path"
75
import * as vscode from "vscode"
86
import { Commands } from "./commands"
97
import { Remote } from "./remote"
108
import { Storage } from "./storage"
119

1210
export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
13-
const productJSON = readFileSync(path.join(vscode.env.appRoot, "product.json"))
14-
const product = JSON.parse(productJSON.toString())
15-
const commit = product.commit
1611
const output = vscode.window.createOutputChannel("Coder")
17-
const storage = new Storage(output, ctx.globalState, ctx.globalStorageUri)
18-
storage.init()
12+
const storage = new Storage(output, ctx.globalState, ctx.secrets, ctx.globalStorageUri, ctx.logUri)
13+
await storage.init()
1914

2015
getUser()
2116
.then(() => {
@@ -45,13 +40,16 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
4540
vscode.commands.registerCommand("coder.logout", commands.logout.bind(commands))
4641
vscode.commands.registerCommand("coder.open", commands.open.bind(commands))
4742

48-
// The remote SSH extension is required to provide the restricted
49-
// proposed API for registering remote authority providers.
43+
// The Remote SSH extension's proposed APIs are used to override
44+
// the SSH host name in VS Code itself. It's visually unappealing
45+
// having a lengthy name!
46+
//
47+
// This is janky, but that's alright since it provides such minimal
48+
// functionality to the extension.
5049
const remoteSSHExtension = vscode.extensions.getExtension("ms-vscode-remote.remote-ssh")
5150
if (!remoteSSHExtension) {
5251
throw new Error("Remote SSH extension not found")
5352
}
54-
5553
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5654
const vscodeProposed: typeof vscode = (module as any)._load(
5755
"vscode",
@@ -61,8 +59,18 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
6159
false,
6260
)
6361

64-
const remote = new Remote(output, vscodeProposed, storage, commit)
65-
ctx.subscriptions.push(remote)
62+
// Since the "onResolveRemoteAuthority:ssh-remote" activation event exists
63+
// in package.json we're able to perform actions before the authority is
64+
// resolved by the remote SSH extension.
65+
const activeRemotes = vscode.workspace.workspaceFolders?.filter((folder) => folder.uri.scheme === "vscode-remote")
66+
// If the currently opened folder isn't remote we can return early!
67+
if (activeRemotes?.length !== 1) {
68+
return
69+
}
70+
const activeRemote = activeRemotes[0].uri
71+
72+
ctx.globalStorageUri
6673

67-
vscodeProposed.workspace.registerRemoteAuthorityResolver("coder", remote)
74+
const remote = new Remote(vscodeProposed, storage, ctx.extensionMode)
75+
await remote.setup(activeRemote)
6876
}

src/install.ps1

-6
This file was deleted.

src/install.sh

-58
This file was deleted.

src/ipc.ts

-172
This file was deleted.

0 commit comments

Comments
 (0)