From 608ad7d1139d80093d1ddd933027d31af7fdee83 Mon Sep 17 00:00:00 2001 From: Jake Correnti Date: Mon, 13 Jun 2022 13:33:19 -0400 Subject: Non-running containers now report statistics via the `podman stats` command Previously, if a container was not running, and the user ran the `podman stats` command, an error would be reported: `Error: container state improper`. Podman now reports stats as the fields' default values for their respective type if the container is not running: ``` $ podman stats --no-stream demo ID NAME CPU % MEM USAGE / LIMIT MEM % NET IO BLOCK IO PIDS CPU TIME AVG CPU % 4b4bf8ce84ed demo 0.00% 0B / 0B 0.00% 0B / 0B 0B / 0B 0 0s 0.00% ``` Closes: #14498 Signed-off-by: Jake Correnti --- cmd/podman/containers/stats.go | 12 +----------- libpod/stats.go | 3 ++- pkg/api/handlers/compat/containers_stats.go | 12 ------------ test/e2e/pause_test.go | 2 +- test/e2e/stats_test.go | 11 +++++++++++ 5 files changed, 15 insertions(+), 25 deletions(-) diff --git a/cmd/podman/containers/stats.go b/cmd/podman/containers/stats.go index 500671d31..02f8c6970 100644 --- a/cmd/podman/containers/stats.go +++ b/cmd/podman/containers/stats.go @@ -214,10 +214,6 @@ func (s *containerStats) BlockIO() string { } func (s *containerStats) PIDS() string { - if s.PIDs == 0 { - // If things go bazinga, return a safe value - return "--" - } return fmt.Sprintf("%d", s.PIDs) } @@ -231,7 +227,7 @@ func (s *containerStats) MemUsageBytes() string { func floatToPercentString(f float64) string { strippedFloat, err := utils.RemoveScientificNotationFromFloat(f) - if err != nil || strippedFloat == 0 { + if err != nil { // If things go bazinga, return a safe value return "--" } @@ -239,16 +235,10 @@ func floatToPercentString(f float64) string { } func combineHumanValues(a, b uint64) string { - if a == 0 && b == 0 { - return "-- / --" - } return fmt.Sprintf("%s / %s", units.HumanSize(float64(a)), units.HumanSize(float64(b))) } func combineBytesValues(a, b uint64) string { - if a == 0 && b == 0 { - return "-- / --" - } return fmt.Sprintf("%s / %s", units.BytesSize(float64(a)), units.BytesSize(float64(b))) } diff --git a/libpod/stats.go b/libpod/stats.go index 25baa378d..d2ffc3b32 100644 --- a/libpod/stats.go +++ b/libpod/stats.go @@ -34,8 +34,9 @@ func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*de } } + // returns stats with the fields' default values respective of their type if c.state.State != define.ContainerStateRunning && c.state.State != define.ContainerStatePaused { - return stats, define.ErrCtrStateInvalid + return stats, nil } if previousStats == nil { diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go index 77b16b03e..6855e369b 100644 --- a/pkg/api/handlers/compat/containers_stats.go +++ b/pkg/api/handlers/compat/containers_stats.go @@ -44,18 +44,6 @@ func StatsContainer(w http.ResponseWriter, r *http.Request) { return } - // If the container isn't running, then let's not bother and return - // immediately. - state, err := ctnr.State() - if err != nil { - utils.InternalServerError(w, err) - return - } - if state != define.ContainerStateRunning { - utils.Error(w, http.StatusConflict, define.ErrCtrStateInvalid) - return - } - stats, err := ctnr.GetContainerStats(nil) if err != nil { utils.InternalServerError(w, errors.Wrapf(err, "failed to obtain Container %s stats", name)) diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go index 402719de2..566aca07e 100644 --- a/test/e2e/pause_test.go +++ b/test/e2e/pause_test.go @@ -82,7 +82,7 @@ var _ = Describe("Podman pause", func() { // check we can read stats for a paused container result = podmanTest.Podman([]string{"stats", "--no-stream", cid}) result.WaitWithDefaultTimeout() - Expect(result).To(ExitWithError()) + Expect(result).Should(Exit(0)) }) It("podman pause a running container by id", func() { diff --git a/test/e2e/stats_test.go b/test/e2e/stats_test.go index b43a81cd3..3000a819f 100644 --- a/test/e2e/stats_test.go +++ b/test/e2e/stats_test.go @@ -236,4 +236,15 @@ var _ = Describe("Podman stats", func() { Expect(customLimit).To(BeNumerically("<", defaultLimit)) }) + + It("podman stats with a container that is not running", func() { + ctr := "created_container" + session := podmanTest.Podman([]string{"create", "--name", ctr, ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"stats", "--no-stream", ctr}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + }) }) -- cgit v1.2.3-54-g00ecf