diff --git a/cli/cliui/resources.go b/cli/cliui/resources.go index def5d6942bcb3..586d37eb5cc81 100644 --- a/cli/cliui/resources.go +++ b/cli/cliui/resources.go @@ -50,6 +50,7 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource row := table.Row{"Resource"} if !options.HideAgentState { row = append(row, "Status") + row = append(row, "Health") row = append(row, "Version") } if !options.HideAccess { @@ -81,6 +82,7 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource DefaultStyles.Bold.Render(resourceAddress), "", "", + "", }) // Display all agents associated with the resource. for index, agent := range resource.Agents { @@ -93,13 +95,13 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource fmt.Sprintf("%s─ %s (%s, %s)", pipe, agent.Name, agent.OperatingSystem, agent.Architecture), } if !options.HideAgentState { - var agentStatus string - var agentVersion string + var agentStatus, agentHealth, agentVersion string if !options.HideAgentState { agentStatus = renderAgentStatus(agent) + agentHealth = renderAgentHealth(agent) agentVersion = renderAgentVersion(agent.Version, options.ServerVersion) } - row = append(row, agentStatus, agentVersion) + row = append(row, agentStatus, agentHealth, agentVersion) } if !options.HideAccess { sshCommand := "coder ssh " + options.WorkspaceName @@ -141,6 +143,13 @@ func renderAgentStatus(agent codersdk.WorkspaceAgent) string { } } +func renderAgentHealth(agent codersdk.WorkspaceAgent) string { + if agent.Health.Healthy { + return DefaultStyles.Keyword.Render("āœ” healthy") + } + return DefaultStyles.Error.Render("✘ " + agent.Health.Reason) +} + func renderAgentVersion(agentVersion, serverVersion string) string { if agentVersion == "" { agentVersion = "(unknown)" diff --git a/cli/cliui/resources_test.go b/cli/cliui/resources_test.go index 59d5120a66291..c9d87c258a6e4 100644 --- a/cli/cliui/resources_test.go +++ b/cli/cliui/resources_test.go @@ -29,6 +29,7 @@ func TestWorkspaceResources(t *testing.T) { LifecycleState: codersdk.WorkspaceAgentLifecycleCreated, Architecture: "amd64", OperatingSystem: "linux", + Health: codersdk.WorkspaceAgentHealth{Healthy: true}, }}, }}, cliui.WorkspaceResourcesOptions{ WorkspaceName: "example", @@ -65,6 +66,7 @@ func TestWorkspaceResources(t *testing.T) { Name: "dev", OperatingSystem: "linux", Architecture: "amd64", + Health: codersdk.WorkspaceAgentHealth{Healthy: true}, }}, }, { Transition: codersdk.WorkspaceTransitionStart, @@ -76,6 +78,7 @@ func TestWorkspaceResources(t *testing.T) { Name: "go", Architecture: "amd64", OperatingSystem: "linux", + Health: codersdk.WorkspaceAgentHealth{Healthy: true}, }, { DisconnectedAt: &disconnected, Status: codersdk.WorkspaceAgentDisconnected, @@ -83,6 +86,10 @@ func TestWorkspaceResources(t *testing.T) { Name: "postgres", Architecture: "amd64", OperatingSystem: "linux", + Health: codersdk.WorkspaceAgentHealth{ + Healthy: false, + Reason: "agent has lost connection", + }, }}, }}, cliui.WorkspaceResourcesOptions{ WorkspaceName: "dev", @@ -94,6 +101,12 @@ func TestWorkspaceResources(t *testing.T) { }() ptty.ExpectMatch("google_compute_disk.root") ptty.ExpectMatch("google_compute_instance.dev") + ptty.ExpectMatch("healthy") + ptty.ExpectMatch("coder ssh dev.dev") + ptty.ExpectMatch("kubernetes_pod.dev") + ptty.ExpectMatch("healthy") + ptty.ExpectMatch("coder ssh dev.go") + ptty.ExpectMatch("agent has lost connection") ptty.ExpectMatch("coder ssh dev.postgres") <-done })