Skip to content

Commit a89315e

Browse files
committed
Deploy coder cli right after doing authentication
- also implement a progress bar to provide better feedback about what is happening behind the scenes
1 parent 0d237aa commit a89315e

File tree

3 files changed

+69
-29
lines changed

3 files changed

+69
-29
lines changed

src/main/kotlin/com/coder/gateway/CoderGatewayConnectionProvider.kt

+38-9
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
package com.coder.gateway
22

33
import com.coder.gateway.views.CoderGatewayConnectionComponent
4+
import com.intellij.remote.AuthType
45
import com.intellij.remote.RemoteCredentialsHolder
6+
import com.intellij.ssh.config.unified.SshConfig
57
import com.jetbrains.gateway.api.ConnectionRequestor
68
import com.jetbrains.gateway.api.GatewayConnectionHandle
79
import com.jetbrains.gateway.api.GatewayConnectionProvider
8-
import com.jetbrains.gateway.ssh.ClientOverSshTunnelConnector
10+
import com.jetbrains.gateway.ssh.IdeInfo
11+
import com.jetbrains.gateway.ssh.IntelliJPlatformProduct
12+
import com.jetbrains.gateway.ssh.SshCommandsExecutor
13+
import com.jetbrains.gateway.ssh.SshDownloadMethod
14+
import com.jetbrains.gateway.ssh.SshMultistagePanelContext
915
import com.jetbrains.rd.util.lifetime.LifetimeDefinition
1016
import kotlinx.coroutines.GlobalScope
1117
import kotlinx.coroutines.launch
12-
import java.net.URI
1318
import java.util.logging.Logger
1419
import javax.swing.JComponent
1520

@@ -19,8 +24,6 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
1924
val coderUrl = parameters["coder_url"]
2025
val workspaceName = parameters["workspace_name"]
2126
val user = parameters["username"]
22-
val pass = parameters["password"]
23-
val token = parameters["session_token"]
2427
val projectPath = parameters["project_path"]
2528

2629
if (coderUrl != null && workspaceName != null) {
@@ -33,13 +36,39 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
3336
val credentials = RemoteCredentialsHolder()
3437
credentials.apply {
3538
setHost("coder.${workspaceName}")
36-
userName = user
37-
password = pass
39+
userName = "coder"
40+
authType = AuthType.OPEN_SSH
3841
}
42+
val context = SshMultistagePanelContext().apply {
43+
deploy = true
44+
sshConfig = SshConfig(true).apply {
45+
setHost("coder.${workspaceName}")
46+
setUsername(user)
47+
authType = AuthType.OPEN_SSH
48+
}
49+
downloadMethod = SshDownloadMethod.SftpUpload
50+
ide = IdeInfo(
51+
IntelliJPlatformProduct.IDEA,
52+
buildNumber = "221.5787.30"
53+
)
54+
}
55+
56+
// GlobalScope.launch {
57+
// val deployPair = withContext(Dispatchers.IO) {
58+
// SshDeployFlowUtil.fullDeployCycle(
59+
// clientLifetime,
60+
// context,
61+
// Duration.ofMinutes(10)
62+
// )
63+
// }
64+
//
65+
//
66+
// println(deployPair)
67+
// }
3968

40-
var tcpJoinLink = "jetbrains-gateway://connect#projectPath=${projectPath}&host=coder.${workspaceName}&port=22&user=${user}&token=$token&type=ssh&deploy=true&buildNumber=221.5591.52&productCode=IU"
4169
GlobalScope.launch {
42-
ClientOverSshTunnelConnector(clientLifetime, credentials, URI(tcpJoinLink)).connect()
70+
val cmdExecutor = SshCommandsExecutor.Companion.create(credentials)
71+
cmdExecutor.getInstalledIDEs()
4372
}
4473

4574
return object : GatewayConnectionHandle(clientLifetime) {
@@ -68,4 +97,4 @@ class CoderGatewayConnectionProvider : GatewayConnectionProvider {
6897
}
6998
}
7099

71-
internal data class CoderConnectionMetadata(val url: String, val workspaceId: String)
100+
internal data class CoderConnectionMetadata(val url: String, val workspaceId: String)

src/main/kotlin/com/coder/gateway/views/steps/CoderAuthStepView.kt

+31-7
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ import com.coder.gateway.CoderGatewayBundle
44
import com.coder.gateway.models.CoderWorkspacesWizardModel
55
import com.coder.gateway.models.LoginModel
66
import com.coder.gateway.models.UriScheme
7+
import com.coder.gateway.sdk.CoderCLIManager
78
import com.coder.gateway.sdk.CoderRestClientService
89
import com.intellij.credentialStore.CredentialAttributes
910
import com.intellij.credentialStore.askPassword
1011
import com.intellij.ide.IdeBundle
1112
import com.intellij.openapi.Disposable
1213
import com.intellij.openapi.application.ApplicationManager
14+
import com.intellij.openapi.progress.ProgressIndicator
15+
import com.intellij.openapi.progress.ProgressManager
16+
import com.intellij.openapi.progress.Task
1317
import com.intellij.openapi.ui.panel.ComponentPanelBuilder
1418
import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeScreenUIManager
1519
import com.intellij.ui.IconManager
@@ -26,7 +30,8 @@ import com.intellij.util.ui.JBFont
2630
import kotlinx.coroutines.CoroutineScope
2731
import kotlinx.coroutines.Dispatchers
2832
import kotlinx.coroutines.cancel
29-
import kotlinx.coroutines.withContext
33+
import org.zeroturnaround.exec.ProcessExecutor
34+
import java.net.URL
3035

3136
class CoderAuthStepView : CoderWorkspacesWizardStep, Disposable {
3237
private val cs = CoroutineScope(Dispatchers.Main)
@@ -88,14 +93,33 @@ class CoderAuthStepView : CoderWorkspacesWizardStep, Disposable {
8893
CredentialAttributes("Coder"),
8994
false
9095
)
91-
9296
model.password = password
93-
withContext(Dispatchers.IO) {
94-
coderClient.initClientSession(model.uriScheme, model.host, model.port, model.email, model.password!!)
95-
}
96-
wizardModel.apply {
97-
loginModel = model.copy()
97+
val authTask = object : Task.Modal(null, "Authenticate and setup coder", false) {
98+
override fun run(pi: ProgressIndicator) {
99+
pi.text = "Authenticating ${model.email} on ${model.host}..."
100+
pi.fraction = 0.3
101+
coderClient.initClientSession(model.uriScheme, model.host, model.port, model.email, model.password!!)
102+
wizardModel.apply {
103+
loginModel = model.copy()
104+
}
105+
106+
pi.text = "Downloading coder cli..."
107+
pi.fraction = 0.4
108+
val url = URL(wizardModel.loginModel.uriScheme.toString().toLowerCase(), wizardModel.loginModel.host, wizardModel.loginModel.port, "")
109+
val cliManager = CoderCLIManager(URL(url.protocol, url.host, url.port, ""))
110+
val cli = cliManager.download() ?: throw IllegalStateException("Could not download coder binary")
111+
112+
pi.text = "Configuring coder cli..."
113+
pi.fraction = 0.5
114+
val loginOutput = ProcessExecutor().command(cli.toAbsolutePath().toString(), "login", url.toString(), "--token", coderClient.sessionToken).readOutput(true).execute().outputUTF8()
115+
CoderWorkspacesStepView.logger.info("coder-cli login output: $loginOutput")
116+
pi.fraction = 0.6
117+
val sshConfigOutput = ProcessExecutor().command(cli.toAbsolutePath().toString(), "config-ssh").readOutput(true).execute().outputUTF8()
118+
CoderWorkspacesStepView.logger.info("coder-cli config-ssh output: $sshConfigOutput")
119+
pi.fraction = 1.0
120+
}
98121
}
122+
ProgressManager.getInstance().run(authTask)
99123
}
100124

101125

src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt

-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.coder.gateway.views.steps
22

33
import com.coder.gateway.CoderGatewayBundle
44
import com.coder.gateway.models.CoderWorkspacesWizardModel
5-
import com.coder.gateway.sdk.CoderCLIManager
65
import com.coder.gateway.sdk.CoderRestClientService
76
import com.coder.gateway.sdk.v2.models.Workspace
87
import com.intellij.ide.IdeBundle
@@ -25,7 +24,6 @@ import kotlinx.coroutines.CoroutineScope
2524
import kotlinx.coroutines.Dispatchers
2625
import kotlinx.coroutines.launch
2726
import kotlinx.coroutines.withContext
28-
import org.zeroturnaround.exec.ProcessExecutor
2927
import java.net.URL
3028
import java.util.logging.Logger
3129
import javax.swing.DefaultComboBoxModel
@@ -94,17 +92,6 @@ class CoderWorkspacesStepView : CoderWorkspacesWizardStep, Disposable {
9492
if (workspace != null) {
9593
logger.info("Connecting to ${workspace.name}...")
9694
cs.launch {
97-
withContext(Dispatchers.IO) {
98-
val url = URL(wizardModel.loginModel.uriScheme.toString().toLowerCase(), wizardModel.loginModel.host, wizardModel.loginModel.port, "")
99-
val cliManager = CoderCLIManager(URL(url.protocol, url.host, url.port, ""))
100-
val cli = cliManager.download() ?: throw IllegalStateException("Could not download coder binary")
101-
val loginOutput = ProcessExecutor().command(cli.toAbsolutePath().toString(), "login", url.toString(), "--token", coderClient.sessionToken).readOutput(true).execute().outputUTF8()
102-
103-
logger.info("coder-cli login output: $loginOutput")
104-
val sshConfigOutput = ProcessExecutor().command(cli.toAbsolutePath().toString(), "config-ssh").readOutput(true).execute().outputUTF8()
105-
logger.info("coder-cli config-ssh output: $sshConfigOutput")
106-
}
107-
10895
GatewayUI.getInstance().connect(
10996
mapOf(
11097
"type" to "coder",

0 commit comments

Comments
 (0)