Skip to content

Commit 6d509d6

Browse files
authored
fix: remote ide no longer reconnects after plugin upgrade (#167)
When the plugin is upgraded while JBClient is connected to a remote dev server via the Coder SSH proxy/tunnel, the upgrade process kills and re-establishes the SSH connection. However, JBClient/Toolbox fails to detect the restored connection and reports "Toolbox: Target environment com.coder.toolbox:bobiverse-bob.dev not found" error. While digging into the Toolbox bytecode—specifically `ClientOverSshTunnelConnector` — I realized the issue likely stems from an incorrect equals implementation in our custom SSH connection info object. In short, when a plugin upgrade terminates the SSH tunnel, the connector’s monitoring logic correctly detects the lost connection and waits. But when the SSH connection is re-established, the monitoring logic fails to recognize it as a valid replacement, because equals is still using the default `Object#equals` rather than a proper value-based implementation. Unfortunately, I wasn’t able to properly test this—specifically, upgrading from a version without the fix to one that includes it—because all Toolbox marketplace feeds are signed, preventing us from using a tool like mitmproxy to serve a locally modified plugin version. Given that, I propose releasing the change first and then performing the upgrade test to confirm the fix. - resolves#61
1 parent 5af07af commit 6d509d6

File tree

2 files changed

+50
-15
lines changed

2 files changed

+50
-15
lines changed

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
- URL validation is stricter in the connection screen and URI protocol handler
1212
- support for verbose logging a sanitized version of the REST API request and responses
1313

14+
### Fixed
15+
16+
- remote IDE reconnects automatically after plugin upgrade
17+
1418
## 0.6.0 - 2025-07-25
1519

1620
### Changed

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

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,51 @@ class EnvironmentView(
2121
privatevalworkspace:Workspace,
2222
privatevalagent:WorkspaceAgent,
2323
) : SshEnvironmentContentsView{
24-
overridesuspendfungetConnectionInfo(): SshConnectionInfo=object:SshConnectionInfo{
25-
/**
26-
* The host name generated by the cli manager for this workspace.
27-
*/
28-
overrideval host:String= cli.getHostname(url, workspace, agent)
29-
30-
/**
31-
* The port is ignored by the Coder proxy command.
32-
*/
33-
overrideval port:Int=22
34-
35-
/**
36-
* The username is ignored by the Coder proxy command.
37-
*/
38-
overrideval userName:String?=null
24+
overridesuspendfungetConnectionInfo(): SshConnectionInfo=WorkspaceSshConnectionInfo(url, cli, workspace, agent)
25+
}
26+
27+
privateclassWorkspaceSshConnectionInfo(
28+
url:URL,
29+
cli:CoderCLIManager,
30+
privatevalworkspace:Workspace,
31+
privatevalagent:WorkspaceAgent,
32+
) : SshConnectionInfo{
33+
/**
34+
* The host name generated by the cli manager for this workspace.
35+
*/
36+
overrideval host:String= cli.getHostname(url, workspace, agent)
37+
38+
/**
39+
* The port is ignored by the Coder proxy command.
40+
*/
41+
overrideval port:Int=22
42+
43+
/**
44+
* The username is ignored by the Coder proxy command.
45+
*/
46+
overrideval userName:String?=null
47+
48+
overridefunequals(other:Any?): Boolean{
49+
if (this=== other) returntrue
50+
if (javaClass != other?.javaClass) returnfalse
51+
52+
other asWorkspaceSshConnectionInfo
53+
54+
if (port != other.port) returnfalse
55+
if (workspace.name != other.workspace.name) returnfalse
56+
if (agent.name != other.agent.name) returnfalse
57+
if (host != other.host) returnfalse
58+
59+
returntrue
60+
}
61+
62+
overridefunhashCode(): Int{
63+
var result = port
64+
result =31* result + workspace.name.hashCode()
65+
result =31* result + agent.name.hashCode()
66+
result =31* result + host.hashCode()
67+
return result
3968
}
69+
70+
4071
}

0 commit comments

Comments
(0)