diff options
Diffstat (limited to 'pkg/api/server')
-rw-r--r-- | pkg/api/server/handler_api.go | 52 | ||||
-rw-r--r-- | pkg/api/server/register_auth.go | 4 | ||||
-rw-r--r-- | pkg/api/server/register_containers.go | 120 | ||||
-rw-r--r-- | pkg/api/server/register_distribution.go | 2 | ||||
-rw-r--r-- | pkg/api/server/register_events.go | 6 | ||||
-rw-r--r-- | pkg/api/server/register_exec.go | 20 | ||||
-rw-r--r-- | pkg/api/server/register_healthcheck.go | 2 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 106 | ||||
-rw-r--r-- | pkg/api/server/register_info.go | 2 | ||||
-rw-r--r-- | pkg/api/server/register_monitor.go | 4 | ||||
-rw-r--r-- | pkg/api/server/register_ping.go | 8 | ||||
-rw-r--r-- | pkg/api/server/register_plugins.go | 4 | ||||
-rw-r--r-- | pkg/api/server/register_pods.go | 43 | ||||
-rw-r--r-- | pkg/api/server/register_swarm.go | 2 | ||||
-rw-r--r-- | pkg/api/server/register_system.go | 4 | ||||
-rw-r--r-- | pkg/api/server/register_version.go | 6 | ||||
-rw-r--r-- | pkg/api/server/register_volumes.go | 16 | ||||
-rw-r--r-- | pkg/api/server/server.go | 120 |
18 files changed, 308 insertions, 213 deletions
diff --git a/pkg/api/server/handler_api.go b/pkg/api/server/handler_api.go index 4b93998ee..30a1680c9 100644 --- a/pkg/api/server/handler_api.go +++ b/pkg/api/server/handler_api.go @@ -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) - // 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) + if err := r.ParseForm(); err != nil { + log.Infof("Failed Request: unable to parse form: %q", err) + } - h(w, r) + // 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) - shutdownFunc := r.Context().Value("shutdownFunc").(func() error) - if err := shutdownFunc(); err != nil { - log.Errorf("Failed to shutdown Server in APIHandler(): %s", err.Error()) + h(w, r) } - }) + fn(w, r) + } } // VersionedPath prepends the version parsing code diff --git a/pkg/api/server/register_auth.go b/pkg/api/server/register_auth.go index 9f312683d..8db131153 100644 --- a/pkg/api/server/register_auth.go +++ b/pkg/api/server/register_auth.go @@ -5,7 +5,7 @@ import ( "github.com/gorilla/mux" ) -func (s *APIServer) RegisterAuthHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/auth"), APIHandler(s.Context, handlers.UnsupportedHandler)) +func (s *APIServer) registerAuthHandlers(r *mux.Router) error { + r.Handle(VersionedPath("/auth"), s.APIHandler(handlers.UnsupportedHandler)) return nil } diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index b1facc27c..6007a2d00 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -9,8 +9,8 @@ import ( "github.com/gorilla/mux" ) -func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { - // swagger:operation POST /containers/create compat containerCreate +func (s *APIServer) registerContainersHandlers(r *mux.Router) error { + // swagger:operation POST /containers/create compat createContainer // --- // summary: Create a container // tags: @@ -33,7 +33,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/create"), APIHandler(s.Context, handlers.CreateContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/create"), s.APIHandler(generic.CreateContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/json compat listContainers // --- // tags: @@ -83,7 +83,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/json"), APIHandler(s.Context, generic.ListContainers)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/containers/json"), s.APIHandler(generic.ListContainers)).Methods(http.MethodGet) // swagger:operation POST /containers/prune compat pruneContainers // --- // tags: @@ -105,7 +105,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/DocsContainerPruneReport" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/prune"), APIHandler(s.Context, handlers.PruneContainers)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/prune"), s.APIHandler(handlers.PruneContainers)).Methods(http.MethodPost) // swagger:operation DELETE /containers/{name} compat removeContainer // --- // tags: @@ -144,7 +144,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}"), APIHandler(s.Context, generic.RemoveContainer)).Methods(http.MethodDelete) + r.HandleFunc(VersionedPath("/containers/{name}"), s.APIHandler(generic.RemoveContainer)).Methods(http.MethodDelete) // swagger:operation GET /containers/{name}/json compat getContainer // --- // tags: @@ -171,8 +171,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/json"), APIHandler(s.Context, generic.GetContainer)).Methods(http.MethodGet) - // swagger:operation post /containers/{name}/kill compat killcontainer + r.HandleFunc(VersionedPath("/containers/{name}/json"), s.APIHandler(generic.GetContainer)).Methods(http.MethodGet) + // swagger:operation POST /containers/{name}/kill compat killContainer // --- // tags: // - containers (compat) @@ -201,8 +201,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/kill"), APIHandler(s.Context, generic.KillContainer)).Methods(http.MethodPost) - // swagger:operation GET /containers/{name}/logs compat LogsFromContainer + r.HandleFunc(VersionedPath("/containers/{name}/kill"), s.APIHandler(generic.KillContainer)).Methods(http.MethodPost) + // swagger:operation GET /containers/{name}/logs compat logsFromContainer // --- // tags: // - containers (compat) @@ -253,7 +253,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/logs"), APIHandler(s.Context, generic.LogsFromContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/containers/{name}/logs"), s.APIHandler(generic.LogsFromContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/pause compat pauseContainer // --- // tags: @@ -275,8 +275,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/pause"), APIHandler(s.Context, handlers.PauseContainer)).Methods(http.MethodPost) - r.HandleFunc(VersionedPath("/containers/{name}/rename"), APIHandler(s.Context, handlers.UnsupportedHandler)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/pause"), s.APIHandler(handlers.PauseContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/rename"), s.APIHandler(handlers.UnsupportedHandler)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/restart compat restartContainer // --- // tags: @@ -301,7 +301,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/restart"), APIHandler(s.Context, handlers.RestartContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/restart"), s.APIHandler(handlers.RestartContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/start compat startContainer // --- // tags: @@ -329,7 +329,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/start"), APIHandler(s.Context, handlers.StartContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/start"), s.APIHandler(handlers.StartContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{name}/stats compat statsContainer // --- // tags: @@ -356,7 +356,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/stats"), APIHandler(s.Context, generic.StatsContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/containers/{name}/stats"), s.APIHandler(generic.StatsContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/stop compat stopContainer // --- // tags: @@ -384,7 +384,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/stop"), APIHandler(s.Context, handlers.StopContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/stop"), s.APIHandler(handlers.StopContainer)).Methods(http.MethodPost) // swagger:operation GET /containers/{name}/top compat topContainer // --- // tags: @@ -409,7 +409,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/top"), APIHandler(s.Context, handlers.TopContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/containers/{name}/top"), s.APIHandler(handlers.TopContainer)).Methods(http.MethodGet) // swagger:operation POST /containers/{name}/unpause compat unpauseContainer // --- // tags: @@ -431,7 +431,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/unpause"), APIHandler(s.Context, handlers.UnpauseContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/unpause"), s.APIHandler(handlers.UnpauseContainer)).Methods(http.MethodPost) // swagger:operation POST /containers/{name}/wait compat waitContainer // --- // tags: @@ -457,8 +457,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/wait"), APIHandler(s.Context, generic.WaitContainer)).Methods(http.MethodPost) - // swagger:operation POST /containers/{name}/attach compat attach + r.HandleFunc(VersionedPath("/containers/{name}/wait"), s.APIHandler(generic.WaitContainer)).Methods(http.MethodPost) + // swagger:operation POST /containers/{name}/attach compat attachContainer // --- // tags: // - containers (compat) @@ -512,8 +512,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/attach"), APIHandler(s.Context, handlers.AttachContainer)).Methods(http.MethodPost) - // swagger:operation POST /containers/{name}/resize compat resize + r.HandleFunc(VersionedPath("/containers/{name}/attach"), s.APIHandler(handlers.AttachContainer)).Methods(http.MethodPost) + // swagger:operation POST /containers/{name}/resize compat resizeContainer // --- // tags: // - containers (compat) @@ -544,13 +544,37 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/containers/{name}/resize"), APIHandler(s.Context, handlers.ResizeContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/containers/{name}/resize"), s.APIHandler(handlers.ResizeContainer)).Methods(http.MethodPost) /* libpod endpoints */ - r.HandleFunc(VersionedPath("/libpod/containers/create"), APIHandler(s.Context, handlers.CreateContainer)).Methods(http.MethodPost) + // swagger:operation POST /containers/create libpod libpodContainerCreate + // --- + // summary: Create a container + // tags: + // - containers + // produces: + // - application/json + // parameters: + // - in: body + // name: create + // description: attributes for creating a container + // schema: + // $ref: "#/definitions/SpecGenerator" + // responses: + // 201: + // $ref: "#/responses/ContainerCreateResponse" + // 400: + // $ref: "#/responses/BadParamError" + // 404: + // $ref: "#/responses/NoSuchContainer" + // 409: + // $ref: "#/responses/ConflictError" + // 500: + // $ref: "#/responses/InternalError" + r.HandleFunc(VersionedPath("/libpod/containers/create"), s.APIHandler(libpod.CreateContainer)).Methods(http.MethodPost) // swagger:operation GET /libpod/containers/json libpod libpodListContainers // --- // tags: @@ -615,7 +639,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/json"), APIHandler(s.Context, libpod.ListContainers)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/containers/json"), s.APIHandler(libpod.ListContainers)).Methods(http.MethodGet) // swagger:operation POST /libpod/containers/prune libpod libpodPruneContainers // --- // tags: @@ -637,8 +661,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/DocsLibpodPruneResponse" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/prune"), APIHandler(s.Context, handlers.PruneContainers)).Methods(http.MethodPost) - // swagger:operation GET /libpod/containers/showmounted libpod showMounterContainers + r.HandleFunc(VersionedPath("/libpod/containers/prune"), s.APIHandler(handlers.PruneContainers)).Methods(http.MethodPost) + // swagger:operation GET /libpod/containers/showmounted libpod showMountedContainers // --- // tags: // - containers @@ -655,7 +679,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // type: string // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/showmounted"), APIHandler(s.Context, libpod.ShowMountedContainers)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/containers/showmounted"), s.APIHandler(libpod.ShowMountedContainers)).Methods(http.MethodGet) // swagger:operation DELETE /libpod/containers/{name} libpod libpodRemoveContainer // --- // tags: @@ -689,7 +713,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}"), APIHandler(s.Context, libpod.RemoveContainer)).Methods(http.MethodDelete) + r.HandleFunc(VersionedPath("/libpod/containers/{name}"), s.APIHandler(libpod.RemoveContainer)).Methods(http.MethodDelete) // swagger:operation GET /libpod/containers/{name}/json libpod libpodGetContainer // --- // tags: @@ -715,7 +739,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/json"), APIHandler(s.Context, libpod.GetContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/json"), s.APIHandler(libpod.GetContainer)).Methods(http.MethodGet) // swagger:operation POST /libpod/containers/{name}/kill libpod libpodKillContainer // --- // tags: @@ -744,8 +768,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/kill"), APIHandler(s.Context, libpod.KillContainer)).Methods(http.MethodGet) - // swagger:operation GET /libpod/containers/{name}/mount libpod mountContainer + r.HandleFunc(VersionedPath("/libpod/containers/{name}/kill"), s.APIHandler(libpod.KillContainer)).Methods(http.MethodPost) + // swagger:operation POST /libpod/containers/{name}/mount libpod mountContainer // --- // tags: // - containers @@ -770,7 +794,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/mount"), APIHandler(s.Context, libpod.MountContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/mount"), s.APIHandler(libpod.MountContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/unmount libpod libpodUnmountContainer // --- // tags: @@ -792,7 +816,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/unmount"), APIHandler(s.Context, libpod.UnmountContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/unmount"), s.APIHandler(libpod.UnmountContainer)).Methods(http.MethodPost) // swagger:operation GET /libpod/containers/{name}/logs libpod libpodLogsFromContainer // --- // tags: @@ -844,7 +868,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/logs"), APIHandler(s.Context, generic.LogsFromContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/logs"), s.APIHandler(generic.LogsFromContainer)).Methods(http.MethodGet) // swagger:operation POST /libpod/containers/{name}/pause libpod libpodPauseContainer // --- // tags: @@ -866,7 +890,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // "$ref": "#/responses/NoSuchContainer" // 500: // "$ref": "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/pause"), APIHandler(s.Context, handlers.PauseContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/pause"), s.APIHandler(handlers.PauseContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/restart libpod libpodRestartContainer // --- // tags: @@ -891,7 +915,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/restart"), APIHandler(s.Context, handlers.RestartContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/restart"), s.APIHandler(handlers.RestartContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/start libpod libpodStartContainer // --- // tags: @@ -919,7 +943,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/start"), APIHandler(s.Context, handlers.StartContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/start"), s.APIHandler(handlers.StartContainer)).Methods(http.MethodPost) // swagger:operation GET /libpod/containers/{name}/stats libpod libpodStatsContainer // --- // tags: @@ -946,7 +970,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/stats"), APIHandler(s.Context, generic.StatsContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/stats"), s.APIHandler(generic.StatsContainer)).Methods(http.MethodGet) // swagger:operation GET /libpod/containers/{name}/top libpod libpodTopContainer // --- // tags: @@ -980,7 +1004,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/top"), APIHandler(s.Context, handlers.TopContainer)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/top"), s.APIHandler(handlers.TopContainer)).Methods(http.MethodGet) // swagger:operation POST /libpod/containers/{name}/unpause libpod libpodUnpauseContainer // --- // tags: @@ -1001,7 +1025,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/unpause"), APIHandler(s.Context, handlers.UnpauseContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/unpause"), s.APIHandler(handlers.UnpauseContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/wait libpod libpodWaitContainer // --- // tags: @@ -1022,8 +1046,8 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/wait"), APIHandler(s.Context, libpod.WaitContainer)).Methods(http.MethodPost) - // swagger:operation POST /libpod/containers/{name}/exists libpod containerExists + r.HandleFunc(VersionedPath("/libpod/containers/{name}/wait"), s.APIHandler(libpod.WaitContainer)).Methods(http.MethodPost) + // swagger:operation GET /libpod/containers/{name}/exists libpod containerExists // --- // tags: // - containers @@ -1044,7 +1068,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/exists"), APIHandler(s.Context, libpod.ContainerExists)).Methods(http.MethodGet) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/exists"), s.APIHandler(libpod.ContainerExists)).Methods(http.MethodGet) // swagger:operation POST /libpod/containers/{name}/stop libpod libpodStopContainer // --- // tags: @@ -1071,7 +1095,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/stop"), APIHandler(s.Context, handlers.StopContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/stop"), s.APIHandler(handlers.StopContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/attach libpod libpodAttach // --- // tags: @@ -1126,7 +1150,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/attach"), APIHandler(s.Context, handlers.AttachContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/attach"), s.APIHandler(handlers.AttachContainer)).Methods(http.MethodPost) // swagger:operation POST /libpod/containers/{name}/resize libpod libpodResize // --- // tags: @@ -1158,6 +1182,6 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchContainer" // 500: // $ref: "#/responses/InternalError" - r.HandleFunc(VersionedPath("/libpod/containers/{name}/resize"), APIHandler(s.Context, handlers.ResizeContainer)).Methods(http.MethodPost) + r.HandleFunc(VersionedPath("/libpod/containers/{name}/resize"), s.APIHandler(handlers.ResizeContainer)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/register_distribution.go b/pkg/api/server/register_distribution.go index b0ac61fb8..f03662224 100644 --- a/pkg/api/server/register_distribution.go +++ b/pkg/api/server/register_distribution.go @@ -5,7 +5,7 @@ import ( "github.com/gorilla/mux" ) -func (s *APIServer) RegisterDistributionHandlers(r *mux.Router) error { +func (s *APIServer) registerDistributionHandlers(r *mux.Router) error { r.HandleFunc(VersionedPath("/distribution/{name}/json"), handlers.UnsupportedHandler) return nil } diff --git a/pkg/api/server/register_events.go b/pkg/api/server/register_events.go index 090f66323..bc3b62662 100644 --- a/pkg/api/server/register_events.go +++ b/pkg/api/server/register_events.go @@ -1,11 +1,13 @@ package server import ( + "net/http" + "github.com/containers/libpod/pkg/api/handlers" "github.com/gorilla/mux" ) -func (s *APIServer) RegisterEventsHandlers(r *mux.Router) error { +func (s *APIServer) registerEventsHandlers(r *mux.Router) error { // swagger:operation GET /events system getEvents // --- // tags: @@ -32,6 +34,6 @@ func (s *APIServer) RegisterEventsHandlers(r *mux.Router) error { // description: returns a string of json data describing an event // 500: // "$ref": "#/responses/InternalError" - r.Handle(VersionedPath("/events"), APIHandler(s.Context, handlers.GetEvents)) + r.Handle(VersionedPath("/events"), s.APIHandler(handlers.GetEvents)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_exec.go b/pkg/api/server/register_exec.go index dbf04dc19..ad62de3f5 100644 --- a/pkg/api/server/register_exec.go +++ b/pkg/api/server/register_exec.go @@ -74,7 +74,7 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // description: container is paused // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/containers/{name}/create"), APIHandler(s.Context, handlers.CreateExec)).Methods(http.MethodPost) + r.Handle(VersionedPath("/containers/{name}/create"), s.APIHandler(handlers.CreateExec)).Methods(http.MethodPost) // swagger:operation POST /exec/{id}/start compat startExec // --- // tags: @@ -110,7 +110,7 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // description: container is stopped or paused // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/exec/{id}/start"), APIHandler(s.Context, handlers.StartExec)).Methods(http.MethodPost) + r.Handle(VersionedPath("/exec/{id}/start"), s.APIHandler(handlers.StartExec)).Methods(http.MethodPost) // swagger:operation POST /exec/{id}/resize compat resizeExec // --- // tags: @@ -141,8 +141,8 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchExecInstance" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/exec/{id}/resize"), APIHandler(s.Context, handlers.ResizeExec)).Methods(http.MethodPost) - // swagger:operation GET /exec/{id}/inspect compat inspectExec + r.Handle(VersionedPath("/exec/{id}/resize"), s.APIHandler(handlers.ResizeExec)).Methods(http.MethodPost) + // swagger:operation GET /exec/{id}/json compat inspectExec // --- // tags: // - exec (compat) @@ -163,7 +163,7 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchExecInstance" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/exec/{id}/json"), APIHandler(s.Context, handlers.InspectExec)).Methods(http.MethodGet) + r.Handle(VersionedPath("/exec/{id}/json"), s.APIHandler(handlers.InspectExec)).Methods(http.MethodGet) /* libpod api follows @@ -235,7 +235,7 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // description: container is paused // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/containers/{name}/create"), APIHandler(s.Context, handlers.CreateExec)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/containers/{name}/create"), s.APIHandler(handlers.CreateExec)).Methods(http.MethodPost) // swagger:operation POST /libpod/exec/{id}/start libpod libpodStartExec // --- // tags: @@ -271,7 +271,7 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // description: container is stopped or paused // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/exec/{id}/start"), APIHandler(s.Context, handlers.StartExec)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/exec/{id}/start"), s.APIHandler(handlers.StartExec)).Methods(http.MethodPost) // swagger:operation POST /libpod/exec/{id}/resize libpod libpodResizeExec // --- // tags: @@ -302,8 +302,8 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchExecInstance" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/exec/{id}/resize"), APIHandler(s.Context, handlers.ResizeExec)).Methods(http.MethodPost) - // swagger:operation GET /libpod/exec/{id}/inspect libpod libpodInspectExec + r.Handle(VersionedPath("/libpod/exec/{id}/resize"), s.APIHandler(handlers.ResizeExec)).Methods(http.MethodPost) + // swagger:operation GET /libpod/exec/{id}/json libpod libpodInspectExec // --- // tags: // - exec @@ -324,6 +324,6 @@ func (s *APIServer) registerExecHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchExecInstance" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/exec/{id}/json"), APIHandler(s.Context, handlers.InspectExec)).Methods(http.MethodGet) + r.Handle(VersionedPath("/libpod/exec/{id}/json"), s.APIHandler(handlers.InspectExec)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_healthcheck.go b/pkg/api/server/register_healthcheck.go index 1286324f0..5466e2905 100644 --- a/pkg/api/server/register_healthcheck.go +++ b/pkg/api/server/register_healthcheck.go @@ -8,6 +8,6 @@ import ( ) func (s *APIServer) registerHealthCheckHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/libpod/containers/{name}/runhealthcheck"), APIHandler(s.Context, libpod.RunHealthCheck)).Methods(http.MethodGet) + r.Handle(VersionedPath("/libpod/containers/{name}/runhealthcheck"), s.APIHandler(libpod.RunHealthCheck)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 4706a7c69..4c8f05385 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -47,8 +47,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchImage" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/images/create"), APIHandler(s.Context, generic.CreateImageFromImage)).Methods(http.MethodPost).Queries("fromImage", "{fromImage}") - r.Handle(VersionedPath("/images/create"), APIHandler(s.Context, generic.CreateImageFromSrc)).Methods(http.MethodPost).Queries("fromSrc", "{fromSrc}") + r.Handle(VersionedPath("/images/create"), s.APIHandler(generic.CreateImageFromImage)).Methods(http.MethodPost).Queries("fromImage", "{fromImage}") + r.Handle(VersionedPath("/images/create"), s.APIHandler(generic.CreateImageFromSrc)).Methods(http.MethodPost).Queries("fromSrc", "{fromSrc}") // swagger:operation GET /images/json compat listImages // --- // tags: @@ -83,7 +83,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/DockerImageSummary" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/json"), APIHandler(s.Context, generic.GetImages)).Methods(http.MethodGet) + r.Handle(VersionedPath("/images/json"), s.APIHandler(generic.GetImages)).Methods(http.MethodGet) // swagger:operation POST /images/load compat importImage // --- // tags: @@ -107,7 +107,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: no error // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/load"), APIHandler(s.Context, generic.LoadImages)).Methods(http.MethodPost) + r.Handle(VersionedPath("/images/load"), s.APIHandler(generic.LoadImages)).Methods(http.MethodPost) // swagger:operation POST /images/prune compat pruneImages // --- // tags: @@ -132,7 +132,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/DocsImageDeleteResponse" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/prune"), APIHandler(s.Context, generic.PruneImages)).Methods(http.MethodPost) + r.Handle(VersionedPath("/images/prune"), s.APIHandler(generic.PruneImages)).Methods(http.MethodPost) // swagger:operation GET /images/search compat searchImages // --- // tags: @@ -161,10 +161,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // responses: // 200: // $ref: "#/responses/DocsSearchResponse" + // 400: + // $ref: "#/responses/BadParamError" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/search"), APIHandler(s.Context, handlers.SearchImages)).Methods(http.MethodGet) - // swagger:operation DELETE /images/{name} compat removeImage + r.Handle(VersionedPath("/images/search"), s.APIHandler(handlers.SearchImages)).Methods(http.MethodGet) + // swagger:operation DELETE /images/{name:.*} compat removeImage // --- // tags: // - images (compat) @@ -172,7 +174,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Delete an image from local storage // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: name or ID of image to delete @@ -195,8 +197,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/ConflictError' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/{name}"), APIHandler(s.Context, handlers.RemoveImage)).Methods(http.MethodDelete) - // swagger:operation GET /images/{name}/get compat exportImage + r.Handle(VersionedPath("/images/{name:.*}"), s.APIHandler(handlers.RemoveImage)).Methods(http.MethodDelete) + // swagger:operation GET /images/{name:.*}/get compat exportImage // --- // tags: // - images (compat) @@ -204,7 +206,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Export an image in tarball format // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: the name or ID of the container @@ -218,8 +220,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // format: binary // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/{name}/get"), APIHandler(s.Context, generic.ExportImage)).Methods(http.MethodGet) - // swagger:operation GET /images/{name}/history compat imageHistory + r.Handle(VersionedPath("/images/{name:.*}/get"), s.APIHandler(generic.ExportImage)).Methods(http.MethodGet) + // swagger:operation GET /images/{name:.*}/history compat imageHistory // --- // tags: // - images (compat) @@ -227,7 +229,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Return parent layers of an image. // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: the name or ID of the container @@ -240,8 +242,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchImage" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/images/{name}/history"), APIHandler(s.Context, handlers.HistoryImage)).Methods(http.MethodGet) - // swagger:operation GET /images/{name}/json compat inspectImage + r.Handle(VersionedPath("/images/{name:.*}/history"), s.APIHandler(handlers.HistoryImage)).Methods(http.MethodGet) + // swagger:operation GET /images/{name:.*}/json compat inspectImage // --- // tags: // - images (compat) @@ -249,7 +251,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Return low-level information about an image. // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: the name or ID of the container @@ -262,8 +264,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchImage" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/images/{name}/json"), APIHandler(s.Context, generic.GetImage)) - // swagger:operation POST /images/{name}/tag compat tagImage + r.Handle(VersionedPath("/images/{name:.*}/json"), s.APIHandler(generic.GetImage)).Methods(http.MethodGet) + // swagger:operation POST /images/{name:.*}/tag compat tagImage // --- // tags: // - images (compat) @@ -271,7 +273,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Tag an image so that it becomes part of a repository. // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: the name or ID of the container @@ -296,8 +298,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/ConflictError' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/images/{name}/tag"), APIHandler(s.Context, handlers.TagImage)).Methods(http.MethodPost) - // swagger:operation POST /commit/ compat commitContainer + r.Handle(VersionedPath("/images/{name:.*}/tag"), s.APIHandler(handlers.TagImage)).Methods(http.MethodPost) + // swagger:operation POST /commit compat commitContainer // --- // tags: // - containers (compat) @@ -341,9 +343,9 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/NoSuchImage' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/commit"), APIHandler(s.Context, generic.CommitContainer)).Methods(http.MethodPost) + r.Handle(VersionedPath("/commit"), s.APIHandler(generic.CommitContainer)).Methods(http.MethodPost) - // swagger:operation POST /build images buildImage + // swagger:operation POST /build compat buildImage // --- // tags: // - images @@ -551,12 +553,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/build"), APIHandler(s.Context, handlers.BuildImage)).Methods(http.MethodPost) + r.Handle(VersionedPath("/build"), s.APIHandler(handlers.BuildImage)).Methods(http.MethodPost) /* libpod endpoints */ - // swagger:operation POST /libpod/images/{name}/exists libpod libpodImageExists + // swagger:operation GET /libpod/images/{name:.*}/exists libpod libpodImageExists // --- // tags: // - images @@ -564,7 +566,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Check if image exists in local store // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: the name or ID of the container @@ -577,8 +579,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/NoSuchImage' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/{name}/exists"), APIHandler(s.Context, libpod.ImageExists)) - // swagger:operation POST /libpod/images/{name}/tree libpod libpodImageTree + r.Handle(VersionedPath("/libpod/images/{name:.*}/exists"), s.APIHandler(libpod.ImageExists)).Methods(http.MethodGet) + // swagger:operation GET /libpod/images/{name:.*}/tree libpod libpodImageTree // --- // tags: // - images @@ -586,7 +588,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Retrieve the image tree for the provided image name or ID // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: the name or ID of the container @@ -603,8 +605,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/NoSuchImage' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/{name}/tree"), APIHandler(s.Context, libpod.ImageTree)) - // swagger:operation GET /libpod/images/{name}/history libpod libpodImageHistory + r.Handle(VersionedPath("/libpod/images/{name:.*}/tree"), s.APIHandler(libpod.ImageTree)).Methods(http.MethodGet) + // swagger:operation GET /libpod/images/{name:.*}/history libpod libpodImageHistory // --- // tags: // - images @@ -612,7 +614,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Return parent layers of an image. // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: the name or ID of the container @@ -625,7 +627,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/NoSuchImage' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/{name}/history"), APIHandler(s.Context, handlers.HistoryImage)).Methods(http.MethodGet) + r.Handle(VersionedPath("/libpod/images/{name:.*}/history"), s.APIHandler(handlers.HistoryImage)).Methods(http.MethodGet) // swagger:operation GET /libpod/images/json libpod libpodListImages // --- // tags: @@ -655,7 +657,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/DockerImageSummary" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/json"), APIHandler(s.Context, libpod.GetImages)).Methods(http.MethodGet) + r.Handle(VersionedPath("/libpod/images/json"), s.APIHandler(libpod.GetImages)).Methods(http.MethodGet) // swagger:operation POST /libpod/images/load libpod libpodImagesLoad // --- // tags: @@ -681,7 +683,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/load"), APIHandler(s.Context, libpod.ImagesLoad)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/images/load"), s.APIHandler(libpod.ImagesLoad)).Methods(http.MethodPost) // swagger:operation POST /libpod/images/import libpod libpodImagesImport // --- // tags: @@ -721,7 +723,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/import"), APIHandler(s.Context, libpod.ImagesImport)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/images/import"), s.APIHandler(libpod.ImagesImport)).Methods(http.MethodPost) // swagger:operation POST /libpod/images/pull libpod libpodImagesPull // --- // tags: @@ -763,7 +765,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/pull"), APIHandler(s.Context, libpod.ImagesPull)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/images/pull"), s.APIHandler(libpod.ImagesPull)).Methods(http.MethodPost) // swagger:operation POST /libpod/images/prune libpod libpodPruneImages // --- // tags: @@ -788,7 +790,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/DocsImageDeleteResponse" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/prune"), APIHandler(s.Context, libpod.PruneImages)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/images/prune"), s.APIHandler(libpod.PruneImages)).Methods(http.MethodPost) // swagger:operation GET /libpod/images/search libpod libpodSearchImages // --- // tags: @@ -819,8 +821,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: "#/responses/DocsSearchResponse" // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/search"), APIHandler(s.Context, handlers.SearchImages)).Methods(http.MethodGet) - // swagger:operation DELETE /libpod/images/{name} libpod libpodRemoveImage + r.Handle(VersionedPath("/libpod/images/search"), s.APIHandler(handlers.SearchImages)).Methods(http.MethodGet) + // swagger:operation DELETE /libpod/images/{name:.*} libpod libpodRemoveImage // --- // tags: // - images @@ -828,7 +830,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Delete an image from local store // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: name or ID of image to delete @@ -849,8 +851,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/ConflictError' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/{name}"), APIHandler(s.Context, handlers.RemoveImage)).Methods(http.MethodDelete) - // swagger:operation GET /libpod/images/{name}/get libpod libpoodExportImage + r.Handle(VersionedPath("/libpod/images/{name:.*}"), s.APIHandler(handlers.RemoveImage)).Methods(http.MethodDelete) + // swagger:operation GET /libpod/images/{name:.*}/get libpod libpodExportImage // --- // tags: // - images @@ -858,7 +860,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Export an image as a tarball // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: the name or ID of the container @@ -882,8 +884,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/NoSuchImage' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/{name}/get"), APIHandler(s.Context, libpod.ExportImage)).Methods(http.MethodGet) - // swagger:operation GET /libpod/images/{name}/json libpod libpodInspectImage + r.Handle(VersionedPath("/libpod/images/{name:.*}/get"), s.APIHandler(libpod.ExportImage)).Methods(http.MethodGet) + // swagger:operation GET /libpod/images/{name:.*}/json libpod libpodInspectImage // --- // tags: // - images @@ -891,7 +893,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Obtain low-level information about an image // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: the name or ID of the container @@ -904,8 +906,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/NoSuchImage' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/{name}/json"), APIHandler(s.Context, libpod.GetImage)) - // swagger:operation POST /libpod/images/{name}/tag libpod libpodTagImage + r.Handle(VersionedPath("/libpod/images/{name:.*}/json"), s.APIHandler(libpod.GetImage)).Methods(http.MethodGet) + // swagger:operation POST /libpod/images/{name:.*}/tag libpod libpodTagImage // --- // tags: // - images @@ -913,7 +915,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // description: Tag an image so that it becomes part of a repository. // parameters: // - in: path - // name: name + // name: name:.* // type: string // required: true // description: the name or ID of the container @@ -938,7 +940,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // $ref: '#/responses/ConflictError' // 500: // $ref: '#/responses/InternalError' - r.Handle(VersionedPath("/libpod/images/{name}/tag"), APIHandler(s.Context, handlers.TagImage)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/images/{name:.*}/tag"), s.APIHandler(handlers.TagImage)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/register_info.go b/pkg/api/server/register_info.go index 8c50fed7f..36c467cc3 100644 --- a/pkg/api/server/register_info.go +++ b/pkg/api/server/register_info.go @@ -21,6 +21,6 @@ func (s *APIServer) registerInfoHandlers(r *mux.Router) error { // description: to be determined // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/info"), APIHandler(s.Context, generic.GetInfo)).Methods(http.MethodGet) + r.Handle(VersionedPath("/info"), s.APIHandler(generic.GetInfo)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_monitor.go b/pkg/api/server/register_monitor.go index e6c235419..dbe0d27ce 100644 --- a/pkg/api/server/register_monitor.go +++ b/pkg/api/server/register_monitor.go @@ -5,7 +5,7 @@ import ( "github.com/gorilla/mux" ) -func (s *APIServer) RegisterMonitorHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/monitor"), APIHandler(s.Context, handlers.UnsupportedHandler)) +func (s *APIServer) registerMonitorHandlers(r *mux.Router) error { + r.Handle(VersionedPath("/monitor"), s.APIHandler(handlers.UnsupportedHandler)) return nil } diff --git a/pkg/api/server/register_ping.go b/pkg/api/server/register_ping.go index 086e674a1..349a8a71a 100644 --- a/pkg/api/server/register_ping.go +++ b/pkg/api/server/register_ping.go @@ -9,8 +9,8 @@ import ( func (s *APIServer) registerPingHandlers(r *mux.Router) error { - r.Handle("/_ping", APIHandler(s.Context, handlers.Ping)).Methods(http.MethodGet) - r.Handle("/_ping", APIHandler(s.Context, handlers.Ping)).Methods(http.MethodHead) + r.Handle("/_ping", s.APIHandler(handlers.Ping)).Methods(http.MethodGet) + r.Handle("/_ping", s.APIHandler(handlers.Ping)).Methods(http.MethodHead) // swagger:operation GET /libpod/_ping libpod libpodPingGet // --- @@ -61,7 +61,7 @@ func (s *APIServer) registerPingHandlers(r *mux.Router) error { // determine if talking to Podman engine or another engine // 500: // $ref: "#/responses/InternalError" - r.Handle("/libpod/_ping", APIHandler(s.Context, handlers.Ping)).Methods(http.MethodGet) - r.Handle("/libpod/_ping", APIHandler(s.Context, handlers.Ping)).Methods(http.MethodHead) + r.Handle("/libpod/_ping", s.APIHandler(handlers.Ping)).Methods(http.MethodGet) + r.Handle("/libpod/_ping", s.APIHandler(handlers.Ping)).Methods(http.MethodHead) return nil } diff --git a/pkg/api/server/register_plugins.go b/pkg/api/server/register_plugins.go index 7fd6b9c4c..479a79d1f 100644 --- a/pkg/api/server/register_plugins.go +++ b/pkg/api/server/register_plugins.go @@ -5,7 +5,7 @@ import ( "github.com/gorilla/mux" ) -func (s *APIServer) RegisterPluginsHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/plugins"), APIHandler(s.Context, handlers.UnsupportedHandler)) +func (s *APIServer) registerPluginsHandlers(r *mux.Router) error { + r.Handle(VersionedPath("/plugins"), s.APIHandler(handlers.UnsupportedHandler)) return nil } diff --git a/pkg/api/server/register_pods.go b/pkg/api/server/register_pods.go index 974568d47..af2330665 100644 --- a/pkg/api/server/register_pods.go +++ b/pkg/api/server/register_pods.go @@ -25,8 +25,27 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // $ref: "#/responses/BadParamError" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/json"), APIHandler(s.Context, libpod.Pods)).Methods(http.MethodGet) - r.Handle(VersionedPath("/libpod/pods/create"), APIHandler(s.Context, libpod.PodCreate)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/pods/json"), s.APIHandler(libpod.Pods)).Methods(http.MethodGet) + // swagger:operation POST /libpod/pods/create pods CreatePod + // --- + // summary: Create a pod + // produces: + // - application/json + // parameters: + // - in: body + // name: create + // description: attributes for creating a pod + // schema: + // type: object + // $ref: "#/definitions/PodCreateConfig" + // responses: + // 200: + // $ref: "#/definitions/IdResponse" + // 400: + // $ref: "#/responses/BadParamError" + // 500: + // $ref: "#/responses/InternalError" + r.Handle(VersionedPath("/libpod/pods/create"), s.APIHandler(libpod.PodCreate)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/prune pods PrunePods // --- // summary: Prune unused pods @@ -45,7 +64,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // description: pod already exists // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/prune"), APIHandler(s.Context, libpod.PodPrune)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/pods/prune"), s.APIHandler(libpod.PodPrune)).Methods(http.MethodPost) // swagger:operation DELETE /libpod/pods/{name} pods removePod // --- // summary: Remove pod @@ -70,7 +89,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchPod" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/{name}"), APIHandler(s.Context, libpod.PodDelete)).Methods(http.MethodDelete) + r.Handle(VersionedPath("/libpod/pods/{name}"), s.APIHandler(libpod.PodDelete)).Methods(http.MethodDelete) // swagger:operation GET /libpod/pods/{name}/json pods inspectPod // --- // summary: Inspect pod @@ -89,7 +108,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchPod" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/{name}/json"), APIHandler(s.Context, libpod.PodInspect)).Methods(http.MethodGet) + r.Handle(VersionedPath("/libpod/pods/{name}/json"), s.APIHandler(libpod.PodInspect)).Methods(http.MethodGet) // swagger:operation GET /libpod/pods/{name}/exists pods podExists // --- // summary: Pod exists @@ -109,7 +128,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchPod" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/{name}/exists"), APIHandler(s.Context, libpod.PodExists)).Methods(http.MethodGet) + r.Handle(VersionedPath("/libpod/pods/{name}/exists"), s.APIHandler(libpod.PodExists)).Methods(http.MethodGet) // swagger:operation POST /libpod/pods/{name}/kill pods killPod // --- // summary: Kill a pod @@ -137,7 +156,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // $ref: "#/responses/ConflictError" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/{name}/kill"), APIHandler(s.Context, libpod.PodKill)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/pods/{name}/kill"), s.APIHandler(libpod.PodKill)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{name}/pause pods pausePod // --- // summary: Pause a pod @@ -157,7 +176,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchPod" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/{name}/pause"), APIHandler(s.Context, libpod.PodPause)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/pods/{name}/pause"), s.APIHandler(libpod.PodPause)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{name}/restart pods restartPod // --- // summary: Restart a pod @@ -176,7 +195,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchPod" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/{name}/restart"), APIHandler(s.Context, libpod.PodRestart)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/pods/{name}/restart"), s.APIHandler(libpod.PodRestart)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{name}/start pods startPod // --- // summary: Start a pod @@ -197,7 +216,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchPod" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/{name}/start"), APIHandler(s.Context, libpod.PodStart)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/pods/{name}/start"), s.APIHandler(libpod.PodStart)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{name}/stop pods stopPod // --- // summary: Stop a pod @@ -224,7 +243,7 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchPod" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/{name}/stop"), APIHandler(s.Context, libpod.PodStop)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/pods/{name}/stop"), s.APIHandler(libpod.PodStop)).Methods(http.MethodPost) // swagger:operation POST /libpod/pods/{name}/unpause pods unpausePod // --- // summary: Unpause a pod @@ -243,6 +262,6 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchPod" // 500: // $ref: "#/responses/InternalError" - r.Handle(VersionedPath("/libpod/pods/{name}/unpause"), APIHandler(s.Context, libpod.PodUnpause)).Methods(http.MethodPost) + r.Handle(VersionedPath("/libpod/pods/{name}/unpause"), s.APIHandler(libpod.PodUnpause)).Methods(http.MethodPost) return nil } diff --git a/pkg/api/server/register_swarm.go b/pkg/api/server/register_swarm.go index 63d8acfde..e37ac4e41 100644 --- a/pkg/api/server/register_swarm.go +++ b/pkg/api/server/register_swarm.go @@ -9,7 +9,7 @@ import ( "github.com/sirupsen/logrus" ) -func (s *APIServer) RegisterSwarmHandlers(r *mux.Router) error { +func (s *APIServer) registerSwarmHandlers(r *mux.Router) error { r.PathPrefix("/v{version:[0-9.]+}/configs/").HandlerFunc(noSwarm) r.PathPrefix("/v{version:[0-9.]+}/nodes/").HandlerFunc(noSwarm) r.PathPrefix("/v{version:[0-9.]+}/secrets/").HandlerFunc(noSwarm) diff --git a/pkg/api/server/register_system.go b/pkg/api/server/register_system.go index f0eaeffd2..188c1cdac 100644 --- a/pkg/api/server/register_system.go +++ b/pkg/api/server/register_system.go @@ -1,11 +1,13 @@ package server import ( + "net/http" + "github.com/containers/libpod/pkg/api/handlers/generic" "github.com/gorilla/mux" ) func (s *APIServer) registerSystemHandlers(r *mux.Router) error { - r.Handle(VersionedPath("/system/df"), APIHandler(s.Context, generic.GetDiskUsage)) + r.Handle(VersionedPath("/system/df"), s.APIHandler(generic.GetDiskUsage)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_version.go b/pkg/api/server/register_version.go index d3b47c2a9..ee01ad4b3 100644 --- a/pkg/api/server/register_version.go +++ b/pkg/api/server/register_version.go @@ -1,12 +1,14 @@ package server import ( + "net/http" + "github.com/containers/libpod/pkg/api/handlers" "github.com/gorilla/mux" ) func (s *APIServer) registerVersionHandlers(r *mux.Router) error { - r.Handle("/version", APIHandler(s.Context, handlers.VersionHandler)) - r.Handle(VersionedPath("/version"), APIHandler(s.Context, handlers.VersionHandler)) + r.Handle("/version", s.APIHandler(handlers.VersionHandler)).Methods(http.MethodGet) + r.Handle(VersionedPath("/version"), s.APIHandler(handlers.VersionHandler)).Methods(http.MethodGet) return nil } diff --git a/pkg/api/server/register_volumes.go b/pkg/api/server/register_volumes.go index d34c71238..efe56a3ad 100644 --- a/pkg/api/server/register_volumes.go +++ b/pkg/api/server/register_volumes.go @@ -18,9 +18,9 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // description: tbd // '500': // "$ref": "#/responses/InternalError" - r.Handle("/libpod/volumes/create", APIHandler(s.Context, libpod.CreateVolume)).Methods(http.MethodPost) - r.Handle("/libpod/volumes/json", APIHandler(s.Context, libpod.ListVolumes)).Methods(http.MethodGet) - // swagger:operation POST /volumes/prune volumes pruneVolumes + r.Handle("/libpod/volumes/create", s.APIHandler(libpod.CreateVolume)).Methods(http.MethodPost) + r.Handle("/libpod/volumes/json", s.APIHandler(libpod.ListVolumes)).Methods(http.MethodGet) + // swagger:operation POST /libpod/volumes/prune volumes pruneVolumes // --- // summary: Prune volumes // produces: @@ -30,8 +30,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // description: no error // '500': // "$ref": "#/responses/InternalError" - r.Handle("/libpod/volumes/prune", APIHandler(s.Context, libpod.PruneVolumes)).Methods(http.MethodPost) - // swagger:operation GET /volumes/{name}/json volumes inspectVolume + r.Handle("/libpod/volumes/prune", s.APIHandler(libpod.PruneVolumes)).Methods(http.MethodPost) + // swagger:operation GET /libpod/volumes/{name}/json volumes inspectVolume // --- // summary: Inspect volume // parameters: @@ -49,8 +49,8 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // "$ref": "#/responses/NoSuchVolume" // '500': // "$ref": "#/responses/InternalError" - r.Handle("/libpod/volumes/{name}/json", APIHandler(s.Context, libpod.InspectVolume)).Methods(http.MethodGet) - // swagger:operation DELETE /volumes/{name} volumes removeVolume + r.Handle("/libpod/volumes/{name}/json", s.APIHandler(libpod.InspectVolume)).Methods(http.MethodGet) + // swagger:operation DELETE /libpod/volumes/{name} volumes removeVolume // --- // summary: Remove volume // parameters: @@ -74,6 +74,6 @@ func (s *APIServer) registerVolumeHandlers(r *mux.Router) error { // $ref: "#/responses/NoSuchVolume" // 500: // $ref: "#/responses/InternalError" - r.Handle("/libpod/volumes/{name}", APIHandler(s.Context, libpod.RemoveVolume)).Methods(http.MethodDelete) + r.Handle("/libpod/volumes/{name}", s.APIHandler(libpod.RemoveVolume)).Methods(http.MethodDelete) return nil } diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index 2c709bc59..e7b2a5525 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -20,20 +20,26 @@ import ( ) type APIServer struct { - http.Server // The HTTP work happens here - *schema.Decoder // Decoder for Query parameters to structs - 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 - *time.Timer // Hold timer for sliding window - time.Duration // Duration of client access sliding window + http.Server // The HTTP work happens here + *schema.Decoder // Decoder for Query parameters to structs + 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 + *time.Timer // Hold timer for sliding window + time.Duration // Duration of client access sliding window + ActiveConnections uint64 // Number of handlers holding a connection + TotalConnections uint64 // Number of connections handled + ConnectionCh chan int // Channel for signalling handler enter/exit } // Number of seconds to wait for next request, if exceeded shutdown server const ( DefaultServiceDuration = 300 * time.Second UnlimitedServiceDuration = 0 * time.Second + EnterHandler = 1 + ExitHandler = -1 + NOOPHandler = 0 ) // NewServer will create and configure a new API server with all defaults @@ -68,31 +74,19 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li Server: http.Server{ Handler: router, ReadHeaderTimeout: 20 * time.Second, - ReadTimeout: 20 * time.Second, - WriteTimeout: 2 * time.Minute, + IdleTimeout: duration, }, - Decoder: handlers.NewAPIDecoder(), - Context: nil, - Runtime: runtime, - Listener: *listener, - CancelFunc: nil, - Duration: duration, + Decoder: handlers.NewAPIDecoder(), + Runtime: runtime, + Listener: *listener, + Duration: duration, + ConnectionCh: make(chan int), } + server.Timer = time.AfterFunc(server.Duration, func() { - if err := server.Shutdown(); err != nil { - logrus.Errorf("unable to shutdown server: %q", err) - } + server.ConnectionCh <- NOOPHandler }) - 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) - ctx = context.WithValue(ctx, "runtime", runtime) - ctx = context.WithValue(ctx, "shutdownFunc", server.Shutdown) - server.Context = ctx - router.NotFoundHandler = http.HandlerFunc( func(w http.ResponseWriter, r *http.Request) { // We can track user errors... @@ -102,20 +96,19 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li ) for _, fn := range []func(*mux.Router) error{ - server.RegisterAuthHandlers, - server.RegisterContainersHandlers, - server.RegisterDistributionHandlers, + server.registerAuthHandlers, + server.registerContainersHandlers, + server.registerDistributionHandlers, server.registerExecHandlers, - server.RegisterEventsHandlers, + server.registerEventsHandlers, server.registerHealthCheckHandlers, server.registerImagesHandlers, server.registerInfoHandlers, - server.RegisterMonitorHandlers, + server.registerMonitorHandlers, server.registerPingHandlers, - server.RegisterPluginsHandlers, + server.registerPluginsHandlers, server.registerPodsHandlers, - server.RegisterSwaggerHandlers, - server.RegisterSwarmHandlers, + server.registerSwarmHandlers, server.registerSystemHandlers, server.registerVersionHandlers, server.registerVolumeHandlers, @@ -145,7 +138,41 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li // Serve starts responding to HTTP requests func (s *APIServer) Serve() error { - defer s.CancelFunc() + // stalker to count the connections. Should the timer expire it will shutdown the service. + go func() { + for { + select { + case delta := <-s.ConnectionCh: + // Always stop the current timer, things will change... + s.Timer.Stop() + switch delta { + case EnterHandler: + s.ActiveConnections += 1 + s.TotalConnections += 1 + case ExitHandler: + s.ActiveConnections -= 1 + if s.ActiveConnections == 0 { + // Server will be shutdown iff the timer expires before being reset or stopped + s.Timer = time.AfterFunc(s.Duration, func() { + if err := s.Shutdown(); err != nil { + logrus.Errorf("Failed to shutdown APIServer: %v", err) + os.Exit(1) + } + }) + } else { + s.Timer.Reset(s.Duration) + } + case NOOPHandler: + // push the check out another duration... + s.Timer.Reset(s.Duration) + default: + logrus.Errorf("ConnectionCh received unsupported input %d", delta) + } + default: + time.Sleep(1 * time.Second) + } + } + }() sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) @@ -155,6 +182,7 @@ func (s *APIServer) Serve() error { err := s.Server.Serve(s.Listener) if err != nil && err != http.ErrServerClosed { errChan <- errors.Wrap(err, "Failed to start APIServer") + return } errChan <- nil }() @@ -171,27 +199,23 @@ 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 + // Duration == 0 flags no auto-shutdown of the server if s.Duration == 0 { + logrus.Debug("APIServer.Shutdown ignored as Duration == 0") return nil } + logrus.Debugf("APIServer.Shutdown called %v, conn %d/%d", time.Now(), s.ActiveConnections, s.TotalConnections) - // We're still in the sliding service window - if s.Timer.Stop() { - s.Timer.Reset(s.Duration) - return nil - } + // Gracefully shutdown server + ctx, cancel := context.WithTimeout(context.Background(), s.Duration) + defer cancel() - // We've been idle for the service window, really shutdown go func() { - err := s.Server.Shutdown(s.Context) + err := s.Server.Shutdown(ctx) if err != nil && err != context.Canceled { logrus.Errorf("Failed to cleanly shutdown APIServer: %s", err.Error()) } }() - - // Wait for graceful shutdown vs. just killing connections and dropping data - <-s.Context.Done() return nil } |