diff options
author | Jakub Guzik <jguzik@redhat.com> | 2022-07-05 22:01:51 +0200 |
---|---|---|
committer | Jakub Guzik <jguzik@redhat.com> | 2022-07-05 22:02:04 +0200 |
commit | 72aa00aca00467ee17cd971e2234379c1f694551 (patch) | |
tree | ee225d6151f7753609445c5efb0a266a2515ec30 | |
parent | cf747399b13432d000cfd9556a248681363dda2d (diff) | |
download | podman-72aa00aca00467ee17cd971e2234379c1f694551.tar.gz podman-72aa00aca00467ee17cd971e2234379c1f694551.tar.bz2 podman-72aa00aca00467ee17cd971e2234379c1f694551.zip |
Fix streaming for libpod/pods/stats endpoint
This commit fixes libpod/pods/stats endpoint which should stream the data.
Additional option param is added to disable streaming and the delay value
to choose the desired delay between streamed messages (default 5s).
Signed-off-by: Jakub Guzik <jguzik@redhat.com>
-rw-r--r-- | pkg/api/handlers/libpod/pods.go | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go index 92fd94390..8b1d456ec 100644 --- a/pkg/api/handlers/libpod/pods.go +++ b/pkg/api/handlers/libpod/pods.go @@ -530,8 +530,12 @@ func PodStats(w http.ResponseWriter, r *http.Request) { query := struct { NamesOrIDs []string `schema:"namesOrIDs"` All bool `schema:"all"` + Stream bool `schema:"stream"` + Delay int `schema:"delay"` }{ // default would go here + Delay: 5, + Stream: false, } if err := decoder.Decode(&query, r.URL.Query()); err != nil { utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err)) @@ -544,6 +548,10 @@ func PodStats(w http.ResponseWriter, r *http.Request) { utils.InternalServerError(w, err) } + var flush = func() {} + if flusher, ok := w.(http.Flusher); ok { + flush = flusher.Flush + } // Collect the stats and send them over the wire. containerEngine := abi.ContainerEngine{Libpod: runtime} reports, err := containerEngine.PodStats(r.Context(), query.NamesOrIDs, options) @@ -554,10 +562,35 @@ func PodStats(w http.ResponseWriter, r *http.Request) { utils.Error(w, http.StatusNotFound, err) return } - utils.InternalServerError(w, err) return } - utils.WriteResponse(w, http.StatusOK, reports) + w.Header().Set("Content-Type", "application/json") + coder := json.NewEncoder(w) + coder.SetEscapeHTML(true) + + if err := coder.Encode(reports); err != nil { + logrus.Infof("Error from %s %q : %v", r.Method, r.URL, err) + } + flush() + if query.Stream { + for { + select { + case <-r.Context().Done(): + return + default: + time.Sleep(time.Duration(query.Delay) * time.Second) + reports, err = containerEngine.PodStats(r.Context(), query.NamesOrIDs, options) + if err != nil { + return + } + if err := coder.Encode(reports); err != nil { + logrus.Infof("Error from %s %q : %v", r.Method, r.URL, err) + return + } + flush() + } + } + } } |