Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return nil health when inspecting containers without healthchecks #21388

Merged
merged 1 commit into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions libpod/container_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,20 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver
data.OCIConfigPath = c.state.ConfigPath
}

if c.config.HealthCheckConfig != nil {
// Check if healthcheck is not nil and --no-healthcheck option is not set.
// If --no-healthcheck is set Test will be always set to `[NONE]`, so the
// inspect status should be set to nil.
if c.config.HealthCheckConfig != nil && !(len(c.config.HealthCheckConfig.Test) == 1 && c.config.HealthCheckConfig.Test[0] == "NONE") {
// This container has a healthcheck defined in it; we need to add its state
healthCheckState, err := c.getHealthCheckLog()
if err != nil {
// An error here is not considered fatal; no health state will be displayed
logrus.Error(err)
} else {
data.State.Health = healthCheckState
data.State.Health = &healthCheckState
}
} else {
data.State.Health = nil
}

networkConfig, err := c.getContainerNetworkInfo()
Expand Down
48 changes: 24 additions & 24 deletions libpod/define/container_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
38 changes: 22 additions & 16 deletions pkg/api/handlers/compat/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -442,22 +442,28 @@ 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, err := time.Parse(time.RFC3339Nano, item.Start)
if err != nil {
return nil, err
}
e, err := time.Parse(time.RFC3339Nano, item.End)
if err != nil {
return nil, err
}
res.Start = s
res.End = e
res.ExitCode = item.ExitCode
res.Output = item.Output
state.Health.Log = append(state.Health.Log, res)
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions test/e2e/healthcheck_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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("<nil>"))
})

It("podman run healthcheck and logs should contain healthcheck output", func() {
Expand Down
Loading