Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: add ability to attach to devcontainers#463

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
DanielleMaywood merged 1 commit intomainfromdm-devcontainers
Apr 2, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 51 additions & 5 deletionssrc/commands.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,7 +6,7 @@ import { makeCoderSdk, needToken } from "./api"
import{extractAgents}from"./api-helper"
import{CertificateError}from"./error"
import{Storage}from"./storage"
import{AuthorityPrefix,toSafeHost}from"./util"
import{toRemoteAuthority,toSafeHost}from"./util"
import{OpenableTreeItem}from"./workspacesProvider"

exportclassCommands{
Expand DownExpand Up@@ -499,6 +499,26 @@ export class Commands {
awaitopenWorkspace(baseUrl,workspaceOwner,workspaceName,workspaceAgent,folderPath,openRecent)
}

/**
* Open a devcontainer from a workspace belonging to the currently logged-in deployment.
*
* Throw if not logged into a deployment.
*/
publicasyncopenDevContainer(...args:string[]):Promise<void>{
constbaseUrl=this.restClient.getAxiosInstance().defaults.baseURL
if(!baseUrl){
thrownewError("You are not logged in")
}

constworkspaceOwner=args[0]asstring
constworkspaceName=args[1]asstring
constworkspaceAgent=undefined// args[2] is reserved, but we do not support multiple agents yet.
constdevContainerName=args[3]asstring
Comment on lines +515 to +516
Copy link
Preview

CopilotAIApr 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The extension passes a workspaceAgent parameter for the openDevContainer command, but this parameter is being discarded by explicitly setting workspaceAgent to undefined. Consider either using args[2] if provided or updating the extension to no longer supply the parameter.

Suggested change
constworkspaceAgent=undefined// args[2] is reserved, but we do not support multiple agents yet.
constdevContainerName=args[3]asstring
constworkspaceAgent=args[2]asWorkspaceAgent|undefined// Use args[2] if provided.

Copilot uses AI. Check for mistakes.

Copy link
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We already have precedent for doing this with theopenWorkspace flow

constdevContainerFolder=args[4]asstring

awaitopenDevContainer(baseUrl,workspaceOwner,workspaceName,workspaceAgent,devContainerName,devContainerFolder)
}

/**
* Update the current workspace. If there is no active workspace connection,
* this is a no-op.
Expand DownExpand Up@@ -536,10 +556,7 @@ async function openWorkspace(
){
// A workspace can have multiple agents, but that's handled
// when opening a workspace unless explicitly specified.
letremoteAuthority=`ssh-remote+${AuthorityPrefix}.${toSafeHost(baseUrl)}--${workspaceOwner}--${workspaceName}`
if(workspaceAgent){
remoteAuthority+=`.${workspaceAgent}`
}
constremoteAuthority=toRemoteAuthority(baseUrl,workspaceOwner,workspaceName,workspaceAgent)

letnewWindow=true
// Open in the existing window if no workspaces are open.
Expand DownExpand Up@@ -598,3 +615,32 @@ async function openWorkspace(
reuseWindow:!newWindow,
})
}

asyncfunctionopenDevContainer(
baseUrl:string,
workspaceOwner:string,
workspaceName:string,
workspaceAgent:string|undefined,
devContainerName:string,
devContainerFolder:string,
){
constremoteAuthority=toRemoteAuthority(baseUrl,workspaceOwner,workspaceName,workspaceAgent)

constdevContainer=Buffer.from(JSON.stringify({containerName:devContainerName}),"utf-8").toString("hex")
constdevContainerAuthority=`attached-container+${devContainer}@${remoteAuthority}`

letnewWindow=true
if(!vscode.workspace.workspaceFolders?.length){
newWindow=false
}

awaitvscode.commands.executeCommand(
"vscode.openFolder",
vscode.Uri.from({
scheme:"vscode-remote",
authority:devContainerAuthority,
path:devContainerFolder,
}),
newWindow,
)
}
56 changes: 56 additions & 0 deletionssrc/extension.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -111,6 +111,61 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
await storage.configureCli(toSafeHost(url), url, token)

vscode.commands.executeCommand("coder.open", owner, workspace, agent, folder, openRecent)
} else if (uri.path === "/openDevContainer") {
const workspaceOwner = params.get("owner")
const workspaceName = params.get("workspace")
const workspaceAgent = params.get("agent")
const devContainerName = params.get("devContainerName")
const devContainerFolder = params.get("devContainerFolder")

if (!workspaceOwner) {
throw new Error("workspace owner must be specified as a query parameter")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

No need to change in this PR since this is a pattern that already existed, but at some point I wonder if we should catch handler errors and show them in an error notification. Currently the only way to see them seems to be to go to the extension's features > runtime status > uncaught errors.

DanielleMaywood reacted with thumbs up emoji
}

if (!workspaceName) {
throw new Error("workspace name must be specified as a query parameter")
}

if (!devContainerName) {
throw new Error("dev container name must be specified as a query parameter")
}

if (!devContainerFolder) {
throw new Error("dev container folder must be specified as a query parameter")
}

// We are not guaranteed that the URL we currently have is for the URL
// this workspace belongs to, or that we even have a URL at all (the
// queries will default to localhost) so ask for it if missing.
// Pre-populate in case we do have the right URL so the user can just
// hit enter and move on.
const url = await commands.maybeAskUrl(params.get("url"), storage.getUrl())
if (url) {
restClient.setHost(url)
await storage.setUrl(url)
} else {
throw new Error("url must be provided or specified as a query parameter")
}

// If the token is missing we will get a 401 later and the user will be
// prompted to sign in again, so we do not need to ensure it is set now.
// For non-token auth, we write a blank token since the `vscodessh`
// command currently always requires a token file. However, if there is
// a query parameter for non-token auth go ahead and use it anyway; all
// that really matters is the file is created.
const token = needToken() ? params.get("token") : (params.get("token") ?? "")

// Store on disk to be used by the cli.
await storage.configureCli(toSafeHost(url), url, token)

vscode.commands.executeCommand(
"coder.openDevContainer",
workspaceOwner,
workspaceName,
workspaceAgent,
devContainerName,
devContainerFolder,
)
} else {
throw new Error(`Unknown path ${uri.path}`)
}
Expand All@@ -123,6 +178,7 @@ export async function activate(ctx: vscode.ExtensionContext): Promise<void> {
vscode.commands.registerCommand("coder.login", commands.login.bind(commands))
vscode.commands.registerCommand("coder.logout", commands.logout.bind(commands))
vscode.commands.registerCommand("coder.open", commands.open.bind(commands))
vscode.commands.registerCommand("coder.openDevContainer", commands.openDevContainer.bind(commands))
vscode.commands.registerCommand("coder.openFromSidebar", commands.openFromSidebar.bind(commands))
vscode.commands.registerCommand("coder.workspace.update", commands.updateWorkspace.bind(commands))
vscode.commands.registerCommand("coder.createWorkspace", commands.createWorkspace.bind(commands))
Expand Down
13 changes: 13 additions & 0 deletionssrc/util.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -61,6 +61,19 @@ export function parseRemoteAuthority(authority: string): AuthorityParts | null {
}
}

export function toRemoteAuthority(
baseUrl: string,
workspaceOwner: string,
workspaceName: string,
workspaceAgent: string | undefined,
): string {
let remoteAuthority = `ssh-remote+${AuthorityPrefix}.${toSafeHost(baseUrl)}--${workspaceOwner}--${workspaceName}`
if (workspaceAgent) {
remoteAuthority += `.${workspaceAgent}`
}
return remoteAuthority
}

/**
* Given a URL, return the host in a format that is safe to write.
*/
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp