Skip to content
This repository has been archived by the owner on Jan 20, 2021. It is now read-only.

Commit

Permalink
Enable pprof/debug endpoints by default
Browse files Browse the repository at this point in the history
Makes sure that debug endpoints are always available, which will aid in
debugging demon issues.

Wraps debug endpoints in the middleware chain so the can be blocked by
authz.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
  • Loading branch information
cpuguy83 committed Jul 17, 2017
1 parent 458f671 commit 408c7ad
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 65 deletions.
46 changes: 0 additions & 46 deletions api/server/profiler.go

This file was deleted.

53 changes: 53 additions & 0 deletions api/server/router/debug/debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package debug

import (
"expvar"
"net/http"
"net/http/pprof"

"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/server/router"
"golang.org/x/net/context"
)

// NewRouter creates a new debug router
// The debug router holds endpoints for debug the daemon, such as those for pprof.
func NewRouter() router.Router {
r := &debugRouter{}
r.initRoutes()
return r
}

type debugRouter struct {
routes []router.Route
}

func (r *debugRouter) initRoutes() {
r.routes = []router.Route{
router.NewGetRoute("/vars", frameworkAdaptHandler(expvar.Handler())),
router.NewGetRoute("/pprof/", frameworkAdaptHandlerFunc(pprof.Index)),
router.NewGetRoute("/pprof/cmdline", frameworkAdaptHandlerFunc(pprof.Cmdline)),
router.NewGetRoute("/pprof/profile", frameworkAdaptHandlerFunc(pprof.Profile)),
router.NewGetRoute("/pprof/symbol", frameworkAdaptHandlerFunc(pprof.Symbol)),
router.NewGetRoute("/pprof/trace", frameworkAdaptHandlerFunc(pprof.Trace)),
router.NewGetRoute("/pprof/{name}", handlePprof),
}
}

func (r *debugRouter) Routes() []router.Route {
return r.routes
}

func frameworkAdaptHandler(handler http.Handler) httputils.APIFunc {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
handler.ServeHTTP(w, r)
return nil
}
}

func frameworkAdaptHandlerFunc(handler http.HandlerFunc) httputils.APIFunc {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
handler(w, r)
return nil
}
}
13 changes: 13 additions & 0 deletions api/server/router/debug/debug_routes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package debug

import (
"net/http"
"net/http/pprof"

"golang.org/x/net/context"
)

func handlePprof(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
pprof.Handler(vars["name"]).ServeHTTP(w, r)
return nil
}
25 changes: 9 additions & 16 deletions api/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/docker/docker/api/server/httputils"
"github.com/docker/docker/api/server/middleware"
"github.com/docker/docker/api/server/router"
"github.com/docker/docker/api/server/router/debug"
"github.com/docker/docker/dockerversion"
"github.com/gorilla/mux"
"golang.org/x/net/context"
Expand Down Expand Up @@ -148,13 +149,10 @@ func (s *Server) makeHTTPHandler(handler httputils.APIFunc) http.HandlerFunc {

// InitRouter initializes the list of routers for the server.
// This method also enables the Go profiler if enableProfiler is true.
func (s *Server) InitRouter(enableProfiler bool, routers ...router.Router) {
func (s *Server) InitRouter(routers ...router.Router) {
s.routers = append(s.routers, routers...)

m := s.createMux()
if enableProfiler {
profilerSetup(m)
}
s.routerSwapper = &routerSwapper{
router: m,
}
Expand All @@ -175,6 +173,13 @@ func (s *Server) createMux() *mux.Router {
}
}

debugRouter := debug.NewRouter()
s.routers = append(s.routers, debugRouter)
for _, r := range debugRouter.Routes() {
f := s.makeHTTPHandler(r.Handler())
m.Path("/debug" + r.Path()).Handler(f)
}

err := errors.NewRequestNotFoundError(fmt.Errorf("page not found"))
notFoundHandler := httputils.MakeErrorHandler(err)
m.HandleFunc(versionMatcher+"/{path:.*}", notFoundHandler)
Expand All @@ -194,15 +199,3 @@ func (s *Server) Wait(waitChan chan error) {
}
waitChan <- nil
}

// DisableProfiler reloads the server mux without adding the profiler routes.
func (s *Server) DisableProfiler() {
s.routerSwapper.Swap(s.createMux())
}

// EnableProfiler reloads the server mux adding the profiler routes.
func (s *Server) EnableProfiler() {
m := s.createMux()
profilerSetup(m)
s.routerSwapper.Swap(m)
}
4 changes: 1 addition & 3 deletions cmd/dockerd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,10 +383,8 @@ func (cli *DaemonCli) reloadConfig() {
switch {
case debugEnabled && !config.Debug: // disable debug
debug.Disable()
cli.api.DisableProfiler()
case config.Debug && !debugEnabled: // enable debug
debug.Enable()
cli.api.EnableProfiler()
}

}
Expand Down Expand Up @@ -536,7 +534,7 @@ func initRouter(opts routerOptions) {
}
}

opts.api.InitRouter(debug.IsEnabled(), routers...)
opts.api.InitRouter(routers...)
}

// TODO: remove this from cli and return the authzMiddleware
Expand Down

0 comments on commit 408c7ad

Please sign in to comment.