diff options
Diffstat (limited to 'pkg/api/server/server.go')
-rw-r--r-- | pkg/api/server/server.go | 86 |
1 files changed, 42 insertions, 44 deletions
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index 2bda5ad01..8c940763e 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -1,32 +1,3 @@ -// Package serviceapi Provides a Container compatible interface. -// -// This documentation describes the HTTP LibPod interface -// -// Schemes: http, https -// Host: podman.io -// BasePath: / -// Version: 0.0.1 -// License: Apache-2.0 https://opensource.org/licenses/Apache-2.0 -// Contact: Podman <podman@lists.podman.io> https://podman.io/community/ -// -// Consumes: -// - application/json -// - application/x-tar -// -// Produces: -// - application/json -// - text/plain -// - text/html -// -// tags: -// - name: "Containers" -// description: manage containers -// - name: "Images" -// description: manage images -// - name: "System" -// description: manage system resources -// -// swagger:meta package server import ( @@ -40,6 +11,7 @@ import ( "time" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/api/handlers" "github.com/coreos/go-systemd/activation" "github.com/gorilla/mux" "github.com/gorilla/schema" @@ -48,9 +20,9 @@ import ( ) type APIServer struct { - http.Server // Where the HTTP work happens + http.Server // The HTTP work happens here *schema.Decoder // Decoder for Query parameters to structs - context.Context // Context for graceful server shutdown + context.Context // Context to carry objects to handlers *libpod.Runtime // Where the real work happens net.Listener // mux for routing HTTP API calls to libpod routines context.CancelFunc // Stop APIServer @@ -58,14 +30,37 @@ type APIServer struct { time.Duration // Duration of client access sliding window } -// NewServer will create and configure a new API HTTP server +// Number of seconds to wait for next request, if exceeded shutdown server +const ( + DefaultServiceDuration = 300 * time.Second + UnlimitedServiceDuration = 0 * time.Second +) + +// NewServer will create and configure a new API server with all defaults func NewServer(runtime *libpod.Runtime) (*APIServer, error) { - listeners, err := activation.Listeners() - if err != nil { - return nil, errors.Wrap(err, "Cannot retrieve file descriptors from systemd") - } - if len(listeners) != 1 { - return nil, errors.Errorf("Wrong number of file descriptors from systemd for socket activation (%d != 1)", len(listeners)) + return newServer(runtime, DefaultServiceDuration, nil) +} + +// NewServerWithSettings will create and configure a new API server using provided settings +func NewServerWithSettings(runtime *libpod.Runtime, duration time.Duration, listener *net.Listener) (*APIServer, error) { + return newServer(runtime, duration, listener) +} + +func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Listener) (*APIServer, error) { + // If listener not provided try socket activation protocol + if listener == nil { + if _, found := os.LookupEnv("LISTEN_FDS"); !found { + return nil, errors.Errorf("Cannot create Server, no listener provided and socket activation protocol is not active.") + } + + listeners, err := activation.Listeners() + if err != nil { + return nil, errors.Wrap(err, "Cannot retrieve file descriptors from systemd") + } + if len(listeners) != 1 { + return nil, errors.Errorf("Wrong number of file descriptors for socket activation protocol (%d != 1)", len(listeners)) + } + listener = &listeners[0] } router := mux.NewRouter() @@ -77,12 +72,12 @@ func NewServer(runtime *libpod.Runtime) (*APIServer, error) { ReadTimeout: 20 * time.Second, WriteTimeout: 2 * time.Minute, }, - Decoder: schema.NewDecoder(), + Decoder: handlers.NewAPIDecoder(), Context: nil, Runtime: runtime, - Listener: listeners[0], + Listener: *listener, CancelFunc: nil, - Duration: 300 * time.Second, + Duration: duration, } server.Timer = time.AfterFunc(server.Duration, func() { if err := server.Shutdown(); err != nil { @@ -91,6 +86,7 @@ func NewServer(runtime *libpod.Runtime) (*APIServer, error) { }) ctx, cancelFn := context.WithCancel(context.Background()) + server.CancelFunc = cancelFn // TODO: Use ConnContext when ported to go 1.13 ctx = context.WithValue(ctx, "decoder", server.Decoder) @@ -98,9 +94,6 @@ func NewServer(runtime *libpod.Runtime) (*APIServer, error) { ctx = context.WithValue(ctx, "shutdownFunc", server.Shutdown) server.Context = ctx - server.CancelFunc = cancelFn - server.Decoder.IgnoreUnknownKeys(true) - router.NotFoundHandler = http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { // We can track user errors... @@ -176,6 +169,11 @@ func (s *APIServer) Serve() error { // Shutdown is a clean shutdown waiting on existing clients func (s *APIServer) Shutdown() error { + // Duration == 0 flags no auto-shutdown of server + if s.Duration == 0 { + return nil + } + // We're still in the sliding service window if s.Timer.Stop() { s.Timer.Reset(s.Duration) |