diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index b3aa2510f47b..1ac45c9b25dd 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -5,6 +5,7 @@ package libpod import ( "errors" "fmt" + "reflect" "strings" "github.com/containers/podman/v4/libpod/define" @@ -196,7 +197,10 @@ 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.Health = healthCheckState + if reflect.DeepEqual(healthCheckState, define.HealthCheckResults{}) { + data.State.Health = &healthCheckState + } + data.State.Health = nil } } diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go index 879dd139595e..dbb7a06c91b9 100644 --- a/libpod/define/container_inspect.go +++ b/libpod/define/container_inspect.go @@ -206,34 +206,34 @@ type InspectMount struct { // Docker, but here we see more fields that are unused (nonsensical in the // context of Libpod). type InspectContainerState struct { - OciVersion string `json:"OciVersion"` - Status string `json:"Status"` - Running bool `json:"Running"` - Paused bool `json:"Paused"` - Restarting bool `json:"Restarting"` // TODO - OOMKilled bool `json:"OOMKilled"` - Dead bool `json:"Dead"` - Pid int `json:"Pid"` - ConmonPid int `json:"ConmonPid,omitempty"` - ExitCode int32 `json:"ExitCode"` - Error string `json:"Error"` // TODO - StartedAt time.Time `json:"StartedAt"` - FinishedAt time.Time `json:"FinishedAt"` - Health HealthCheckResults `json:"Health,omitempty"` - Checkpointed bool `json:"Checkpointed,omitempty"` - CgroupPath string `json:"CgroupPath,omitempty"` - CheckpointedAt time.Time `json:"CheckpointedAt,omitempty"` - RestoredAt time.Time `json:"RestoredAt,omitempty"` - CheckpointLog string `json:"CheckpointLog,omitempty"` - CheckpointPath string `json:"CheckpointPath,omitempty"` - RestoreLog string `json:"RestoreLog,omitempty"` - Restored bool `json:"Restored,omitempty"` - StoppedByUser bool `json:"StoppedByUser,omitempty"` + OciVersion string `json:"OciVersion"` + Status string `json:"Status"` + Running bool `json:"Running"` + Paused bool `json:"Paused"` + Restarting bool `json:"Restarting"` // TODO + OOMKilled bool `json:"OOMKilled"` + Dead bool `json:"Dead"` + Pid int `json:"Pid"` + ConmonPid int `json:"ConmonPid,omitempty"` + ExitCode int32 `json:"ExitCode"` + Error string `json:"Error"` // TODO + StartedAt time.Time `json:"StartedAt"` + FinishedAt time.Time `json:"FinishedAt"` + Health *HealthCheckResults `json:"Health,omitempty"` + Checkpointed bool `json:"Checkpointed,omitempty"` + CgroupPath string `json:"CgroupPath,omitempty"` + CheckpointedAt time.Time `json:"CheckpointedAt,omitempty"` + RestoredAt time.Time `json:"RestoredAt,omitempty"` + CheckpointLog string `json:"CheckpointLog,omitempty"` + CheckpointPath string `json:"CheckpointPath,omitempty"` + RestoreLog string `json:"RestoreLog,omitempty"` + Restored bool `json:"Restored,omitempty"` + StoppedByUser bool `json:"StoppedByUser,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 { +func (s *InspectContainerState) Healthcheck() *HealthCheckResults { return s.Health } diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go index 34646b5a91e9..8ddc13143af1 100644 --- a/pkg/api/handlers/compat/containers.go +++ b/pkg/api/handlers/compat/containers.go @@ -442,22 +442,22 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON, } if l.HasHealthCheck() && state.Status != "created" { - state.Health = &types.Health{ - Status: inspect.State.Health.Status, - FailingStreak: inspect.State.Health.FailingStreak, - } - - log := inspect.State.Health.Log - - for _, item := range log { - res := &types.HealthcheckResult{} - s, _ := time.Parse(time.RFC3339Nano, item.Start) - e, _ := time.Parse(time.RFC3339Nano, item.End) - res.Start = s - res.End = e - res.ExitCode = item.ExitCode - res.Output = item.Output - state.Health.Log = append(state.Health.Log, res) + state.Health = &types.Health{} + if inspect.State.Health != nil { + state.Health.Status = inspect.State.Health.Status + state.Health.FailingStreak = inspect.State.Health.FailingStreak + log := inspect.State.Health.Log + + for _, item := range log { + res := &types.HealthcheckResult{} + s, _ := time.Parse(time.RFC3339Nano, item.Start) + e, _ := time.Parse(time.RFC3339Nano, item.End) + res.Start = s + res.End = e + res.ExitCode = item.ExitCode + res.Output = item.Output + state.Health.Log = append(state.Health.Log, res) + } } } 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 0c8ce881aaf9..151786e52881 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 @@ -86,7 +86,7 @@ def test_inspect(self): self.assertEqual(r.status_code, 200, r.text) self.assertId(r.content) out = r.json() - self.assertIsNotNone(out["State"].get("Health")) + self.assertIsNone(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 bd09a2074dff..a84ee2c32530 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -34,10 +34,10 @@ var _ = Describe("Podman healthcheck run", func() { session := podmanTest.Podman([]string{"run", "-dt", "--no-healthcheck", "--name", "hc", HEALTHCHECK_IMAGE}) session.WaitWithDefaultTimeout() Expect(session).Should(ExitCleanly()) - hc := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.State.Health.Status}}", "hc"}) + hc := podmanTest.Podman([]string{"container", "inspect", "--format", "{{.State.Health}}", "hc"}) hc.WaitWithDefaultTimeout() Expect(hc).Should(ExitCleanly()) - Expect(hc.OutputToString()).To(Not(ContainSubstring("starting"))) + Expect(hc.OutputToString()).To(Equal("")) }) It("podman run healthcheck and logs should contain healthcheck output", func() {