-
Notifications
You must be signed in to change notification settings - Fork 24
feat: coder connect integration #482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 1 commit
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
95b5b4e
feat: coder connect integration
ethanndickson a65e550
lint
ethanndickson 2ecf1df
support stopped workspaces
ethanndickson fb9a263
fixup
ethanndickson 3a77138
review
ethanndickson 2a3500e
fixup
ethanndickson 9252fff
fixup
ethanndickson 195151a
switch to coder connect dynamically
ethanndickson e7cad82
handle dev containers
ethanndickson ea4b179
lint
ethanndickson 5e4e795
comment
ethanndickson c3287eb
lint
ethanndickson a2df5cc
fixup
ethanndickson feb1021
review
ethanndickson File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next
Next commit
feat: coder connect integration
- Loading branch information
commit 95b5b4eb89b3d67a98c6e03bc5b40e2aefa23193
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,10 @@ | ||
import { isAxiosError } from "axios" | ||
import { Api } from "coder/site/src/api/api" | ||
import { getErrorMessage } from "coder/site/src/api/errors" | ||
import { User, Workspace, WorkspaceAgent } from "coder/site/src/api/typesGenerated" | ||
import { lookup } from "dns" | ||
import { inRange } from "range_check" | ||
import { promisify } from "util" | ||
import * as vscode from "vscode" | ||
import { makeCoderSdk, needToken } from "./api" | ||
import { extractAgents } from "./api-helper" | ||
|
@@ -392,14 +396,33 @@ | |
if (!baseUrl) { | ||
throw new Error("You are not logged in") | ||
} | ||
await openWorkspace( | ||
baseUrl, | ||
treeItem.workspaceOwner, | ||
treeItem.workspaceName, | ||
treeItem.workspaceAgent, | ||
treeItem.workspaceFolderPath, | ||
true, | ||
) | ||
|
||
let agent = treeItem.workspaceAgent | ||
if (!agent) { | ||
// `openFromSidebar` is only callable on agents or single-agent workspaces, | ||
// where this will always be set. | ||
return | ||
} | ||
|
||
try { | ||
await openWorkspace( | ||
this.restClient, | ||
baseUrl, | ||
treeItem.workspaceOwner, | ||
treeItem.workspaceName, | ||
agent, | ||
treeItem.workspaceFolderPath, | ||
true, | ||
) | ||
} catch (err) { | ||
const message = getErrorMessage(err, "no response from the server") | ||
ethanndickson marked this conversation as resolved.
Show resolved
Hide resolved
|
||
this.storage.writeToCoderOutputChannel(`Failed to open workspace: ${message}`) | ||
this.vscodeProposed.window.showErrorMessage("Failed to open workspace", { | ||
detail: message, | ||
modal: true, | ||
useCustom: true, | ||
}) | ||
} | ||
} else { | ||
// If there is no tree item, then the user manually ran this command. | ||
// Default to the regular open instead. | ||
|
@@ -491,12 +514,30 @@ | |
} else { | ||
workspaceOwner = args[0] as string | ||
workspaceName = args[1] as string | ||
// workspaceAgent is reserved for args[2], but multiple agents aren't supported yet. | ||
workspaceAgent = args[2] as string | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The URI handler does indeed populate the agent name in
The original comment is years out of date. |
||
folderPath = args[3] as string | undefined | ||
openRecent = args[4] as boolean | undefined | ||
} | ||
|
||
await openWorkspace(baseUrl, workspaceOwner, workspaceName, workspaceAgent, folderPath, openRecent) | ||
try { | ||
await openWorkspace( | ||
this.restClient, | ||
baseUrl, | ||
workspaceOwner, | ||
workspaceName, | ||
workspaceAgent, | ||
folderPath, | ||
openRecent, | ||
) | ||
} catch (err) { | ||
const message = getErrorMessage(err, "no response from the server") | ||
this.storage.writeToCoderOutputChannel(`Failed to open workspace: ${message}`) | ||
this.vscodeProposed.window.showErrorMessage("Failed to open workspace", { | ||
detail: message, | ||
modal: true, | ||
useCustom: true, | ||
}) | ||
} | ||
} | ||
|
||
/** | ||
|
@@ -547,16 +588,42 @@ | |
* both to the Remote SSH plugin in the form of a remote authority URI. | ||
*/ | ||
async function openWorkspace( | ||
restClient: Api, | ||
baseUrl: string, | ||
workspaceOwner: string, | ||
workspaceName: string, | ||
workspaceAgent: string | undefined, | ||
workspaceAgent: string, | ||
folderPath: string | undefined, | ||
openRecent: boolean | undefined, | ||
) { | ||
// A workspace can have multiple agents, but that's handled | ||
// when opening a workspace unless explicitly specified. | ||
const remoteAuthority = toRemoteAuthority(baseUrl, workspaceOwner, workspaceName, workspaceAgent) | ||
let remoteAuthority = toRemoteAuthority(baseUrl, workspaceOwner, workspaceName, workspaceAgent) | ||
|
||
let hostnameSuffix = "coder" | ||
try { | ||
const sshConfig = await restClient.getDeploymentSSHConfig() | ||
// If the field is undefined, it's an older server, and always 'coder' | ||
hostnameSuffix = sshConfig.hostname_suffix ?? hostnameSuffix | ||
} catch (error) { | ||
if (!isAxiosError(error)) { | ||
throw error | ||
} | ||
switch (error.response?.status) { | ||
case 404: { | ||
// Likely a very old deployment, just use the default. | ||
break | ||
} | ||
case 401: { | ||
throw error | ||
} | ||
default: | ||
throw error | ||
} | ||
} | ||
|
||
const coderConnectAddr = await maybeCoderConnectAddr(workspaceAgent, workspaceName, workspaceOwner, hostnameSuffix) | ||
if (coderConnectAddr) { | ||
remoteAuthority = `ssh-remote+${coderConnectAddr}` | ||
} | ||
|
||
let newWindow = true | ||
// Open in the existing window if no workspaces are open. | ||
|
@@ -616,6 +683,21 @@ | |
}) | ||
} | ||
|
||
async function maybeCoderConnectAddr( | ||
agent: string, | ||
workspace: string, | ||
owner: string, | ||
hostnameSuffix: string, | ||
): Promise<string | undefined> { | ||
const coderConnectHostname = `${agent}.${workspace}.${owner}.${hostnameSuffix}` | ||
try { | ||
const res = await promisify(lookup)(coderConnectHostname) | ||
return res.family == 6 && inRange(res.address, "fd60:627a:a42b::/48") ? coderConnectHostname : undefined | ||
} catch { | ||
return undefined | ||
} | ||
} | ||
|
||
async function openDevContainer( | ||
baseUrl: string, | ||
workspaceOwner: string, | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.