Skip to content

Commit f255edb

Browse files
committed
impl: persist last active SSH connections
Adds support for remembering SSH connections that were not manually disconnected by the user. This allows the plugin to automatically restore those connections on the next startup enabling remote IDEs that remained open to reconnect once the SSH link is re-established.
1 parent acd4f22 commit f255edb

File tree

4 files changed

+29
-5
lines changed

4 files changed

+29
-5
lines changed

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ class CoderRemoteEnvironment(
6868
private val proxyCommandHandle = SshCommandProcessHandle(context)
6969
private var pollJob: Job? = null
7070

71+
init {
72+
if (context.settingsStore.shouldAutoConnect(id)) {
73+
context.logger.info("resuming SSH connection to $id — last session was still active.")
74+
startSshConnection()
75+
}
76+
}
77+
7178
fun asPairOfWorkspaceAndAgent(): Pair<Workspace, WorkspaceAgent> = Pair(workspace, agent)
7279

7380
private fun getAvailableActions(): List<ActionDescription> {
@@ -158,6 +165,7 @@ class CoderRemoteEnvironment(
158165
override fun beforeConnection() {
159166
context.logger.info("Connecting to $id...")
160167
isConnected.update { true }
168+
context.settingsStore.updateAutoConnect(this.id, true)
161169
pollJob = pollNetworkMetrics()
162170
}
163171

@@ -180,12 +188,9 @@ class CoderRemoteEnvironment(
180188
}
181189
context.logger.debug("Loading metrics from ${metricsFile.absolutePath} for $id")
182190
try {
183-
val metrics = networkMetricsMarshaller.fromJson(metricsFile.readText())
184-
if (metrics == null) {
185-
return@launch
186-
}
191+
val metrics = networkMetricsMarshaller.fromJson(metricsFile.readText()) ?: return@launch
187192
context.logger.debug("$id metrics: $metrics")
188-
additionalEnvironmentInformation.put(context.i18n.ptrl("Network Status"), metrics.toPretty())
193+
additionalEnvironmentInformation[context.i18n.ptrl("Network Status")] = metrics.toPretty()
189194
} catch (e: Exception) {
190195
context.logger.error(
191196
e,
@@ -203,6 +208,10 @@ class CoderRemoteEnvironment(
203208
pollJob?.cancel()
204209
this.connectionRequest.update { false }
205210
isConnected.update { false }
211+
if (isManual) {
212+
// if the user manually disconnects the ssh connection we should not connect automatically
213+
context.settingsStore.updateAutoConnect(this.id, false)
214+
}
206215
context.logger.info("Disconnected from $id")
207216
}
208217

src/main/kotlin/com/coder/toolbox/settings/ReadOnlyCoderSettings.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ interface ReadOnlyCoderSettings {
146146
* Return the URL and token from the config, if they exist.
147147
*/
148148
fun readConfig(dir: Path): Pair<String?, String?>
149+
150+
/**
151+
* Returns whether the SSH connection should be automatically established.
152+
*/
153+
fun shouldAutoConnect(workspaceId: String): Boolean
149154
}
150155

151156
/**

src/main/kotlin/com/coder/toolbox/store/CoderSettingsStore.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ class CoderSettingsStore(
142142
}
143143
}
144144

145+
override fun shouldAutoConnect(workspaceId: String): Boolean {
146+
return store["$SSH_AUTO_CONNECT_PREFIX$workspaceId"]?.toBooleanStrictOrNull() ?: false
147+
}
148+
145149
// a readonly cast
146150
fun readOnly(): ReadOnlyCoderSettings = this
147151

@@ -213,6 +217,10 @@ class CoderSettingsStore(
213217
store[SSH_CONFIG_OPTIONS] = options
214218
}
215219

220+
fun updateAutoConnect(workspaceId: String, autoConnect: Boolean) {
221+
store["$SSH_AUTO_CONNECT_PREFIX$workspaceId"] = autoConnect.toString()
222+
}
223+
216224
private fun getDefaultGlobalDataDir(): Path {
217225
return when (getOS()) {
218226
OS.WINDOWS -> Paths.get(env.get("LOCALAPPDATA"), "coder-toolbox")

src/main/kotlin/com/coder/toolbox/store/StoreKeys.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,5 @@ internal const val SSH_CONFIG_OPTIONS = "sshConfigOptions"
4242

4343
internal const val NETWORK_INFO_DIR = "networkInfoDir"
4444

45+
internal const val SSH_AUTO_CONNECT_PREFIX = "ssh_auto_connect_"
46+

0 commit comments

Comments
 (0)