feat(agent): add http debug routes for magicsock (#7287)

This commit is contained in:
Colin Adler 2023-04-26 13:01:49 -05:00 committed by GitHub
parent 272573e9f0
commit 3eb7f06bf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 9 deletions

View File

@ -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()

View File

@ -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

View File

@ -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.

View File

@ -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