mirror of https://github.com/containers/podman.git
Return nil health when inspecting containers without healthchecks
When inspecting a container that does not define any health check, the health field should return nil. This matches docker behavior. Signed-off-by: Ashley Cui <acui@redhat.com>
This commit is contained in:
parent
4bef65240e
commit
a1c47f0299
|
@ -189,15 +189,20 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver
|
||||||
data.OCIConfigPath = c.state.ConfigPath
|
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
|
// This container has a healthcheck defined in it; we need to add its state
|
||||||
healthCheckState, err := c.getHealthCheckLog()
|
healthCheckState, err := c.getHealthCheckLog()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// An error here is not considered fatal; no health state will be displayed
|
// An error here is not considered fatal; no health state will be displayed
|
||||||
logrus.Error(err)
|
logrus.Error(err)
|
||||||
} else {
|
} else {
|
||||||
data.State.Health = healthCheckState
|
data.State.Health = &healthCheckState
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
data.State.Health = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
networkConfig, err := c.getContainerNetworkInfo()
|
networkConfig, err := c.getContainerNetworkInfo()
|
||||||
|
|
|
@ -206,34 +206,34 @@ type InspectMount struct {
|
||||||
// Docker, but here we see more fields that are unused (nonsensical in the
|
// Docker, but here we see more fields that are unused (nonsensical in the
|
||||||
// context of Libpod).
|
// context of Libpod).
|
||||||
type InspectContainerState struct {
|
type InspectContainerState struct {
|
||||||
OciVersion string `json:"OciVersion"`
|
OciVersion string `json:"OciVersion"`
|
||||||
Status string `json:"Status"`
|
Status string `json:"Status"`
|
||||||
Running bool `json:"Running"`
|
Running bool `json:"Running"`
|
||||||
Paused bool `json:"Paused"`
|
Paused bool `json:"Paused"`
|
||||||
Restarting bool `json:"Restarting"` // TODO
|
Restarting bool `json:"Restarting"` // TODO
|
||||||
OOMKilled bool `json:"OOMKilled"`
|
OOMKilled bool `json:"OOMKilled"`
|
||||||
Dead bool `json:"Dead"`
|
Dead bool `json:"Dead"`
|
||||||
Pid int `json:"Pid"`
|
Pid int `json:"Pid"`
|
||||||
ConmonPid int `json:"ConmonPid,omitempty"`
|
ConmonPid int `json:"ConmonPid,omitempty"`
|
||||||
ExitCode int32 `json:"ExitCode"`
|
ExitCode int32 `json:"ExitCode"`
|
||||||
Error string `json:"Error"` // TODO
|
Error string `json:"Error"` // TODO
|
||||||
StartedAt time.Time `json:"StartedAt"`
|
StartedAt time.Time `json:"StartedAt"`
|
||||||
FinishedAt time.Time `json:"FinishedAt"`
|
FinishedAt time.Time `json:"FinishedAt"`
|
||||||
Health HealthCheckResults `json:"Health,omitempty"`
|
Health *HealthCheckResults `json:"Health,omitempty"`
|
||||||
Checkpointed bool `json:"Checkpointed,omitempty"`
|
Checkpointed bool `json:"Checkpointed,omitempty"`
|
||||||
CgroupPath string `json:"CgroupPath,omitempty"`
|
CgroupPath string `json:"CgroupPath,omitempty"`
|
||||||
CheckpointedAt time.Time `json:"CheckpointedAt,omitempty"`
|
CheckpointedAt time.Time `json:"CheckpointedAt,omitempty"`
|
||||||
RestoredAt time.Time `json:"RestoredAt,omitempty"`
|
RestoredAt time.Time `json:"RestoredAt,omitempty"`
|
||||||
CheckpointLog string `json:"CheckpointLog,omitempty"`
|
CheckpointLog string `json:"CheckpointLog,omitempty"`
|
||||||
CheckpointPath string `json:"CheckpointPath,omitempty"`
|
CheckpointPath string `json:"CheckpointPath,omitempty"`
|
||||||
RestoreLog string `json:"RestoreLog,omitempty"`
|
RestoreLog string `json:"RestoreLog,omitempty"`
|
||||||
Restored bool `json:"Restored,omitempty"`
|
Restored bool `json:"Restored,omitempty"`
|
||||||
StoppedByUser bool `json:"StoppedByUser,omitempty"`
|
StoppedByUser bool `json:"StoppedByUser,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Healthcheck returns the HealthCheckResults. This is used for old podman compat
|
// Healthcheck returns the HealthCheckResults. This is used for old podman compat
|
||||||
// to make the "Healthcheck" key available in the go template.
|
// to make the "Healthcheck" key available in the go template.
|
||||||
func (s *InspectContainerState) Healthcheck() HealthCheckResults {
|
func (s *InspectContainerState) Healthcheck() *HealthCheckResults {
|
||||||
return s.Health
|
return s.Health
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -442,22 +442,28 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
|
||||||
}
|
}
|
||||||
|
|
||||||
if l.HasHealthCheck() && state.Status != "created" {
|
if l.HasHealthCheck() && state.Status != "created" {
|
||||||
state.Health = &types.Health{
|
state.Health = &types.Health{}
|
||||||
Status: inspect.State.Health.Status,
|
if inspect.State.Health != nil {
|
||||||
FailingStreak: inspect.State.Health.FailingStreak,
|
state.Health.Status = inspect.State.Health.Status
|
||||||
}
|
state.Health.FailingStreak = inspect.State.Health.FailingStreak
|
||||||
|
log := inspect.State.Health.Log
|
||||||
|
|
||||||
log := inspect.State.Health.Log
|
for _, item := range log {
|
||||||
|
res := &types.HealthcheckResult{}
|
||||||
for _, item := range log {
|
s, err := time.Parse(time.RFC3339Nano, item.Start)
|
||||||
res := &types.HealthcheckResult{}
|
if err != nil {
|
||||||
s, _ := time.Parse(time.RFC3339Nano, item.Start)
|
return nil, err
|
||||||
e, _ := time.Parse(time.RFC3339Nano, item.End)
|
}
|
||||||
res.Start = s
|
e, err := time.Parse(time.RFC3339Nano, item.End)
|
||||||
res.End = e
|
if err != nil {
|
||||||
res.ExitCode = item.ExitCode
|
return nil, err
|
||||||
res.Output = item.Output
|
}
|
||||||
state.Health.Log = append(state.Health.Log, res)
|
res.Start = s
|
||||||
|
res.End = e
|
||||||
|
res.ExitCode = item.ExitCode
|
||||||
|
res.Output = item.Output
|
||||||
|
state.Health.Log = append(state.Health.Log, res)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,10 +34,10 @@ var _ = Describe("Podman healthcheck run", func() {
|
||||||
session := podmanTest.Podman([]string{"run", "-dt", "--no-healthcheck", "--name", "hc", HEALTHCHECK_IMAGE})
|
session := podmanTest.Podman([]string{"run", "-dt", "--no-healthcheck", "--name", "hc", HEALTHCHECK_IMAGE})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session).Should(ExitCleanly())
|
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()
|
hc.WaitWithDefaultTimeout()
|
||||||
Expect(hc).Should(ExitCleanly())
|
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() {
|
It("podman run healthcheck and logs should contain healthcheck output", func() {
|
||||||
|
|
Loading…
Reference in New Issue