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

Commit24a9a36

Browse files
committed
fix: make cli respect deployment --docs-url
1 parent33e896d commit24a9a36

File tree

20 files changed

+190
-99
lines changed

20 files changed

+190
-99
lines changed

‎cli/cliui/agent.go

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@ type AgentOptions struct {
2525
Fetchfunc(ctx context.Context,agentID uuid.UUID) (codersdk.WorkspaceAgent,error)
2626
FetchLogsfunc(ctx context.Context,agentID uuid.UUID,afterint64,followbool) (<-chan []codersdk.WorkspaceAgentLog, io.Closer,error)
2727
Waitbool// If true, wait for the agent to be ready (startup script).
28+
DocsURLstring
2829
}
2930

3031
// Agent displays a spinning indicator that waits for a workspace agent to connect.
3132
funcAgent(ctx context.Context,writer io.Writer,agentID uuid.UUID,optsAgentOptions)error {
3233
ctx,cancel:=context.WithCancel(ctx)
3334
defercancel()
3435

36+
ifopts.DocsURL=="" {
37+
opts.DocsURL="https://coder.com/docs"
38+
}
39+
3540
ifopts.FetchInterval==0 {
3641
opts.FetchInterval=500*time.Millisecond
3742
}
@@ -119,7 +124,7 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
119124
ifagent.Status==codersdk.WorkspaceAgentTimeout {
120125
now:=time.Now()
121126
sw.Log(now,codersdk.LogLevelInfo,"The workspace agent is having trouble connecting, wait for it to connect or restart your workspace.")
122-
sw.Log(now,codersdk.LogLevelInfo,troubleshootingMessage(agent,"https://coder.com/docs/templates#agent-connection-issues"))
127+
sw.Log(now,codersdk.LogLevelInfo,troubleshootingMessage(agent,fmt.Sprintf("%s/templates#agent-connection-issues",opts.DocsURL)))
123128
foragent.Status==codersdk.WorkspaceAgentTimeout {
124129
ifagent,err=fetch();err!=nil {
125130
returnxerrors.Errorf("fetch: %w",err)
@@ -224,13 +229,13 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
224229
sw.Fail(stage,safeDuration(sw,agent.ReadyAt,agent.StartedAt))
225230
// Use zero time (omitted) to separate these from the startup logs.
226231
sw.Log(time.Time{},codersdk.LogLevelWarn,"Warning: A startup script exited with an error and your workspace may be incomplete.")
227-
sw.Log(time.Time{},codersdk.LogLevelWarn,troubleshootingMessage(agent,"https://coder.com/docs/templates/troubleshooting#startup-script-exited-with-an-error"))
232+
sw.Log(time.Time{},codersdk.LogLevelWarn,troubleshootingMessage(agent,fmt.Sprintf("%s/templates#startup-script-exited-with-an-error",opts.DocsURL)))
228233
default:
229234
switch {
230235
caseagent.LifecycleState.Starting():
231236
// Use zero time (omitted) to separate these from the startup logs.
232237
sw.Log(time.Time{},codersdk.LogLevelWarn,"Notice: The startup scripts are still running and your workspace may be incomplete.")
233-
sw.Log(time.Time{},codersdk.LogLevelWarn,troubleshootingMessage(agent,"https://coder.com/docs/templates/troubleshooting#your-workspace-may-be-incomplete"))
238+
sw.Log(time.Time{},codersdk.LogLevelWarn,troubleshootingMessage(agent,fmt.Sprintf("%s/templates#your-workspace-may-be-incomplete",opts.DocsURL)))
234239
// Note: We don't complete or fail the stage here, it's
235240
// intentionally left open to indicate this stage didn't
236241
// complete.
@@ -252,7 +257,7 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
252257
stage:="The workspace agent lost connection"
253258
sw.Start(stage)
254259
sw.Log(time.Now(),codersdk.LogLevelWarn,"Wait for it to reconnect or restart your workspace.")
255-
sw.Log(time.Now(),codersdk.LogLevelWarn,troubleshootingMessage(agent,"https://coder.com/docs/templates/troubleshooting#agent-connection-issues"))
260+
sw.Log(time.Now(),codersdk.LogLevelWarn,troubleshootingMessage(agent,fmt.Sprintf("%s/templates#agent-connection-issues",opts.DocsURL)))
256261

257262
disconnectedAt:=agent.DisconnectedAt
258263
foragent.Status==codersdk.WorkspaceAgentDisconnected {
@@ -351,16 +356,16 @@ func PeerDiagnostics(w io.Writer, d tailnet.PeerDiagnostics) {
351356
}
352357

353358
typeConnDiagsstruct {
354-
ConnInfo workspacesdk.AgentConnectionInfo
355-
PingP2Pbool
356-
DisableDirectbool
357-
LocalNetInfo*tailcfg.NetInfo
358-
LocalInterfaces*healthsdk.InterfacesReport
359-
AgentNetcheck*healthsdk.AgentNetcheckReport
360-
ClientIPIsAWSbool
361-
AgentIPIsAWSbool
362-
Verbosebool
363-
// TODO: More diagnostics
359+
ConnInfoworkspacesdk.AgentConnectionInfo
360+
PingP2Pbool
361+
DisableDirectbool
362+
LocalNetInfo*tailcfg.NetInfo
363+
LocalInterfaces*healthsdk.InterfacesReport
364+
AgentNetcheck*healthsdk.AgentNetcheckReport
365+
ClientIPIsAWSbool
366+
AgentIPIsAWSbool
367+
Verbosebool
368+
TroubleshootingURLstring
364369
}
365370

366371
func (dConnDiags)Write(w io.Writer) {
@@ -395,7 +400,7 @@ func (d ConnDiags) splitDiagnostics() (general, client, agent []string) {
395400
agent=append(agent,msg.Message)
396401
}
397402
iflen(d.AgentNetcheck.Interfaces.Warnings)>0 {
398-
agent[len(agent)-1]+="\nhttps://coder.com/docs/networking/troubleshooting#low-mtu"
403+
agent[len(agent)-1]+=fmt.Sprintf("\n%s#low-mtu",d.TroubleshootingURL)
399404
}
400405
}
401406

@@ -404,7 +409,7 @@ func (d ConnDiags) splitDiagnostics() (general, client, agent []string) {
404409
client=append(client,msg.Message)
405410
}
406411
iflen(d.LocalInterfaces.Warnings)>0 {
407-
client[len(client)-1]+="\nhttps://coder.com/docs/networking/troubleshooting#low-mtu"
412+
client[len(client)-1]+=fmt.Sprintf("\n%s#low-mtu",d.TroubleshootingURL)
408413
}
409414
}
410415

@@ -420,45 +425,45 @@ func (d ConnDiags) splitDiagnostics() (general, client, agent []string) {
420425
}
421426

422427
ifd.ConnInfo.DisableDirectConnections {
423-
general=append(general,"❗ Your Coder administrator has blocked direct connections\n"+
424-
" https://coder.com/docs/networking/troubleshooting#disabled-deployment-wide")
428+
general=append(general,
429+
fmt.Sprintf("❗ Your Coder administrator has blocked direct connections\n %s#disabled-deployment-wide",d.TroubleshootingURL))
425430
if!d.Verbose {
426431
returngeneral,client,agent
427432
}
428433
}
429434

430435
if!d.ConnInfo.DERPMap.HasSTUN() {
431-
general=append(general,"❗ The DERP map is not configured to use STUN\n"+
432-
" https://coder.com/docs/networking/troubleshooting#no-stun-servers")
436+
general=append(general,
437+
fmt.Sprintf("❗ The DERP map is not configured to use STUN\n %s#no-stun-servers",d.TroubleshootingURL))
433438
}elseifd.LocalNetInfo!=nil&&!d.LocalNetInfo.UDP {
434-
client=append(client,"Client could not connect to STUN over UDP\n"+
435-
" https://coder.com/docs/networking/troubleshooting#udp-blocked")
439+
client=append(client,
440+
fmt.Sprintf("Client could not connect to STUN over UDP\n %s#udp-blocked",d.TroubleshootingURL))
436441
}
437442

438443
ifd.LocalNetInfo!=nil&&d.LocalNetInfo.MappingVariesByDestIP.EqualBool(true) {
439-
client=append(client,"Client is potentially behind a hard NAT, as multiple endpoints were retrieved from different STUN servers\n"+
440-
" https://coder.com/docs/networking/troubleshooting#Endpoint-Dependent-Nat-Hard-NAT")
444+
client=append(client,
445+
fmt.Sprintf("Client is potentially behind a hard NAT, as multiple endpoints were retrieved from different STUN servers\n %s#endpoint-dependent-nat-hard-nat",d.TroubleshootingURL))
441446
}
442447

443448
ifd.AgentNetcheck!=nil&&d.AgentNetcheck.NetInfo!=nil {
444449
ifd.AgentNetcheck.NetInfo.MappingVariesByDestIP.EqualBool(true) {
445-
agent=append(agent,"Agent is potentially behind a hard NAT, as multiple endpoints were retrieved from different STUN servers\n"+
446-
" https://coder.com/docs/networking/troubleshooting#Endpoint-Dependent-Nat-Hard-NAT")
450+
agent=append(agent,
451+
fmt.Sprintf("Agent is potentially behind a hard NAT, as multiple endpoints were retrieved from different STUN servers\n %s#endpoint-dependent-nat-hard-nat",d.TroubleshootingURL))
447452
}
448453
if!d.AgentNetcheck.NetInfo.UDP {
449-
agent=append(agent,"Agent could not connect to STUN over UDP\n"+
450-
" https://coder.com/docs/networking/troubleshooting#udp-blocked")
454+
agent=append(agent,
455+
fmt.Sprintf("Agent could not connect to STUN over UDP\n %s#udp-blocked",d.TroubleshootingURL))
451456
}
452457
}
453458

454459
ifd.ClientIPIsAWS {
455-
client=append(client,"Client IP address is within an AWS range (AWS uses hard NAT)\n"+
456-
" https://coder.com/docs/networking/troubleshooting#Endpoint-Dependent-Nat-Hard-NAT")
460+
client=append(client,
461+
fmt.Sprintf("Client IP address is within an AWS range (AWS uses hard NAT)\n %s#endpoint-dependent-nat-hard-nat",d.TroubleshootingURL))
457462
}
458463

459464
ifd.AgentIPIsAWS {
460-
agent=append(agent,"Agent IP address is within an AWS range (AWS uses hard NAT)\n"+
461-
" https://coder.com/docs/networking/troubleshooting#Endpoint-Dependent-Nat-Hard-NAT")
465+
agent=append(agent,
466+
fmt.Sprintf("Agent IP address is within an AWS range (AWS uses hard NAT)\n %s#endpoint-dependent-nat-hard-nat",d.TroubleshootingURL))
462467
}
463468
returngeneral,client,agent
464469
}

‎cli/dotfiles.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ func (r *RootCmd) dotfiles() *serpent.Command {
203203
}
204204

205205
iffi.Mode()&0o111==0 {
206-
returnxerrors.Errorf("script %q is not executable. See https://coder.com/docs/dotfiles for information on how to resolve the issue.",script)
206+
returnxerrors.Errorf("script %q is not executable",script)
207207
}
208208

209209
// it is safe to use a variable command here because it's from

‎cli/open.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ const vscodeDesktopName = "VS Code Desktop"
3535

3636
func (r*RootCmd)openVSCode()*serpent.Command {
3737
var (
38-
generateTokenbool
39-
testOpenErrorbool
38+
generateTokenbool
39+
testOpenErrorbool
40+
appearanceConfig codersdk.AppearanceConfig
4041
)
4142

4243
client:=new(codersdk.Client)
@@ -47,6 +48,7 @@ func (r *RootCmd) openVSCode() *serpent.Command {
4748
Middleware:serpent.Chain(
4849
serpent.RequireRangeArgs(1,2),
4950
r.InitClient(client),
51+
initAppearance(client,&appearanceConfig),
5052
),
5153
Handler:func(inv*serpent.Invocation)error {
5254
ctx,cancel:=context.WithCancel(inv.Context())
@@ -79,6 +81,7 @@ func (r *RootCmd) openVSCode() *serpent.Command {
7981
Fetch:client.WorkspaceAgent,
8082
FetchLogs:nil,
8183
Wait:false,
84+
DocsURL:appearanceConfig.DocsURL,
8285
})
8386
iferr!=nil {
8487
ifxerrors.Is(err,context.Canceled) {

‎cli/ping.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ import (
2626

2727
func (r*RootCmd)ping()*serpent.Command {
2828
var (
29-
pingNumint64
30-
pingTimeout time.Duration
31-
pingWait time.Duration
29+
pingNumint64
30+
pingTimeout time.Duration
31+
pingWait time.Duration
32+
appearanceConfig codersdk.AppearanceConfig
3233
)
3334

3435
client:=new(codersdk.Client)
@@ -39,6 +40,7 @@ func (r *RootCmd) ping() *serpent.Command {
3940
Middleware:serpent.Chain(
4041
serpent.RequireNArgs(1),
4142
r.InitClient(client),
43+
initAppearance(client,&appearanceConfig),
4244
),
4345
Handler:func(inv*serpent.Invocation)error {
4446
ctx,cancel:=context.WithCancel(inv.Context())
@@ -67,8 +69,8 @@ func (r *RootCmd) ping() *serpent.Command {
6769
if!r.disableNetworkTelemetry {
6870
opts.EnableTelemetry=true
6971
}
70-
client:=workspacesdk.New(client)
71-
conn,err:=client.DialAgent(ctx,workspaceAgent.ID,opts)
72+
wsClient:=workspacesdk.New(client)
73+
conn,err:=wsClient.DialAgent(ctx,workspaceAgent.ID,opts)
7274
iferr!=nil {
7375
returnerr
7476
}
@@ -155,10 +157,11 @@ func (r *RootCmd) ping() *serpent.Command {
155157

156158
ni:=conn.GetNetInfo()
157159
connDiags:= cliui.ConnDiags{
158-
PingP2P:didP2p,
159-
DisableDirect:r.disableDirect,
160-
LocalNetInfo:ni,
161-
Verbose:r.verbose,
160+
PingP2P:didP2p,
161+
DisableDirect:r.disableDirect,
162+
LocalNetInfo:ni,
163+
Verbose:r.verbose,
164+
TroubleshootingURL:appearanceConfig.DocsURL+"/networking/troubleshooting",
162165
}
163166

164167
awsRanges,err:=cliutil.FetchAWSIPRanges(diagCtx,cliutil.AWSIPRangesURL)
@@ -168,7 +171,7 @@ func (r *RootCmd) ping() *serpent.Command {
168171

169172
connDiags.ClientIPIsAWS=isAWSIP(awsRanges,ni)
170173

171-
connInfo,err:=client.AgentConnectionInfoGeneric(diagCtx)
174+
connInfo,err:=wsClient.AgentConnectionInfoGeneric(diagCtx)
172175
iferr!=nil||connInfo.DERPMap==nil {
173176
returnxerrors.Errorf("Failed to retrieve connection info from server: %w\n",err)
174177
}

‎cli/portforward.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func (r *RootCmd) portForward() *serpent.Command {
2929
tcpForwards []string// <port>:<port>
3030
udpForwards []string// <port>:<port>
3131
disableAutostartbool
32+
appearanceConfig codersdk.AppearanceConfig
3233
)
3334
client:=new(codersdk.Client)
3435
cmd:=&serpent.Command{
@@ -60,6 +61,7 @@ func (r *RootCmd) portForward() *serpent.Command {
6061
Middleware:serpent.Chain(
6162
serpent.RequireNArgs(1),
6263
r.InitClient(client),
64+
initAppearance(client,&appearanceConfig),
6365
),
6466
Handler:func(inv*serpent.Invocation)error {
6567
ctx,cancel:=context.WithCancel(inv.Context())
@@ -88,8 +90,9 @@ func (r *RootCmd) portForward() *serpent.Command {
8890
}
8991

9092
err=cliui.Agent(ctx,inv.Stderr,workspaceAgent.ID, cliui.AgentOptions{
91-
Fetch:client.WorkspaceAgent,
92-
Wait:false,
93+
Fetch:client.WorkspaceAgent,
94+
Wait:false,
95+
DocsURL:appearanceConfig.DocsURL,
9396
})
9497
iferr!=nil {
9598
returnxerrors.Errorf("await agent: %w",err)

‎cli/rename.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
)
1414

1515
func (r*RootCmd)rename()*serpent.Command {
16+
varappearanceConfig codersdk.AppearanceConfig
1617
client:=new(codersdk.Client)
1718
cmd:=&serpent.Command{
1819
Annotations:workspaceCommand,
@@ -21,6 +22,7 @@ func (r *RootCmd) rename() *serpent.Command {
2122
Middleware:serpent.Chain(
2223
serpent.RequireNArgs(2),
2324
r.InitClient(client),
25+
initAppearance(client,&appearanceConfig),
2426
),
2527
Handler:func(inv*serpent.Invocation)error {
2628
workspace,err:=namedWorkspace(inv.Context(),client,inv.Args[0])
@@ -31,7 +33,7 @@ func (r *RootCmd) rename() *serpent.Command {
3133
_,_=fmt.Fprintf(inv.Stdout,"%s\n\n",
3234
pretty.Sprint(cliui.DefaultStyles.Wrap,"WARNING: A rename can result in data loss if a resource references the workspace name in the template (e.g volumes). Please backup any data before proceeding."),
3335
)
34-
_,_=fmt.Fprintf(inv.Stdout,"See: %s\n\n","https://coder.com/docs/templates/resource-persistence#%EF%B8%8F-persistence-pitfalls")
36+
_,_=fmt.Fprintf(inv.Stdout,"See: %s%s\n\n",appearanceConfig.DocsURL,"/templates/resource-persistence#%EF%B8%8F-persistence-pitfalls")
3537
_,err=cliui.Prompt(inv, cliui.PromptOptions{
3638
Text:fmt.Sprintf("Type %q to confirm rename:",workspace.Name),
3739
Validate:func(sstring)error {

‎cli/root.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,26 @@ func namedWorkspace(ctx context.Context, client *codersdk.Client, identifier str
687687
returnclient.WorkspaceByOwnerAndName(ctx,owner,name, codersdk.WorkspaceOptions{})
688688
}
689689

690+
funcinitAppearance(client*codersdk.Client,outConfig*codersdk.AppearanceConfig) serpent.MiddlewareFunc {
691+
returnfunc(next serpent.HandlerFunc) serpent.HandlerFunc {
692+
returnfunc(inv*serpent.Invocation)error {
693+
varerrerror
694+
cfg,err:=client.Appearance(inv.Context())
695+
iferr!=nil {
696+
varsdkErr*codersdk.Error
697+
if!(xerrors.As(err,&sdkErr)&&sdkErr.StatusCode()==http.StatusNotFound) {
698+
returnerr
699+
}
700+
}
701+
ifcfg.DocsURL=="" {
702+
cfg.DocsURL=codersdk.DefaultDocsURL()
703+
}
704+
*outConfig=cfg
705+
returnnext(inv)
706+
}
707+
}
708+
}
709+
690710
// createConfig consumes the global configuration flag to produce a config root.
691711
func (r*RootCmd)createConfig() config.Root {
692712
returnconfig.Root(r.globalConfig)

‎cli/server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
630630
"new version of coder available",
631631
slog.F("new_version",r.Version),
632632
slog.F("url",r.URL),
633-
slog.F("upgrade_instructions","https://coder.com/docs/admin/upgrade"),
633+
slog.F("upgrade_instructions",fmt.Sprintf("%s/admin/upgrade",vals.DocsURL.String())),
634634
)
635635
}
636636
},
@@ -856,7 +856,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
856856
}
857857
deferoptions.Telemetry.Close()
858858
}else {
859-
logger.Warn(ctx,`telemetry disabled, unable to notify of security issues. Read more:https://coder.com/docs/admin/telemetry`)
859+
logger.Warn(ctx,fmt.Sprintf(`telemetry disabled, unable to notify of security issues. Read more:%s/admin/telemetry`,vals.DocsURL.String()))
860860
}
861861

862862
// This prevents the pprof import from being accidentally deleted.

‎cli/speedtest.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,12 @@ type speedtestTableItem struct {
3636

3737
func (r*RootCmd)speedtest()*serpent.Command {
3838
var (
39-
directbool
40-
duration time.Duration
41-
directionstring
42-
pcapFilestring
43-
formatter=cliui.NewOutputFormatter(
39+
directbool
40+
duration time.Duration
41+
directionstring
42+
pcapFilestring
43+
appearanceConfig codersdk.AppearanceConfig
44+
formatter=cliui.NewOutputFormatter(
4445
cliui.ChangeFormatterData(cliui.TableFormat([]speedtestTableItem{}, []string{"Interval","Throughput"}),func(dataany) (any,error) {
4546
res,ok:=data.(SpeedtestResult)
4647
if!ok {
@@ -72,6 +73,7 @@ func (r *RootCmd) speedtest() *serpent.Command {
7273
Middleware:serpent.Chain(
7374
serpent.RequireNArgs(1),
7475
r.InitClient(client),
76+
initAppearance(client,&appearanceConfig),
7577
),
7678
Handler:func(inv*serpent.Invocation)error {
7779
ctx,cancel:=context.WithCancel(inv.Context())
@@ -87,8 +89,9 @@ func (r *RootCmd) speedtest() *serpent.Command {
8789
}
8890

8991
err=cliui.Agent(ctx,inv.Stderr,workspaceAgent.ID, cliui.AgentOptions{
90-
Fetch:client.WorkspaceAgent,
91-
Wait:false,
92+
Fetch:client.WorkspaceAgent,
93+
Wait:false,
94+
DocsURL:appearanceConfig.DocsURL,
9295
})
9396
iferr!=nil {
9497
returnxerrors.Errorf("await agent: %w",err)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp