Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit695d552

Browse files
authored
feat(cli): add display of open ports in coder show (#16464)
Relates to#16418 -- devcontainerswill be shown in a similar manner.Without ports (status quo):![Screenshot 2025-02-10 at 12 5046](https://github.com/user-attachments/assets/c25fd532-2e35-469c-bb28-26e59ded3eb4)With ports:![Screenshot 2025-02-10 at 12 5006](https://github.com/user-attachments/assets/a4671349-5866-4e1e-848e-a6e819479793)
1 parente9b3561 commit695d552

File tree

2 files changed

+100
-26
lines changed

2 files changed

+100
-26
lines changed

‎cli/cliui/resources.go

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"io"
66
"sort"
77
"strconv"
8+
"strings"
89

10+
"github.com/google/uuid"
911
"github.com/jedib0t/go-pretty/v6/table"
1012
"golang.org/x/mod/semver"
1113

@@ -14,12 +16,18 @@ import (
1416
"github.com/coder/pretty"
1517
)
1618

19+
var (
20+
pipeMid="├"
21+
pipeEnd="└"
22+
)
23+
1724
typeWorkspaceResourcesOptionsstruct {
1825
WorkspaceNamestring
1926
HideAgentStatebool
2027
HideAccessbool
2128
Titlestring
2229
ServerVersionstring
30+
ListeningPortsmap[uuid.UUID]codersdk.WorkspaceAgentListeningPortsResponse
2331
}
2432

2533
// WorkspaceResources displays the connection status and tree-view of provided resources.
@@ -86,39 +94,61 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource
8694
})
8795
// Display all agents associated with the resource.
8896
forindex,agent:=rangeresource.Agents {
89-
pipe:="├"
90-
ifindex==len(resource.Agents)-1 {
91-
pipe="└"
92-
}
93-
row:= table.Row{
94-
// These tree from a resource!
95-
fmt.Sprintf("%s─ %s (%s, %s)",pipe,agent.Name,agent.OperatingSystem,agent.Architecture),
96-
}
97-
if!options.HideAgentState {
98-
varagentStatus,agentHealth,agentVersionstring
99-
if!options.HideAgentState {
100-
agentStatus=renderAgentStatus(agent)
101-
agentHealth=renderAgentHealth(agent)
102-
agentVersion=renderAgentVersion(agent.Version,options.ServerVersion)
103-
}
104-
row=append(row,agentStatus,agentHealth,agentVersion)
105-
}
106-
if!options.HideAccess {
107-
sshCommand:="coder ssh "+options.WorkspaceName
108-
iftotalAgents>1 {
109-
sshCommand+="."+agent.Name
97+
tableWriter.AppendRow(renderAgentRow(agent,index,totalAgents,options))
98+
ifoptions.ListeningPorts!=nil {
99+
iflp,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:=rangelp.Ports {
104+
tableWriter.AppendRow(renderPortRow(port,index,totalAgents))
105+
}
110106
}
111-
sshCommand=pretty.Sprint(DefaultStyles.Code,sshCommand)
112-
row=append(row,sshCommand)
113107
}
114-
tableWriter.AppendRow(row)
115108
}
116109
tableWriter.AppendSeparator()
117110
}
118111
_,err:=fmt.Fprintln(writer,tableWriter.Render())
119112
returnerr
120113
}
121114

115+
funcrenderAgentRow(agent codersdk.WorkspaceAgent,index,totalAgentsint,optionsWorkspaceResourcesOptions) table.Row {
116+
row:= table.Row{
117+
// These tree from a resource!
118+
fmt.Sprintf("%s─ %s (%s, %s)",renderPipe(index,totalAgents),agent.Name,agent.OperatingSystem,agent.Architecture),
119+
}
120+
if!options.HideAgentState {
121+
varagentStatus,agentHealth,agentVersionstring
122+
if!options.HideAgentState {
123+
agentStatus=renderAgentStatus(agent)
124+
agentHealth=renderAgentHealth(agent)
125+
agentVersion=renderAgentVersion(agent.Version,options.ServerVersion)
126+
}
127+
row=append(row,agentStatus,agentHealth,agentVersion)
128+
}
129+
if!options.HideAccess {
130+
sshCommand:="coder ssh "+options.WorkspaceName
131+
iftotalAgents>1 {
132+
sshCommand+="."+agent.Name
133+
}
134+
sshCommand=pretty.Sprint(DefaultStyles.Code,sshCommand)
135+
row=append(row,sshCommand)
136+
}
137+
returnrow
138+
}
139+
140+
funcrenderPortRow(port codersdk.WorkspaceAgentListeningPort,index,totalPortsint) table.Row {
141+
varsb strings.Builder
142+
_,_=sb.WriteString(" ")
143+
_,_=sb.WriteString(renderPipe(index,totalPorts))
144+
_,_=sb.WriteString("─ ")
145+
_,_=sb.WriteString(pretty.Sprintf(DefaultStyles.Code,"%5d/%s",port.Port,port.Network))
146+
ifport.ProcessName!="" {
147+
_,_=sb.WriteString(pretty.Sprintf(DefaultStyles.Keyword," [%s]",port.ProcessName))
148+
}
149+
return table.Row{sb.String()}
150+
}
151+
122152
funcrenderAgentStatus(agent codersdk.WorkspaceAgent)string {
123153
switchagent.Status {
124154
casecodersdk.WorkspaceAgentConnecting:
@@ -163,3 +193,10 @@ func renderAgentVersion(agentVersion, serverVersion string) string {
163193
}
164194
returnpretty.Sprint(DefaultStyles.Keyword,agentVersion)
165195
}
196+
197+
funcrenderPipe(idx,totalint)string {
198+
ifidx==total-1 {
199+
returnpipeEnd
200+
}
201+
returnpipeMid
202+
}

‎cli/show.go

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package cli
22

33
import (
4+
"sort"
5+
"sync"
6+
47
"golang.org/x/xerrors"
58

9+
"github.com/google/uuid"
10+
611
"github.com/coder/coder/v2/cli/cliui"
712
"github.com/coder/coder/v2/codersdk"
813
"github.com/coder/serpent"
@@ -26,10 +31,42 @@ func (r *RootCmd) show() *serpent.Command {
2631
iferr!=nil {
2732
returnxerrors.Errorf("get workspace: %w",err)
2833
}
29-
returncliui.WorkspaceResources(inv.Stdout,workspace.LatestBuild.Resources, cliui.WorkspaceResourcesOptions{
34+
35+
options:= cliui.WorkspaceResourcesOptions{
3036
WorkspaceName:workspace.Name,
3137
ServerVersion:buildInfo.Version,
32-
})
38+
}
39+
ifworkspace.LatestBuild.Status==codersdk.WorkspaceStatusRunning {
40+
// Get listening ports for each agent.
41+
options.ListeningPorts=fetchListeningPorts(inv,client,workspace.LatestBuild.Resources...)
42+
}
43+
returncliui.WorkspaceResources(inv.Stdout,workspace.LatestBuild.Resources,options)
3344
},
3445
}
3546
}
47+
48+
funcfetchListeningPorts(inv*serpent.Invocation,client*codersdk.Client,resources...codersdk.WorkspaceResource)map[uuid.UUID]codersdk.WorkspaceAgentListeningPortsResponse {
49+
ports:=make(map[uuid.UUID]codersdk.WorkspaceAgentListeningPortsResponse)
50+
varwg sync.WaitGroup
51+
varmu sync.Mutex
52+
for_,res:=rangeresources {
53+
for_,agent:=rangeres.Agents {
54+
wg.Add(1)
55+
gofunc() {
56+
deferwg.Done()
57+
lp,err:=client.WorkspaceAgentListeningPorts(inv.Context(),agent.ID)
58+
iferr!=nil {
59+
cliui.Warnf(inv.Stderr,"Failed to get listening ports for agent %s: %v",agent.Name,err)
60+
}
61+
sort.Slice(lp.Ports,func(i,jint)bool {
62+
returnlp.Ports[i].Port<lp.Ports[j].Port
63+
})
64+
mu.Lock()
65+
ports[agent.ID]=lp
66+
mu.Unlock()
67+
}()
68+
}
69+
}
70+
wg.Wait()
71+
returnports
72+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp