Skip to content

Commit

Permalink
sync container state before reading the healthcheck
Browse files Browse the repository at this point in the history
The health check result is stored in the container state. Since the
state can change or might not even be set we have to retrive the current
state before we try to read the health check result.

Fixes containers#11687

Signed-off-by: Paul Holzinger <[email protected]>
  • Loading branch information
Luap99 committed Sep 22, 2021
1 parent 8e2d25e commit db44add
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
2 changes: 1 addition & 1 deletion libpod/container_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver

if c.config.HealthCheckConfig != nil {
// This container has a healthcheck defined in it; we need to add it's state
healthCheckState, err := c.GetHealthCheckLog()
healthCheckState, err := c.getHealthCheckLog()
if err != nil {
// An error here is not considered fatal; no health state will be displayed
logrus.Error(err)
Expand Down
16 changes: 11 additions & 5 deletions libpod/healthcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func newHealthCheckLog(start, end time.Time, exitCode int, log string) define.He
// updatedHealthCheckStatus updates the health status of the container
// in the healthcheck log
func (c *Container) updateHealthStatus(status string) error {
healthCheck, err := c.GetHealthCheckLog()
healthCheck, err := c.getHealthCheckLog()
if err != nil {
return err
}
Expand All @@ -176,7 +176,7 @@ func (c *Container) updateHealthStatus(status string) error {

// UpdateHealthCheckLog parses the health check results and writes the log
func (c *Container) updateHealthCheckLog(hcl define.HealthCheckLog, inStartPeriod bool) error {
healthCheck, err := c.GetHealthCheckLog()
healthCheck, err := c.getHealthCheckLog()
if err != nil {
return err
}
Expand Down Expand Up @@ -213,10 +213,11 @@ func (c *Container) healthCheckLogPath() string {
return filepath.Join(filepath.Dir(c.state.RunDir), "healthcheck.log")
}

// GetHealthCheckLog returns HealthCheck results by reading the container's
// getHealthCheckLog returns HealthCheck results by reading the container's
// health check log file. If the health check log file does not exist, then
// an empty healthcheck struct is returned
func (c *Container) GetHealthCheckLog() (define.HealthCheckResults, error) {
// The caller should lock the container before this function is called.
func (c *Container) getHealthCheckLog() (define.HealthCheckResults, error) {
var healthCheck define.HealthCheckResults
if _, err := os.Stat(c.healthCheckLogPath()); os.IsNotExist(err) {
return healthCheck, nil
Expand All @@ -236,7 +237,12 @@ func (c *Container) HealthCheckStatus() (string, error) {
if !c.HasHealthCheck() {
return "", errors.Errorf("container %s has no defined healthcheck", c.ID())
}
results, err := c.GetHealthCheckLog()
c.lock.Lock()
defer c.lock.Unlock()
if err := c.syncContainer(); err != nil {
return "", err
}
results, err := c.getHealthCheckLog()
if err != nil {
return "", errors.Wrapf(err, "unable to get healthcheck log for %s", c.ID())
}
Expand Down
7 changes: 7 additions & 0 deletions test/e2e/healthcheck_run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,12 @@ var _ = Describe("Podman healthcheck run", func() {

inspect = podmanTest.InspectContainer("hc")
Expect(inspect[0].State.Healthcheck.Status).To(Equal(define.HealthCheckHealthy))

// Test podman ps --filter heath is working (#11687)
ps := podmanTest.Podman([]string{"ps", "--filter", "health=healthy"})
ps.WaitWithDefaultTimeout()
Expect(ps).Should(Exit(0))
Expect(len(ps.OutputToStringArray())).To(Equal(2))
Expect(ps.OutputToString()).To(ContainSubstring("hc"))
})
})

0 comments on commit db44add

Please sign in to comment.