diff options
Diffstat (limited to 'pkg/api/server')
-rw-r--r-- | pkg/api/server/listener_api.go | 31 | ||||
-rw-r--r-- | pkg/api/server/register_containers.go | 25 | ||||
-rw-r--r-- | pkg/api/server/register_images.go | 12 | ||||
-rw-r--r-- | pkg/api/server/register_pods.go | 3 | ||||
-rw-r--r-- | pkg/api/server/server.go | 50 |
5 files changed, 100 insertions, 21 deletions
diff --git a/pkg/api/server/listener_api.go b/pkg/api/server/listener_api.go new file mode 100644 index 000000000..4984216b8 --- /dev/null +++ b/pkg/api/server/listener_api.go @@ -0,0 +1,31 @@ +package server + +import ( + "net" + "os" + "path/filepath" + + "github.com/pkg/errors" +) + +// ListenUnix follows stdlib net.Listen() API, providing a unix listener for given path +// ListenUnix will delete and create files/directories as needed +func ListenUnix(network string, path string) (net.Listener, error) { + // setup custom listener for API server + err := os.MkdirAll(filepath.Dir(path), 0770) + if err != nil { + return nil, errors.Wrapf(err, "api.ListenUnix() failed to create %s", filepath.Dir(path)) + } + os.Remove(path) + + listener, err := net.Listen(network, path) + if err != nil { + return nil, errors.Wrapf(err, "api.ListenUnix() failed to create net.Listen(%s, %s)", network, path) + } + + _, err = os.Stat(path) + if err != nil { + return nil, errors.Wrapf(err, "net.Listen(%s, %s) failed to report the failure to create socket", network, path) + } + return listener, nil +} diff --git a/pkg/api/server/register_containers.go b/pkg/api/server/register_containers.go index 6f4222d8f..833bb5197 100644 --- a/pkg/api/server/register_containers.go +++ b/pkg/api/server/register_containers.go @@ -665,7 +665,7 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/kill"), APIHandler(s.Context, libpod.KillContainer)).Methods(http.MethodGet) - // swagger:operation GET /libpod/containers/{nameOrID}/mount libpod mountContainer + // swagger:operation POST /libpod/containers/{nameOrID}/mount libpod mountContainer // --- // tags: // - containers @@ -684,12 +684,33 @@ func (s *APIServer) RegisterContainersHandlers(r *mux.Router) error { // schema: // description: id // type: string - // example: 3c784de79b791b4ebd3ac55e511f97fedc042328499554937a3f8bfd9c1a2cb8 + // example: /var/lib/containers/storage/overlay/f3f693bd88872a1e3193f4ebb925f4c282e8e73aadb8ab3e7492754dda3a02a4/merged // '404': // "$ref": "#/responses/NoSuchContainer" // '500': // "$ref": "#/responses/InternalError" r.HandleFunc(VersionedPath("/libpod/containers/{name:..*}/mount"), APIHandler(s.Context, libpod.MountContainer)).Methods(http.MethodPost) + // swagger:operation GET /libpod/containers/{nameOrID}/unmount libpod unmountContainer + // --- + // tags: + // - containers + // summary: Unmount a container + // description: Unmount a container from the filesystem + // parameters: + // - in: path + // name: nameOrID + // required: true + // description: the name or ID of the container + // produces: + // - application/json + // responses: + // '204': + // description: no error + // '404': + // "$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:..*}/logs"), APIHandler(s.Context, libpod.LogsFromContainer)).Methods(http.MethodGet) // swagger:operation POST /libpod/containers/{nameOrID}/pause libpod libpodPauseContainer // --- diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go index 744bc1ace..8ea079654 100644 --- a/pkg/api/server/register_images.go +++ b/pkg/api/server/register_images.go @@ -193,8 +193,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // responses: // '200': // $ref: "#/responses/DocsImageDeleteResponse" - // '400': - // $ref: '#/responses/BadParamError' + // '404': + // $ref: '#/responses/NoSuchImage' // '409': // $ref: '#/responses/ConflictError' // '500': @@ -710,11 +710,7 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // - application/json // responses: // '200': - // schema: - // items: - // $ref: "#/responses/DocsIageDeleteResponse" - // '400': - // $ref: "#/responses/BadParamError" + // $ref: "#/responses/DocsImageDeleteResponse" // '404': // $ref: '#/responses/NoSuchImage' // '409': @@ -737,10 +733,12 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error { // name: format // type: string // description: format for exported image + // default: oci-archive // - in: query // name: compress // type: bool // description: use compression on image + // default: false // produces: // - application/json // responses: diff --git a/pkg/api/server/register_pods.go b/pkg/api/server/register_pods.go index 5069326b6..4018cfbe8 100644 --- a/pkg/api/server/register_pods.go +++ b/pkg/api/server/register_pods.go @@ -121,8 +121,9 @@ func (s *APIServer) registerPodsHandlers(r *mux.Router) error { // description: the name or ID of the pod // - in: query // name: signal - // type: int + // type: string // description: signal to be sent to pod + // default: SIGKILL // responses: // '204': // description: no error diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go index a64995a26..69a44f21a 100644 --- a/pkg/api/server/server.go +++ b/pkg/api/server/server.go @@ -60,9 +60,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 @@ -70,14 +70,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() @@ -92,9 +115,9 @@ func NewServer(runtime *libpod.Runtime) (*APIServer, error) { Decoder: schema.NewDecoder(), 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 { @@ -188,6 +211,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) |