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

Commit9b982d9

Browse files
authored
Merge branch 'main' into rowansmithau/feat/db-read-creds-from-file
2 parentsc8f2d05 +e340560 commit9b982d9

File tree

102 files changed

+3766
-1876
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+3766
-1876
lines changed

‎CODEOWNERS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ coderd/schedule/autostop.go @deansheather @DanielleMaywood
2727
# well as guidance from revenue.
2828
coderd/usage/@deansheather@spikecurtis
2929
enterprise/coderd/usage/@deansheather@spikecurtis
30+
31+
.github/@jdomeracki-coder

‎agent/agent.go‎

Lines changed: 56 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"hash/fnv"
1010
"io"
11+
"maps"
1112
"net"
1213
"net/http"
1314
"net/netip"
@@ -70,16 +71,21 @@ const (
7071
)
7172

7273
typeOptionsstruct {
73-
Filesystem afero.Fs
74-
LogDirstring
75-
TempDirstring
76-
ScriptDataDirstring
77-
ClientClient
78-
ReconnectingPTYTimeout time.Duration
79-
EnvironmentVariablesmap[string]string
80-
Logger slog.Logger
81-
IgnorePortsmap[int]string
82-
PortCacheDuration time.Duration
74+
Filesystem afero.Fs
75+
LogDirstring
76+
TempDirstring
77+
ScriptDataDirstring
78+
ClientClient
79+
ReconnectingPTYTimeout time.Duration
80+
EnvironmentVariablesmap[string]string
81+
Logger slog.Logger
82+
// IgnorePorts tells the api handler which ports to ignore when
83+
// listing all listening ports. This is helpful to hide ports that
84+
// are used by the agent, that the user does not care about.
85+
IgnorePortsmap[int]string
86+
// ListeningPortsGetter is used to get the list of listening ports. Only
87+
// tests should set this. If unset, a default that queries the OS will be used.
88+
ListeningPortsGetterListeningPortsGetter
8389
SSHMaxTimeout time.Duration
8490
TailnetListenPortuint16
8591
Subsystems []codersdk.AgentSubsystem
@@ -137,9 +143,7 @@ func New(options Options) Agent {
137143
ifoptions.ServiceBannerRefreshInterval==0 {
138144
options.ServiceBannerRefreshInterval=2*time.Minute
139145
}
140-
ifoptions.PortCacheDuration==0 {
141-
options.PortCacheDuration=1*time.Second
142-
}
146+
143147
ifoptions.Clock==nil {
144148
options.Clock=quartz.NewReal()
145149
}
@@ -153,30 +157,38 @@ func New(options Options) Agent {
153157
options.Execer=agentexec.DefaultExecer
154158
}
155159

160+
ifoptions.ListeningPortsGetter==nil {
161+
options.ListeningPortsGetter=&osListeningPortsGetter{
162+
cacheDuration:1*time.Second,
163+
}
164+
}
165+
156166
hardCtx,hardCancel:=context.WithCancel(context.Background())
157167
gracefulCtx,gracefulCancel:=context.WithCancel(hardCtx)
158168
a:=&agent{
159-
clock:options.Clock,
160-
tailnetListenPort:options.TailnetListenPort,
161-
reconnectingPTYTimeout:options.ReconnectingPTYTimeout,
162-
logger:options.Logger,
163-
gracefulCtx:gracefulCtx,
164-
gracefulCancel:gracefulCancel,
165-
hardCtx:hardCtx,
166-
hardCancel:hardCancel,
167-
coordDisconnected:make(chanstruct{}),
168-
environmentVariables:options.EnvironmentVariables,
169-
client:options.Client,
170-
filesystem:options.Filesystem,
171-
logDir:options.LogDir,
172-
tempDir:options.TempDir,
173-
scriptDataDir:options.ScriptDataDir,
174-
lifecycleUpdate:make(chanstruct{},1),
175-
lifecycleReported:make(chan codersdk.WorkspaceAgentLifecycle,1),
176-
lifecycleStates: []agentsdk.PostLifecycleRequest{{State:codersdk.WorkspaceAgentLifecycleCreated}},
177-
reportConnectionsUpdate:make(chanstruct{},1),
178-
ignorePorts:options.IgnorePorts,
179-
portCacheDuration:options.PortCacheDuration,
169+
clock:options.Clock,
170+
tailnetListenPort:options.TailnetListenPort,
171+
reconnectingPTYTimeout:options.ReconnectingPTYTimeout,
172+
logger:options.Logger,
173+
gracefulCtx:gracefulCtx,
174+
gracefulCancel:gracefulCancel,
175+
hardCtx:hardCtx,
176+
hardCancel:hardCancel,
177+
coordDisconnected:make(chanstruct{}),
178+
environmentVariables:options.EnvironmentVariables,
179+
client:options.Client,
180+
filesystem:options.Filesystem,
181+
logDir:options.LogDir,
182+
tempDir:options.TempDir,
183+
scriptDataDir:options.ScriptDataDir,
184+
lifecycleUpdate:make(chanstruct{},1),
185+
lifecycleReported:make(chan codersdk.WorkspaceAgentLifecycle,1),
186+
lifecycleStates: []agentsdk.PostLifecycleRequest{{State:codersdk.WorkspaceAgentLifecycleCreated}},
187+
reportConnectionsUpdate:make(chanstruct{},1),
188+
listeningPortsHandler:listeningPortsHandler{
189+
getter:options.ListeningPortsGetter,
190+
ignorePorts:maps.Clone(options.IgnorePorts),
191+
},
180192
reportMetadataInterval:options.ReportMetadataInterval,
181193
announcementBannersRefreshInterval:options.ServiceBannerRefreshInterval,
182194
sshMaxTimeout:options.SSHMaxTimeout,
@@ -202,20 +214,16 @@ func New(options Options) Agent {
202214
}
203215

204216
typeagentstruct {
205-
clock quartz.Clock
206-
logger slog.Logger
207-
clientClient
208-
tailnetListenPortuint16
209-
filesystem afero.Fs
210-
logDirstring
211-
tempDirstring
212-
scriptDataDirstring
213-
// ignorePorts tells the api handler which ports to ignore when
214-
// listing all listening ports. This is helpful to hide ports that
215-
// are used by the agent, that the user does not care about.
216-
ignorePortsmap[int]string
217-
portCacheDuration time.Duration
218-
subsystems []codersdk.AgentSubsystem
217+
clock quartz.Clock
218+
logger slog.Logger
219+
clientClient
220+
tailnetListenPortuint16
221+
filesystem afero.Fs
222+
logDirstring
223+
tempDirstring
224+
scriptDataDirstring
225+
listeningPortsHandlerlisteningPortsHandler
226+
subsystems []codersdk.AgentSubsystem
219227

220228
reconnectingPTYTimeout time.Duration
221229
reconnectingPTYServer*reconnectingpty.Server

‎agent/api.go‎

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ package agent
22

33
import (
44
"net/http"
5-
"sync"
6-
"time"
75

86
"github.com/go-chi/chi/v5"
97
"github.com/google/uuid"
108

119
"github.com/coder/coder/v2/coderd/httpapi"
1210
"github.com/coder/coder/v2/codersdk"
11+
"github.com/coder/coder/v2/codersdk/workspacesdk"
1312
)
1413

1514
func (a*agent)apiHandler() http.Handler {
@@ -20,23 +19,6 @@ func (a *agent) apiHandler() http.Handler {
2019
})
2120
})
2221

23-
// Make a copy to ensure the map is not modified after the handler is
24-
// created.
25-
cpy:=make(map[int]string)
26-
fork,b:=rangea.ignorePorts {
27-
cpy[k]=b
28-
}
29-
30-
cacheDuration:=1*time.Second
31-
ifa.portCacheDuration>0 {
32-
cacheDuration=a.portCacheDuration
33-
}
34-
35-
lp:=&listeningPortsHandler{
36-
ignorePorts:cpy,
37-
cacheDuration:cacheDuration,
38-
}
39-
4022
ifa.devcontainers {
4123
r.Mount("/api/v0/containers",a.containerAPI.Routes())
4224
}elseifmanifest:=a.manifest.Load();manifest!=nil&&manifest.ParentID!=uuid.Nil {
@@ -57,7 +39,7 @@ func (a *agent) apiHandler() http.Handler {
5739

5840
promHandler:=PrometheusMetricsHandler(a.prometheusRegistry,a.logger)
5941

60-
r.Get("/api/v0/listening-ports",lp.handler)
42+
r.Get("/api/v0/listening-ports",a.listeningPortsHandler.handler)
6143
r.Get("/api/v0/netcheck",a.HandleNetcheck)
6244
r.Post("/api/v0/list-directory",a.HandleLS)
6345
r.Get("/api/v0/read-file",a.HandleReadFile)
@@ -72,22 +54,21 @@ func (a *agent) apiHandler() http.Handler {
7254
returnr
7355
}
7456

75-
typelisteningPortsHandlerstruct {
76-
ignorePortsmap[int]string
77-
cacheDuration time.Duration
57+
typeListeningPortsGetterinterface {
58+
GetListeningPorts() ([]codersdk.WorkspaceAgentListeningPort,error)
59+
}
7860

79-
//nolint: unused // used on some but not all platforms
80-
mut sync.Mutex
81-
//nolint: unused // used on some but not all platforms
82-
ports []codersdk.WorkspaceAgentListeningPort
83-
//nolint: unused // used on some but not all platforms
84-
mtime time.Time
61+
typelisteningPortsHandlerstruct {
62+
// In production code, this is set to an osListeningPortsGetter, but it can be overridden for
63+
// testing.
64+
getterListeningPortsGetter
65+
ignorePortsmap[int]string
8566
}
8667

8768
// handler returns a list of listening ports. This is tested by coderd's
8869
// TestWorkspaceAgentListeningPorts test.
8970
func (lp*listeningPortsHandler)handler(rw http.ResponseWriter,r*http.Request) {
90-
ports,err:=lp.getListeningPorts()
71+
ports,err:=lp.getter.GetListeningPorts()
9172
iferr!=nil {
9273
httpapi.Write(r.Context(),rw,http.StatusInternalServerError, codersdk.Response{
9374
Message:"Could not scan for listening ports.",
@@ -96,7 +77,20 @@ func (lp *listeningPortsHandler) handler(rw http.ResponseWriter, r *http.Request
9677
return
9778
}
9879

80+
filteredPorts:=make([]codersdk.WorkspaceAgentListeningPort,0,len(ports))
81+
for_,port:=rangeports {
82+
ifport.Port<workspacesdk.AgentMinimumListeningPort {
83+
continue
84+
}
85+
86+
// Ignore ports that we've been told to ignore.
87+
if_,ok:=lp.ignorePorts[int(port.Port)];ok {
88+
continue
89+
}
90+
filteredPorts=append(filteredPorts,port)
91+
}
92+
9993
httpapi.Write(r.Context(),rw,http.StatusOK, codersdk.WorkspaceAgentListeningPortsResponse{
100-
Ports:ports,
94+
Ports:filteredPorts,
10195
})
10296
}

‎agent/ports_supported.go‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@
33
package agent
44

55
import (
6+
"sync"
67
"time"
78

89
"github.com/cakturk/go-netstat/netstat"
910
"golang.org/x/xerrors"
1011

1112
"github.com/coder/coder/v2/codersdk"
12-
"github.com/coder/coder/v2/codersdk/workspacesdk"
1313
)
1414

15-
func (lp*listeningPortsHandler)getListeningPorts() ([]codersdk.WorkspaceAgentListeningPort,error) {
15+
typeosListeningPortsGetterstruct {
16+
cacheDuration time.Duration
17+
mut sync.Mutex
18+
ports []codersdk.WorkspaceAgentListeningPort
19+
mtime time.Time
20+
}
21+
22+
func (lp*osListeningPortsGetter)GetListeningPorts() ([]codersdk.WorkspaceAgentListeningPort,error) {
1623
lp.mut.Lock()
1724
deferlp.mut.Unlock()
1825

@@ -33,12 +40,7 @@ func (lp *listeningPortsHandler) getListeningPorts() ([]codersdk.WorkspaceAgentL
3340
seen:=make(map[uint16]struct{},len(tabs))
3441
ports:= []codersdk.WorkspaceAgentListeningPort{}
3542
for_,tab:=rangetabs {
36-
iftab.LocalAddr==nil||tab.LocalAddr.Port<workspacesdk.AgentMinimumListeningPort {
37-
continue
38-
}
39-
40-
// Ignore ports that we've been told to ignore.
41-
if_,ok:=lp.ignorePorts[int(tab.LocalAddr.Port)];ok {
43+
iftab.LocalAddr==nil {
4244
continue
4345
}
4446

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//go:build linux || (windows && amd64)
2+
3+
package agent
4+
5+
import (
6+
"net"
7+
"testing"
8+
"time"
9+
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
funcTestOSListeningPortsGetter(t*testing.T) {
14+
t.Parallel()
15+
16+
uut:=&osListeningPortsGetter{
17+
cacheDuration:1*time.Hour,
18+
}
19+
20+
l,err:=net.Listen("tcp","localhost:0")
21+
require.NoError(t,err)
22+
deferl.Close()
23+
24+
ports,err:=uut.GetListeningPorts()
25+
require.NoError(t,err)
26+
found:=false
27+
for_,port:=rangeports {
28+
// #nosec G115 - Safe conversion as TCP port numbers are within uint16 range (0-65535)
29+
ifport.Port==uint16(l.Addr().(*net.TCPAddr).Port) {
30+
found=true
31+
break
32+
}
33+
}
34+
require.True(t,found)
35+
36+
// check that we cache the ports
37+
err=l.Close()
38+
require.NoError(t,err)
39+
portsNew,err:=uut.GetListeningPorts()
40+
require.NoError(t,err)
41+
require.Equal(t,ports,portsNew)
42+
43+
// note that it's unsafe to try to assert that a port does not exist in the response
44+
// because the OS may reallocate the port very quickly.
45+
}

‎agent/ports_unsupported.go‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,17 @@
22

33
package agent
44

5-
import"github.com/coder/coder/v2/codersdk"
5+
import (
6+
"time"
67

7-
func (*listeningPortsHandler)getListeningPorts() ([]codersdk.WorkspaceAgentListeningPort,error) {
8+
"github.com/coder/coder/v2/codersdk"
9+
)
10+
11+
typeosListeningPortsGetterstruct {
12+
cacheDuration time.Duration
13+
}
14+
15+
func (*osListeningPortsGetter)GetListeningPorts() ([]codersdk.WorkspaceAgentListeningPort,error) {
816
// Can't scan for ports on non-linux or non-windows_amd64 systems at the
917
// moment. The UI will not show any "no ports found" message to the user, so
1018
// the user won't suspect a thing.

‎cli/root.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ func (r *RootCmd) CoreSubcommands() []*serpent.Command {
104104
r.resetPassword(),
105105
r.sharing(),
106106
r.state(),
107+
r.tasksCommand(),
107108
r.templates(),
108109
r.tokens(),
109110
r.users(),
@@ -149,7 +150,6 @@ func (r *RootCmd) AGPLExperimental() []*serpent.Command {
149150
r.mcpCommand(),
150151
r.promptExample(),
151152
r.rptyCommand(),
152-
r.tasksCommand(),
153153
r.boundary(),
154154
}
155155
}

‎cli/exp_task.go‎renamed to ‎cli/task.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ func (r *RootCmd) tasksCommand() *serpent.Command {
88
cmd:=&serpent.Command{
99
Use:"task",
1010
Aliases: []string{"tasks"},
11-
Short:"Experimental task commands.",
11+
Short:"Manage tasks",
1212
Handler:func(i*serpent.Invocation)error {
1313
returni.Command.HelpHandler(i)
1414
},

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp