|
| 1 | +package com.coder.gateway.models |
| 2 | + |
| 3 | +import com.coder.gateway.sdk.v2.models.Workspace |
| 4 | +import com.coder.gateway.sdk.v2.models.WorkspaceAgent |
| 5 | +import com.coder.gateway.sdk.v2.models.WorkspaceAgentLifecycleState |
| 6 | +import com.coder.gateway.sdk.v2.models.WorkspaceAgentStatus |
| 7 | +import com.coder.gateway.sdk.v2.models.WorkspaceStatus |
| 8 | +import com.intellij.ui.JBColor |
| 9 | + |
| 10 | +/** |
| 11 | + * WorkspaceAndAgentStatus represents the combined status of a single agent and |
| 12 | + * its workspace (or just the workspace if there are no agents). |
| 13 | + */ |
| 14 | +enum class WorkspaceAndAgentStatus(val label: String, val description: String) { |
| 15 | + // Workspace states. |
| 16 | + QUEUED("◍ Queued", "The workspace is queueing to start."), |
| 17 | + STARTING("⦿ Starting", "The workspace is starting."), |
| 18 | + FAILED("ⓧ Failed", "The workspace has failed to start."), |
| 19 | + DELETING("⦸ Deleting", "The workspace is being deleted."), |
| 20 | + DELETED("⦸ Deleted", "The workspace has been deleted."), |
| 21 | + STOPPING("◍ Stopping", "The workspace is stopping."), |
| 22 | + STOPPED("◍ Stopped", "The workspace has stopped."), |
| 23 | + CANCELING("◍ Canceling action", "The workspace is being canceled."), |
| 24 | + CANCELED("◍ Canceled action", "The workspace has been canceled."), |
| 25 | + RUNNING("⦿ Running", "The workspace is running, waiting for agents."), |
| 26 | + |
| 27 | + // Agent states. |
| 28 | + CONNECTING("⦿ Connecting", "The agent is connecting."), |
| 29 | + DISCONNECTED("⦸ Disconnected", "The agent has disconnected."), |
| 30 | + TIMEOUT("ⓧ Timeout", "The agent is taking longer than expected to connect."), |
| 31 | + AGENT_STARTING("⦿ Starting", "The startup script is running."), |
| 32 | + AGENT_STARTING_READY("⦿ Starting", "The startup script is still running but the agent is ready to accept connections."), |
| 33 | + CREATED("⦿ Created", "The agent has been created."), |
| 34 | + START_ERROR("◍ Started with error", "The agent is ready but the startup script errored."), |
| 35 | + START_TIMEOUT("◍ Starting", "The startup script is taking longer than expected."), |
| 36 | + START_TIMEOUT_READY("◍ Starting", "The startup script is taking longer than expected but the agent is ready to accept connections."), |
| 37 | + SHUTTING_DOWN("◍ Shutting down", "The agent is shutting down."), |
| 38 | + SHUTDOWN_ERROR("⦸ Shutdown with error", "The agent shut down but the shutdown script errored."), |
| 39 | + SHUTDOWN_TIMEOUT("⦸ Shutting down", "The shutdown script is taking longer than expected."), |
| 40 | + OFF("⦸ Off", "The agent has shut down."), |
| 41 | + READY("⦿ Ready", "The agent is ready to accept connections."); |
| 42 | + |
| 43 | + fun statusColor(): JBColor = when (this) { |
| 44 | + READY, AGENT_STARTING_READY, START_TIMEOUT_READY -> JBColor.GREEN |
| 45 | + START_ERROR, START_TIMEOUT, SHUTDOWN_TIMEOUT -> JBColor.YELLOW |
| 46 | + FAILED, DISCONNECTED, TIMEOUT, SHUTDOWN_ERROR -> JBColor.RED |
| 47 | + else -> if (JBColor.isBright()) JBColor.LIGHT_GRAY else JBColor.DARK_GRAY |
| 48 | + } |
| 49 | + |
| 50 | + /** |
| 51 | + * Return true if the agent is in a connectable state. |
| 52 | + */ |
| 53 | + fun ready(): Boolean { |
| 54 | + return listOf(READY, START_ERROR, AGENT_STARTING_READY, START_TIMEOUT_READY) |
| 55 | + .contains(this) |
| 56 | + } |
| 57 | + |
| 58 | + // We want to check that the workspace is `running`, the agent is |
| 59 | + // `connected`, and the agent lifecycle state is `ready` to ensure the best |
| 60 | + // possible scenario for attempting a connection. |
| 61 | + // |
| 62 | + // We can also choose to allow `start_error` for the agent lifecycle state; |
| 63 | + // this means the startup script did not successfully complete but the agent |
| 64 | + // will still accept SSH connections. |
| 65 | + // |
| 66 | + // Lastly we can also allow connections when the agent lifecycle state is |
| 67 | + // `starting` or `start_timeout` if `login_before_ready` is true on the |
| 68 | + // workspace response since this bypasses the need to wait for the script. |
| 69 | + // |
| 70 | + // Note that latest_build.status is derived from latest_build.job.status and |
| 71 | + // latest_build.job.transition so there is no need to check those. |
| 72 | + companion object { |
| 73 | + fun from(workspace: Workspace, agent: WorkspaceAgent? = null) = when (workspace.latestBuild.status) { |
| 74 | + WorkspaceStatus.PENDING -> QUEUED |
| 75 | + WorkspaceStatus.STARTING -> STARTING |
| 76 | + WorkspaceStatus.RUNNING -> when (agent?.status) { |
| 77 | + WorkspaceAgentStatus.CONNECTED -> when (agent.lifecycleState) { |
| 78 | + WorkspaceAgentLifecycleState.CREATED -> CREATED |
| 79 | + WorkspaceAgentLifecycleState.STARTING -> if (agent.loginBeforeReady == true) AGENT_STARTING_READY else AGENT_STARTING |
| 80 | + WorkspaceAgentLifecycleState.START_TIMEOUT -> if (agent.loginBeforeReady == true) START_TIMEOUT_READY else START_TIMEOUT |
| 81 | + WorkspaceAgentLifecycleState.START_ERROR -> START_ERROR |
| 82 | + WorkspaceAgentLifecycleState.READY -> READY |
| 83 | + WorkspaceAgentLifecycleState.SHUTTING_DOWN -> SHUTTING_DOWN |
| 84 | + WorkspaceAgentLifecycleState.SHUTDOWN_TIMEOUT -> SHUTDOWN_TIMEOUT |
| 85 | + WorkspaceAgentLifecycleState.SHUTDOWN_ERROR -> SHUTDOWN_ERROR |
| 86 | + WorkspaceAgentLifecycleState.OFF -> OFF |
| 87 | + } |
| 88 | + |
| 89 | + WorkspaceAgentStatus.DISCONNECTED -> DISCONNECTED |
| 90 | + WorkspaceAgentStatus.TIMEOUT -> TIMEOUT |
| 91 | + WorkspaceAgentStatus.CONNECTING -> CONNECTING |
| 92 | + else -> RUNNING |
| 93 | + } |
| 94 | + |
| 95 | + WorkspaceStatus.STOPPING -> STOPPING |
| 96 | + WorkspaceStatus.STOPPED -> STOPPED |
| 97 | + WorkspaceStatus.FAILED -> FAILED |
| 98 | + WorkspaceStatus.CANCELING -> CANCELING |
| 99 | + WorkspaceStatus.CANCELED -> CANCELED |
| 100 | + WorkspaceStatus.DELETING -> DELETING |
| 101 | + WorkspaceStatus.DELETED -> DELETED |
| 102 | + } |
| 103 | + |
| 104 | + fun from(str: String) = WorkspaceAndAgentStatus.values().first { it.label.contains(str, true) } |
| 105 | + } |
| 106 | +} |
0 commit comments