Remove timer for HealthCheck when container is paused.

If is unpaused then new timer for  HealthCheck is created.

Fixes: https://issues.redhat.com/browse/RUN-2468

Signed-off-by: Jan Rodák <hony.com@seznam.cz>
This commit is contained in:
Jan Rodák
2025-01-27 10:49:28 +01:00
parent 3857bffb8e
commit 511c8b249d
2 changed files with 80 additions and 0 deletions

View File

@ -1546,6 +1546,14 @@ func (c *Container) pause() error {
}
}
if c.state.HCUnitName != "" {
if err := c.removeTransientFiles(context.Background(),
c.config.StartupHealthCheckConfig != nil && !c.state.StartupHCPassed,
c.state.HCUnitName); err != nil {
return fmt.Errorf("failed to remove HealthCheck timer: %v", err)
}
}
if err := c.ociRuntime.PauseContainer(c); err != nil {
// TODO when using docker-py there is some sort of race/incompatibility here
return err
@ -1554,6 +1562,7 @@ func (c *Container) pause() error {
logrus.Debugf("Paused container %s", c.ID())
c.state.State = define.ContainerStatePaused
c.state.HCUnitName = ""
return c.save()
}
@ -1569,6 +1578,28 @@ func (c *Container) unpause() error {
return err
}
isStartupHealthCheck := c.config.StartupHealthCheckConfig != nil && !c.state.StartupHCPassed
isHealthCheckEnabled := c.config.HealthCheckConfig != nil &&
!(len(c.config.HealthCheckConfig.Test) == 1 && c.config.HealthCheckConfig.Test[0] == "NONE")
if isHealthCheckEnabled || isStartupHealthCheck {
timer := c.config.HealthCheckConfig.Interval.String()
if isStartupHealthCheck {
timer = c.config.StartupHealthCheckConfig.Interval.String()
}
if err := c.createTimer(timer, isStartupHealthCheck); err != nil {
return err
}
}
if isHealthCheckEnabled {
if err := c.updateHealthStatus(define.HealthCheckReset); err != nil {
return err
}
if err := c.startTimer(isStartupHealthCheck); err != nil {
return err
}
}
logrus.Debugf("Unpaused container %s", c.ID())
c.state.State = define.ContainerStateRunning

View File

@ -4,6 +4,7 @@
#
load helpers
load helpers.systemd
# bats test_tags=distro-integration, ci:parallel
@test "podman pause/unpause" {
@ -86,4 +87,52 @@ load helpers
run_podman rm -t 0 -f $cname $cname_notrunning
}
# bats test_tags=ci:parallel
@test "podman pause/unpause with HealthCheck interval" {
if is_rootless && ! is_cgroupsv2; then
skip "'podman pause' (rootless) only works with cgroups v2"
fi
local ctrname="c-$(safename)"
local msg="healthmsg-$(random_string)"
run_podman run -d --name $ctrname \
--health-cmd "echo $msg" \
--health-interval 1s \
$IMAGE /home/podman/pause
cid="$output"
run_podman healthcheck run $ctrname
is "$output" "" "output from 'podman healthcheck run'"
run -0 systemctl status $cid-*.{service,timer}
assert "$output" =~ "active" "service should be running"
run_podman --noout pause $ctrname
assert "$output" == "" "output should be empty"
run -0 systemctl status $cid-*.{service,timer}
assert "$output" == "" "service should not be running"
run_podman --noout unpause $ctrname
assert "$output" == "" "output should be empty"
run_podman healthcheck run $ctrname
is "$output" "" "output from 'podman healthcheck run'"
run -0 systemctl status $cid-*.{service,timer}
assert "$output" =~ "active" "service should be running"
run_podman rm -t 0 -f $ctrname
# Important check for https://github.com/containers/podman/issues/22884
# We never should leak the unit files, healthcheck uses the cid in name so just grep that.
# (Ignore .scope units, those are conmon and can linger for 5 minutes)
# (Ignore .mount, too. They are created/removed by systemd based on the actual real mounts
# on the host and that is async and might be slow enough in CI to cause failures.)
run -0 systemctl list-units --quiet "*$cid*"
except_scope_mount=$(grep -vF ".scope " <<<"$output" | { grep -vF ".mount" || true; } )
assert "$except_scope_mount" == "" "Healthcheck systemd unit cleanup: no units leaked"
}
# vim: filetype=sh