diff options
-rw-r--r-- | libpod/container_internal.go | 4 | ||||
-rw-r--r-- | libpod/healthcheck_linux.go | 24 | ||||
-rw-r--r-- | test/e2e/healthcheck_run_test.go | 16 |
3 files changed, 34 insertions, 10 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go index a68de3173..7df82eb18 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -1877,7 +1877,7 @@ func (c *Container) cleanupStorage() error { return cleanupErr } -// Unmount the a container and free its resources +// Unmount the container and free its resources func (c *Container) cleanup(ctx context.Context) error { var lastError error @@ -1885,7 +1885,7 @@ func (c *Container) cleanup(ctx context.Context) error { // Remove healthcheck unit/timer file if it execs if c.config.HealthCheckConfig != nil { - if err := c.removeTimer(); err != nil { + if err := c.removeTransientFiles(ctx); err != nil { logrus.Errorf("Removing timer for container %s healthcheck: %v", c.ID(), err) } } diff --git a/libpod/healthcheck_linux.go b/libpod/healthcheck_linux.go index e08214809..2c19e0a61 100644 --- a/libpod/healthcheck_linux.go +++ b/libpod/healthcheck_linux.go @@ -1,6 +1,7 @@ package libpod import ( + "context" "fmt" "os" "os/exec" @@ -59,9 +60,9 @@ func (c *Container) startTimer() error { return err } -// removeTimer removes the systemd timer and unit files +// removeTransientFiles removes the systemd timer and unit files // for the container -func (c *Container) removeTimer() error { +func (c *Container) removeTransientFiles(ctx context.Context) error { if c.disableHealthCheckSystemd() { return nil } @@ -71,12 +72,19 @@ func (c *Container) removeTimer() error { } defer conn.Close() timerFile := fmt.Sprintf("%s.timer", c.ID()) - _, err = conn.StopUnit(timerFile, "fail", nil) - - // We want to ignore errors where the timer unit has already been removed. The error - // return is generic so we have to check against the string in the error - if err != nil && strings.HasSuffix(err.Error(), ".timer not loaded.") { - return nil + serviceFile := fmt.Sprintf("%s.service", c.ID()) + // We want to ignore errors where the timer unit and/or service unit has already + // been removed. The error return is generic so we have to check against the + // string in the error + if _, err = conn.StopUnitContext(ctx, serviceFile, "fail", nil); err != nil { + if !strings.HasSuffix(err.Error(), ".service not loaded.") { + return errors.Wrapf(err, "unable to remove service file") + } + } + if _, err = conn.StopUnitContext(ctx, timerFile, "fail", nil); err != nil { + if strings.HasSuffix(err.Error(), ".timer not loaded.") { + return nil + } } return err } diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index 6e4dc5bbf..c2084a6fd 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -242,4 +242,20 @@ var _ = Describe("Podman healthcheck run", func() { Expect(ps.OutputToStringArray()).To(HaveLen(2)) Expect(ps.OutputToString()).To(ContainSubstring("hc")) }) + + It("stopping and then starting a container with healthcheck cmd", func() { + session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-cmd", "[\"ls\", \"/foo\"]", ALPINE, "top"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + stop := podmanTest.Podman([]string{"stop", "-t0", "hc"}) + stop.WaitWithDefaultTimeout() + Expect(stop).Should(Exit(0)) + + startAgain := podmanTest.Podman([]string{"start", "hc"}) + startAgain.WaitWithDefaultTimeout() + Expect(startAgain).Should(Exit(0)) + Expect(startAgain.OutputToString()).To(Equal("hc")) + Expect(startAgain.ErrorToString()).To(Equal("")) + }) }) |