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

Commita54de60

Browse files
authored
feat: addcoder ping (#6161)
1 parent2157bff commita54de60

File tree

14 files changed

+276
-12
lines changed

14 files changed

+276
-12
lines changed

‎cli/ping.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package cli
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
"github.com/spf13/cobra"
9+
"golang.org/x/xerrors"
10+
11+
"cdr.dev/slog"
12+
"cdr.dev/slog/sloggers/sloghuman"
13+
14+
"github.com/coder/coder/cli/cliui"
15+
"github.com/coder/coder/codersdk"
16+
)
17+
18+
funcping()*cobra.Command {
19+
var (
20+
pingNumint
21+
pingTimeout time.Duration
22+
pingWait time.Duration
23+
verbosebool
24+
)
25+
cmd:=&cobra.Command{
26+
Annotations:workspaceCommand,
27+
Use:"ping <workspace>",
28+
Short:"Ping a workspace",
29+
Args:cobra.ExactArgs(1),
30+
RunE:func(cmd*cobra.Command,args []string)error {
31+
ctx,cancel:=context.WithCancel(cmd.Context())
32+
defercancel()
33+
34+
client,err:=CreateClient(cmd)
35+
iferr!=nil {
36+
returnerr
37+
}
38+
39+
workspaceName:=args[0]
40+
_,workspaceAgent,err:=getWorkspaceAndAgent(ctx,cmd,client,codersdk.Me,workspaceName,false)
41+
iferr!=nil {
42+
returnerr
43+
}
44+
45+
varlogger slog.Logger
46+
ifverbose {
47+
logger=slog.Make(sloghuman.Sink(cmd.OutOrStdout())).Leveled(slog.LevelDebug)
48+
}
49+
50+
conn,err:=client.DialWorkspaceAgent(ctx,workspaceAgent.ID,&codersdk.DialWorkspaceAgentOptions{Logger:logger})
51+
iferr!=nil {
52+
returnerr
53+
}
54+
deferconn.Close()
55+
56+
derpMap:=conn.DERPMap()
57+
_=derpMap
58+
59+
n:=0
60+
didP2p:=false
61+
start:=time.Now()
62+
for {
63+
ifn>0 {
64+
time.Sleep(time.Second)
65+
}
66+
n++
67+
68+
ctx,cancel:=context.WithTimeout(ctx,pingTimeout)
69+
dur,p2p,pong,err:=conn.Ping(ctx)
70+
cancel()
71+
iferr!=nil {
72+
ifxerrors.Is(err,context.DeadlineExceeded) {
73+
_,_=fmt.Fprintf(cmd.OutOrStdout(),"ping to %q timed out\n",workspaceName)
74+
ifn==pingNum {
75+
returnnil
76+
}
77+
continue
78+
}
79+
ifxerrors.Is(err,context.Canceled) {
80+
returnnil
81+
}
82+
83+
iferr.Error()=="no matching peer" {
84+
continue
85+
}
86+
87+
_,_=fmt.Fprintf(cmd.OutOrStdout(),"ping to %q failed %s\n",workspaceName,err.Error())
88+
ifn==pingNum {
89+
returnnil
90+
}
91+
continue
92+
}
93+
94+
dur=dur.Round(time.Millisecond)
95+
varviastring
96+
ifp2p {
97+
if!didP2p {
98+
_,_=fmt.Fprintln(cmd.OutOrStdout(),"p2p connection established in",
99+
cliui.Styles.DateTimeStamp.Render(time.Since(start).Round(time.Millisecond).String()),
100+
)
101+
}
102+
didP2p=true
103+
104+
via=fmt.Sprintf("%s via %s",
105+
cliui.Styles.Fuchsia.Render("p2p"),
106+
cliui.Styles.Code.Render(pong.Endpoint),
107+
)
108+
}else {
109+
derpName:="unknown"
110+
derpRegion,ok:=derpMap.Regions[pong.DERPRegionID]
111+
ifok {
112+
derpName=derpRegion.RegionName
113+
}
114+
via=fmt.Sprintf("%s via %s",
115+
cliui.Styles.Fuchsia.Render("proxied"),
116+
cliui.Styles.Code.Render(fmt.Sprintf("DERP(%s)",derpName)),
117+
)
118+
}
119+
120+
_,_=fmt.Fprintf(cmd.OutOrStdout(),"pong from %s %s in %s\n",
121+
cliui.Styles.Keyword.Render(workspaceName),
122+
via,
123+
cliui.Styles.DateTimeStamp.Render(dur.String()),
124+
)
125+
126+
ifn==pingNum {
127+
returnnil
128+
}
129+
}
130+
},
131+
}
132+
133+
cmd.Flags().BoolVarP(&verbose,"verbose","v",false,"Enables verbose logging.")
134+
cmd.Flags().DurationVarP(&pingWait,"wait","",time.Second,"Specifies how long to wait between pings.")
135+
cmd.Flags().DurationVarP(&pingTimeout,"timeout","t",5*time.Second,"Specifies how long to wait for a ping to complete.")
136+
cmd.Flags().IntVarP(&pingNum,"num","n",10,"Specifies the number of pings to perform.")
137+
returncmd
138+
}

‎cli/ping_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package cli_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
9+
"cdr.dev/slog/sloggers/slogtest"
10+
11+
"github.com/coder/coder/agent"
12+
"github.com/coder/coder/cli/clitest"
13+
"github.com/coder/coder/codersdk/agentsdk"
14+
"github.com/coder/coder/pty/ptytest"
15+
"github.com/coder/coder/testutil"
16+
)
17+
18+
funcTestPing(t*testing.T) {
19+
t.Parallel()
20+
21+
t.Run("OK",func(t*testing.T) {
22+
t.Parallel()
23+
24+
client,workspace,agentToken:=setupWorkspaceForAgent(t,nil)
25+
cmd,root:=clitest.New(t,"ping",workspace.Name)
26+
clitest.SetupConfig(t,client,root)
27+
pty:=ptytest.New(t)
28+
cmd.SetIn(pty.Input())
29+
cmd.SetErr(pty.Output())
30+
cmd.SetOut(pty.Output())
31+
32+
agentClient:=agentsdk.New(client.URL)
33+
agentClient.SetSessionToken(agentToken)
34+
agentCloser:=agent.New(agent.Options{
35+
Client:agentClient,
36+
Logger:slogtest.Make(t,nil).Named("agent"),
37+
})
38+
deferfunc() {
39+
_=agentCloser.Close()
40+
}()
41+
42+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
43+
defercancel()
44+
45+
cmdDone:=tGo(t,func() {
46+
err:=cmd.ExecuteContext(ctx)
47+
assert.NoError(t,err)
48+
})
49+
50+
pty.ExpectMatch("pong from "+workspace.Name)
51+
cancel()
52+
<-cmdDone
53+
})
54+
}

‎cli/root.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,12 @@ func Core() []*cobra.Command {
8585
login(),
8686
logout(),
8787
parameters(),
88+
ping(),
8889
portForward(),
8990
publickey(),
9091
rename(),
9192
resetPassword(),
93+
restart(),
9294
scaletest(),
9395
schedules(),
9496
show(),
@@ -97,7 +99,6 @@ func Core() []*cobra.Command {
9799
start(),
98100
state(),
99101
stop(),
100-
restart(),
101102
templates(),
102103
tokens(),
103104
update(),

‎cli/speedtest.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func speedtest() *cobra.Command {
7171
returnctx.Err()
7272
case<-ticker.C:
7373
}
74-
dur,p2p,err:=conn.Ping(ctx)
74+
dur,p2p,_,err:=conn.Ping(ctx)
7575
iferr!=nil {
7676
continue
7777
}

‎cli/testdata/coder_--help.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Workspace Commands:
3636
create Create a workspace
3737
delete Delete a workspace
3838
list List workspaces
39+
ping Ping a workspace
3940
rename Rename a workspace
4041
restart Restart a workspace
4142
schedule Schedule automated start and stop times for workspaces

‎cli/testdata/coder_ping_--help.golden

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Ping a workspace
2+
3+
Usage:
4+
coder ping <workspace> [flags]
5+
6+
Flags:
7+
-h, --help help for ping
8+
-n, --num int Specifies the number of pings to perform. (default 10)
9+
-t, --timeout duration Specifies how long to wait for a ping to complete. (default 5s)
10+
-v, --verbose Enables verbose logging.
11+
--wait duration Specifies how long to wait between pings. (default 1s)
12+
13+
Global Flags:
14+
--global-config coder Path to the global coder config directory.
15+
Consumes $CODER_CONFIG_DIR (default "~/.config/coderv2")
16+
--header stringArray HTTP headers added to all requests. Provide as "Key=Value".
17+
Consumes $CODER_HEADER
18+
--no-feature-warning Suppress warnings about unlicensed features.
19+
Consumes $CODER_NO_FEATURE_WARNING
20+
--no-version-warning Suppress warning when client and server versions do not match.
21+
Consumes $CODER_NO_VERSION_WARNING
22+
--token string Specify an authentication token. For security reasons setting
23+
CODER_SESSION_TOKEN is preferred.
24+
Consumes $CODER_SESSION_TOKEN
25+
--url string URL to a deployment.
26+
Consumes $CODER_URL

‎cli/vscodessh.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ type sshNetworkStats struct {
204204
}
205205

206206
funccollectNetworkStats(ctx context.Context,agentConn*codersdk.WorkspaceAgentConn,start,end time.Time,countsmap[netlogtype.Connection]netlogtype.Counts) (*sshNetworkStats,error) {
207-
latency,p2p,err:=agentConn.Ping(ctx)
207+
latency,p2p,_,err:=agentConn.Ping(ctx)
208208
iferr!=nil {
209209
returnnil,err
210210
}

‎codersdk/workspaceagentconn.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"github.com/google/uuid"
1818
"golang.org/x/crypto/ssh"
1919
"golang.org/x/xerrors"
20+
"tailscale.com/ipn/ipnstate"
2021
"tailscale.com/net/speedtest"
2122

2223
"github.com/coder/coder/coderd/tracing"
@@ -136,7 +137,7 @@ func (c *WorkspaceAgentConn) AwaitReachable(ctx context.Context) bool {
136137

137138
// Ping pings the agent and returns the round-trip time.
138139
// The bool returns true if the ping was made P2P.
139-
func (c*WorkspaceAgentConn)Ping(ctx context.Context) (time.Duration,bool,error) {
140+
func (c*WorkspaceAgentConn)Ping(ctx context.Context) (time.Duration,bool,*ipnstate.PingResult,error) {
140141
ctx,span:=tracing.StartSpan(ctx)
141142
deferspan.End()
142143

‎docs/cli/coder.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ coder [flags]
4949
-[coder list](coder_list.md) - List workspaces
5050
-[coder login](coder_login.md) - Authenticate with Coder deployment
5151
-[coder logout](coder_logout.md) - Unauthenticate your local session
52+
-[coder ping](coder_ping.md) - Ping a workspace
5253
-[coder port-forward](coder_port-forward.md) - Forward ports from machine to a workspace
5354
-[coder publickey](coder_publickey.md) - Output your Coder public key used for Git operations
5455
-[coder rename](coder_rename.md) - Rename a workspace

‎docs/cli/coder_ping.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
##coder ping
2+
3+
Ping a workspace
4+
5+
```
6+
coder ping <workspace> [flags]
7+
```
8+
9+
###Options
10+
11+
```
12+
-h, --help help for ping
13+
-n, --num int Specifies the number of pings to perform. (default 10)
14+
-t, --timeout duration Specifies how long to wait for a ping to complete. (default 5s)
15+
-v, --verbose Enables verbose logging.
16+
--wait duration Specifies how long to wait between pings. (default 1s)
17+
```
18+
19+
###Options inherited from parent commands
20+
21+
```
22+
--global-config coder Path to the global coder config directory.
23+
Consumes $CODER_CONFIG_DIR (default "~/.config/coderv2")
24+
--header stringArray HTTP headers added to all requests. Provide as "Key=Value".
25+
Consumes $CODER_HEADER
26+
--no-feature-warning Suppress warnings about unlicensed features.
27+
Consumes $CODER_NO_FEATURE_WARNING
28+
--no-version-warning Suppress warning when client and server versions do not match.
29+
Consumes $CODER_NO_VERSION_WARNING
30+
--token string Specify an authentication token. For security reasons setting CODER_SESSION_TOKEN is preferred.
31+
Consumes $CODER_SESSION_TOKEN
32+
--url string URL to a deployment.
33+
Consumes $CODER_URL
34+
```
35+
36+
###SEE ALSO
37+
38+
-[coder](coder.md) -

‎docs/manifest.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,10 @@
453453
"title":"logout",
454454
"path":"./cli/coder_logout.md"
455455
},
456+
{
457+
"title":"ping",
458+
"path":"./cli/coder_ping.md"
459+
},
456460
{
457461
"title":"port-forward",
458462
"path":"./cli/coder_port-forward.md"

‎enterprise/coderd/replicas_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func TestReplicas(t *testing.T) {
8484
require.Eventually(t,func()bool {
8585
ctx,cancelFunc:=context.WithTimeout(context.Background(),testutil.WaitShort)
8686
defercancelFunc()
87-
_,_,err=conn.Ping(ctx)
87+
_,_,_,err=conn.Ping(ctx)
8888
returnerr==nil
8989
},testutil.WaitLong,testutil.IntervalFast)
9090
_=conn.Close()
@@ -129,7 +129,7 @@ func TestReplicas(t *testing.T) {
129129
require.Eventually(t,func()bool {
130130
ctx,cancelFunc:=context.WithTimeout(context.Background(),testutil.IntervalSlow)
131131
defercancelFunc()
132-
_,_,err=conn.Ping(ctx)
132+
_,_,_,err=conn.Ping(ctx)
133133
returnerr==nil
134134
},testutil.WaitLong,testutil.IntervalFast)
135135
_=conn.Close()

‎scaletest/agentconn/run.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func waitForDisco(ctx context.Context, logs io.Writer, conn *codersdk.WorkspaceA
141141
fori:=0;i<pingAttempts;i++ {
142142
_,_=fmt.Fprintf(logs,"\tDisco ping attempt %d/%d...\n",i+1,pingAttempts)
143143
pingCtx,cancel:=context.WithTimeout(ctx,defaultRequestTimeout)
144-
_,p2p,err:=conn.Ping(pingCtx)
144+
_,p2p,_,err:=conn.Ping(pingCtx)
145145
cancel()
146146
iferr==nil {
147147
_,_=fmt.Fprintf(logs,"\tDisco ping succeeded after %d attempts, p2p = %v\n",i+1,p2p)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp