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

Commit2abae42

Browse files
authored
feat: Ignore agent pprof port in listening ports (#6515)
* feat: Ignore agent pprof port in listening ports
1 parent3de2930 commit2abae42

File tree

5 files changed

+126
-5
lines changed

5 files changed

+126
-5
lines changed

‎agent/agent.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ type Options struct {
7777
ReconnectingPTYTimeout time.Duration
7878
EnvironmentVariablesmap[string]string
7979
Logger slog.Logger
80+
AgentPortsmap[int]string
8081
}
8182

8283
typeClientinterface {
@@ -123,6 +124,7 @@ func New(options Options) io.Closer {
123124
tempDir:options.TempDir,
124125
lifecycleUpdate:make(chanstruct{},1),
125126
lifecycleReported:make(chan codersdk.WorkspaceAgentLifecycle,1),
127+
ignorePorts:options.AgentPorts,
126128
connStatsChan:make(chan*agentsdk.Stats,1),
127129
}
128130
a.init(ctx)
@@ -136,6 +138,10 @@ type agent struct {
136138
filesystem afero.Fs
137139
logDirstring
138140
tempDirstring
141+
// ignorePorts tells the api handler which ports to ignore when
142+
// listing all listening ports. This is helpful to hide ports that
143+
// are used by the agent, that the user does not care about.
144+
ignorePortsmap[int]string
139145

140146
reconnectingPTYs sync.Map
141147
reconnectingPTYTimeout time.Duration

‎agent/api.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,32 @@ import (
1111
"github.com/coder/coder/codersdk"
1212
)
1313

14-
func (*agent)apiHandler() http.Handler {
14+
func (a*agent)apiHandler() http.Handler {
1515
r:=chi.NewRouter()
1616
r.Get("/",func(rw http.ResponseWriter,r*http.Request) {
1717
httpapi.Write(r.Context(),rw,http.StatusOK, codersdk.Response{
1818
Message:"Hello from the agent!",
1919
})
2020
})
2121

22-
lp:=&listeningPortsHandler{}
22+
// Make a copy to ensure the map is not modified after the handler is
23+
// created.
24+
cpy:=make(map[int]string)
25+
fork,b:=rangea.ignorePorts {
26+
cpy[k]=b
27+
}
28+
29+
lp:=&listeningPortsHandler{ignorePorts:cpy}
2330
r.Get("/api/v0/listening-ports",lp.handler)
2431

2532
returnr
2633
}
2734

2835
typelisteningPortsHandlerstruct {
29-
mut sync.Mutex
30-
ports []codersdk.WorkspaceAgentListeningPort
31-
mtime time.Time
36+
mut sync.Mutex
37+
ports []codersdk.WorkspaceAgentListeningPort
38+
mtime time.Time
39+
ignorePortsmap[int]string
3240
}
3341

3442
// handler returns a list of listening ports. This is tested by coderd's

‎agent/ports_supported.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ func (lp *listeningPortsHandler) getListeningPorts() ([]codersdk.WorkspaceAgentL
3636
continue
3737
}
3838

39+
// Ignore ports that we've been told to ignore.
40+
if_,ok:=lp.ignorePorts[int(tab.LocalAddr.Port)];ok {
41+
continue
42+
}
43+
3944
// Don't include ports that we've already seen. This can happen on
4045
// Windows, and maybe on Linux if you're using a shared listener socket.
4146
if_,ok:=seen[tab.LocalAddr.Port];ok {

‎cli/agent.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"os/signal"
1212
"path/filepath"
1313
"runtime"
14+
"strconv"
1415
"sync"
1516
"time"
1617

@@ -51,6 +52,7 @@ func workspaceAgent() *cobra.Command {
5152
iferr!=nil {
5253
returnxerrors.Errorf("parse %q: %w",rawURL,err)
5354
}
55+
agentPorts:=map[int]string{}
5456

5557
isLinux:=runtime.GOOS=="linux"
5658

@@ -122,6 +124,10 @@ func workspaceAgent() *cobra.Command {
122124
_=pprof.Handler
123125
pprofSrvClose:=serveHandler(ctx,logger,nil,pprofAddress,"pprof")
124126
deferpprofSrvClose()
127+
// Do a best effort here. If this fails, it's not a big deal.
128+
ifport,err:=urlPort(pprofAddress);err==nil {
129+
agentPorts[port]="pprof"
130+
}
125131

126132
// exchangeToken returns a session token.
127133
// This is abstracted to allow for the same looping condition
@@ -202,6 +208,7 @@ func workspaceAgent() *cobra.Command {
202208
EnvironmentVariables:map[string]string{
203209
"GIT_ASKPASS":executablePath,
204210
},
211+
AgentPorts:agentPorts,
205212
})
206213
<-ctx.Done()
207214
returncloser.Close()
@@ -264,3 +271,35 @@ func (c *closeWriter) Write(p []byte) (int, error) {
264271
}
265272
returnc.w.Write(p)
266273
}
274+
275+
// extractPort handles different url strings.
276+
// - localhost:6060
277+
// - http://localhost:6060
278+
funcextractPort(ustring) (int,error) {
279+
port,firstError:=urlPort(u)
280+
iffirstError==nil {
281+
returnport,nil
282+
}
283+
284+
// Try with a scheme
285+
port,err:=urlPort("http://"+u)
286+
iferr==nil {
287+
returnport,nil
288+
}
289+
return-1,xerrors.Errorf("invalid url %q: %w",u,firstError)
290+
}
291+
292+
// urlPort extracts the port from a valid URL.
293+
funcurlPort(ustring) (int,error) {
294+
parsed,err:=url.Parse(u)
295+
iferr!=nil {
296+
return-1,xerrors.Errorf("invalid url %q: %w",u,err)
297+
}
298+
ifparsed.Port()!="" {
299+
port,err:=strconv.ParseInt(parsed.Port(),10,64)
300+
iferr==nil&&port>0 {
301+
returnint(port),nil
302+
}
303+
}
304+
return-1,xerrors.Errorf("invalid port: %s",u)
305+
}

‎cli/agent_internal_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
funcTest_extractPort(t*testing.T) {
11+
t.Parallel()
12+
13+
tests:= []struct {
14+
namestring
15+
urlStringstring
16+
wantint
17+
wantErrbool
18+
}{
19+
{
20+
name:"Empty",
21+
urlString:"",
22+
wantErr:true,
23+
},
24+
{
25+
name:"NoScheme",
26+
urlString:"localhost:6060",
27+
want:6060,
28+
},
29+
{
30+
name:"WithScheme",
31+
urlString:"http://localhost:6060",
32+
want:6060,
33+
},
34+
{
35+
name:"NoPort",
36+
urlString:"http://localhost",
37+
wantErr:true,
38+
},
39+
{
40+
name:"NoPortNoScheme",
41+
urlString:"localhost",
42+
wantErr:true,
43+
},
44+
{
45+
name:"OnlyPort",
46+
urlString:"6060",
47+
wantErr:true,
48+
},
49+
}
50+
for_,tt:=rangetests {
51+
tt:=tt
52+
t.Run(tt.name,func(t*testing.T) {
53+
t.Parallel()
54+
got,err:=extractPort(tt.urlString)
55+
iftt.wantErr {
56+
require.Error(t,err,fmt.Sprintf("extractPort(%v)",tt.urlString))
57+
}else {
58+
require.NoError(t,err,fmt.Sprintf("extractPort(%v)",tt.urlString))
59+
require.Equal(t,tt.want,got,fmt.Sprintf("extractPort(%v)",tt.urlString))
60+
}
61+
})
62+
}
63+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp