summaryrefslogtreecommitdiff
path: root/pkg/api
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/api')
-rw-r--r--pkg/api/handlers/compat/containers.go2
-rw-r--r--pkg/api/handlers/compat/images_history.go2
-rw-r--r--pkg/api/handlers/libpod/pods.go7
-rw-r--r--pkg/api/handlers/libpod/swagger.go29
-rw-r--r--pkg/api/handlers/utils/containers.go2
-rw-r--r--pkg/api/handlers/utils/pods.go45
-rw-r--r--pkg/api/server/register_manifest.go12
-rw-r--r--pkg/api/server/register_swagger.go15
-rw-r--r--pkg/api/server/server.go91
9 files changed, 142 insertions, 63 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index 1298e7fa4..e7031f471 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -87,7 +87,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
utils.InternalServerError(w, err)
return
}
- if _, found := r.URL.Query()["limit"]; found {
+ if _, found := r.URL.Query()["limit"]; found && query.Limit != -1 {
last := query.Limit
if len(containers) > last {
containers = containers[len(containers)-last:]
diff --git a/pkg/api/handlers/compat/images_history.go b/pkg/api/handlers/compat/images_history.go
index 04304caa4..afadf4c48 100644
--- a/pkg/api/handlers/compat/images_history.go
+++ b/pkg/api/handlers/compat/images_history.go
@@ -28,7 +28,7 @@ func HistoryImage(w http.ResponseWriter, r *http.Request) {
for _, h := range history {
l := handlers.HistoryResponse{
ID: h.ID,
- Created: h.Created.UnixNano(),
+ Created: h.Created.Unix(),
CreatedBy: h.CreatedBy,
Tags: h.Tags,
Size: h.Size,
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index f93c8f8d5..27ec64d89 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -103,7 +103,6 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
func Pods(w http.ResponseWriter, r *http.Request) {
var (
- runtime = r.Context().Value("runtime").(*libpod.Runtime)
podInspectData []*libpod.PodInspect
)
decoder := r.Context().Value("decoder").(*schema.Decoder)
@@ -118,12 +117,8 @@ func Pods(w http.ResponseWriter, r *http.Request) {
return
}
- if len(query.Filters) > 0 {
- utils.Error(w, "filters are not implemented yet", http.StatusInternalServerError, define.ErrNotImplemented)
- return
- }
+ pods, err := utils.GetPods(w, r)
- pods, err := runtime.GetAllPods()
if err != nil {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
diff --git a/pkg/api/handlers/libpod/swagger.go b/pkg/api/handlers/libpod/swagger.go
index f6a26134b..149fa10dc 100644
--- a/pkg/api/handlers/libpod/swagger.go
+++ b/pkg/api/handlers/libpod/swagger.go
@@ -1,6 +1,16 @@
package libpod
-import "github.com/containers/image/v5/manifest"
+import (
+ "net/http"
+ "os"
+
+ "github.com/containers/image/v5/manifest"
+ "github.com/containers/libpod/pkg/api/handlers/utils"
+ "github.com/pkg/errors"
+)
+
+// DefaultPodmanSwaggerSpec provides the default path to the podman swagger spec file
+const DefaultPodmanSwaggerSpec = "/usr/share/containers/podman/swagger.yaml"
// List Containers
// swagger:response ListContainers
@@ -15,3 +25,20 @@ type swagInspectManifestResponse struct {
// in:body
Body manifest.List
}
+
+func ServeSwagger(w http.ResponseWriter, r *http.Request) {
+ path := DefaultPodmanSwaggerSpec
+ if p, found := os.LookupEnv("PODMAN_SWAGGER_SPEC"); found {
+ path = p
+ }
+ if _, err := os.Stat(path); err != nil {
+ if os.IsNotExist(err) {
+ utils.InternalServerError(w, errors.Errorf("file %q does not exist", path))
+ return
+ }
+ utils.InternalServerError(w, err)
+ return
+ }
+ w.Header().Set("Content-Type", "text/yaml")
+ http.ServeFile(w, r, path)
+}
diff --git a/pkg/api/handlers/utils/containers.go b/pkg/api/handlers/utils/containers.go
index d5a79bdc8..bbe4cee3c 100644
--- a/pkg/api/handlers/utils/containers.go
+++ b/pkg/api/handlers/utils/containers.go
@@ -16,7 +16,7 @@ import (
// ContainerCreateResponse is the response struct for creating a container
type ContainerCreateResponse struct {
// ID of the container created
- ID string `json:"id"`
+ ID string `json:"Id"`
// Warnings during container creation
Warnings []string `json:"Warnings"`
}
diff --git a/pkg/api/handlers/utils/pods.go b/pkg/api/handlers/utils/pods.go
new file mode 100644
index 000000000..266ad9a4b
--- /dev/null
+++ b/pkg/api/handlers/utils/pods.go
@@ -0,0 +1,45 @@
+package utils
+
+import (
+ "fmt"
+ "net/http"
+
+ "github.com/containers/libpod/cmd/podman/shared"
+ "github.com/containers/libpod/libpod"
+ "github.com/gorilla/schema"
+)
+
+func GetPods(w http.ResponseWriter, r *http.Request) ([]*libpod.Pod, error) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+
+ query := struct {
+ All bool
+ Filters map[string][]string `schema:"filters"`
+ Digests bool
+ }{}
+
+ if err := decoder.Decode(&query, r.URL.Query()); err != nil {
+ return nil, err
+ }
+ var filters = []string{}
+ if _, found := r.URL.Query()["digests"]; found && query.Digests {
+ UnSupportedParameter("digests")
+ }
+
+ if len(query.Filters) > 0 {
+ for k, v := range query.Filters {
+ for _, val := range v {
+ filters = append(filters, fmt.Sprintf("%s=%s", k, val))
+ }
+ }
+ filterFuncs, err := shared.GenerateFilterFunction(runtime, filters)
+ if err != nil {
+ return nil, err
+ }
+ return shared.FilterAllPodsWithFilterFunc(runtime, filterFuncs...)
+ }
+
+ return runtime.GetAllPods()
+
+}
diff --git a/pkg/api/server/register_manifest.go b/pkg/api/server/register_manifest.go
index ccfc2192d..8fd84f205 100644
--- a/pkg/api/server/register_manifest.go
+++ b/pkg/api/server/register_manifest.go
@@ -38,7 +38,7 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/manifests/create"), s.APIHandler(libpod.ManifestCreate)).Methods(http.MethodPost)
- // swagger:operation GET /libpod/manifests/{name}/json manifests Inspect
+ // swagger:operation GET /libpod/manifests/{name:.*}/json manifests Inspect
// ---
// summary: Inspect
// description: Display a manifest list
@@ -46,7 +46,7 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// - application/json
// parameters:
// - in: path
- // name: name
+ // name: name:.*
// type: string
// required: true
// description: the name or ID of the manifest
@@ -58,14 +58,14 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/manifests/{name:.*}/json"), s.APIHandler(libpod.ManifestInspect)).Methods(http.MethodGet)
- // swagger:operation POST /libpod/manifests/{name}/add manifests AddManifest
+ // swagger:operation POST /libpod/manifests/{name:.*}/add manifests AddManifest
// ---
// description: Add an image to a manifest list
// produces:
// - application/json
// parameters:
// - in: path
- // name: name
+ // name: name:.*
// type: string
// required: true
// description: the name or ID of the manifest
@@ -84,7 +84,7 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// 500:
// $ref: "#/responses/InternalError"
r.Handle(VersionedPath("/libpod/manifests/{name:.*}/add"), s.APIHandler(libpod.ManifestAdd)).Methods(http.MethodPost)
- // swagger:operation DELETE /libpod/manifests/{name} manifests RemoveManifest
+ // swagger:operation DELETE /libpod/manifests/{name:.*} manifests RemoveManifest
// ---
// summary: Remove
// description: Remove an image from a manifest list
@@ -92,7 +92,7 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// - application/json
// parameters:
// - in: path
- // name: name
+ // name: name:.*
// type: string
// required: true
// description: the image associated with the manifest
diff --git a/pkg/api/server/register_swagger.go b/pkg/api/server/register_swagger.go
index 5564ec096..9048c1951 100644
--- a/pkg/api/server/register_swagger.go
+++ b/pkg/api/server/register_swagger.go
@@ -2,25 +2,14 @@ package server
import (
"net/http"
- "os"
+ "github.com/containers/libpod/pkg/api/handlers/libpod"
"github.com/gorilla/mux"
)
-// DefaultPodmanSwaggerSpec provides the default path to the podman swagger spec file
-const DefaultPodmanSwaggerSpec = "/usr/share/containers/podman/swagger.yaml"
-
// RegisterSwaggerHandlers maps the swagger endpoint for the server
func (s *APIServer) RegisterSwaggerHandlers(r *mux.Router) error {
// This handler does _*NOT*_ provide an UI rather just a swagger spec that an UI could render
- r.PathPrefix("/swagger/").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- path := DefaultPodmanSwaggerSpec
- if p, found := os.LookupEnv("PODMAN_SWAGGER_SPEC"); found {
- path = p
- }
- w.Header().Set("Content-Type", "text/yaml")
-
- http.ServeFile(w, r, path)
- })
+ r.HandleFunc(VersionedPath("/libpod/swagger"), s.APIHandler(libpod.ServeSwagger)).Methods(http.MethodGet)
return nil
}
diff --git a/pkg/api/server/server.go b/pkg/api/server/server.go
index 8496cd11c..59f1f95cb 100644
--- a/pkg/api/server/server.go
+++ b/pkg/api/server/server.go
@@ -83,10 +83,6 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
ConnectionCh: make(chan int),
}
- server.Timer = time.AfterFunc(server.Duration, func() {
- server.ConnectionCh <- NOOPHandler
- })
-
router.NotFoundHandler = http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
// We can track user errors...
@@ -109,6 +105,7 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
server.registerPingHandlers,
server.registerPluginsHandlers,
server.registerPodsHandlers,
+ server.RegisterSwaggerHandlers,
server.registerSwarmHandlers,
server.registerSystemHandlers,
server.registerVersionHandlers,
@@ -139,36 +136,15 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
// Serve starts responding to HTTP requests
func (s *APIServer) Serve() error {
- // stalker to count the connections. Should the timer expire it will shutdown the service.
- go func() {
- for delta := range s.ConnectionCh {
- switch delta {
- case EnterHandler:
- s.Timer.Stop()
- s.ActiveConnections += 1
- s.TotalConnections += 1
- case ExitHandler:
- s.Timer.Stop()
- 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)
- }
- }
- }()
+ // This is initialized here as Timer is not needed until Serve'ing
+ if s.Duration > 0 {
+ s.Timer = time.AfterFunc(s.Duration, func() {
+ s.ConnectionCh <- NOOPHandler
+ })
+ go s.ReadChannelWithTimeout()
+ } else {
+ go s.ReadChannelNoTimeout()
+ }
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
@@ -193,6 +169,53 @@ func (s *APIServer) Serve() error {
return nil
}
+func (s *APIServer) ReadChannelWithTimeout() {
+ // stalker to count the connections. Should the timer expire it will shutdown the service.
+ for delta := range s.ConnectionCh {
+ switch delta {
+ case EnterHandler:
+ s.Timer.Stop()
+ s.ActiveConnections += 1
+ s.TotalConnections += 1
+ case ExitHandler:
+ s.Timer.Stop()
+ 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.Warnf("ConnectionCh received unsupported input %d", delta)
+ }
+ }
+}
+
+func (s *APIServer) ReadChannelNoTimeout() {
+ // stalker to count the connections.
+ for delta := range s.ConnectionCh {
+ switch delta {
+ case EnterHandler:
+ s.ActiveConnections += 1
+ s.TotalConnections += 1
+ case ExitHandler:
+ s.ActiveConnections -= 1
+ case NOOPHandler:
+ default:
+ logrus.Warnf("ConnectionCh received unsupported input %d", delta)
+ }
+ }
+}
+
// Shutdown is a clean shutdown waiting on existing clients
func (s *APIServer) Shutdown() error {
// Duration == 0 flags no auto-shutdown of the server