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

fix: make cli respect deployment --docs-url#14568

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 33 additions & 32 deletionscli/cliui/agent.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,7 @@ type AgentOptions struct {
Fetch func(ctx context.Context, agentID uuid.UUID) (codersdk.WorkspaceAgent, error)
FetchLogs func(ctx context.Context, agentID uuid.UUID, after int64, follow bool) (<-chan []codersdk.WorkspaceAgentLog, io.Closer, error)
Wait bool // If true, wait for the agent to be ready (startup script).
DocsURL string
}

// Agent displays a spinning indicator that waits for a workspace agent to connect.
Expand DownExpand Up@@ -119,7 +120,7 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
if agent.Status == codersdk.WorkspaceAgentTimeout {
now := time.Now()
sw.Log(now, codersdk.LogLevelInfo, "The workspace agent is having trouble connecting, wait for it to connect or restart your workspace.")
sw.Log(now, codersdk.LogLevelInfo, troubleshootingMessage(agent,"https://coder.com/docs/templates#agent-connection-issues"))
sw.Log(now, codersdk.LogLevelInfo, troubleshootingMessage(agent,fmt.Sprintf("%s/templates#agent-connection-issues", opts.DocsURL)))
for agent.Status == codersdk.WorkspaceAgentTimeout {
if agent, err = fetch(); err != nil {
return xerrors.Errorf("fetch: %w", err)
Expand DownExpand Up@@ -224,13 +225,13 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
sw.Fail(stage, safeDuration(sw, agent.ReadyAt, agent.StartedAt))
// Use zero time (omitted) to separate these from the startup logs.
sw.Log(time.Time{}, codersdk.LogLevelWarn, "Warning: A startup script exited with an error and your workspace may be incomplete.")
sw.Log(time.Time{}, codersdk.LogLevelWarn, troubleshootingMessage(agent,"https://coder.com/docs/templates/troubleshooting#startup-script-exited-with-an-error"))
sw.Log(time.Time{}, codersdk.LogLevelWarn, troubleshootingMessage(agent,fmt.Sprintf("%s/templates#startup-script-exited-with-an-error", opts.DocsURL)))
default:
switch {
case agent.LifecycleState.Starting():
// Use zero time (omitted) to separate these from the startup logs.
sw.Log(time.Time{}, codersdk.LogLevelWarn, "Notice: The startup scripts are still running and your workspace may be incomplete.")
sw.Log(time.Time{}, codersdk.LogLevelWarn, troubleshootingMessage(agent,"https://coder.com/docs/templates/troubleshooting#your-workspace-may-be-incomplete"))
sw.Log(time.Time{}, codersdk.LogLevelWarn, troubleshootingMessage(agent,fmt.Sprintf("%s/templates#your-workspace-may-be-incomplete", opts.DocsURL)))
// Note: We don't complete or fail the stage here, it's
// intentionally left open to indicate this stage didn't
// complete.
Expand All@@ -252,7 +253,7 @@ func Agent(ctx context.Context, writer io.Writer, agentID uuid.UUID, opts AgentO
stage := "The workspace agent lost connection"
sw.Start(stage)
sw.Log(time.Now(), codersdk.LogLevelWarn, "Wait for it to reconnect or restart your workspace.")
sw.Log(time.Now(), codersdk.LogLevelWarn, troubleshootingMessage(agent,"https://coder.com/docs/templates/troubleshooting#agent-connection-issues"))
sw.Log(time.Now(), codersdk.LogLevelWarn, troubleshootingMessage(agent,fmt.Sprintf("%s/templates#agent-connection-issues", opts.DocsURL)))

disconnectedAt := agent.DisconnectedAt
for agent.Status == codersdk.WorkspaceAgentDisconnected {
Expand DownExpand Up@@ -351,16 +352,16 @@ func PeerDiagnostics(w io.Writer, d tailnet.PeerDiagnostics) {
}

type ConnDiags struct {
ConnInfo workspacesdk.AgentConnectionInfo
PingP2P bool
DisableDirect bool
LocalNetInfo *tailcfg.NetInfo
LocalInterfaces *healthsdk.InterfacesReport
AgentNetcheck *healthsdk.AgentNetcheckReport
ClientIPIsAWS bool
AgentIPIsAWS bool
Verbose bool
// TODO: More diagnostics
ConnInfoworkspacesdk.AgentConnectionInfo
PingP2Pbool
DisableDirectbool
LocalNetInfo*tailcfg.NetInfo
LocalInterfaces*healthsdk.InterfacesReport
AgentNetcheck*healthsdk.AgentNetcheckReport
ClientIPIsAWSbool
AgentIPIsAWSbool
Verbosebool
TroubleshootingURL string
}

func (d ConnDiags) Write(w io.Writer) {
Expand DownExpand Up@@ -395,7 +396,7 @@ func (d ConnDiags) splitDiagnostics() (general, client, agent []string) {
agent = append(agent, msg.Message)
}
if len(d.AgentNetcheck.Interfaces.Warnings) > 0 {
agent[len(agent)-1] +="\nhttps://coder.com/docs/networking/troubleshooting#low-mtu"
agent[len(agent)-1] +=fmt.Sprintf("\n%s#low-mtu", d.TroubleshootingURL)
}
}

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

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

if d.ConnInfo.DisableDirectConnections {
general = append(general, "❗ Your Coder administrator has blocked direct connections\n"+
" https://coder.com/docs/networking/troubleshooting#disabled-deployment-wide")
general = append(general,
fmt.Sprintf("❗ Your Coder administrator has blocked direct connections\n %s#disabled-deployment-wide", d.TroubleshootingURL))
if !d.Verbose {
return general, client, agent
}
}

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

if d.LocalNetInfo != nil && d.LocalNetInfo.MappingVariesByDestIP.EqualBool(true) {
client = append(client, "Client is potentially behind a hard NAT, as multiple endpoints were retrieved from different STUN servers\n"+
" https://coder.com/docs/networking/troubleshooting#Endpoint-Dependent-Nat-Hard-NAT")
client = append(client,
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))
}

if d.AgentNetcheck != nil && d.AgentNetcheck.NetInfo != nil {
if d.AgentNetcheck.NetInfo.MappingVariesByDestIP.EqualBool(true) {
agent = append(agent, "Agent is potentially behind a hard NAT, as multiple endpoints were retrieved from different STUN servers\n"+
" https://coder.com/docs/networking/troubleshooting#Endpoint-Dependent-Nat-Hard-NAT")
agent = append(agent,
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))
}
if !d.AgentNetcheck.NetInfo.UDP {
agent = append(agent, "Agent could not connect to STUN over UDP\n"+
" https://coder.com/docs/networking/troubleshooting#udp-blocked")
agent = append(agent,
fmt.Sprintf("Agent could not connect to STUN over UDP\n %s#udp-blocked", d.TroubleshootingURL))
}
}

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

if d.AgentIPIsAWS {
agent = append(agent, "Agent IP address is within an AWS range (AWS uses hard NAT)\n"+
" https://coder.com/docs/networking/troubleshooting#Endpoint-Dependent-Nat-Hard-NAT")
agent = append(agent,
fmt.Sprintf("Agent IP address is within an AWS range (AWS uses hard NAT)\n %s#endpoint-dependent-nat-hard-nat", d.TroubleshootingURL))
}
return general, client, agent
}
2 changes: 1 addition & 1 deletioncli/dotfiles.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -203,7 +203,7 @@ func (r *RootCmd) dotfiles() *serpent.Command {
}

if fi.Mode()&0o111 == 0 {
return xerrors.Errorf("script %qis notexecutable. See https://coder.com/docs/dotfiles for information on how to resolve the issue.", script)
return xerrors.Errorf("script %qdoes nothave execute permissions", script)
}

// it is safe to use a variable command here because it's from
Expand Down
7 changes: 5 additions & 2 deletionscli/open.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -35,8 +35,9 @@ const vscodeDesktopName = "VS Code Desktop"

func (r *RootCmd) openVSCode() *serpent.Command {
var (
generateToken bool
testOpenError bool
generateToken bool
testOpenError bool
appearanceConfig codersdk.AppearanceConfig
)

client := new(codersdk.Client)
Expand All@@ -47,6 +48,7 @@ func (r *RootCmd) openVSCode() *serpent.Command {
Middleware: serpent.Chain(
serpent.RequireRangeArgs(1, 2),
r.InitClient(client),
initAppearance(client, &appearanceConfig),
),
Handler: func(inv *serpent.Invocation) error {
ctx, cancel := context.WithCancel(inv.Context())
Expand DownExpand Up@@ -79,6 +81,7 @@ func (r *RootCmd) openVSCode() *serpent.Command {
Fetch: client.WorkspaceAgent,
FetchLogs: nil,
Wait: false,
DocsURL: appearanceConfig.DocsURL,
})
if err != nil {
if xerrors.Is(err, context.Canceled) {
Expand Down
23 changes: 13 additions & 10 deletionscli/ping.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,9 +26,10 @@ import (

func (r *RootCmd) ping() *serpent.Command {
var (
pingNum int64
pingTimeout time.Duration
pingWait time.Duration
pingNum int64
pingTimeout time.Duration
pingWait time.Duration
appearanceConfig codersdk.AppearanceConfig
)

client := new(codersdk.Client)
Expand All@@ -39,6 +40,7 @@ func (r *RootCmd) ping() *serpent.Command {
Middleware: serpent.Chain(
serpent.RequireNArgs(1),
r.InitClient(client),
initAppearance(client, &appearanceConfig),
),
Handler: func(inv *serpent.Invocation) error {
ctx, cancel := context.WithCancel(inv.Context())
Expand DownExpand Up@@ -67,8 +69,8 @@ func (r *RootCmd) ping() *serpent.Command {
if !r.disableNetworkTelemetry {
opts.EnableTelemetry = true
}
client := workspacesdk.New(client)
conn, err :=client.DialAgent(ctx, workspaceAgent.ID, opts)
wsClient := workspacesdk.New(client)
conn, err :=wsClient.DialAgent(ctx, workspaceAgent.ID, opts)
if err != nil {
return err
}
Expand DownExpand Up@@ -155,10 +157,11 @@ func (r *RootCmd) ping() *serpent.Command {

ni := conn.GetNetInfo()
connDiags := cliui.ConnDiags{
PingP2P: didP2p,
DisableDirect: r.disableDirect,
LocalNetInfo: ni,
Verbose: r.verbose,
PingP2P: didP2p,
DisableDirect: r.disableDirect,
LocalNetInfo: ni,
Verbose: r.verbose,
TroubleshootingURL: appearanceConfig.DocsURL + "/networking/troubleshooting",
}

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

connDiags.ClientIPIsAWS = isAWSIP(awsRanges, ni)

connInfo, err :=client.AgentConnectionInfoGeneric(diagCtx)
connInfo, err :=wsClient.AgentConnectionInfoGeneric(diagCtx)
if err != nil || connInfo.DERPMap == nil {
return xerrors.Errorf("Failed to retrieve connection info from server: %w\n", err)
}
Expand Down
7 changes: 5 additions & 2 deletionscli/portforward.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,6 +29,7 @@ func (r *RootCmd) portForward() *serpent.Command {
tcpForwards []string // <port>:<port>
udpForwards []string // <port>:<port>
disableAutostart bool
appearanceConfig codersdk.AppearanceConfig
)
client := new(codersdk.Client)
cmd := &serpent.Command{
Expand DownExpand Up@@ -60,6 +61,7 @@ func (r *RootCmd) portForward() *serpent.Command {
Middleware: serpent.Chain(
serpent.RequireNArgs(1),
r.InitClient(client),
initAppearance(client, &appearanceConfig),
),
Handler: func(inv *serpent.Invocation) error {
ctx, cancel := context.WithCancel(inv.Context())
Expand DownExpand Up@@ -88,8 +90,9 @@ func (r *RootCmd) portForward() *serpent.Command {
}

err = cliui.Agent(ctx, inv.Stderr, workspaceAgent.ID, cliui.AgentOptions{
Fetch: client.WorkspaceAgent,
Wait: false,
Fetch: client.WorkspaceAgent,
Wait: false,
DocsURL: appearanceConfig.DocsURL,
})
if err != nil {
return xerrors.Errorf("await agent: %w", err)
Expand Down
4 changes: 3 additions & 1 deletioncli/rename.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,6 +13,7 @@ import (
)

func (r *RootCmd) rename() *serpent.Command {
var appearanceConfig codersdk.AppearanceConfig
client := new(codersdk.Client)
cmd := &serpent.Command{
Annotations: workspaceCommand,
Expand All@@ -21,6 +22,7 @@ func (r *RootCmd) rename() *serpent.Command {
Middleware: serpent.Chain(
serpent.RequireNArgs(2),
r.InitClient(client),
initAppearance(client, &appearanceConfig),
),
Handler: func(inv *serpent.Invocation) error {
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
Expand All@@ -31,7 +33,7 @@ func (r *RootCmd) rename() *serpent.Command {
_, _ = fmt.Fprintf(inv.Stdout, "%s\n\n",
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."),
)
_, _ = fmt.Fprintf(inv.Stdout, "See: %s\n\n","https://coder.com/docs/templates/resource-persistence#%EF%B8%8F-persistence-pitfalls")
_, _ = fmt.Fprintf(inv.Stdout, "See: %s%s\n\n",appearanceConfig.DocsURL, "/templates/resource-persistence#%EF%B8%8F-persistence-pitfalls")
_, err = cliui.Prompt(inv, cliui.PromptOptions{
Text: fmt.Sprintf("Type %q to confirm rename:", workspace.Name),
Validate: func(s string) error {
Expand Down
20 changes: 20 additions & 0 deletionscli/root.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -692,6 +692,26 @@ func namedWorkspace(ctx context.Context, client *codersdk.Client, identifier str
return client.WorkspaceByOwnerAndName(ctx, owner, name, codersdk.WorkspaceOptions{})
}

func initAppearance(client *codersdk.Client, outConfig *codersdk.AppearanceConfig) serpent.MiddlewareFunc {
return func(next serpent.HandlerFunc) serpent.HandlerFunc {
return func(inv *serpent.Invocation) error {
var err error
cfg, err := client.Appearance(inv.Context())
if err != nil {
var sdkErr *codersdk.Error
if !(xerrors.As(err, &sdkErr) && sdkErr.StatusCode() == http.StatusNotFound) {
return err
}
}
if cfg.DocsURL == "" {
cfg.DocsURL = codersdk.DefaultDocsURL()
}
*outConfig = cfg
return next(inv)
}
}
}

// createConfig consumes the global configuration flag to produce a config root.
func (r *RootCmd) createConfig() config.Root {
return config.Root(r.globalConfig)
Expand Down
4 changes: 2 additions & 2 deletionscli/server.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -628,7 +628,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
"new version of coder available",
slog.F("new_version", r.Version),
slog.F("url", r.URL),
slog.F("upgrade_instructions","https://coder.com/docs/admin/upgrade"),
slog.F("upgrade_instructions",fmt.Sprintf("%s/admin/upgrade", vals.DocsURL.String())),
)
}
},
Expand DownExpand Up@@ -854,7 +854,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
}
defer options.Telemetry.Close()
} else {
logger.Warn(ctx, `telemetry disabled, unable to notify of security issues. Read more:https://coder.com/docs/admin/telemetry`)
logger.Warn(ctx,fmt.Sprintf(`telemetry disabled, unable to notify of security issues. Read more:%s/admin/telemetry`, vals.DocsURL.String()))
}

// This prevents the pprof import from being accidentally deleted.
Expand Down
17 changes: 10 additions & 7 deletionscli/speedtest.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -36,11 +36,12 @@ type speedtestTableItem struct {

func (r *RootCmd) speedtest() *serpent.Command {
var (
direct bool
duration time.Duration
direction string
pcapFile string
formatter = cliui.NewOutputFormatter(
direct bool
duration time.Duration
direction string
pcapFile string
appearanceConfig codersdk.AppearanceConfig
formatter = cliui.NewOutputFormatter(
cliui.ChangeFormatterData(cliui.TableFormat([]speedtestTableItem{}, []string{"Interval", "Throughput"}), func(data any) (any, error) {
res, ok := data.(SpeedtestResult)
if !ok {
Expand DownExpand Up@@ -72,6 +73,7 @@ func (r *RootCmd) speedtest() *serpent.Command {
Middleware: serpent.Chain(
serpent.RequireNArgs(1),
r.InitClient(client),
initAppearance(client, &appearanceConfig),
),
Handler: func(inv *serpent.Invocation) error {
ctx, cancel := context.WithCancel(inv.Context())
Expand All@@ -87,8 +89,9 @@ func (r *RootCmd) speedtest() *serpent.Command {
}

err = cliui.Agent(ctx, inv.Stderr, workspaceAgent.ID, cliui.AgentOptions{
Fetch: client.WorkspaceAgent,
Wait: false,
Fetch: client.WorkspaceAgent,
Wait: false,
DocsURL: appearanceConfig.DocsURL,
})
if err != nil {
return xerrors.Errorf("await agent: %w", err)
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp