Skip to content

Commit

Permalink
Non-running containers now report statistics via the podman stats
Browse files Browse the repository at this point in the history
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: containers#14498

Signed-off-by: Jake Correnti <jcorrenti13@gmail.com>
  • Loading branch information
Jake Correnti authored and mheon committed Jun 14, 2022
1 parent ef31978 commit 96ccd69
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 25 deletions.
12 changes: 1 addition & 11 deletions cmd/podman/containers/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -231,24 +227,18 @@ 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 "--"
}
return fmt.Sprintf("%.2f", strippedFloat) + "%"
}

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)))
}

Expand Down
3 changes: 2 additions & 1 deletion libpod/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
12 changes: 0 additions & 12 deletions pkg/api/handlers/compat/containers_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/pause_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
11 changes: 11 additions & 0 deletions test/e2e/stats_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
})

0 comments on commit 96ccd69

Please sign in to comment.