mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: show agent version in UI and CLI (#3709)
This commit adds the ability for agents to set their version upon start. This is then reported in the UI and CLI.
This commit is contained in:
+38
-13
@@ -7,6 +7,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/jedib0t/go-pretty/v6/table"
|
||||
"golang.org/x/mod/semver"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
|
||||
@@ -18,6 +19,7 @@ type WorkspaceResourcesOptions struct {
|
||||
HideAgentState bool
|
||||
HideAccess bool
|
||||
Title string
|
||||
ServerVersion string
|
||||
}
|
||||
|
||||
// WorkspaceResources displays the connection status and tree-view of provided resources.
|
||||
@@ -48,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, "Version")
|
||||
}
|
||||
if !options.HideAccess {
|
||||
row = append(row, "Access")
|
||||
@@ -91,21 +94,12 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource
|
||||
}
|
||||
if !options.HideAgentState {
|
||||
var agentStatus string
|
||||
var agentVersion string
|
||||
if !options.HideAgentState {
|
||||
switch agent.Status {
|
||||
case codersdk.WorkspaceAgentConnecting:
|
||||
since := database.Now().Sub(agent.CreatedAt)
|
||||
agentStatus = Styles.Warn.Render("⦾ connecting") + " " +
|
||||
Styles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]")
|
||||
case codersdk.WorkspaceAgentDisconnected:
|
||||
since := database.Now().Sub(*agent.DisconnectedAt)
|
||||
agentStatus = Styles.Error.Render("⦾ disconnected") + " " +
|
||||
Styles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]")
|
||||
case codersdk.WorkspaceAgentConnected:
|
||||
agentStatus = Styles.Keyword.Render("⦿ connected")
|
||||
}
|
||||
agentStatus = renderAgentStatus(agent)
|
||||
agentVersion = renderAgentVersion(agent.Version, options.ServerVersion)
|
||||
}
|
||||
row = append(row, agentStatus)
|
||||
row = append(row, agentStatus, agentVersion)
|
||||
}
|
||||
if !options.HideAccess {
|
||||
sshCommand := "coder ssh " + options.WorkspaceName
|
||||
@@ -122,3 +116,34 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource
|
||||
_, err := fmt.Fprintln(writer, tableWriter.Render())
|
||||
return err
|
||||
}
|
||||
|
||||
func renderAgentStatus(agent codersdk.WorkspaceAgent) string {
|
||||
switch agent.Status {
|
||||
case codersdk.WorkspaceAgentConnecting:
|
||||
since := database.Now().Sub(agent.CreatedAt)
|
||||
return Styles.Warn.Render("⦾ connecting") + " " +
|
||||
Styles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]")
|
||||
case codersdk.WorkspaceAgentDisconnected:
|
||||
since := database.Now().Sub(*agent.DisconnectedAt)
|
||||
return Styles.Error.Render("⦾ disconnected") + " " +
|
||||
Styles.Placeholder.Render("["+strconv.Itoa(int(since.Seconds()))+"s]")
|
||||
case codersdk.WorkspaceAgentConnected:
|
||||
return Styles.Keyword.Render("⦿ connected")
|
||||
default:
|
||||
return Styles.Warn.Render("○ unknown")
|
||||
}
|
||||
}
|
||||
|
||||
func renderAgentVersion(agentVersion, serverVersion string) string {
|
||||
if agentVersion == "" {
|
||||
agentVersion = "(unknown)"
|
||||
}
|
||||
if !semver.IsValid(serverVersion) || !semver.IsValid(agentVersion) {
|
||||
return Styles.Placeholder.Render(agentVersion)
|
||||
}
|
||||
outdated := semver.Compare(agentVersion, serverVersion) < 0
|
||||
if outdated {
|
||||
return Styles.Warn.Render(agentVersion + " (outdated)")
|
||||
}
|
||||
return Styles.Keyword.Render(agentVersion)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package cliui
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRenderAgentVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCases := []struct {
|
||||
name string
|
||||
agentVersion string
|
||||
serverVersion string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "OK",
|
||||
agentVersion: "v1.2.3",
|
||||
serverVersion: "v1.2.3",
|
||||
expected: "v1.2.3",
|
||||
},
|
||||
{
|
||||
name: "Outdated",
|
||||
agentVersion: "v1.2.3",
|
||||
serverVersion: "v1.2.4",
|
||||
expected: "v1.2.3 (outdated)",
|
||||
},
|
||||
{
|
||||
name: "AgentUnknown",
|
||||
agentVersion: "",
|
||||
serverVersion: "v1.2.4",
|
||||
expected: "(unknown)",
|
||||
},
|
||||
{
|
||||
name: "ServerUnknown",
|
||||
agentVersion: "v1.2.3",
|
||||
serverVersion: "",
|
||||
expected: "v1.2.3",
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
testCase := testCase
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
actual := renderAgentVersion(testCase.agentVersion, testCase.serverVersion)
|
||||
assert.Equal(t, testCase.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user