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

Commitccbb835

Browse files
authored
fix: hostname and proxy command generation (#95)
- latest Coder versions won't accept the SSH connections if proxycommand does not include the workspace owner name- for wildcard configuration the ssh config stays the same but theactual hostname provided to the Toolbox will include the workspace owner nameFor wildcard config:- the ssh config hostname follows the`coder-jetbrains-toolbox-dev.coder.com--*` pattern- the proxy command will have a similar host prefix- the hostname provided to Toolbox follows the`coder-jetbrains-toolbox-dev.coder.com--${ws.ownerName}--${ws.name}.${agent.name}`patternFor non wildcard config:- the ssh config hostname follows the`coder-jetbrains-toolbox--${ws.ownerName}--${ws.name}.${agent.name}--dev.coder.com`pattern- the proxy command will have the username and hostname in the${ws.ownerName}/${ws.name}.${agent.name} format- the hostname provided to Toolbox follows the`coder-jetbrains-toolbox-dev.coder.com--${ws.ownerName}--${ws.name}.${agent.name}`pattern-resolves#94
1 parentd5fddf4 commitccbb835

File tree

31 files changed

+318
-152
lines changed

31 files changed

+318
-152
lines changed

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
- connections to the workspace are no longer established automatically after agent started with error.
1212

13+
###Fixed
14+
15+
- SSH connection will no longer fail with newer Coder deployments due to misconfiguration of hostname and proxy command.
16+
1317
##0.1.5 - 2025-04-14
1418

1519
###Fixed

‎src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
packagecom.coder.toolbox
22

33
importcom.coder.toolbox.browser.BrowserUtil
4+
importcom.coder.toolbox.cli.CoderCLIManager
45
importcom.coder.toolbox.models.WorkspaceAndAgentStatus
56
importcom.coder.toolbox.sdk.CoderRestClient
67
importcom.coder.toolbox.sdk.ex.APIResponseException
@@ -35,6 +36,7 @@ import kotlin.time.Duration.Companion.seconds
3536
classCoderRemoteEnvironment(
3637
privatevalcontext:CoderToolboxContext,
3738
privatevalclient:CoderRestClient,
39+
privatevalcli:CoderCLIManager,
3840
privatevarworkspace:Workspace,
3941
privatevaragent:WorkspaceAgent,
4042
) : RemoteProviderEnvironment("${workspace.name}.${agent.name}"), BeforeConnectionHook, AfterDisconnectHook {
@@ -48,6 +50,8 @@ class CoderRemoteEnvironment(
4850

4951
overrideval actionsList:MutableStateFlow<List<ActionDescription>>=MutableStateFlow(getAvailableActions())
5052

53+
funasPairOfWorkspaceAndAgent():Pair<Workspace,WorkspaceAgent>=Pair(workspace, agent)
54+
5155
privatefungetAvailableActions():List<ActionDescription> {
5256
val actions=mutableListOf(
5357
Action(context.i18n.ptrl("Open web terminal")) {
@@ -151,8 +155,8 @@ class CoderRemoteEnvironment(
151155
*/
152156
overridesuspend
153157
fungetContentsView():EnvironmentContentsView=EnvironmentView(
154-
context.settingsStore.readOnly(),
155158
client.url,
159+
cli,
156160
workspace,
157161
agent
158162
)

‎src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class CoderRemoteProvider(
9191
it.name
9292
}?.map { agent->
9393
// If we have an environment already, update that.
94-
val env=CoderRemoteEnvironment(context, client, ws, agent)
94+
val env=CoderRemoteEnvironment(context, client,cli,ws, agent)
9595
lastEnvironments.firstOrNull { it== env }?.let {
9696
it.update(ws, agent)
9797
it
@@ -109,7 +109,7 @@ class CoderRemoteProvider(
109109
// Reconfigure if environments changed.
110110
if (lastEnvironments.size!= resolvedEnvironments.size|| lastEnvironments!= resolvedEnvironments) {
111111
context.logger.info("Workspaces have changed, reconfiguring CLI:$resolvedEnvironments")
112-
cli.configSsh(resolvedEnvironments.map { it.name }.toSet())
112+
cli.configSsh(resolvedEnvironments.map { it.asPairOfWorkspaceAndAgent() }.toSet())
113113
}
114114

115115
environments.update {
@@ -149,7 +149,7 @@ class CoderRemoteProvider(
149149
triggerSshConfig.onReceive { shouldTrigger->
150150
if (shouldTrigger) {
151151
context.logger.trace("workspace poller waked up because it should reconfigure the ssh configurations")
152-
cli.configSsh(lastEnvironments.map { it.name }.toSet())
152+
cli.configSsh(lastEnvironments.map { it.asPairOfWorkspaceAndAgent() }.toSet())
153153
}
154154
}
155155
}

‎src/main/kotlin/com/coder/toolbox/cli/CoderCLIManager.kt‎

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,11 @@ class CoderCLIManager(
223223
* This can take supported features for testing purposes only.
224224
*/
225225
funconfigSsh(
226-
workspaceNames:Set<String>,
226+
wsWithAgents:Set<Pair<Workspace,WorkspaceAgent>>,
227227
feats:Features = features,
228228
) {
229229
logger.info("Configuring SSH config at${settings.sshConfigPath}")
230-
writeSSHConfig(modifySSHConfig(readSSHConfig(),workspaceNames, feats))
230+
writeSSHConfig(modifySSHConfig(readSSHConfig(),wsWithAgents, feats))
231231
}
232232

233233
/**
@@ -249,13 +249,13 @@ class CoderCLIManager(
249249
*/
250250
privatefunmodifySSHConfig(
251251
contents:String?,
252-
workspaceNames:Set<String>,
252+
wsWithAgents:Set<Pair<Workspace,WorkspaceAgent>>,
253253
feats:Features,
254254
):String? {
255255
val host= deploymentURL.safeHost()
256256
val startBlock="# --- START CODER JETBRAINS TOOLBOX$host"
257257
val endBlock="# --- END CODER JETBRAINS TOOLBOX$host"
258-
val isRemoving=workspaceNames.isEmpty()
258+
val isRemoving=wsWithAgents.isEmpty()
259259
val baseArgs=
260260
listOfNotNull(
261261
escape(localBinaryPath.toString()),
@@ -304,34 +304,39 @@ class CoderCLIManager(
304304
.plus("\n\n")
305305
.plus(
306306
"""
307-
Host${getHostnamePrefix(deploymentURL)}-bg--*
307+
Host${getBackgroundHostnamePrefix(deploymentURL)}--*
308308
ProxyCommand${backgroundProxyArgs.joinToString("")} --ssh-host-prefix${
309-
getHostnamePrefix(
309+
getBackgroundHostnamePrefix(
310310
deploymentURL
311311
)
312-
}-bg-- %h
312+
}-- %h
313313
""".trimIndent()
314314
.plus("\n"+ options.prependIndent(""))
315315
.plus(extraConfig),
316316
).replace("\n",System.lineSeparator())+
317317
System.lineSeparator()+ endBlock
318318
}else {
319-
workspaceNames.joinToString(
319+
wsWithAgents.joinToString(
320320
System.lineSeparator(),
321321
startBlock+System.lineSeparator(),
322322
System.lineSeparator()+ endBlock,
323323
transform= {
324324
"""
325-
Host${getHostName(deploymentURL, it)}
326-
ProxyCommand${proxyArgs.joinToString("")}$it
325+
Host${getHostname(deploymentURL, it.workspace(), it.agent())}
326+
ProxyCommand${proxyArgs.joinToString("")}${getWsByOwner(it.workspace(), it.agent())}
327327
""".trimIndent()
328328
.plus("\n"+ options.prependIndent(""))
329329
.plus(extraConfig)
330330
.plus("\n")
331331
.plus(
332332
"""
333-
Host${getBackgroundHostName(deploymentURL, it)}
334-
ProxyCommand${backgroundProxyArgs.joinToString("")}$it
333+
Host${getBackgroundHostname(deploymentURL, it.workspace(), it.agent())}
334+
ProxyCommand${backgroundProxyArgs.joinToString("")}${
335+
getWsByOwner(
336+
it.workspace(),
337+
it.agent()
338+
)
339+
}
335340
""".trimIndent()
336341
.plus("\n"+ options.prependIndent(""))
337342
.plus(extraConfig),
@@ -506,25 +511,30 @@ class CoderCLIManager(
506511
}
507512
}
508513

514+
fungetHostname(url:URL,ws:Workspace,agent:WorkspaceAgent):String {
515+
returnif (settings.isSshWildcardConfigEnabled&& features.wildcardSsh) {
516+
"${getHostnamePrefix(url)}--${ws.ownerName}--${ws.name}.${agent.name}"
517+
}else {
518+
"coder-jetbrains-toolbox--${ws.ownerName}--${ws.name}.${agent.name}--${url.safeHost()}"
519+
}
520+
}
521+
522+
fungetBackgroundHostname(url:URL,ws:Workspace,agent:WorkspaceAgent):String {
523+
return"${getHostname(url, ws, agent)}--bg"
524+
}
525+
509526
companionobject {
510527
privateval tokenRegex="--token [^ ]+".toRegex()
511528

512-
fungetHostnamePrefix(url:URL):String="coder-jetbrains-toolbox-${url.safeHost()}"
529+
privatefungetHostnamePrefix(url:URL):String="coder-jetbrains-toolbox-${url.safeHost()}"
513530

514-
fungetWildcardHostname(url:URL,workspace:Workspace,agent:WorkspaceAgent):String=
515-
"${getHostnamePrefix(url)}-bg--${workspace.name}.${agent.name}"
531+
privatefungetBackgroundHostnamePrefix(url:URL):String="coder-jetbrains-toolbox-${url.safeHost()}-bg"
516532

517-
fungetHostname(url:URL,workspace:Workspace,agent:WorkspaceAgent)=
518-
getHostName(url,"${workspace.name}.${agent.name}")
533+
privatefungetWsByOwner(ws:Workspace,agent:WorkspaceAgent):String=
534+
"${ws.ownerName}/${ws.name}.${agent.name}"
519535

520-
fungetHostName(
521-
url:URL,
522-
workspaceName:String,
523-
):String="coder-jetbrains-toolbox-$workspaceName--${url.safeHost()}"
536+
privatefunPair<Workspace,WorkspaceAgent>.workspace()=this.first
524537

525-
fungetBackgroundHostName(
526-
url:URL,
527-
workspaceName:String,
528-
):String= getHostName(url, workspaceName)+"--bg"
538+
privatefunPair<Workspace,WorkspaceAgent>.agent()=this.second
529539
}
530540
}

‎src/main/kotlin/com/coder/toolbox/sdk/CoderRestClient.kt‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ import com.coder.toolbox.sdk.v2.models.CreateWorkspaceBuildRequest
1313
importcom.coder.toolbox.sdk.v2.models.Template
1414
importcom.coder.toolbox.sdk.v2.models.User
1515
importcom.coder.toolbox.sdk.v2.models.Workspace
16+
importcom.coder.toolbox.sdk.v2.models.WorkspaceAgent
1617
importcom.coder.toolbox.sdk.v2.models.WorkspaceBuild
1718
importcom.coder.toolbox.sdk.v2.models.WorkspaceResource
19+
importcom.coder.toolbox.sdk.v2.models.WorkspaceStatus
1820
importcom.coder.toolbox.sdk.v2.models.WorkspaceTransition
1921
importcom.coder.toolbox.util.CoderHostnameVerifier
2022
importcom.coder.toolbox.util.coderSocketFactory
@@ -190,15 +192,17 @@ open class CoderRestClient(
190192
}
191193

192194
/**
193-
* Retrieves all the agent names for all workspaces, including those that
194-
* are off. Meant to be used when configuring SSH.
195+
* Maps the list of workspaces to the associated agents.
195196
*/
196-
suspendfunagentNames(workspaces:List<Workspace>):Set<String> {
197+
suspendfungroupByAgents(workspaces:List<Workspace>):Set<Pair<Workspace,WorkspaceAgent>> {
197198
// It is possible for there to be resources with duplicate names so we
198199
// need to use a set.
199200
return workspaces.flatMap { ws->
200-
resources(ws).filter { it.agents!=null }.flatMap { it.agents!! }.map {
201-
"${ws.name}.${it.name}"
201+
when (ws.latestBuild.status) {
202+
WorkspaceStatus.RUNNING-> ws.latestBuild.resources
203+
else-> resources(ws)
204+
}.filter { it.agents!=null }.flatMap { it.agents!! }.map {
205+
ws to it
202206
}
203207
}.toSet()
204208
}

‎src/main/kotlin/com/coder/toolbox/util/CoderProtocolHandler.kt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ open class CoderProtocolHandler(
162162
}
163163

164164
context.logger.info("Configuring Coder CLI...")
165-
cli.configSsh(restClient.agentNames(workspaces))
165+
cli.configSsh(restClient.groupByAgents(workspaces))
166166

167167
if (shouldWaitForAutoLogin) {
168168
isInitialized.waitForTrue()

‎src/main/kotlin/com/coder/toolbox/views/EnvironmentView.kt‎

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.coder.toolbox.views
33
importcom.coder.toolbox.cli.CoderCLIManager
44
importcom.coder.toolbox.sdk.v2.models.Workspace
55
importcom.coder.toolbox.sdk.v2.models.WorkspaceAgent
6-
importcom.coder.toolbox.settings.ReadOnlyCoderSettings
76
importcom.jetbrains.toolbox.api.remoteDev.environments.SshEnvironmentContentsView
87
importcom.jetbrains.toolbox.api.remoteDev.ssh.SshConnectionInfo
98
importjava.net.URL
@@ -17,16 +16,16 @@ import java.net.URL
1716
* SSH must be configured before this will work.
1817
*/
1918
classEnvironmentView(
20-
privatevalsettings:ReadOnlyCoderSettings,
2119
privatevalurl:URL,
20+
privatevalcli:CoderCLIManager,
2221
privatevalworkspace:Workspace,
2322
privatevalagent:WorkspaceAgent,
2423
) : SshEnvironmentContentsView {
2524
overridesuspendfungetConnectionInfo():SshConnectionInfo=object:SshConnectionInfo {
2625
/**
2726
* The host name generated by the cli manager for this workspace.
2827
*/
29-
overrideval host:String=resolveHost()
28+
overrideval host:String=cli.getHostname(url, workspace, agent)
3029

3130
/**
3231
* The port is ignored by the Coder proxy command.
@@ -36,12 +35,6 @@ class EnvironmentView(
3635
/**
3736
* The username is ignored by the Coder proxy command.
3837
*/
39-
overrideval userName:String?="coder"
40-
38+
overrideval userName:String?=null
4139
}
42-
43-
privatefunresolveHost():String=
44-
if (settings.isSshWildcardConfigEnabled)
45-
CoderCLIManager.getWildcardHostname(url, workspace, agent)
46-
elseCoderCLIManager.getHostname(url, workspace, agent)
47-
}
40+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp