mirror of
https://github.com/containers/podman.git
synced 2025-09-19 00:29:42 +08:00
Fix handler and systemd activation errors
On panic from handler: log warning and stack trace, report InternalServerError to client When using `podman system service` make determining the listening endpoint deterministic. // When determining _*THE*_ listening endpoint -- // 1) User input wins always // 2) systemd socket activation // 3) rootless honors XDG_RUNTIME_DIR // 4) if varlink -- adapter.DefaultVarlinkAddress // 5) lastly adapter.DefaultAPIAddress Fixes #5150 Fixes #5151 Signed-off-by: Jhon Honce <jhonce@redhat.com>
This commit is contained in:
@ -2,32 +2,52 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"runtime"
|
||||
|
||||
"github.com/containers/libpod/pkg/api/handlers/utils"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// APIHandler is a wrapper to enhance HandlerFunc's and remove redundant code
|
||||
func APIHandler(ctx context.Context, h http.HandlerFunc) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debugf("APIHandler -- Method: %s URL: %s", r.Method, r.URL.String())
|
||||
if err := r.ParseForm(); err != nil {
|
||||
log.Infof("Failed Request: unable to parse form: %q", err)
|
||||
func (s *APIServer) APIHandler(h http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// http.Server hides panics, we want to see them and fix the cause.
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err != nil {
|
||||
buf := make([]byte, 1<<20)
|
||||
n := runtime.Stack(buf, true)
|
||||
log.Warnf("Recovering from podman handler panic: %v, %s", err, buf[:n])
|
||||
// Try to inform client things went south... won't work if handler already started writing response body
|
||||
utils.InternalServerError(w, fmt.Errorf("%v", err))
|
||||
}
|
||||
}()
|
||||
|
||||
// Wrapper to hide some boiler plate
|
||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||
// Connection counting, ugh. Needed to support the sliding window for idle checking.
|
||||
s.ConnectionCh <- EnterHandler
|
||||
defer func() { s.ConnectionCh <- ExitHandler }()
|
||||
|
||||
log.Debugf("APIHandler -- Method: %s URL: %s (conn %d/%d)",
|
||||
r.Method, r.URL.String(), s.ActiveConnections, s.TotalConnections)
|
||||
|
||||
if err := r.ParseForm(); err != nil {
|
||||
log.Infof("Failed Request: unable to parse form: %q", err)
|
||||
}
|
||||
|
||||
// TODO: Use r.ConnContext when ported to go 1.13
|
||||
c := context.WithValue(r.Context(), "decoder", s.Decoder)
|
||||
c = context.WithValue(c, "runtime", s.Runtime)
|
||||
c = context.WithValue(c, "shutdownFunc", s.Shutdown)
|
||||
r = r.WithContext(c)
|
||||
|
||||
h(w, r)
|
||||
}
|
||||
|
||||
// TODO: Use ConnContext when ported to go 1.13
|
||||
c := context.WithValue(r.Context(), "decoder", ctx.Value("decoder"))
|
||||
c = context.WithValue(c, "runtime", ctx.Value("runtime"))
|
||||
c = context.WithValue(c, "shutdownFunc", ctx.Value("shutdownFunc"))
|
||||
r = r.WithContext(c)
|
||||
|
||||
h(w, r)
|
||||
|
||||
shutdownFunc := r.Context().Value("shutdownFunc").(func() error)
|
||||
if err := shutdownFunc(); err != nil {
|
||||
log.Errorf("Failed to shutdown Server in APIHandler(): %s", err.Error())
|
||||
}
|
||||
})
|
||||
fn(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
// VersionedPath prepends the version parsing code
|
||||
|
Reference in New Issue
Block a user