Skip to content

Commit bdae6e4

Browse files
committed
Impl: support for workspaces with multiple agents
- the hostname for the connection is `coder.WorkspaceName` if there is at most an agent. - whereas if there are multiple agents, the hostname becomes `coder.WorkspaceName.AgentName` - the OS and Arch are also retrieved from the agent. - removed specific Linux distribution icons - refactored the utilities around OS&Arch resolving - resolves #2
1 parent 061c2f4 commit bdae6e4

File tree

7 files changed

+79
-58
lines changed

7 files changed

+79
-58
lines changed

src/main/kotlin/com/coder/gateway/icons/CoderIcons.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ object CoderIcons {
99

1010
val OPEN_TERMINAL = IconLoader.getIcon("open_terminal.svg", javaClass)
1111

12-
val UBUNTU = IconLoader.getIcon("ubuntu.svg", javaClass)
13-
val CENTOS = IconLoader.getIcon("centos.svg", javaClass)
12+
val WINDOWS = IconLoader.getIcon("windows.svg", javaClass)
13+
val MACOS = IconLoader.getIcon("macOS.svg", javaClass)
1414
val LINUX = IconLoader.getIcon("linux.svg", javaClass)
15+
val UNKNOWN = IconLoader.getIcon("unknown.svg", javaClass)
1516

1617
val GREEN_CIRCLE = IconLoader.getIcon("green_circle.svg", javaClass)
1718
val GRAY_CIRCLE = IconLoader.getIcon("gray_circle.svg", javaClass)
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package com.coder.gateway.models
22

3-
import com.coder.gateway.sdk.v2.models.Workspace
4-
53
data class CoderWorkspacesWizardModel(
64
var coderURL: String = "https://localhost",
75
var token: String = "",
86
var buildVersion: String = "",
9-
var workspaces: List<Workspace> = mutableListOf(),
10-
var selectedWorkspace: Workspace? = null
7+
var workspaceAgents: List<WorkspaceAgentModel> = mutableListOf(),
8+
var selectedWorkspace: WorkspaceAgentModel? = null
119
)
+35-22
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,48 @@
11
package com.coder.gateway.sdk
22

33
fun getOS(): OS? {
4-
val os = System.getProperty("os.name").toLowerCase()
5-
return when {
6-
os.contains("win", true) -> {
7-
OS.WINDOWS
8-
}
9-
os.contains("nix", true) || os.contains("nux", true) || os.contains("aix", true) -> {
10-
OS.LINUX
11-
}
12-
os.contains("mac", true) -> {
13-
OS.MAC
14-
}
15-
else -> null
16-
}
4+
return OS.from(System.getProperty("os.name"))
175
}
186

197
fun getArch(): Arch? {
20-
val arch = System.getProperty("os.arch").toLowerCase()
21-
return when {
22-
arch.contains("amd64", true) || arch.contains("x86_64", true) -> Arch.AMD64
23-
arch.contains("arm64", true) || arch.contains("aarch64", true) -> Arch.ARM64
24-
arch.contains("armv7", true) -> Arch.ARMV7
25-
else -> null
26-
}
8+
return Arch.from(System.getProperty("os.arch").toLowerCase())
279
}
2810

2911
enum class OS {
30-
WINDOWS, LINUX, MAC
12+
WINDOWS, LINUX, MAC;
13+
14+
companion object {
15+
fun from(os: String): OS? {
16+
return when {
17+
os.contains("win", true) -> {
18+
WINDOWS
19+
}
20+
21+
os.contains("nix", true) || os.contains("nux", true) || os.contains("aix", true) -> {
22+
LINUX
23+
}
24+
25+
os.contains("mac", true) -> {
26+
MAC
27+
}
28+
29+
else -> null
30+
}
31+
}
32+
}
3133
}
3234

3335
enum class Arch {
34-
AMD64, ARM64, ARMV7
36+
AMD64, ARM64, ARMV7;
37+
38+
companion object {
39+
fun from(arch: String): Arch? {
40+
return when {
41+
arch.contains("amd64", true) || arch.contains("x86_64", true) -> AMD64
42+
arch.contains("arm64", true) || arch.contains("aarch64", true) -> ARM64
43+
arch.contains("armv7", true) -> ARMV7
44+
else -> null
45+
}
46+
}
47+
}
3548
}

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

+20-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ package com.coder.gateway.views.steps
33
import com.coder.gateway.CoderGatewayBundle
44
import com.coder.gateway.icons.CoderIcons
55
import com.coder.gateway.models.CoderWorkspacesWizardModel
6+
import com.coder.gateway.models.WorkspaceAgentModel
7+
import com.coder.gateway.sdk.Arch
68
import com.coder.gateway.sdk.CoderRestClientService
7-
import com.coder.gateway.sdk.v2.models.Workspace
9+
import com.coder.gateway.sdk.OS
810
import com.intellij.ide.IdeBundle
911
import com.intellij.openapi.Disposable
1012
import com.intellij.openapi.application.ApplicationManager
@@ -28,7 +30,7 @@ class CoderWorkspacesStepView : CoderWorkspacesWizardStep, Disposable {
2830
private val cs = CoroutineScope(Dispatchers.Main)
2931

3032
private val coderClient: CoderRestClientService = ApplicationManager.getApplication().getService(CoderRestClientService::class.java)
31-
private var workspaces = CollectionListModel<Workspace>()
33+
private var workspaces = CollectionListModel<WorkspaceAgentModel>()
3234
private var workspacesView = JBList(workspaces)
3335

3436
private lateinit var wizard: CoderWorkspacesWizardModel
@@ -60,7 +62,22 @@ class CoderWorkspacesStepView : CoderWorkspacesWizardStep, Disposable {
6062
cs.launch {
6163
val workspaceList = withContext(Dispatchers.IO) {
6264
try {
63-
coderClient.workspaces()
65+
val workspaces = coderClient.workspaces()
66+
return@withContext workspaces.flatMap { workspace ->
67+
val agents = coderClient.workspaceAgents(workspace)
68+
val shouldContainAgentName = agents.size > 1
69+
agents.map { agent ->
70+
val workspaceName = if (shouldContainAgentName) "${workspace.name}.${agent.operatingSystem}" else workspace.name
71+
WorkspaceAgentModel(
72+
workspaceName,
73+
workspace.latestBuild.job.status,
74+
workspace.latestBuild.workspaceTransition,
75+
OS.from(agent.operatingSystem),
76+
Arch.from(agent.operatingSystem)
77+
78+
)
79+
}
80+
}
6481
} catch (e: Exception) {
6582
logger.error("Could not retrieve workspaces for ${coderClient.me.username} on ${coderClient.coderURL}. Reason: $e")
6683
emptyList()

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

+19-16
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
11
package com.coder.gateway.views.steps
22

3-
import com.coder.gateway.icons.CoderIcons.CENTOS
3+
import com.coder.gateway.icons.CoderIcons
44
import com.coder.gateway.icons.CoderIcons.GRAY_CIRCLE
55
import com.coder.gateway.icons.CoderIcons.GREEN_CIRCLE
6-
import com.coder.gateway.icons.CoderIcons.LINUX
76
import com.coder.gateway.icons.CoderIcons.RED_CIRCLE
8-
import com.coder.gateway.icons.CoderIcons.UBUNTU
7+
import com.coder.gateway.models.WorkspaceAgentModel
8+
import com.coder.gateway.sdk.OS
99
import com.coder.gateway.sdk.v2.models.ProvisionerJobStatus
10-
import com.coder.gateway.sdk.v2.models.Workspace
1110
import com.coder.gateway.sdk.v2.models.WorkspaceBuildTransition
1211
import com.intellij.ui.dsl.builder.panel
1312
import com.intellij.util.ui.JBFont
1413
import java.awt.Component
1514
import javax.swing.JList
1615
import javax.swing.ListCellRenderer
1716

18-
class WorkspaceCellRenderer : ListCellRenderer<Workspace> {
17+
class WorkspaceCellRenderer : ListCellRenderer<WorkspaceAgentModel> {
1918

20-
override fun getListCellRendererComponent(list: JList<out Workspace>, workspace: Workspace, index: Int, isSelected: Boolean, cellHasFocus: Boolean): Component {
19+
override fun getListCellRendererComponent(list: JList<out WorkspaceAgentModel>, workspace: WorkspaceAgentModel, index: Int, isSelected: Boolean, cellHasFocus: Boolean): Component {
2120
return panel {
2221
indent {
2322
row {
@@ -44,32 +43,36 @@ class WorkspaceCellRenderer : ListCellRenderer<Workspace> {
4443
}
4544
}
4645

47-
private fun iconForImageTag(workspace: Workspace) = when (workspace.templateName) {
48-
"ubuntu" -> UBUNTU
49-
"centos" -> CENTOS
50-
else -> LINUX
46+
private fun iconForImageTag(workspace: WorkspaceAgentModel) = when (workspace?.agentOS) {
47+
OS.LINUX -> CoderIcons.LINUX
48+
OS.WINDOWS -> CoderIcons.WINDOWS
49+
OS.MAC -> CoderIcons.MACOS
50+
else -> CoderIcons.UNKNOWN
5151
}
5252

53-
private fun iconForStatus(workspace: Workspace) = when (workspace.latestBuild.job.status) {
54-
ProvisionerJobStatus.SUCCEEDED -> if (workspace.latestBuild.workspaceTransition == WorkspaceBuildTransition.START) GREEN_CIRCLE else RED_CIRCLE
55-
ProvisionerJobStatus.RUNNING -> when (workspace.latestBuild.workspaceTransition) {
53+
private fun iconForStatus(workspace: WorkspaceAgentModel) = when (workspace.jobStatus) {
54+
ProvisionerJobStatus.SUCCEEDED -> if (workspace.buildTransition == WorkspaceBuildTransition.START) GREEN_CIRCLE else RED_CIRCLE
55+
ProvisionerJobStatus.RUNNING -> when (workspace.buildTransition) {
5656
WorkspaceBuildTransition.START, WorkspaceBuildTransition.STOP, WorkspaceBuildTransition.DELETE -> GRAY_CIRCLE
5757
}
58+
5859
else -> RED_CIRCLE
5960
}
6061

61-
private fun labelForStatus(workspace: Workspace) = when (workspace.latestBuild.job.status) {
62+
private fun labelForStatus(workspace: WorkspaceAgentModel) = when (workspace.jobStatus) {
6263
ProvisionerJobStatus.PENDING -> "◍ Queued"
63-
ProvisionerJobStatus.RUNNING -> when (workspace.latestBuild.workspaceTransition) {
64+
ProvisionerJobStatus.RUNNING -> when (workspace.buildTransition) {
6465
WorkspaceBuildTransition.START -> "⦿ Starting"
6566
WorkspaceBuildTransition.STOP -> "◍ Stopping"
6667
WorkspaceBuildTransition.DELETE -> "⦸ Deleting"
6768
}
68-
ProvisionerJobStatus.SUCCEEDED -> when (workspace.latestBuild.workspaceTransition) {
69+
70+
ProvisionerJobStatus.SUCCEEDED -> when (workspace.buildTransition) {
6971
WorkspaceBuildTransition.START -> "⦿ Running"
7072
WorkspaceBuildTransition.STOP -> "◍ Stopped"
7173
WorkspaceBuildTransition.DELETE -> "⦸ Deleted"
7274
}
75+
7376
ProvisionerJobStatus.CANCELING -> "◍ Canceling action"
7477
ProvisionerJobStatus.CANCELED -> "◍ Canceled action"
7578
ProvisionerJobStatus.FAILED -> "ⓧ Failed"

src/main/resources/centos.svg

-10
This file was deleted.

src/main/resources/ubuntu.svg

-1
This file was deleted.

0 commit comments

Comments
 (0)