@@ -28,6 +28,7 @@ type WorkspaceResourcesOptions struct {
28
28
Title string
29
29
ServerVersion string
30
30
ListeningPorts map [uuid.UUID ]codersdk.WorkspaceAgentListeningPortsResponse
31
+ Devcontainers map [uuid.UUID ]codersdk.WorkspaceAgentListContainersResponse
31
32
}
32
33
33
34
// WorkspaceResources displays the connection status and tree-view of provided resources.
@@ -95,15 +96,11 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource
95
96
// Display all agents associated with the resource.
96
97
for index , agent := range resource .Agents {
97
98
tableWriter .AppendRow (renderAgentRow (agent , index , totalAgents , options ))
98
- if options .ListeningPorts != nil {
99
- if lp , ok := options .ListeningPorts [agent .ID ]; ok && len (lp .Ports ) > 0 {
100
- tableWriter .AppendRow (table.Row {
101
- fmt .Sprintf (" %s─ %s" , renderPipe (index , totalAgents ), "Open Ports" ),
102
- })
103
- for _ , port := range lp .Ports {
104
- tableWriter .AppendRow (renderPortRow (port , index , totalAgents ))
105
- }
106
- }
99
+ for _ , row := range renderListeningPorts (options , agent .ID , index , totalAgents ) {
100
+ tableWriter .AppendRow (row )
101
+ }
102
+ for _ , row := range renderDevcontainers (options , agent .ID , index , totalAgents ) {
103
+ tableWriter .AppendRow (row )
107
104
}
108
105
}
109
106
tableWriter .AppendSeparator ()
@@ -137,10 +134,28 @@ func renderAgentRow(agent codersdk.WorkspaceAgent, index, totalAgents int, optio
137
134
return row
138
135
}
139
136
140
- func renderPortRow (port codersdk.WorkspaceAgentListeningPort , index , totalPorts int ) table.Row {
137
+ func renderListeningPorts (wro WorkspaceResourcesOptions , agentID uuid.UUID , idx , total int ) []table.Row {
138
+ var rows []table.Row
139
+ if wro .ListeningPorts == nil {
140
+ return []table.Row {}
141
+ }
142
+ lp , ok := wro .ListeningPorts [agentID ]
143
+ if ! ok || len (lp .Ports ) == 0 {
144
+ return []table.Row {}
145
+ }
146
+ rows = append (rows , table.Row {
147
+ fmt .Sprintf (" %s─ Open Ports" , renderPipe (idx , total )),
148
+ })
149
+ for idx , port := range lp .Ports {
150
+ rows = append (rows , renderPortRow (port , idx , len (lp .Ports )))
151
+ }
152
+ return rows
153
+ }
154
+
155
+ func renderPortRow (port codersdk.WorkspaceAgentListeningPort , idx , total int ) table.Row {
141
156
var sb strings.Builder
142
157
_ , _ = sb .WriteString (" " )
143
- _ , _ = sb .WriteString (renderPipe (index , totalPorts ))
158
+ _ , _ = sb .WriteString (renderPipe (idx , total ))
144
159
_ , _ = sb .WriteString ("─ " )
145
160
_ , _ = sb .WriteString (pretty .Sprintf (DefaultStyles .Code , "%5d/%s" , port .Port , port .Network ))
146
161
if port .ProcessName != "" {
@@ -149,6 +164,47 @@ func renderPortRow(port codersdk.WorkspaceAgentListeningPort, index, totalPorts
149
164
return table.Row {sb .String ()}
150
165
}
151
166
167
+ func renderDevcontainers (wro WorkspaceResourcesOptions , agentID uuid.UUID , index , totalAgents int ) []table.Row {
168
+ var rows []table.Row
169
+ if wro .Devcontainers == nil {
170
+ return []table.Row {}
171
+ }
172
+ dc , ok := wro .Devcontainers [agentID ]
173
+ if ! ok || len (dc .Containers ) == 0 {
174
+ return []table.Row {}
175
+ }
176
+ rows = append (rows , table.Row {
177
+ fmt .Sprintf (" %s─ %s" , renderPipe (index , totalAgents ), "Devcontainers" ),
178
+ })
179
+ for idx , container := range dc .Containers {
180
+ rows = append (rows , renderDevcontainerRow (container , idx , len (dc .Containers )))
181
+ }
182
+ return rows
183
+ }
184
+
185
+ func renderDevcontainerRow (container codersdk.WorkspaceAgentDevcontainer , index , total int ) table.Row {
186
+ var row table.Row
187
+ var sb strings.Builder
188
+ _ , _ = sb .WriteString (" " )
189
+ _ , _ = sb .WriteString (renderPipe (index , total ))
190
+ _ , _ = sb .WriteString ("─ " )
191
+ _ , _ = sb .WriteString (pretty .Sprintf (DefaultStyles .Code , "%s" , container .FriendlyName ))
192
+ row = append (row , sb .String ())
193
+ sb .Reset ()
194
+ if container .Running {
195
+ _ , _ = sb .WriteString (pretty .Sprintf (DefaultStyles .Keyword , "(%s)" , container .Status ))
196
+ } else {
197
+ _ , _ = sb .WriteString (pretty .Sprintf (DefaultStyles .Error , "(%s)" , container .Status ))
198
+ }
199
+ row = append (row , sb .String ())
200
+ sb .Reset ()
201
+ // "health" is not applicable here.
202
+ row = append (row , sb .String ())
203
+ _ , _ = sb .WriteString (container .Image )
204
+ row = append (row , sb .String ())
205
+ return row
206
+ }
207
+
152
208
func renderAgentStatus (agent codersdk.WorkspaceAgent ) string {
153
209
switch agent .Status {
154
210
case codersdk .WorkspaceAgentConnecting :
0 commit comments