From a9cff15f4223da3c94c03e1fe14550e3a34f64be Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 26 Apr 2025 01:14:55 +0300 Subject: [PATCH 1/6] Changelog update - `v0.2.0` (#96) Current pull request contains patched `CHANGELOG.md` file for the `v0.2.0` version. Co-authored-by: GitHub Action --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cf1ae9..a9454c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.2.0 - 2025-04-24 + ### Added - support for using proxies. Proxy authentication is not yet supported. From 970f4c534cebbf74c86f98539c2edd33dd4fd7ec Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Tue, 29 Apr 2025 00:46:47 +0300 Subject: [PATCH 2/6] chore: remove ssh background config (#97) From my testing, Toolbox forwards through SSH (i.e. through Coder) a remote port associated with the IDE running in server mode, to localhost in order for the server (i.e. the remote IDE) to communicate with JBClient. Unlike with Gateway, Toolbox manages to reuse the SSH connection, and it doesn't open a separate one for port forwarding. From Gateway we inherited two ssh hostnames per each workspace, one for background connections that did not involve running IDEs. Coder discards the bg. connection from the collected metrics in order to avoid double counting. Since Toolbox manages to re-use the connection we don't need to worry about double counting. For this particular change, I deployed the latest Coder version with prometheus metrics and experiments enabled (i.e. --prometheus-enable --prometheus-collect-agent-stats --experiments=workspace-usage) and made the following experiment: 1. Opened up Toolbox, logged into Coder. At this point: - agent_sessions_total and coderd_agentstats_session_count_jetbrains were missing from prometheus metrics - jetbrains session count from api/v2/deployment/stats showed 0 2. Opened up a Workspace at which point Toolbox established the SSH connection: - agent_sessions_total and coderd_agentstats_session_count_jetbrains increased to 1 - jetbrains session count from api/v2/deployment/stats increased to 1 as well 3. Hit the install button on RustRover, everything stayed unchanged 4. Open RustRover, nothing changes in the stats. --- CHANGELOG.md | 4 +++ gradle.properties | 2 +- .../com/coder/toolbox/cli/CoderCLIManager.kt | 35 ++----------------- .../outputs/append-blank-newlines.conf | 8 +---- .../fixtures/outputs/append-blank.conf | 8 +---- .../fixtures/outputs/append-no-blocks.conf | 8 +---- .../fixtures/outputs/append-no-newline.conf | 8 +---- .../outputs/append-no-related-blocks.conf | 8 +---- .../fixtures/outputs/disable-autostart.conf | 8 +---- .../fixtures/outputs/extra-config.conf | 10 +----- .../outputs/header-command-windows.conf | 8 +---- .../fixtures/outputs/header-command.conf | 8 +---- .../resources/fixtures/outputs/log-dir.conf | 8 +---- .../fixtures/outputs/multiple-agents.conf | 16 ++------- .../fixtures/outputs/multiple-users.conf | 16 ++------- .../fixtures/outputs/multiple-workspaces.conf | 16 ++------- .../outputs/no-disable-autostart.conf | 8 +---- .../fixtures/outputs/no-report-usage.conf | 8 +---- .../outputs/replace-end-no-newline.conf | 8 +---- .../fixtures/outputs/replace-end.conf | 8 +---- .../replace-middle-ignore-unrelated.conf | 8 +---- .../fixtures/outputs/replace-middle.conf | 8 +---- .../fixtures/outputs/replace-only.conf | 8 +---- .../fixtures/outputs/replace-start.conf | 8 +---- src/test/resources/fixtures/outputs/url.conf | 8 +---- .../resources/fixtures/outputs/wildcard.conf | 7 ---- 26 files changed, 33 insertions(+), 217 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9454c7..058e1f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Changed + +- ssh configuration is simplified, background hostnames have been discarded. + ## 0.2.0 - 2025-04-24 ### Added diff --git a/gradle.properties b/gradle.properties index a4ec268..14e11de 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -version=0.2.0 +version=0.2.1 group=com.coder.toolbox name=coder-toolbox diff --git a/src/main/kotlin/com/coder/toolbox/cli/CoderCLIManager.kt b/src/main/kotlin/com/coder/toolbox/cli/CoderCLIManager.kt index c7e4297..a1b06d6 100644 --- a/src/main/kotlin/com/coder/toolbox/cli/CoderCLIManager.kt +++ b/src/main/kotlin/com/coder/toolbox/cli/CoderCLIManager.kt @@ -301,19 +301,8 @@ class CoderCLIManager( """.trimIndent() .plus("\n" + options.prependIndent(" ")) .plus(extraConfig) - .plus("\n\n") - .plus( - """ - Host ${getBackgroundHostnamePrefix(deploymentURL)}--* - ProxyCommand ${backgroundProxyArgs.joinToString(" ")} --ssh-host-prefix ${ - getBackgroundHostnamePrefix( - deploymentURL - ) - }-- %h - """.trimIndent() - .plus("\n" + options.prependIndent(" ")) - .plus(extraConfig), - ).replace("\n", System.lineSeparator()) + + .plus("\n") + .replace("\n", System.lineSeparator()) + System.lineSeparator() + endBlock } else { wsWithAgents.joinToString( @@ -328,19 +317,7 @@ class CoderCLIManager( .plus("\n" + options.prependIndent(" ")) .plus(extraConfig) .plus("\n") - .plus( - """ - Host ${getBackgroundHostname(deploymentURL, it.workspace(), it.agent())} - ProxyCommand ${backgroundProxyArgs.joinToString(" ")} ${ - getWsByOwner( - it.workspace(), - it.agent() - ) - } - """.trimIndent() - .plus("\n" + options.prependIndent(" ")) - .plus(extraConfig), - ).replace("\n", System.lineSeparator()) + .replace("\n", System.lineSeparator()) }, ) } @@ -519,17 +496,11 @@ class CoderCLIManager( } } - fun getBackgroundHostname(url: URL, ws: Workspace, agent: WorkspaceAgent): String { - return "${getHostname(url, ws, agent)}--bg" - } - companion object { private val tokenRegex = "--token [^ ]+".toRegex() private fun getHostnamePrefix(url: URL): String = "coder-jetbrains-toolbox-${url.safeHost()}" - private fun getBackgroundHostnamePrefix(url: URL): String = "coder-jetbrains-toolbox-${url.safeHost()}-bg" - private fun getWsByOwner(ws: Workspace, agent: WorkspaceAgent): String = "${ws.ownerName}/${ws.name}.${agent.name}" diff --git a/src/test/resources/fixtures/outputs/append-blank-newlines.conf b/src/test/resources/fixtures/outputs/append-blank-newlines.conf index c73e3a2..6a3fa9d 100644 --- a/src/test/resources/fixtures/outputs/append-blank-newlines.conf +++ b/src/test/resources/fixtures/outputs/append-blank-newlines.conf @@ -10,11 +10,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/append-blank.conf b/src/test/resources/fixtures/outputs/append-blank.conf index 7c9df80..4c1ac2b 100644 --- a/src/test/resources/fixtures/outputs/append-blank.conf +++ b/src/test/resources/fixtures/outputs/append-blank.conf @@ -6,11 +6,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/append-no-blocks.conf b/src/test/resources/fixtures/outputs/append-no-blocks.conf index 8db68d4..fbcd928 100644 --- a/src/test/resources/fixtures/outputs/append-no-blocks.conf +++ b/src/test/resources/fixtures/outputs/append-no-blocks.conf @@ -11,11 +11,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/append-no-newline.conf b/src/test/resources/fixtures/outputs/append-no-newline.conf index 0a48b7e..f31936a 100644 --- a/src/test/resources/fixtures/outputs/append-no-newline.conf +++ b/src/test/resources/fixtures/outputs/append-no-newline.conf @@ -10,11 +10,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/append-no-related-blocks.conf b/src/test/resources/fixtures/outputs/append-no-related-blocks.conf index 73ebf8d..6578ea9 100644 --- a/src/test/resources/fixtures/outputs/append-no-related-blocks.conf +++ b/src/test/resources/fixtures/outputs/append-no-related-blocks.conf @@ -17,11 +17,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/disable-autostart.conf b/src/test/resources/fixtures/outputs/disable-autostart.conf index 916aa9f..64f4126 100644 --- a/src/test/resources/fixtures/outputs/disable-autostart.conf +++ b/src/test/resources/fixtures/outputs/disable-autostart.conf @@ -6,11 +6,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --disable-autostart --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/extra-config.conf b/src/test/resources/fixtures/outputs/extra-config.conf index 9a7900c..75bd083 100644 --- a/src/test/resources/fixtures/outputs/extra-config.conf +++ b/src/test/resources/fixtures/outputs/extra-config.conf @@ -8,13 +8,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid SetEnv CODER_SSH_SESSION_TYPE=JetBrains ServerAliveInterval 5 ServerAliveCountMax 3 -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains - ServerAliveInterval 5 - ServerAliveCountMax 3 + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/header-command-windows.conf b/src/test/resources/fixtures/outputs/header-command-windows.conf index a27f0ab..700032c 100644 --- a/src/test/resources/fixtures/outputs/header-command-windows.conf +++ b/src/test/resources/fixtures/outputs/header-command-windows.conf @@ -6,11 +6,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid --header-command "\"C:\Program Files\My Header Command\HeaderCommand.exe\" --url=\"%%CODER_URL%%\" --test=\"foo bar\"" ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/header-command.conf b/src/test/resources/fixtures/outputs/header-command.conf index 61b5d74..b8d6e14 100644 --- a/src/test/resources/fixtures/outputs/header-command.conf +++ b/src/test/resources/fixtures/outputs/header-command.conf @@ -6,11 +6,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid --header-command 'my-header-command --url="$CODER_URL" --test="foo bar" --literal='\''$CODER_URL'\''' ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/log-dir.conf b/src/test/resources/fixtures/outputs/log-dir.conf index 84d7549..e47b5be 100644 --- a/src/test/resources/fixtures/outputs/log-dir.conf +++ b/src/test/resources/fixtures/outputs/log-dir.conf @@ -6,11 +6,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/multiple-agents.conf b/src/test/resources/fixtures/outputs/multiple-agents.conf index a81a8be..c0cbffe 100644 --- a/src/test/resources/fixtures/outputs/multiple-agents.conf +++ b/src/test/resources/fixtures/outputs/multiple-agents.conf @@ -6,13 +6,7 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + Host coder-jetbrains-toolbox--owner--foo.agent2--test.coder.invalid ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains owner/foo.agent2 ConnectTimeout 0 @@ -20,11 +14,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent2--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent2--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent2 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/multiple-users.conf b/src/test/resources/fixtures/outputs/multiple-users.conf index c8cd03d..ed34415 100644 --- a/src/test/resources/fixtures/outputs/multiple-users.conf +++ b/src/test/resources/fixtures/outputs/multiple-users.conf @@ -6,13 +6,7 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains owner/foo.agent1 ConnectTimeout 0 @@ -20,11 +14,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/multiple-workspaces.conf b/src/test/resources/fixtures/outputs/multiple-workspaces.conf index 8629ce3..9e308e7 100644 --- a/src/test/resources/fixtures/outputs/multiple-workspaces.conf +++ b/src/test/resources/fixtures/outputs/multiple-workspaces.conf @@ -6,13 +6,7 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + Host coder-jetbrains-toolbox--owner--bar.agent1--test.coder.invalid ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=jetbrains owner/bar.agent1 ConnectTimeout 0 @@ -20,11 +14,5 @@ Host coder-jetbrains-toolbox--owner--bar.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--bar.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/bar.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/no-disable-autostart.conf b/src/test/resources/fixtures/outputs/no-disable-autostart.conf index 7c9df80..4c1ac2b 100644 --- a/src/test/resources/fixtures/outputs/no-disable-autostart.conf +++ b/src/test/resources/fixtures/outputs/no-disable-autostart.conf @@ -6,11 +6,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/no-report-usage.conf b/src/test/resources/fixtures/outputs/no-report-usage.conf index 7c971e5..2bdfd47 100644 --- a/src/test/resources/fixtures/outputs/no-report-usage.conf +++ b/src/test/resources/fixtures/outputs/no-report-usage.conf @@ -6,11 +6,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/replace-end-no-newline.conf b/src/test/resources/fixtures/outputs/replace-end-no-newline.conf index 77a7cbb..36b8380 100644 --- a/src/test/resources/fixtures/outputs/replace-end-no-newline.conf +++ b/src/test/resources/fixtures/outputs/replace-end-no-newline.conf @@ -9,11 +9,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/replace-end.conf b/src/test/resources/fixtures/outputs/replace-end.conf index 0a48b7e..f31936a 100644 --- a/src/test/resources/fixtures/outputs/replace-end.conf +++ b/src/test/resources/fixtures/outputs/replace-end.conf @@ -10,11 +10,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/replace-middle-ignore-unrelated.conf b/src/test/resources/fixtures/outputs/replace-middle-ignore-unrelated.conf index ce23062..80cd717 100644 --- a/src/test/resources/fixtures/outputs/replace-middle-ignore-unrelated.conf +++ b/src/test/resources/fixtures/outputs/replace-middle-ignore-unrelated.conf @@ -11,13 +11,7 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid Host test2 Port 443 diff --git a/src/test/resources/fixtures/outputs/replace-middle.conf b/src/test/resources/fixtures/outputs/replace-middle.conf index 9125cd8..5c74b95 100644 --- a/src/test/resources/fixtures/outputs/replace-middle.conf +++ b/src/test/resources/fixtures/outputs/replace-middle.conf @@ -8,13 +8,7 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid Host test2 Port 443 diff --git a/src/test/resources/fixtures/outputs/replace-only.conf b/src/test/resources/fixtures/outputs/replace-only.conf index 7c9df80..4c1ac2b 100644 --- a/src/test/resources/fixtures/outputs/replace-only.conf +++ b/src/test/resources/fixtures/outputs/replace-only.conf @@ -6,11 +6,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/replace-start.conf b/src/test/resources/fixtures/outputs/replace-start.conf index 060582d..c99a993 100644 --- a/src/test/resources/fixtures/outputs/replace-start.conf +++ b/src/test/resources/fixtures/outputs/replace-start.conf @@ -6,13 +6,7 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid Host test Port 80 diff --git a/src/test/resources/fixtures/outputs/url.conf b/src/test/resources/fixtures/outputs/url.conf index dd3b17b..4d06a17 100644 --- a/src/test/resources/fixtures/outputs/url.conf +++ b/src/test/resources/fixtures/outputs/url.conf @@ -6,11 +6,5 @@ Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid UserKnownHostsFile /dev/null LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox--owner--foo.agent1--test.coder.invalid--bg - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid?foo=bar&baz=qux ssh --stdio --usage-app=disable owner/foo.agent1 - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains + # --- END CODER JETBRAINS TOOLBOX test.coder.invalid diff --git a/src/test/resources/fixtures/outputs/wildcard.conf b/src/test/resources/fixtures/outputs/wildcard.conf index b3fd6b8..e7c55b1 100644 --- a/src/test/resources/fixtures/outputs/wildcard.conf +++ b/src/test/resources/fixtures/outputs/wildcard.conf @@ -7,11 +7,4 @@ Host coder-jetbrains-toolbox-test.coder.invalid--* LogLevel ERROR SetEnv CODER_SSH_SESSION_TYPE=JetBrains -Host coder-jetbrains-toolbox-test.coder.invalid-bg--* - ProxyCommand /tmp/coder-toolbox/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-toolbox/test.coder.invalid/config --url https://test.coder.invalid ssh --stdio --ssh-host-prefix coder-jetbrains-toolbox-test.coder.invalid-bg-- %h - ConnectTimeout 0 - StrictHostKeyChecking no - UserKnownHostsFile /dev/null - LogLevel ERROR - SetEnv CODER_SSH_SESSION_TYPE=JetBrains # --- END CODER JETBRAINS TOOLBOX test.coder.invalid From 9fdd99b131a16a83f45b5d433c2711552db7ca5a Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Fri, 2 May 2025 16:31:12 +0300 Subject: [PATCH 3/6] fix: rendering glitches when a Workspace is stopped (#102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … while an SSH connection is alive. Toolbox raises a class cast exception when Workspaces are stopped while the SSH connection is running. After the workspace was stopped Toolbox refused to show widget with some weird glitches on the screen. The fix in this case is to safely disconnect the SSH before sending the stop command to the workspace. The code will wait at most 10 seconds for the disconnect to happen, and only after that send the stop. - resolves #98 --- CHANGELOG.md | 4 +++ .../coder/toolbox/CoderRemoteEnvironment.kt | 28 +++++++++++++++---- .../toolbox/util/CoderProtocolHandler.kt | 6 ---- .../coder/toolbox/util/StateFlowExtensions.kt | 22 +++++++++++++++ 4 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 src/main/kotlin/com/coder/toolbox/util/StateFlowExtensions.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 058e1f0..dde6c33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - ssh configuration is simplified, background hostnames have been discarded. +### Fixed + +- rendering glitches when a Workspace is stopped while SSH connection is alive + ## 0.2.0 - 2025-04-24 ### Added diff --git a/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt b/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt index 69ee6cd..adafeb0 100644 --- a/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt +++ b/src/main/kotlin/com/coder/toolbox/CoderRemoteEnvironment.kt @@ -7,6 +7,7 @@ import com.coder.toolbox.sdk.CoderRestClient import com.coder.toolbox.sdk.ex.APIResponseException import com.coder.toolbox.sdk.v2.models.Workspace import com.coder.toolbox.sdk.v2.models.WorkspaceAgent +import com.coder.toolbox.util.waitForFalseWithTimeout import com.coder.toolbox.util.withPath import com.coder.toolbox.views.Action import com.coder.toolbox.views.EnvironmentView @@ -43,6 +44,10 @@ class CoderRemoteEnvironment( private var wsRawStatus = WorkspaceAndAgentStatus.from(workspace, agent) override var name: String = "${workspace.name}.${agent.name}" + + private var isConnected: MutableStateFlow = MutableStateFlow(false) + override val connectionRequest: MutableStateFlow = MutableStateFlow(false) + override val state: MutableStateFlow = MutableStateFlow(wsRawStatus.toRemoteEnvironmentState(context)) override val description: MutableStateFlow = @@ -106,6 +111,8 @@ class CoderRemoteEnvironment( } else { actions.add(Action(context.i18n.ptrl("Stop")) { context.cs.launch { + tryStopSshConnection() + val build = client.stopWorkspace(workspace) update(workspace.copy(latestBuild = build), agent) } @@ -115,18 +122,30 @@ class CoderRemoteEnvironment( return actions } + private suspend fun tryStopSshConnection() { + if (isConnected.value) { + connectionRequest.update { + false + } + + if (isConnected.waitForFalseWithTimeout(10.seconds) == null) { + context.logger.warn("The SSH connection to workspace $name could not be dropped in time, going to stop the workspace while the SSH connection is live") + } + } + } + override fun getBeforeConnectionHooks(): List = listOf(this) override fun getAfterDisconnectHooks(): List = listOf(this) override fun beforeConnection() { context.logger.info("Connecting to $id...") - this.isConnected = true + isConnected.update { true } } override fun afterDisconnect() { this.connectionRequest.update { false } - this.isConnected = false + isConnected.update { false } context.logger.info("Disconnected from $id") } @@ -161,9 +180,6 @@ class CoderRemoteEnvironment( agent ) - private var isConnected = false - override val connectionRequest: MutableStateFlow = MutableStateFlow(false) - /** * Does nothing. In theory, we could do something like start the workspace * when you click into the workspace, but you would still need to press @@ -171,7 +187,7 @@ class CoderRemoteEnvironment( * to be much value. */ override fun setVisible(visibilityState: EnvironmentVisibilityState) { - if (wsRawStatus.ready() && visibilityState.contentsVisible == true && isConnected == false) { + if (wsRawStatus.ready() && visibilityState.contentsVisible == true && isConnected.value == false) { context.cs.launch { connectionRequest.update { true diff --git a/src/main/kotlin/com/coder/toolbox/util/CoderProtocolHandler.kt b/src/main/kotlin/com/coder/toolbox/util/CoderProtocolHandler.kt index aca2464..ad42d18 100644 --- a/src/main/kotlin/com/coder/toolbox/util/CoderProtocolHandler.kt +++ b/src/main/kotlin/com/coder/toolbox/util/CoderProtocolHandler.kt @@ -13,7 +13,6 @@ import com.jetbrains.toolbox.api.localization.LocalizableString import kotlinx.coroutines.TimeoutCancellationException import kotlinx.coroutines.delay import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import kotlinx.coroutines.time.withTimeout import java.net.HttpURLConnection @@ -331,9 +330,4 @@ private fun CoderToolboxContext.popupPluginMainPage() { this.envPageManager.showPluginEnvironmentsPage(true) } -/** - * Suspends the coroutine until first true value is received. - */ -suspend fun StateFlow.waitForTrue() = this.first { it } - class MissingArgumentException(message: String, ex: Throwable? = null) : IllegalArgumentException(message, ex) diff --git a/src/main/kotlin/com/coder/toolbox/util/StateFlowExtensions.kt b/src/main/kotlin/com/coder/toolbox/util/StateFlowExtensions.kt new file mode 100644 index 0000000..46ae602 --- /dev/null +++ b/src/main/kotlin/com/coder/toolbox/util/StateFlowExtensions.kt @@ -0,0 +1,22 @@ +package com.coder.toolbox.util + +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.withTimeoutOrNull +import kotlin.time.Duration + +/** + * Suspends the coroutine until first true value is received. + */ +suspend fun StateFlow.waitForTrue() = this.first { it } + +/** + * Suspends the coroutine until first false value is received. + */ +suspend fun StateFlow.waitForFalseWithTimeout(duration: Duration): Boolean? { + if (!this.value) return false + + return withTimeoutOrNull(duration) { + this@waitForFalseWithTimeout.first { !it } + } +} \ No newline at end of file From db08dfafd8e3b52636306d14c932e955f00d4c28 Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Fri, 2 May 2025 21:42:58 +0300 Subject: [PATCH 4/6] fix: misleading "No workspaces yet" during manual authentication (#104) There is a brief moment between manual authentication and workspace poller initialization and execution where we see a "No workspaces yet" which is misleading. Instead, a loading indicator/message should be displayed. - resolves #103 --- CHANGELOG.md | 1 + src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dde6c33..a9d2eff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Fixed - rendering glitches when a Workspace is stopped while SSH connection is alive +- misleading message saying that there are no workspaces rendered during manual authentication ## 0.2.0 - 2025-04-24 diff --git a/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt b/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt index 4ccce7e..2cdbaf9 100644 --- a/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt +++ b/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt @@ -262,6 +262,7 @@ class CoderRemoteProvider( // start initialization with the new settings this@CoderRemoteProvider.client = restClient coderHeaderPage = NewEnvironmentPage(context, context.i18n.pnotr(restClient.url.toString())) + environments.showLoadingMessage() pollJob = poll(restClient, cli) } } @@ -326,7 +327,14 @@ class CoderRemoteProvider( context.secrets.rememberMe = true this.client = client pollJob?.cancel() + environments.showLoadingMessage() pollJob = poll(client, cli) goToEnvironmentsPage() } + + private fun MutableStateFlow>>.showLoadingMessage() { + this.update { + LoadableState.Loading + } + } } From 97cd0f0f9a3a300a14d367c20d6606a47eb8789d Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Mon, 5 May 2025 21:46:31 +0300 Subject: [PATCH 5/6] fix: access the settings page for the auth. wizard (#105) The Settings menu is only available after we successfully authenticate. This can be somewhat problematic if we want to configure something like coder cli path, or certificate path before doing the authentication. A new "Settings" button at the bottom of the page can now access the Settings page. Toolbox is a bit inflexible with the API because: - I could not find a way to delimit or separate the Settings button from the Back and Sign In/Connect button - we can't put a button or anything else in the top right corner, the traditional place for a settings icon. - resolves #90 --- CHANGELOG.md | 1 + .../kotlin/com/coder/toolbox/CoderRemoteProvider.kt | 4 ++-- .../kotlin/com/coder/toolbox/views/AuthWizardPage.kt | 12 +++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9d2eff..2e63675 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - rendering glitches when a Workspace is stopped while SSH connection is alive - misleading message saying that there are no workspaces rendered during manual authentication +- Coder Settings can now be accessed from the authentication wizard ## 0.2.0 - 2025-04-24 diff --git a/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt b/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt index 2cdbaf9..b422468 100644 --- a/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt +++ b/src/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt @@ -296,7 +296,7 @@ class CoderRemoteProvider( if (autologin && lastDeploymentURL.isNotBlank() && (lastToken.isNotBlank() || !settings.requireTokenAuth)) { try { AuthWizardState.goToStep(WizardStep.LOGIN) - return AuthWizardPage(context, true, ::onConnect) + return AuthWizardPage(context, settingsPage, true, ::onConnect) } catch (ex: Exception) { errorBuffer.add(ex) } @@ -306,7 +306,7 @@ class CoderRemoteProvider( firstRun = false // Login flow. - val authWizard = AuthWizardPage(context, false, ::onConnect) + val authWizard = AuthWizardPage(context, settingsPage, false, ::onConnect) // We might have navigated here due to a polling error. errorBuffer.forEach { authWizard.notify("Error encountered", it) diff --git a/src/main/kotlin/com/coder/toolbox/views/AuthWizardPage.kt b/src/main/kotlin/com/coder/toolbox/views/AuthWizardPage.kt index ca92ed7..feea50d 100644 --- a/src/main/kotlin/com/coder/toolbox/views/AuthWizardPage.kt +++ b/src/main/kotlin/com/coder/toolbox/views/AuthWizardPage.kt @@ -12,14 +12,17 @@ import kotlinx.coroutines.flow.update class AuthWizardPage( private val context: CoderToolboxContext, + private val settingsPage: CoderSettingsPage, initialAutoLogin: Boolean = false, onConnect: ( client: CoderRestClient, cli: CoderCLIManager, ) -> Unit, -) : CoderPage(context, context.i18n.ptrl("Authenticate to Coder")) { +) : CoderPage(context, context.i18n.ptrl("Authenticate to Coder"), false) { private val shouldAutoLogin = MutableStateFlow(initialAutoLogin) - + private val settingsAction = Action(context.i18n.ptrl("Settings"), actionBlock = { + context.ui.showUiPage(settingsPage) + }) private val signInStep = SignInStep(context, this::notify) private val tokenStep = TokenStep(context) private val connectStep = ConnectStep(context, shouldAutoLogin, this::notify, this::displaySteps, onConnect) @@ -47,7 +50,8 @@ class AuthWizardPage( if (signInStep.onNext()) { displaySteps() } - }) + }), + settingsAction ) } signInStep.onVisible() @@ -64,6 +68,7 @@ class AuthWizardPage( displaySteps() } }), + settingsAction, Action(context.i18n.ptrl("Back"), closesPage = false, actionBlock = { tokenStep.onBack() displaySteps() @@ -79,6 +84,7 @@ class AuthWizardPage( } actionButtons.update { listOf( + settingsAction, Action(context.i18n.ptrl("Back"), closesPage = false, actionBlock = { connectStep.onBack() shouldAutoLogin.update { From 6a96e98922048bc369e1552d02a3844940eb51f3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 5 May 2025 22:41:32 +0300 Subject: [PATCH 6/6] Changelog update - `v0.2.1` (#107) Current pull request contains patched `CHANGELOG.md` file for the `v0.2.1` version. Co-authored-by: GitHub Action --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e63675..32831c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## 0.2.1 - 2025-05-05 + ### Changed - ssh configuration is simplified, background hostnames have been discarded.