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
forked fromcoder/coder

Commit37885e2

Browse files
fix: make cli respect deployment --docs-url (coder#14568)
1 parent20a3801 commit37885e2

26 files changed

+201
-108
lines changed

‎cli/cliui/agent.go

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ 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.
@@ -119,7 +120,7 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
119120
ifagent.Status==codersdk.WorkspaceAgentTimeout {
120121
now:=time.Now()
121122
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"))
123+
sw.Log(now,codersdk.LogLevelInfo,troubleshootingMessage(agent,fmt.Sprintf("%s/templates#agent-connection-issues",opts.DocsURL)))
123124
foragent.Status==codersdk.WorkspaceAgentTimeout {
124125
ifagent,err=fetch();err!=nil {
125126
returnxerrors.Errorf("fetch: %w",err)
@@ -224,13 +225,13 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
224225
sw.Fail(stage,safeDuration(sw,agent.ReadyAt,agent.StartedAt))
225226
// Use zero time (omitted) to separate these from the startup logs.
226227
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"))
228+
sw.Log(time.Time{},codersdk.LogLevelWarn,troubleshootingMessage(agent,fmt.Sprintf("%s/templates#startup-script-exited-with-an-error",opts.DocsURL)))
228229
default:
229230
switch {
230231
caseagent.LifecycleState.Starting():
231232
// Use zero time (omitted) to separate these from the startup logs.
232233
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"))
234+
sw.Log(time.Time{},codersdk.LogLevelWarn,troubleshootingMessage(agent,fmt.Sprintf("%s/templates#your-workspace-may-be-incomplete",opts.DocsURL)))
234235
// Note: We don't complete or fail the stage here, it's
235236
// intentionally left open to indicate this stage didn't
236237
// complete.
@@ -252,7 +253,7 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
252253
stage:="The workspace agent lost connection"
253254
sw.Start(stage)
254255
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"))
256+
sw.Log(time.Now(),codersdk.LogLevelWarn,troubleshootingMessage(agent,fmt.Sprintf("%s/templates#agent-connection-issues",opts.DocsURL)))
256257

257258
disconnectedAt:=agent.DisconnectedAt
258259
foragent.Status==codersdk.WorkspaceAgentDisconnected {
@@ -351,16 +352,16 @@ func PeerDiagnostics(w io.Writer, d tailnet.PeerDiagnostics) {
351352
}
352353

353354
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
355+
ConnInfoworkspacesdk.AgentConnectionInfo
356+
PingP2Pbool
357+
DisableDirectbool
358+
LocalNetInfo*tailcfg.NetInfo
359+
LocalInterfaces*healthsdk.InterfacesReport
360+
AgentNetcheck*healthsdk.AgentNetcheckReport
361+
ClientIPIsAWSbool
362+
AgentIPIsAWSbool
363+
Verbosebool
364+
TroubleshootingURLstring
364365
}
365366

366367
func (dConnDiags)Write(w io.Writer) {
@@ -395,7 +396,7 @@ func (d ConnDiags) splitDiagnostics() (general, client, agent []string) {
395396
agent=append(agent,msg.Message)
396397
}
397398
iflen(d.AgentNetcheck.Interfaces.Warnings)>0 {
398-
agent[len(agent)-1]+="\nhttps://coder.com/docs/networking/troubleshooting#low-mtu"
399+
agent[len(agent)-1]+=fmt.Sprintf("\n%s#low-mtu",d.TroubleshootingURL)
399400
}
400401
}
401402

@@ -404,7 +405,7 @@ func (d ConnDiags) splitDiagnostics() (general, client, agent []string) {
404405
client=append(client,msg.Message)
405406
}
406407
iflen(d.LocalInterfaces.Warnings)>0 {
407-
client[len(client)-1]+="\nhttps://coder.com/docs/networking/troubleshooting#low-mtu"
408+
client[len(client)-1]+=fmt.Sprintf("\n%s#low-mtu",d.TroubleshootingURL)
408409
}
409410
}
410411

@@ -420,45 +421,45 @@ func (d ConnDiags) splitDiagnostics() (general, client, agent []string) {
420421
}
421422

422423
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")
424+
general=append(general,
425+
fmt.Sprintf("❗ Your Coder administrator has blocked direct connections\n %s#disabled-deployment-wide",d.TroubleshootingURL))
425426
if!d.Verbose {
426427
returngeneral,client,agent
427428
}
428429
}
429430

430431
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")
432+
general=append(general,
433+
fmt.Sprintf("❗ The DERP map is not configured to use STUN\n %s#no-stun-servers",d.TroubleshootingURL))
433434
}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")
435+
client=append(client,
436+
fmt.Sprintf("Client could not connect to STUN over UDP\n %s#udp-blocked",d.TroubleshootingURL))
436437
}
437438

438439
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")
440+
client=append(client,
441+
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))
441442
}
442443

443444
ifd.AgentNetcheck!=nil&&d.AgentNetcheck.NetInfo!=nil {
444445
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")
446+
agent=append(agent,
447+
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))
447448
}
448449
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")
450+
agent=append(agent,
451+
fmt.Sprintf("Agent could not connect to STUN over UDP\n %s#udp-blocked",d.TroubleshootingURL))
451452
}
452453
}
453454

454455
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")
456+
client=append(client,
457+
fmt.Sprintf("Client IP address is within an AWS range (AWS uses hard NAT)\n %s#endpoint-dependent-nat-hard-nat",d.TroubleshootingURL))
457458
}
458459

459460
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")
461+
agent=append(agent,
462+
fmt.Sprintf("Agent IP address is within an AWS range (AWS uses hard NAT)\n %s#endpoint-dependent-nat-hard-nat",d.TroubleshootingURL))
462463
}
463464
returngeneral,client,agent
464465
}

‎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 %qis notexecutable. See https://coder.com/docs/dotfiles for information on how to resolve the issue.",script)
206+
returnxerrors.Errorf("script %qdoes nothave execute permissions",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
@@ -692,6 +692,26 @@ func namedWorkspace(ctx context.Context, client *codersdk.Client, identifier str
692692
returnclient.WorkspaceByOwnerAndName(ctx,owner,name, codersdk.WorkspaceOptions{})
693693
}
694694

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

‎cli/server.go

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

860860
// 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