From 1199733754b1185d0d2a7a3d832c57565864d0f4 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Mon, 20 Sep 2021 13:19:50 +0200 Subject: podman inspect add State.Health field for docker compat podman inspect shows the healthcheck status in `.State.Healthcheck`, docker uses `.State.Health`. To make sure docker scripts work we should add the `Health` key. Because we do not want to display both keys by default we only use the new `Health` key. This is a breaking change for podman users but matches what docker does. To provide some form of compatibility users can still use `--format {{.State.Healthcheck}}`. IT is just not shown by default. Fixes #11645 Signed-off-by: Paul Holzinger --- libpod/container_inspect.go | 2 +- libpod/define/container_inspect.go | 8 +++++++- pkg/api/handlers/compat/containers.go | 6 +++--- test/apiv2/python/rest_api/test_v2_0_0_container.py | 2 +- test/e2e/healthcheck_run_test.go | 21 ++++++++++++--------- test/system/220-healthcheck.bats | 4 ++-- 6 files changed, 26 insertions(+), 17 deletions(-) diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 42d8da52d..35526afb3 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -156,7 +156,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver // An error here is not considered fatal; no health state will be displayed logrus.Error(err) } else { - data.State.Healthcheck = healthCheckState + data.State.Health = healthCheckState } } diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go index 90703a807..7decb18a8 100644 --- a/libpod/define/container_inspect.go +++ b/libpod/define/container_inspect.go @@ -202,10 +202,16 @@ type InspectContainerState struct { Error string `json:"Error"` // TODO StartedAt time.Time `json:"StartedAt"` FinishedAt time.Time `json:"FinishedAt"` - Healthcheck HealthCheckResults `json:"Healthcheck,omitempty"` + Health HealthCheckResults `json:"Health,omitempty"` Checkpointed bool `json:"Checkpointed,omitempty"` } +// Healthcheck returns the HealthCheckResults. This is used for old podman compat +// to make the "Healthcheck" key available in the go template. +func (s *InspectContainerState) Healthcheck() HealthCheckResults { + return s.Health +} + // HealthCheckResults describes the results/logs from a healthcheck type HealthCheckResults struct { // Status healthy or unhealthy diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go index a15fdb553..18005e24a 100644 --- a/pkg/api/handlers/compat/containers.go +++ b/pkg/api/handlers/compat/containers.go @@ -410,11 +410,11 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON, if l.HasHealthCheck() && state.Status != "created" { state.Health = &types.Health{ - Status: inspect.State.Healthcheck.Status, - FailingStreak: inspect.State.Healthcheck.FailingStreak, + Status: inspect.State.Health.Status, + FailingStreak: inspect.State.Health.FailingStreak, } - log := inspect.State.Healthcheck.Log + log := inspect.State.Health.Log for _, item := range log { res := &types.HealthcheckResult{} diff --git a/test/apiv2/python/rest_api/test_v2_0_0_container.py b/test/apiv2/python/rest_api/test_v2_0_0_container.py index dbad6824f..853e9da88 100644 --- a/test/apiv2/python/rest_api/test_v2_0_0_container.py +++ b/test/apiv2/python/rest_api/test_v2_0_0_container.py @@ -56,7 +56,7 @@ class ContainerTestCase(APITestCase): self.assertEqual(r.status_code, 200, r.text) self.assertId(r.content) out = r.json() - self.assertIsNone(out["State"].get("Health")) + self.assertIsNotNone(out["State"].get("Health")) self.assertListEqual(["CMD", "pidof", "top"], out["Config"]["Healthcheck"]["Test"]) self.assertEqual(5000000000, out["Config"]["Healthcheck"]["Interval"]) self.assertEqual(2000000000, out["Config"]["Healthcheck"]["Timeout"]) diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index 1445a634b..2826f2b34 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -117,7 +117,7 @@ var _ = Describe("Podman healthcheck run", func() { session.WaitWithDefaultTimeout() Expect(session).Should(Exit(0)) inspect := podmanTest.InspectContainer("hc") - Expect(inspect[0].State.Healthcheck.Status).To(Equal("starting")) + Expect(inspect[0].State.Health.Status).To(Equal("starting")) }) It("podman healthcheck failed checks in start-period should not change status", func() { @@ -138,7 +138,9 @@ var _ = Describe("Podman healthcheck run", func() { Expect(hc).Should(Exit(1)) inspect := podmanTest.InspectContainer("hc") - Expect(inspect[0].State.Healthcheck.Status).To(Equal("starting")) + Expect(inspect[0].State.Health.Status).To(Equal("starting")) + // test old podman compat (see #11645) + Expect(inspect[0].State.Healthcheck().Status).To(Equal("starting")) }) It("podman healthcheck failed checks must reach retries before unhealthy ", func() { @@ -151,15 +153,16 @@ var _ = Describe("Podman healthcheck run", func() { Expect(hc).Should(Exit(1)) inspect := podmanTest.InspectContainer("hc") - Expect(inspect[0].State.Healthcheck.Status).To(Equal("starting")) + Expect(inspect[0].State.Health.Status).To(Equal("starting")) hc = podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() Expect(hc).Should(Exit(1)) inspect = podmanTest.InspectContainer("hc") - Expect(inspect[0].State.Healthcheck.Status).To(Equal(define.HealthCheckUnhealthy)) - + Expect(inspect[0].State.Health.Status).To(Equal(define.HealthCheckUnhealthy)) + // test old podman compat (see #11645) + Expect(inspect[0].State.Healthcheck().Status).To(Equal(define.HealthCheckUnhealthy)) }) It("podman healthcheck good check results in healthy even in start-period", func() { @@ -172,7 +175,7 @@ var _ = Describe("Podman healthcheck run", func() { Expect(hc).Should(Exit(0)) inspect := podmanTest.InspectContainer("hc") - Expect(inspect[0].State.Healthcheck.Status).To(Equal(define.HealthCheckHealthy)) + Expect(inspect[0].State.Health.Status).To(Equal(define.HealthCheckHealthy)) }) It("podman healthcheck unhealthy but valid arguments check", func() { @@ -195,14 +198,14 @@ var _ = Describe("Podman healthcheck run", func() { Expect(hc).Should(Exit(1)) inspect := podmanTest.InspectContainer("hc") - Expect(inspect[0].State.Healthcheck.Status).To(Equal("starting")) + Expect(inspect[0].State.Health.Status).To(Equal("starting")) hc = podmanTest.Podman([]string{"healthcheck", "run", "hc"}) hc.WaitWithDefaultTimeout() Expect(hc).Should(Exit(1)) inspect = podmanTest.InspectContainer("hc") - Expect(inspect[0].State.Healthcheck.Status).To(Equal(define.HealthCheckUnhealthy)) + Expect(inspect[0].State.Health.Status).To(Equal(define.HealthCheckUnhealthy)) foo := podmanTest.Podman([]string{"exec", "hc", "touch", "/foo"}) foo.WaitWithDefaultTimeout() @@ -213,7 +216,7 @@ var _ = Describe("Podman healthcheck run", func() { Expect(hc).Should(Exit(0)) inspect = podmanTest.InspectContainer("hc") - Expect(inspect[0].State.Healthcheck.Status).To(Equal(define.HealthCheckHealthy)) + Expect(inspect[0].State.Health.Status).To(Equal(define.HealthCheckHealthy)) // Test podman ps --filter heath is working (#11687) ps := podmanTest.Podman([]string{"ps", "--filter", "health=healthy"}) diff --git a/test/system/220-healthcheck.bats b/test/system/220-healthcheck.bats index e416629e6..e5a0e7e88 100644 --- a/test/system/220-healthcheck.bats +++ b/test/system/220-healthcheck.bats @@ -12,13 +12,13 @@ function _check_health { local testname="$1" local tests="$2" - run_podman inspect --format json healthcheck_c + run_podman inspect --format "{{json .State.Healthcheck}}" healthcheck_c parse_table "$tests" | while read field expect;do # (kludge to deal with parse_table and empty strings) if [ "$expect" = "''" ]; then expect=""; fi - actual=$(jq -r ".[0].State.Healthcheck.$field" <<<"$output") + actual=$(jq -r ".$field" <<<"$output") is "$actual" "$expect" "$testname - .State.Healthcheck.$field" done } -- cgit v1.2.3-54-g00ecf