aboutsummaryrefslogtreecommitdiff
path: root/pkg/api/handlers/libpod
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2020-09-23 13:33:17 +0200
committerValentin Rothberg <rothberg@redhat.com>2020-09-24 14:09:55 +0200
commit762b787fbf741eec0e59d81aaebbfc467351ceaa (patch)
tree7e18776a8fb6c843609487a27f1e0dd4da788122 /pkg/api/handlers/libpod
parent376ba349bfadc47a938084ccb3c2d112c92f09ca (diff)
downloadpodman-762b787fbf741eec0e59d81aaebbfc467351ceaa.tar.gz
podman-762b787fbf741eec0e59d81aaebbfc467351ceaa.tar.bz2
podman-762b787fbf741eec0e59d81aaebbfc467351ceaa.zip
new endpoint: /libpod/containers/stats
Add a new endpoint for container stats allowing for batch operations on more than one container. The new endpoint deprecates the single-container endpoint which will eventually be removed with the next major release. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'pkg/api/handlers/libpod')
-rw-r--r--pkg/api/handlers/libpod/containers_stats.go73
1 files changed, 73 insertions, 0 deletions
diff --git a/pkg/api/handlers/libpod/containers_stats.go b/pkg/api/handlers/libpod/containers_stats.go
new file mode 100644
index 000000000..3066d5ebc
--- /dev/null
+++ b/pkg/api/handlers/libpod/containers_stats.go
@@ -0,0 +1,73 @@
+package libpod
+
+import (
+ "encoding/json"
+ "net/http"
+ "time"
+
+ "github.com/containers/podman/v2/libpod"
+ "github.com/containers/podman/v2/pkg/api/handlers/utils"
+ "github.com/containers/podman/v2/pkg/domain/entities"
+ "github.com/containers/podman/v2/pkg/domain/infra/abi"
+ "github.com/gorilla/schema"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+)
+
+const DefaultStatsPeriod = 5 * time.Second
+
+func StatsContainer(w http.ResponseWriter, r *http.Request) {
+ runtime := r.Context().Value("runtime").(*libpod.Runtime)
+ decoder := r.Context().Value("decoder").(*schema.Decoder)
+
+ query := struct {
+ Containers []string `schema:"containers"`
+ Stream bool `schema:"stream"`
+ }{
+ Stream: true,
+ }
+ if err := decoder.Decode(&query, r.URL.Query()); err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "Failed to parse parameters for %s", r.URL.String()))
+ return
+ }
+
+ // Reduce code duplication and use the local/abi implementation of
+ // container stats.
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
+
+ statsOptions := entities.ContainerStatsOptions{
+ All: len(query.Containers) == 0, // no containers -> query all of them
+ NoStream: !query.Stream,
+ }
+
+ // Stats will stop if the connection is closed.
+ statsChan, err := containerEngine.ContainerStats(r.Context(), query.Containers, statsOptions)
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+
+ // Write header and content type.
+ w.WriteHeader(http.StatusOK)
+ w.Header().Add("Content-Type", "application/json")
+ if flusher, ok := w.(http.Flusher); ok {
+ flusher.Flush()
+ }
+
+ // Setup JSON encoder for streaming.
+ coder := json.NewEncoder(w)
+ coder.SetEscapeHTML(true)
+
+ for stats := range statsChan {
+ if err := coder.Encode(stats); err != nil {
+ // Note: even when streaming, the stats goroutine will
+ // be notified (and stop) as the connection will be
+ // closed.
+ logrus.Errorf("Unable to encode stats: %v", err)
+ return
+ }
+ if flusher, ok := w.(http.Flusher); ok {
+ flusher.Flush()
+ }
+ }
+}