From 6cb2f9b1225ade1248ed954e5e03fea9ff279730 Mon Sep 17 00:00:00 2001 From: Alex Palaistras Date: Sat, 18 Nov 2023 21:37:00 +0000 Subject: [PATCH] quadlet: Support `healthy` for `Notify` directives This expands support for the (previously) boolean `Notify` directive, in support of healthcheck determined SD-NOTIFY event emission, as supported by Podman with the `--sdnotify=healthy` option. Closes: #18189 Signed-off-by: Alex Palaistras --- docs/source/markdown/podman-systemd.unit.5.md | 4 ++++ pkg/systemd/quadlet/quadlet.go | 9 ++++++--- test/e2e/quadlet/notify-healthy.container | 5 +++++ test/e2e/quadlet_test.go | 1 + 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 test/e2e/quadlet/notify-healthy.container diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index 79659ded24..01ca6293a0 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -496,6 +496,10 @@ starts the child in the container. However, if the container application support `Notify` to true passes the notification details to the container allowing it to notify of startup on its own. +In addition, setting `Notify` to `healthy` will postpone startup notifications until such time as +the container is marked healthy, as determined by Podman healthchecks. Note that this requires +setting up a container healthcheck, see the `HealthCmd` option for more. + ### `PidsLimit=` Tune the container's pids limit. diff --git a/pkg/systemd/quadlet/quadlet.go b/pkg/systemd/quadlet/quadlet.go index 26e1745b1e..3328087900 100644 --- a/pkg/systemd/quadlet/quadlet.go +++ b/pkg/systemd/quadlet/quadlet.go @@ -496,10 +496,13 @@ func ConvertContainer(container *parser.UnitFile, names map[string]string, isUse if serviceType != "oneshot" { // If we're not in oneshot mode always use some form of sd-notify, normally via conmon, // but we also allow passing it to the container by setting Notify=yes - notify := container.LookupBooleanWithDefault(ContainerGroup, KeyNotify, false) - if notify { + notify, ok := container.Lookup(ContainerGroup, KeyNotify) + switch { + case ok && strings.EqualFold(notify, "healthy"): + podman.add("--sdnotify=healthy") + case container.LookupBooleanWithDefault(ContainerGroup, KeyNotify, false): podman.add("--sdnotify=container") - } else { + default: podman.add("--sdnotify=conmon") } service.Setv(ServiceGroup, diff --git a/test/e2e/quadlet/notify-healthy.container b/test/e2e/quadlet/notify-healthy.container new file mode 100644 index 0000000000..6dc3d8c092 --- /dev/null +++ b/test/e2e/quadlet/notify-healthy.container @@ -0,0 +1,5 @@ +## assert-podman-args "--sdnotify=healthy" + +[Container] +Image=localhost/imagename +Notify=healthy diff --git a/test/e2e/quadlet_test.go b/test/e2e/quadlet_test.go index 34de882930..ad3061f4cd 100644 --- a/test/e2e/quadlet_test.go +++ b/test/e2e/quadlet_test.go @@ -712,6 +712,7 @@ BOGUS=foo Entry("network.quadlet.container", "network.quadlet.container", 0, ""), Entry("noimage.container", "noimage.container", 1, "converting \"noimage.container\": no Image or Rootfs key specified"), Entry("notify.container", "notify.container", 0, ""), + Entry("notify-healthy.container", "notify-healthy.container", 0, ""), Entry("oneshot.container", "oneshot.container", 0, ""), Entry("other-sections.container", "other-sections.container", 0, ""), Entry("podmanargs.container", "podmanargs.container", 0, ""),