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

Commit4432cd0

Browse files
authored
chore: update tailscale (#6091)
1 parente6da7af commit4432cd0

File tree

11 files changed

+250
-184
lines changed

11 files changed

+250
-184
lines changed

‎agent/agent.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ type Options struct {
7272
typeClientinterface {
7373
Metadata(ctx context.Context) (agentsdk.Metadata,error)
7474
Listen(ctx context.Context) (net.Conn,error)
75-
ReportStats(ctx context.Context,log slog.Logger,statsfunc()*agentsdk.Stats) (io.Closer,error)
75+
ReportStats(ctx context.Context,log slog.Logger,statsChan<-chan*agentsdk.Stats,setIntervalfunc(time.Duration)) (io.Closer,error)
7676
PostLifecycle(ctx context.Context,state agentsdk.PostLifecycleRequest)error
7777
PostAppHealth(ctx context.Context,req agentsdk.PostAppHealthsRequest)error
7878
PostStartup(ctx context.Context,req agentsdk.PostStartupRequest)error
@@ -112,6 +112,7 @@ func New(options Options) io.Closer {
112112
logDir:options.LogDir,
113113
tempDir:options.TempDir,
114114
lifecycleUpdate:make(chanstruct{},1),
115+
connStatsChan:make(chan*agentsdk.Stats,1),
115116
}
116117
a.init(ctx)
117118
returna
@@ -143,7 +144,8 @@ type agent struct {
143144
lifecycleMu sync.Mutex// Protects following.
144145
lifecycleState codersdk.WorkspaceAgentLifecycle
145146

146-
network*tailnet.Conn
147+
network*tailnet.Conn
148+
connStatsChanchan*agentsdk.Stats
147149
}
148150

149151
// runLoop attempts to start the agent in a retry loop.
@@ -351,11 +353,20 @@ func (a *agent) run(ctx context.Context) error {
351353
returnxerrors.New("agent is closed")
352354
}
353355

356+
setStatInterval:=func(d time.Duration) {
357+
network.SetConnStatsCallback(d,2048,
358+
func(_,_ time.Time,virtual,_map[netlogtype.Connection]netlogtype.Counts) {
359+
select {
360+
casea.connStatsChan<-convertAgentStats(virtual):
361+
default:
362+
a.logger.Warn(ctx,"network stat dropped")
363+
}
364+
},
365+
)
366+
}
367+
354368
// Report statistics from the created network.
355-
cl,err:=a.client.ReportStats(ctx,a.logger,func()*agentsdk.Stats {
356-
stats:=network.ExtractTrafficStats()
357-
returnconvertAgentStats(stats)
358-
})
369+
cl,err:=a.client.ReportStats(ctx,a.logger,a.connStatsChan,setStatInterval)
359370
iferr!=nil {
360371
a.logger.Error(ctx,"report stats",slog.Error(err))
361372
}else {
@@ -399,10 +410,9 @@ func (a *agent) trackConnGoroutine(fn func()) error {
399410

400411
func (a*agent)createTailnet(ctx context.Context,derpMap*tailcfg.DERPMap) (_*tailnet.Conn,errerror) {
401412
network,err:=tailnet.NewConn(&tailnet.Options{
402-
Addresses: []netip.Prefix{netip.PrefixFrom(codersdk.WorkspaceAgentIP,128)},
403-
DERPMap:derpMap,
404-
Logger:a.logger.Named("tailnet"),
405-
EnableTrafficStats:true,
413+
Addresses: []netip.Prefix{netip.PrefixFrom(codersdk.WorkspaceAgentIP,128)},
414+
DERPMap:derpMap,
415+
Logger:a.logger.Named("tailnet"),
406416
})
407417
iferr!=nil {
408418
returnnil,xerrors.Errorf("create tailnet: %w",err)

‎agent/agent_test.go

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ import (
2222
"testing"
2323
"time"
2424

25-
"golang.org/x/xerrors"
26-
"tailscale.com/net/speedtest"
27-
"tailscale.com/tailcfg"
28-
2925
scp"github.com/bramvdbogaerde/go-scp"
3026
"github.com/google/uuid"
3127
"github.com/pion/udp"
@@ -37,6 +33,9 @@ import (
3733
"golang.org/x/crypto/ssh"
3834
"golang.org/x/text/encoding/unicode"
3935
"golang.org/x/text/transform"
36+
"golang.org/x/xerrors"
37+
"tailscale.com/net/speedtest"
38+
"tailscale.com/tailcfg"
4039

4140
"cdr.dev/slog"
4241
"cdr.dev/slog/sloggers/slogtest"
@@ -53,6 +52,8 @@ func TestMain(m *testing.M) {
5352
goleak.VerifyTestMain(m)
5453
}
5554

55+
// NOTE: These tests only work when your default shell is bash for some reason.
56+
5657
funcTestAgent_Stats_SSH(t*testing.T) {
5758
t.Parallel()
5859
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
@@ -1153,17 +1154,16 @@ func setupAgent(t *testing.T, metadata agentsdk.Metadata, ptyTimeout time.Durati
11531154
closer:=agent.New(agent.Options{
11541155
Client:c,
11551156
Filesystem:fs,
1156-
Logger:slogtest.Make(t,nil).Leveled(slog.LevelDebug),
1157+
Logger:slogtest.Make(t,nil).Named("agent").Leveled(slog.LevelDebug),
11571158
ReconnectingPTYTimeout:ptyTimeout,
11581159
})
11591160
t.Cleanup(func() {
11601161
_=closer.Close()
11611162
})
11621163
conn,err:=tailnet.NewConn(&tailnet.Options{
1163-
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(),128)},
1164-
DERPMap:metadata.DERPMap,
1165-
Logger:slogtest.Make(t,nil).Named("client").Leveled(slog.LevelDebug),
1166-
EnableTrafficStats:true,
1164+
Addresses: []netip.Prefix{netip.PrefixFrom(tailnet.IP(),128)},
1165+
DERPMap:metadata.DERPMap,
1166+
Logger:slogtest.Make(t,nil).Named("client").Leveled(slog.LevelDebug),
11671167
})
11681168
require.NoError(t,err)
11691169
clientConn,serverConn:=net.Pipe()
@@ -1251,28 +1251,27 @@ func (c *client) Listen(_ context.Context) (net.Conn, error) {
12511251
returnclientConn,nil
12521252
}
12531253

1254-
func (c*client)ReportStats(ctx context.Context,_ slog.Logger,statsfunc()*agentsdk.Stats) (io.Closer,error) {
1254+
func (c*client)ReportStats(ctx context.Context,_ slog.Logger,statsChan<-chan*agentsdk.Stats,setIntervalfunc(time.Duration)) (io.Closer,error) {
12551255
doneCh:=make(chanstruct{})
12561256
ctx,cancel:=context.WithCancel(ctx)
12571257

12581258
gofunc() {
12591259
deferclose(doneCh)
12601260

1261-
t:=time.NewTicker(500*time.Millisecond)
1262-
defert.Stop()
1261+
setInterval(500*time.Millisecond)
12631262
for {
12641263
select {
12651264
case<-ctx.Done():
12661265
return
1267-
case<-t.C:
1268-
}
1269-
select {
1270-
casec.statsChan<-stats():
1271-
case<-ctx.Done():
1272-
return
1273-
default:
1274-
// We don't want to send old stats.
1275-
continue
1266+
casestat:=<-statsChan:
1267+
select {
1268+
casec.statsChan<-stat:
1269+
case<-ctx.Done():
1270+
return
1271+
default:
1272+
// We don't want to send old stats.
1273+
continue
1274+
}
12761275
}
12771276
}
12781277
}()

‎cli/vscodessh.go

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/spf13/cobra"
1717
"golang.org/x/xerrors"
1818
"tailscale.com/tailcfg"
19+
"tailscale.com/types/netlogtype"
1920

2021
"github.com/coder/coder/codersdk"
2122
)
@@ -92,6 +93,7 @@ func vscodeSSH() *cobra.Command {
9293
iferr!=nil {
9394
returnxerrors.Errorf("find workspace: %w",err)
9495
}
96+
9597
varagent codersdk.WorkspaceAgent
9698
varfoundbool
9799
for_,resource:=rangeworkspace.LatestBuild.Resources {
@@ -117,61 +119,78 @@ func vscodeSSH() *cobra.Command {
117119
break
118120
}
119121
}
120-
agentConn,err:=client.DialWorkspaceAgent(ctx,agent.ID,&codersdk.DialWorkspaceAgentOptions{
121-
EnableTrafficStats:true,
122-
})
122+
123+
agentConn,err:=client.DialWorkspaceAgent(ctx,agent.ID,&codersdk.DialWorkspaceAgentOptions{})
123124
iferr!=nil {
124125
returnxerrors.Errorf("dial workspace agent: %w",err)
125126
}
126127
deferagentConn.Close()
128+
127129
agentConn.AwaitReachable(ctx)
128130
rawSSH,err:=agentConn.SSH(ctx)
129131
iferr!=nil {
130132
returnerr
131133
}
132134
deferrawSSH.Close()
135+
133136
// Copy SSH traffic over stdio.
134137
gofunc() {
135138
_,_=io.Copy(cmd.OutOrStdout(),rawSSH)
136139
}()
137140
gofunc() {
138141
_,_=io.Copy(rawSSH,cmd.InOrStdin())
139142
}()
143+
140144
// The VS Code extension obtains the PID of the SSH process to
141145
// read the file below which contains network information to display.
142146
//
143147
// We get the parent PID because it's assumed `ssh` is calling this
144148
// command via the ProxyCommand SSH option.
145149
networkInfoFilePath:=filepath.Join(networkInfoDir,fmt.Sprintf("%d.json",os.Getppid()))
146-
ticker:=time.NewTicker(networkInfoInterval)
147-
deferticker.Stop()
148-
lastCollected:=time.Now()
149-
for {
150-
select {
151-
case<-ctx.Done():
152-
returnnil
153-
case<-ticker.C:
150+
151+
statsErrChan:=make(chanerror,1)
152+
cb:=func(start,endtime.Time,virtual,_map[netlogtype.Connection]netlogtype.Counts) {
153+
sendErr:=func(errerror) {
154+
select {
155+
casestatsErrChan<-err:
156+
default:
157+
}
154158
}
155-
stats,err:=collectNetworkStats(ctx,agentConn,lastCollected)
159+
160+
stats,err:=collectNetworkStats(ctx,agentConn,start,end,virtual)
156161
iferr!=nil {
157-
returnerr
162+
sendErr(err)
163+
return
158164
}
165+
159166
rawStats,err:=json.Marshal(stats)
160167
iferr!=nil {
161-
returnerr
168+
sendErr(err)
169+
return
162170
}
163171
err=afero.WriteFile(fs,networkInfoFilePath,rawStats,0600)
164172
iferr!=nil {
165-
returnerr
173+
sendErr(err)
174+
return
166175
}
167-
lastCollected=time.Now()
176+
}
177+
178+
now:=time.Now()
179+
cb(now,now.Add(time.Nanosecond),map[netlogtype.Connection]netlogtype.Counts{},map[netlogtype.Connection]netlogtype.Counts{})
180+
agentConn.SetConnStatsCallback(networkInfoInterval,2048,cb)
181+
182+
select {
183+
case<-ctx.Done():
184+
returnnil
185+
caseerr:=<-statsErrChan:
186+
returnerr
168187
}
169188
},
170189
}
171190
cmd.Flags().StringVarP(&networkInfoDir,"network-info-dir","","","Specifies a directory to write network information periodically.")
172191
cmd.Flags().StringVarP(&sessionTokenFile,"session-token-file","","","Specifies a file that contains a session token.")
173192
cmd.Flags().StringVarP(&urlFile,"url-file","","","Specifies a file that contains the Coder URL.")
174-
cmd.Flags().DurationVarP(&networkInfoInterval,"network-info-interval","",3*time.Second,"Specifies the interval to update network information.")
193+
cmd.Flags().DurationVarP(&networkInfoInterval,"network-info-interval","",5*time.Second,"Specifies the interval to update network information.")
175194
returncmd
176195
}
177196

@@ -184,7 +203,7 @@ type sshNetworkStats struct {
184203
DownloadBytesSecint64`json:"download_bytes_sec"`
185204
}
186205

187-
funccollectNetworkStats(ctx context.Context,agentConn*codersdk.WorkspaceAgentConn,lastCollectedtime.Time) (*sshNetworkStats,error) {
206+
funccollectNetworkStats(ctx context.Context,agentConn*codersdk.WorkspaceAgentConn,start,endtime.Time,countsmap[netlogtype.Connection]netlogtype.Counts) (*sshNetworkStats,error) {
188207
latency,p2p,err:=agentConn.Ping(ctx)
189208
iferr!=nil {
190209
returnnil,err
@@ -216,13 +235,13 @@ func collectNetworkStats(ctx context.Context, agentConn *codersdk.WorkspaceAgent
216235

217236
totalRx:=uint64(0)
218237
totalTx:=uint64(0)
219-
for_,stat:=rangeagentConn.ExtractTrafficStats() {
238+
for_,stat:=rangecounts {
220239
totalRx+=stat.RxBytes
221240
totalTx+=stat.TxBytes
222241
}
223242
// Tracking the time since last request is required because
224243
// ExtractTrafficStats() resets its counters after each call.
225-
dur:=time.Since(lastCollected)
244+
dur:=end.Sub(start)
226245
uploadSecs:=float64(totalTx)/dur.Seconds()
227246
downloadSecs:=float64(totalRx)/dur.Seconds()
228247

‎coderd/wsconncache/wsconncache_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ func (c *client) Listen(_ context.Context) (net.Conn, error) {
214214
returnclientConn,nil
215215
}
216216

217-
func (*client)ReportStats(_ context.Context,_ slog.Logger,_func()*agentsdk.Stats) (io.Closer,error) {
217+
func (*client)ReportStats(_ context.Context,_ slog.Logger,_<-chan*agentsdk.Stats,_func(time.Duration)) (io.Closer,error) {
218218
returnio.NopCloser(strings.NewReader("")),nil
219219
}
220220

‎codersdk/agentsdk/agentsdk.go

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -368,44 +368,55 @@ func (c *Client) AuthAzureInstanceIdentity(ctx context.Context) (AuthenticateRes
368368

369369
// ReportStats begins a stat streaming connection with the Coder server.
370370
// It is resilient to network failures and intermittent coderd issues.
371-
func (c*Client)ReportStats(
372-
ctx context.Context,
373-
log slog.Logger,
374-
getStatsfunc()*Stats,
375-
) (io.Closer,error) {
371+
func (c*Client)ReportStats(ctx context.Context,log slog.Logger,statsChan<-chan*Stats,setIntervalfunc(time.Duration)) (io.Closer,error) {
372+
varinterval time.Duration
376373
ctx,cancel:=context.WithCancel(ctx)
374+
exited:=make(chanstruct{})
375+
376+
postStat:=func(stat*Stats) {
377+
varnextInterval time.Duration
378+
forr:=retry.New(100*time.Millisecond,time.Minute);r.Wait(ctx); {
379+
resp,err:=c.PostStats(ctx,stat)
380+
iferr!=nil {
381+
if!xerrors.Is(err,context.Canceled) {
382+
log.Error(ctx,"report stats",slog.Error(err))
383+
}
384+
continue
385+
}
386+
387+
nextInterval=resp.ReportInterval
388+
break
389+
}
390+
391+
ifnextInterval!=0&&interval!=nextInterval {
392+
setInterval(nextInterval)
393+
}
394+
interval=nextInterval
395+
}
396+
397+
// Send an empty stat to get the interval.
398+
postStat(&Stats{ConnsByProto:map[string]int64{}})
377399

378400
gofunc() {
379-
// Immediately trigger a stats push to get the correct interval.
380-
timer:=time.NewTimer(time.Nanosecond)
381-
defertimer.Stop()
401+
deferclose(exited)
382402

383403
for {
384404
select {
385405
case<-ctx.Done():
386406
return
387-
case<-timer.C:
388-
}
389-
390-
varnextInterval time.Duration
391-
forr:=retry.New(100*time.Millisecond,time.Minute);r.Wait(ctx); {
392-
resp,err:=c.PostStats(ctx,getStats())
393-
iferr!=nil {
394-
if!xerrors.Is(err,context.Canceled) {
395-
log.Error(ctx,"report stats",slog.Error(err))
396-
}
397-
continue
407+
casestat,ok:=<-statsChan:
408+
if!ok {
409+
return
398410
}
399411

400-
nextInterval=resp.ReportInterval
401-
break
412+
postStat(stat)
402413
}
403-
timer.Reset(nextInterval)
404414
}
405415
}()
406416

407417
returncloseFunc(func()error {
408418
cancel()
419+
<-exited
409420
returnnil
410421
}),nil
411422
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp