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 <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger 2021-09-20 13:19:50 +02:00
parent aa628b82b1
commit 1199733754
No known key found for this signature in database
GPG key ID: EB145DD938A3CAF2
6 changed files with 26 additions and 17 deletions

View file

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

View file

@ -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

View file

@ -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{}

View file

@ -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"])

View file

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

View file

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