mirror of https://github.com/coder/coder.git
feat(agent): add http debug routes for magicsock (#7287)
This commit is contained in:
parent
272573e9f0
commit
3eb7f06bf1
|
@ -60,7 +60,7 @@ type Options struct {
|
|||
ReconnectingPTYTimeout time.Duration
|
||||
EnvironmentVariables map[string]string
|
||||
Logger slog.Logger
|
||||
AgentPorts map[int]string
|
||||
IgnorePorts map[int]string
|
||||
SSHMaxTimeout time.Duration
|
||||
TailnetListenPort uint16
|
||||
}
|
||||
|
@ -76,7 +76,12 @@ type Client interface {
|
|||
PatchStartupLogs(ctx context.Context, req agentsdk.PatchStartupLogs) error
|
||||
}
|
||||
|
||||
func New(options Options) io.Closer {
|
||||
type Agent interface {
|
||||
HTTPDebug() http.Handler
|
||||
io.Closer
|
||||
}
|
||||
|
||||
func New(options Options) Agent {
|
||||
if options.ReconnectingPTYTimeout == 0 {
|
||||
options.ReconnectingPTYTimeout = 5 * time.Minute
|
||||
}
|
||||
|
@ -112,7 +117,7 @@ func New(options Options) io.Closer {
|
|||
tempDir: options.TempDir,
|
||||
lifecycleUpdate: make(chan struct{}, 1),
|
||||
lifecycleReported: make(chan codersdk.WorkspaceAgentLifecycle, 1),
|
||||
ignorePorts: options.AgentPorts,
|
||||
ignorePorts: options.IgnorePorts,
|
||||
connStatsChan: make(chan *agentsdk.Stats, 1),
|
||||
sshMaxTimeout: options.SSHMaxTimeout,
|
||||
}
|
||||
|
@ -1264,6 +1269,27 @@ func (a *agent) isClosed() bool {
|
|||
}
|
||||
}
|
||||
|
||||
func (a *agent) HTTPDebug() http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
a.closeMutex.Lock()
|
||||
network := a.network
|
||||
a.closeMutex.Unlock()
|
||||
|
||||
if network == nil {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte("network is not ready yet"))
|
||||
return
|
||||
}
|
||||
|
||||
if r.URL.Path == "/debug/magicsock" {
|
||||
network.MagicsockServeHTTPDebug(w, r)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
_, _ = w.Write([]byte("404 not found"))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (a *agent) Close() error {
|
||||
a.closeMutex.Lock()
|
||||
defer a.closeMutex.Unlock()
|
||||
|
|
28
cli/agent.go
28
cli/agent.go
|
@ -38,6 +38,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
|
|||
sshMaxTimeout time.Duration
|
||||
tailnetListenPort int64
|
||||
prometheusAddress string
|
||||
debugAddress string
|
||||
)
|
||||
cmd := &clibase.Cmd{
|
||||
Use: "agent",
|
||||
|
@ -48,7 +49,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
|
|||
ctx, cancel := context.WithCancel(inv.Context())
|
||||
defer cancel()
|
||||
|
||||
agentPorts := map[int]string{}
|
||||
ignorePorts := map[int]string{}
|
||||
|
||||
isLinux := runtime.GOOS == "linux"
|
||||
|
||||
|
@ -125,14 +126,14 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
|
|||
defer pprofSrvClose()
|
||||
// Do a best effort here. If this fails, it's not a big deal.
|
||||
if port, err := urlPort(pprofAddress); err == nil {
|
||||
agentPorts[port] = "pprof"
|
||||
ignorePorts[port] = "pprof"
|
||||
}
|
||||
|
||||
prometheusSrvClose := ServeHandler(ctx, logger, prometheusMetricsHandler(), prometheusAddress, "prometheus")
|
||||
defer prometheusSrvClose()
|
||||
// Do a best effort here. If this fails, it's not a big deal.
|
||||
if port, err := urlPort(prometheusAddress); err == nil {
|
||||
agentPorts[port] = "prometheus"
|
||||
ignorePorts[port] = "prometheus"
|
||||
}
|
||||
|
||||
// exchangeToken returns a session token.
|
||||
|
@ -196,7 +197,7 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
|
|||
return xerrors.Errorf("add executable to $PATH: %w", err)
|
||||
}
|
||||
|
||||
closer := agent.New(agent.Options{
|
||||
agnt := agent.New(agent.Options{
|
||||
Client: client,
|
||||
Logger: logger,
|
||||
LogDir: logDir,
|
||||
|
@ -215,11 +216,19 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
|
|||
EnvironmentVariables: map[string]string{
|
||||
"GIT_ASKPASS": executablePath,
|
||||
},
|
||||
AgentPorts: agentPorts,
|
||||
IgnorePorts: ignorePorts,
|
||||
SSHMaxTimeout: sshMaxTimeout,
|
||||
})
|
||||
|
||||
debugSrvClose := ServeHandler(ctx, logger, agnt.HTTPDebug(), debugAddress, "debug")
|
||||
defer debugSrvClose()
|
||||
// Do a best effort here. If this fails, it's not a big deal.
|
||||
if port, err := urlPort(debugAddress); err == nil {
|
||||
ignorePorts[port] = "debug"
|
||||
}
|
||||
|
||||
<-ctx.Done()
|
||||
return closer.Close()
|
||||
return agnt.Close()
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -273,6 +282,13 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
|
|||
Value: clibase.StringOf(&prometheusAddress),
|
||||
Description: "The bind address to serve Prometheus metrics.",
|
||||
},
|
||||
{
|
||||
Flag: "debug-address",
|
||||
Default: "127.0.0.1:2113",
|
||||
Env: "CODER_AGENT_DEBUG_ADDRESS",
|
||||
Value: clibase.StringOf(&debugAddress),
|
||||
Description: "The bind address to serve a debug HTTP server.",
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
|
|
@ -6,6 +6,9 @@ Starts the Coder workspace agent.
|
|||
--auth string, $CODER_AGENT_AUTH (default: token)
|
||||
Specify the authentication type to use for the agent.
|
||||
|
||||
--debug-address string, $CODER_AGENT_DEBUG_ADDRESS (default: 127.0.0.1:2113)
|
||||
The bind address to serve a debug HTTP server.
|
||||
|
||||
--log-dir string, $CODER_AGENT_LOG_DIR (default: /tmp)
|
||||
Specify the location for the agent log files.
|
||||
|
||||
|
|
|
@ -828,6 +828,10 @@ func (c *Conn) SetConnStatsCallback(maxPeriod time.Duration, maxConns int, dump
|
|||
c.tunDevice.SetStatistics(connStats)
|
||||
}
|
||||
|
||||
func (c *Conn) MagicsockServeHTTPDebug(w http.ResponseWriter, r *http.Request) {
|
||||
c.magicConn.ServeHTTPDebug(w, r)
|
||||
}
|
||||
|
||||
type listenKey struct {
|
||||
network string
|
||||
host string
|
||||
|
|
Loading…
Reference in New Issue