apiv2 stream events

the events endpoint should be stream-based.  it also needed to be registered to answer and not produce 404s.

Signed-off-by: Brent Baude <bbaude@redhat.com>
This commit is contained in:
Brent Baude
2020-02-11 15:00:41 -06:00
parent 86b5a89d1a
commit 5b830cca90
4 changed files with 34 additions and 16 deletions

View File

@ -1,19 +1,24 @@
package handlers package handlers
import ( import (
"encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"strings"
"time"
"github.com/containers/libpod/libpod/events"
"github.com/containers/libpod/pkg/api/handlers/utils" "github.com/containers/libpod/pkg/api/handlers/utils"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus"
) )
func GetEvents(w http.ResponseWriter, r *http.Request) { func GetEvents(w http.ResponseWriter, r *http.Request) {
var (
fromStart bool
eventsError error
)
query := struct { query := struct {
Since time.Time `schema:"since"` Since string `schema:"since"`
Until time.Time `schema:"until"` Until string `schema:"until"`
Filters map[string][]string `schema:"filters"` Filters map[string][]string `schema:"filters"`
}{} }{}
if err := decodeQuery(r, &query); err != nil { if err := decodeQuery(r, &query); err != nil {
@ -27,15 +32,30 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
} }
} }
libpodEvents, err := getRuntime(r).GetEvents(libpodFilters) if len(query.Since) > 0 || len(query.Until) > 0 {
if err != nil { fromStart = true
utils.BadRequest(w, "filters", strings.Join(r.URL.Query()["filters"], ", "), err) }
eventChannel := make(chan *events.Event)
go func() {
readOpts := events.ReadOptions{FromStart: fromStart, Stream: true, Filters: libpodFilters, EventChannel: eventChannel, Since: query.Since, Until: query.Until}
eventsError = getRuntime(r).Events(readOpts)
}()
if eventsError != nil {
utils.InternalServerError(w, eventsError)
return return
} }
w.Header().Set("Content-Type", "application/json")
var apiEvents = make([]*Event, len(libpodEvents)) w.WriteHeader(http.StatusOK)
for _, v := range libpodEvents { for event := range eventChannel {
apiEvents = append(apiEvents, EventToApiEvent(v)) e := EventToApiEvent(event)
//utils.WriteJSON(w, http.StatusOK, e)
coder := json.NewEncoder(w)
coder.SetEscapeHTML(true)
if err := coder.Encode(e); err != nil {
logrus.Errorf("unable to write json: %q", err)
}
if flusher, ok := w.(http.Flusher); ok {
flusher.Flush()
}
} }
utils.WriteJSON(w, http.StatusOK, apiEvents)
} }

View File

@ -19,9 +19,6 @@ import (
const DefaultStatsPeriod = 5 * time.Second const DefaultStatsPeriod = 5 * time.Second
func StatsContainer(w http.ResponseWriter, r *http.Request) { func StatsContainer(w http.ResponseWriter, r *http.Request) {
// 200 no error
// 404 no such
// 500 internal
runtime := r.Context().Value("runtime").(*libpod.Runtime) runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder) decoder := r.Context().Value("decoder").(*schema.Decoder)

View File

@ -29,7 +29,7 @@ func (s *APIServer) RegisterEventsHandlers(r *mux.Router) error {
// description: JSON encoded map[string][]string of constraints // description: JSON encoded map[string][]string of constraints
// responses: // responses:
// 200: // 200:
// $ref: "#/responses/ok" // description: returns a string of json data describing an event
// 500: // 500:
// "$ref": "#/responses/InternalError" // "$ref": "#/responses/InternalError"
r.Handle(VersionedPath("/events"), APIHandler(s.Context, handlers.GetEvents)) r.Handle(VersionedPath("/events"), APIHandler(s.Context, handlers.GetEvents))

View File

@ -106,6 +106,7 @@ func newServer(runtime *libpod.Runtime, duration time.Duration, listener *net.Li
server.RegisterContainersHandlers, server.RegisterContainersHandlers,
server.RegisterDistributionHandlers, server.RegisterDistributionHandlers,
server.registerExecHandlers, server.registerExecHandlers,
server.RegisterEventsHandlers,
server.registerHealthCheckHandlers, server.registerHealthCheckHandlers,
server.registerImagesHandlers, server.registerImagesHandlers,
server.registerInfoHandlers, server.registerInfoHandlers,