aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Guzik <jguzik@redhat.com>2022-07-05 22:01:51 +0200
committerJakub Guzik <jguzik@redhat.com>2022-07-05 22:02:04 +0200
commit72aa00aca00467ee17cd971e2234379c1f694551 (patch)
treeee225d6151f7753609445c5efb0a266a2515ec30
parentcf747399b13432d000cfd9556a248681363dda2d (diff)
downloadpodman-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.go37
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()
+ }
+ }
+ }
}