From 21d0711a027bd07a56e630c2b9a3e17832d79c69 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 17 Oct 2024 13:34:44 +0200 Subject: [PATCH 1/6] contrib/systemd: move podman-auto-update units There is really no reason why these should be in separate dir. Signed-off-by: Paul Holzinger --- Makefile | 10 +++++----- .../podman-auto-update.service.in | 0 .../{auto-update => system}/podman-auto-update.timer | 0 3 files changed, 5 insertions(+), 5 deletions(-) rename contrib/systemd/{auto-update => system}/podman-auto-update.service.in (100%) rename contrib/systemd/{auto-update => system}/podman-auto-update.timer (100%) diff --git a/Makefile b/Makefile index b0e604f407..1597d0abbf 100644 --- a/Makefile +++ b/Makefile @@ -982,7 +982,7 @@ install.docker-full: install.docker install.docker-docs .PHONY: install.systemd ifneq (,$(findstring systemd,$(BUILDTAGS))) -PODMAN_UNIT_FILES = contrib/systemd/auto-update/podman-auto-update.service \ +PODMAN_UNIT_FILES = contrib/systemd/system/podman-auto-update.service \ contrib/systemd/system/podman.service \ contrib/systemd/system/podman-restart.service \ contrib/systemd/system/podman-kube@.service \ @@ -995,16 +995,16 @@ PODMAN_UNIT_FILES = contrib/systemd/auto-update/podman-auto-update.service \ install.systemd: $(PODMAN_UNIT_FILES) install ${SELINUXOPT} -m 755 -d $(DESTDIR)${SYSTEMDDIR} $(DESTDIR)${USERSYSTEMDDIR} # User services - install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.service $(DESTDIR)${USERSYSTEMDDIR}/podman-auto-update.service - install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.timer $(DESTDIR)${USERSYSTEMDDIR}/podman-auto-update.timer + install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-auto-update.service $(DESTDIR)${USERSYSTEMDDIR}/podman-auto-update.service + install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-auto-update.timer $(DESTDIR)${USERSYSTEMDDIR}/podman-auto-update.timer install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.socket $(DESTDIR)${USERSYSTEMDDIR}/podman.socket install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.service $(DESTDIR)${USERSYSTEMDDIR}/podman.service install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-restart.service $(DESTDIR)${USERSYSTEMDDIR}/podman-restart.service install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-kube@.service $(DESTDIR)${USERSYSTEMDDIR}/podman-kube@.service install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-clean-transient.service $(DESTDIR)${USERSYSTEMDDIR}/podman-clean-transient.service # System services - install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.service $(DESTDIR)${SYSTEMDDIR}/podman-auto-update.service - install ${SELINUXOPT} -m 644 contrib/systemd/auto-update/podman-auto-update.timer $(DESTDIR)${SYSTEMDDIR}/podman-auto-update.timer + install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-auto-update.service $(DESTDIR)${SYSTEMDDIR}/podman-auto-update.service + install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-auto-update.timer $(DESTDIR)${SYSTEMDDIR}/podman-auto-update.timer install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.socket $(DESTDIR)${SYSTEMDDIR}/podman.socket install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.service $(DESTDIR)${SYSTEMDDIR}/podman.service install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-restart.service $(DESTDIR)${SYSTEMDDIR}/podman-restart.service diff --git a/contrib/systemd/auto-update/podman-auto-update.service.in b/contrib/systemd/system/podman-auto-update.service.in similarity index 100% rename from contrib/systemd/auto-update/podman-auto-update.service.in rename to contrib/systemd/system/podman-auto-update.service.in diff --git a/contrib/systemd/auto-update/podman-auto-update.timer b/contrib/systemd/system/podman-auto-update.timer similarity index 100% rename from contrib/systemd/auto-update/podman-auto-update.timer rename to contrib/systemd/system/podman-auto-update.timer From 1462b520902639039746dd91f60c13f56674e78c Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 17 Oct 2024 13:48:02 +0200 Subject: [PATCH 2/6] Makefile: remove some duplication from install.systemd Use a single loop for both the user and system service so we do not have to duplicate the full paths every time. In particular we can use `$^` to list all dependecies and then add the not generated files to the loop as well to simplify this. And to make things clear rename PODMAN_UNIT_FILES to PODMAN_GENERATED_UNIT_FILES so readers immediately know they are generated and are safe to delete in contrast to the .socket/.timer unit that are not and part of the git history. Signed-off-by: Paul Holzinger --- Makefile | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 1597d0abbf..d8b416291a 100644 --- a/Makefile +++ b/Makefile @@ -982,7 +982,7 @@ install.docker-full: install.docker install.docker-docs .PHONY: install.systemd ifneq (,$(findstring systemd,$(BUILDTAGS))) -PODMAN_UNIT_FILES = contrib/systemd/system/podman-auto-update.service \ +PODMAN_GENERATED_UNIT_FILES = contrib/systemd/system/podman-auto-update.service \ contrib/systemd/system/podman.service \ contrib/systemd/system/podman-restart.service \ contrib/systemd/system/podman-kube@.service \ @@ -992,25 +992,15 @@ PODMAN_UNIT_FILES = contrib/systemd/system/podman-auto-update.service \ sed -e 's;@@PODMAN@@;$(BINDIR)/podman;g' $< >$@.tmp.$$ \ && mv -f $@.tmp.$$ $@ -install.systemd: $(PODMAN_UNIT_FILES) +install.systemd: $(PODMAN_GENERATED_UNIT_FILES) install ${SELINUXOPT} -m 755 -d $(DESTDIR)${SYSTEMDDIR} $(DESTDIR)${USERSYSTEMDDIR} - # User services - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-auto-update.service $(DESTDIR)${USERSYSTEMDDIR}/podman-auto-update.service - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-auto-update.timer $(DESTDIR)${USERSYSTEMDDIR}/podman-auto-update.timer - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.socket $(DESTDIR)${USERSYSTEMDDIR}/podman.socket - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.service $(DESTDIR)${USERSYSTEMDDIR}/podman.service - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-restart.service $(DESTDIR)${USERSYSTEMDDIR}/podman-restart.service - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-kube@.service $(DESTDIR)${USERSYSTEMDDIR}/podman-kube@.service - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-clean-transient.service $(DESTDIR)${USERSYSTEMDDIR}/podman-clean-transient.service - # System services - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-auto-update.service $(DESTDIR)${SYSTEMDDIR}/podman-auto-update.service - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-auto-update.timer $(DESTDIR)${SYSTEMDDIR}/podman-auto-update.timer - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.socket $(DESTDIR)${SYSTEMDDIR}/podman.socket - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman.service $(DESTDIR)${SYSTEMDDIR}/podman.service - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-restart.service $(DESTDIR)${SYSTEMDDIR}/podman-restart.service - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-kube@.service $(DESTDIR)${SYSTEMDDIR}/podman-kube@.service - install ${SELINUXOPT} -m 644 contrib/systemd/system/podman-clean-transient.service $(DESTDIR)${SYSTEMDDIR}/podman-clean-transient.service - rm -f $(PODMAN_UNIT_FILES) + for unit in $^ \ + contrib/systemd/system/podman-auto-update.timer \ + contrib/systemd/system/podman.socket; do \ + install ${SELINUXOPT} -m 644 $$unit $(DESTDIR)${USERSYSTEMDDIR}/$$(basename $$unit); \ + install ${SELINUXOPT} -m 644 $$unit $(DESTDIR)${SYSTEMDDIR}/$$(basename $$unit); \ + done + rm -f $^ else install.systemd: endif From a6c4e00e9ad81ab2a48f64386c507e3bd7509eff Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 17 Oct 2024 13:57:32 +0200 Subject: [PATCH 3/6] contrib/systemd: switch user symlink for file symlinks The reason being that I plan to add a unit that should only be used for the user session and otherwise there is no way to only keep a unit in user. Signed-off-by: Paul Holzinger --- contrib/systemd/user | 1 - contrib/systemd/user/podman-auto-update.service.in | 1 + contrib/systemd/user/podman-auto-update.timer | 1 + contrib/systemd/user/podman-clean-transient.service.in | 1 + contrib/systemd/user/podman-kube@.service.in | 1 + contrib/systemd/user/podman-restart.service.in | 1 + contrib/systemd/user/podman.service.in | 1 + contrib/systemd/user/podman.socket | 1 + 8 files changed, 7 insertions(+), 1 deletion(-) delete mode 120000 contrib/systemd/user create mode 120000 contrib/systemd/user/podman-auto-update.service.in create mode 120000 contrib/systemd/user/podman-auto-update.timer create mode 120000 contrib/systemd/user/podman-clean-transient.service.in create mode 120000 contrib/systemd/user/podman-kube@.service.in create mode 120000 contrib/systemd/user/podman-restart.service.in create mode 120000 contrib/systemd/user/podman.service.in create mode 120000 contrib/systemd/user/podman.socket diff --git a/contrib/systemd/user b/contrib/systemd/user deleted file mode 120000 index 3f3d9896bf..0000000000 --- a/contrib/systemd/user +++ /dev/null @@ -1 +0,0 @@ -./system/ \ No newline at end of file diff --git a/contrib/systemd/user/podman-auto-update.service.in b/contrib/systemd/user/podman-auto-update.service.in new file mode 120000 index 0000000000..3b0f2542c1 --- /dev/null +++ b/contrib/systemd/user/podman-auto-update.service.in @@ -0,0 +1 @@ +../system/podman-auto-update.service.in \ No newline at end of file diff --git a/contrib/systemd/user/podman-auto-update.timer b/contrib/systemd/user/podman-auto-update.timer new file mode 120000 index 0000000000..7ca2ed211d --- /dev/null +++ b/contrib/systemd/user/podman-auto-update.timer @@ -0,0 +1 @@ +../system/podman-auto-update.timer \ No newline at end of file diff --git a/contrib/systemd/user/podman-clean-transient.service.in b/contrib/systemd/user/podman-clean-transient.service.in new file mode 120000 index 0000000000..6c89f3ec12 --- /dev/null +++ b/contrib/systemd/user/podman-clean-transient.service.in @@ -0,0 +1 @@ +../system/podman-clean-transient.service.in \ No newline at end of file diff --git a/contrib/systemd/user/podman-kube@.service.in b/contrib/systemd/user/podman-kube@.service.in new file mode 120000 index 0000000000..0382eab620 --- /dev/null +++ b/contrib/systemd/user/podman-kube@.service.in @@ -0,0 +1 @@ +../system/podman-kube@.service.in \ No newline at end of file diff --git a/contrib/systemd/user/podman-restart.service.in b/contrib/systemd/user/podman-restart.service.in new file mode 120000 index 0000000000..b4b3c0e9ac --- /dev/null +++ b/contrib/systemd/user/podman-restart.service.in @@ -0,0 +1 @@ +../system/podman-restart.service.in \ No newline at end of file diff --git a/contrib/systemd/user/podman.service.in b/contrib/systemd/user/podman.service.in new file mode 120000 index 0000000000..0ccbeeaec7 --- /dev/null +++ b/contrib/systemd/user/podman.service.in @@ -0,0 +1 @@ +../system/podman.service.in \ No newline at end of file diff --git a/contrib/systemd/user/podman.socket b/contrib/systemd/user/podman.socket new file mode 120000 index 0000000000..64fdbf019f --- /dev/null +++ b/contrib/systemd/user/podman.socket @@ -0,0 +1 @@ +../system/podman.socket \ No newline at end of file From 203ab6573b054cf81318d724fe12182d14c66313 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 17 Oct 2024 14:27:10 +0200 Subject: [PATCH 4/6] add new podman-user-wait-network-online.service This service is meant to be used by quadlet as replacement for network-online.target as this does not work for rootless users. see #22197 Signed-off-by: Paul Holzinger --- .gitignore | 2 +- Makefile | 3 +++ .../user/podman-user-wait-network-online.service | 12 ++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 contrib/systemd/user/podman-user-wait-network-online.service diff --git a/.gitignore b/.gitignore index 1b596b2b44..9ad295735e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ /build/ /conmon/ contrib/spec/podman.spec -contrib/systemd/*/*.service +contrib/systemd/system/*.service *.coverprofile coverprofile /.coverage diff --git a/Makefile b/Makefile index d8b416291a..41582736ce 100644 --- a/Makefile +++ b/Makefile @@ -1000,6 +1000,9 @@ install.systemd: $(PODMAN_GENERATED_UNIT_FILES) install ${SELINUXOPT} -m 644 $$unit $(DESTDIR)${USERSYSTEMDDIR}/$$(basename $$unit); \ install ${SELINUXOPT} -m 644 $$unit $(DESTDIR)${SYSTEMDDIR}/$$(basename $$unit); \ done + # Important this unit should only be installed for the user session and is thus not added to the loop above. + install ${SELINUXOPT} -m 644 contrib/systemd/user/podman-user-wait-network-online.service \ + $(DESTDIR)${USERSYSTEMDDIR}/podman-user-wait-network-online.service rm -f $^ else install.systemd: diff --git a/contrib/systemd/user/podman-user-wait-network-online.service b/contrib/systemd/user/podman-user-wait-network-online.service new file mode 100644 index 0000000000..757948ac0d --- /dev/null +++ b/contrib/systemd/user/podman-user-wait-network-online.service @@ -0,0 +1,12 @@ +[Unit] +Description=Wait for system level network-online.target as user. +Documentation=https://github.com/containers/podman/issues/22197 +Documentation=man:podman-systemd.unit(5) + +[Service] +Type=oneshot +# Set a timeout as by default oneshot does not have one and in case network-online.target +# never comes online we do not want to block forever, 90s is the default systemd unit timeout. +TimeoutStartSec=90s +ExecStart=sh -c 'until systemctl is-active network-online.target; do sleep 0.5; done' +RemainAfterExit=yes From 57b022782bba8cd48865f9dd84e9fea8a1588e4c Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 17 Oct 2024 14:40:18 +0200 Subject: [PATCH 5/6] quadlet: ensure user units wait for the network As documented in the issue there is no way to wait for system units from the user session[1]. This causes problems for rootless quadlet units as they might be started before the network is fully up. TWhile this was always the case and thus was never really noticed the main thing that trigger a bunch of errors was the switch to pasta. Pasta requires the network to be fully up in order to correctly select the right "template" interface based on the routes. If it cannot find a suitable interface it just fails and we cannot start the container understandingly leading to a lot of frustration from users. As there is no sign of any movement on the systemd issue we work around here by using our own user unit that check if the system session network-online.target it ready. Now for testing it is a bit complicated. While we do now correctly test the root and rootless generator since commit ada75c0bb8 the resulting Wants/After= lines differ between them and there is no logic in the testfiles themself to say if root/rootless to match specifics. One idea was to use `assert-key-is-rootless/root` but that seemed like more duplication for little reason so use a regex and allow both to make it pass always. To still have some test coverage add a check in the system test to ask systemd if we did indeed have the right depdendencies where we can check for exact root/rootless name match. [1] https://github.com/systemd/systemd/issues/3312 Fixes #22197 Signed-off-by: Paul Holzinger --- cmd/quadlet/main.go | 4 +- docs/source/markdown/podman-systemd.unit.5.md | 22 +++++---- pkg/systemd/quadlet/quadlet.go | 47 ++++++++++--------- test/e2e/quadlet/basic.build | 4 +- test/e2e/quadlet/basic.container | 4 +- test/e2e/quadlet/basic.image | 4 +- test/e2e/quadlet/mount.container | 2 +- test/e2e/quadlet/mount.servicename.container | 2 +- test/e2e/quadlet/network.quadlet.build | 2 +- test/e2e/quadlet/network.quadlet.container | 2 +- .../quadlet/network.quadlet.servicename.build | 2 +- .../network.quadlet.servicename.container | 2 +- test/e2e/quadlet/network.reuse.container | 2 +- test/e2e/quadlet/network.reuse.name.container | 2 +- test/e2e/quadlet/volume.quadlet.build | 2 +- .../quadlet/volume.quadlet.servicename.build | 2 +- test/e2e/quadlet/volume.servicename.container | 2 +- test/system/252-quadlet.bats | 9 ++++ 18 files changed, 66 insertions(+), 50 deletions(-) diff --git a/cmd/quadlet/main.go b/cmd/quadlet/main.go index 4433fb9a15..49efe103f2 100644 --- a/cmd/quadlet/main.go +++ b/cmd/quadlet/main.go @@ -739,9 +739,9 @@ func process() error { service, err = quadlet.ConvertNetwork(unit, unit.Filename, unitsInfoMap) case strings.HasSuffix(unit.Filename, ".image"): warnIfAmbiguousName(unit, quadlet.ImageGroup) - service, err = quadlet.ConvertImage(unit, unitsInfoMap) + service, err = quadlet.ConvertImage(unit, unitsInfoMap, isUserFlag) case strings.HasSuffix(unit.Filename, ".build"): - service, err = quadlet.ConvertBuild(unit, unitsInfoMap) + service, err = quadlet.ConvertBuild(unit, unitsInfoMap, isUserFlag) case strings.HasSuffix(unit.Filename, ".pod"): service, err = quadlet.ConvertPod(unit, unit.Filename, unitsInfoMap, isUserFlag) default: diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index a204d62004..47d7dda91a 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -238,9 +238,14 @@ that limit the output to only the units you are debugging. ### Implicit network dependencies -In the case of Container, Image and Build units, Quadlet will add dependencies on the `network-online.target` -by adding `After=` and `Wants=` properties to the unit. This is to ensure that the network is reachable if -an image needs to be pulled. +In the case of Container, Image and Build units, Quadlet will add dependencies on the `network-online.target` (as root) +or `podman-user-wait-network-online.service` (as user) by adding `After=` and `Wants=` properties to the unit. +This is to ensure that the network is reachable if an image needs to be pulled and by the time the container is started. + +The special case `podman-user-wait-network-online.service` unit is needed as user because user units are unable to wait +for system (root) units so `network-online.target` doesn't do anything there and is instead ignored. As this caused +a significant amount of issues we decided to work around this with our own special purpose unit that simply checks if +the `network-online.target` unit is active with `systemctl is-active network-online.target`. This behavior can be disabled by adding `DefaultDependencies=false` in the `Quadlet` section. @@ -1791,10 +1796,10 @@ exists on the host, pulling it if needed. Using image units allows containers and volumes to depend on images being automatically pulled. This is particularly interesting when using special options to control image pulls. -Note: The generated service have a dependency on `network-online.target` assuring the network is reachable if -an image needs to be pulled. -If the image service needs to run without available network (e.g. early in boot), the requirement can be -overridden simply by adding an empty `After=` in the unit file. This will unset all previously set After's. +Note: The generated service have a dependency on `network-online.target` or +`podman-user-wait-network-online.service` assuring the network is reachable if an image needs to be pulled. +If the image service needs to run without available network (e.g. early in boot), this behavior +can be disabled by adding `DefaultDependencies=false` in the `Quadlet` section. Valid options for `[Image]` are listed below: @@ -1936,7 +1941,8 @@ Valid options for `[Quadlet]` are listed below: Add Quadlet's default network dependencies to the unit (default is `true`). -When set to false, Quadlet will **not** add a dependency (After=, Wants=) to `network-online.target` to the generated unit. +When set to false, Quadlet will **not** add a dependency (After=, Wants=) to +`network-online.target`/`podman-user-wait-network-online.service` to the generated unit. ## EXAMPLES diff --git a/pkg/systemd/quadlet/quadlet.go b/pkg/systemd/quadlet/quadlet.go index a369482fdf..611b510143 100644 --- a/pkg/systemd/quadlet/quadlet.go +++ b/pkg/systemd/quadlet/quadlet.go @@ -524,13 +524,7 @@ func ConvertContainer(container *parser.UnitFile, isUser bool, unitsInfoMap map[ service := container.Dup() service.Filename = unitInfo.ServiceFileName() - // Add a dependency on network-online.target so the image pull does not happen - // before network is ready - // https://github.com/containers/podman/issues/21873 - if service.LookupBooleanWithDefault(QuadletGroup, KeyDefaultDependencies, true) { - service.PrependUnitLine(UnitGroup, "After", "network-online.target") - service.PrependUnitLine(UnitGroup, "Wants", "network-online.target") - } + addDefaultDependencies(service, isUser) if container.Path != "" { service.Add(UnitGroup, "SourcePath", container.Path) @@ -1282,7 +1276,7 @@ func ConvertKube(kube *parser.UnitFile, unitsInfoMap map[string]*UnitInfo, isUse return service, nil } -func ConvertImage(image *parser.UnitFile, unitsInfoMap map[string]*UnitInfo) (*parser.UnitFile, error) { +func ConvertImage(image *parser.UnitFile, unitsInfoMap map[string]*UnitInfo, isUser bool) (*parser.UnitFile, error) { unitInfo, ok := unitsInfoMap[image.Filename] if !ok { return nil, fmt.Errorf("internal error while processing network %s", image.Filename) @@ -1291,13 +1285,7 @@ func ConvertImage(image *parser.UnitFile, unitsInfoMap map[string]*UnitInfo) (*p service := image.Dup() service.Filename = unitInfo.ServiceFileName() - // Add a dependency on network-online.target so the image pull does not happen - // before network is ready - // https://github.com/containers/podman/issues/21873 - if service.LookupBooleanWithDefault(QuadletGroup, KeyDefaultDependencies, true) { - service.PrependUnitLine(UnitGroup, "After", "network-online.target") - service.PrependUnitLine(UnitGroup, "Wants", "network-online.target") - } + addDefaultDependencies(service, isUser) if image.Path != "" { service.Add(UnitGroup, "SourcePath", image.Path) @@ -1365,7 +1353,7 @@ func ConvertImage(image *parser.UnitFile, unitsInfoMap map[string]*UnitInfo) (*p return service, nil } -func ConvertBuild(build *parser.UnitFile, unitsInfoMap map[string]*UnitInfo) (*parser.UnitFile, error) { +func ConvertBuild(build *parser.UnitFile, unitsInfoMap map[string]*UnitInfo, isUser bool) (*parser.UnitFile, error) { unitInfo, ok := unitsInfoMap[build.Filename] if !ok { return nil, fmt.Errorf("internal error while processing network %s", build.Filename) @@ -1379,13 +1367,7 @@ func ConvertBuild(build *parser.UnitFile, unitsInfoMap map[string]*UnitInfo) (*p service := build.Dup() service.Filename = unitInfo.ServiceFileName() - // Add a dependency on network-online.target so the image pull does not happen - // before network is ready - // https://github.com/containers/podman/issues/21873 - if service.LookupBooleanWithDefault(QuadletGroup, KeyDefaultDependencies, true) { - service.PrependUnitLine(UnitGroup, "After", "network-online.target") - service.PrependUnitLine(UnitGroup, "Wants", "network-online.target") - } + addDefaultDependencies(service, isUser) /* Rename old Build group to X-Build so that systemd ignores it */ service.RenameGroup(BuildGroup, XBuildGroup) @@ -2184,3 +2166,22 @@ func addVolumes(quadletUnitFile, serviceUnitFile *parser.UnitFile, groupName str return nil } + +func addDefaultDependencies(service *parser.UnitFile, isUser bool) { + // Add a dependency on network-online.target so the image pull container startup + // does not happen before network is ready. + // https://github.com/containers/podman/issues/21873 + if service.LookupBooleanWithDefault(QuadletGroup, KeyDefaultDependencies, true) { + networkUnit := "network-online.target" + // network-online.target only exists as root and user session cannot wait for it + // https://github.com/systemd/systemd/issues/3312 + // Given this is a bad problem with pasta which can fail to start or use the + // wrong interface if the network is not fully set up we need to work around + // that: https://github.com/containers/podman/issues/22197. + if isUser { + networkUnit = "podman-user-wait-network-online.service" + } + service.PrependUnitLine(UnitGroup, "After", networkUnit) + service.PrependUnitLine(UnitGroup, "Wants", networkUnit) + } +} diff --git a/test/e2e/quadlet/basic.build b/test/e2e/quadlet/basic.build index b8d5d08c4c..ebc7cbc791 100644 --- a/test/e2e/quadlet/basic.build +++ b/test/e2e/quadlet/basic.build @@ -1,7 +1,7 @@ ## assert-podman-final-args-regex /.*/podman-e2e-.*/subtest-.*/quadlet ## assert-podman-args "--tag" "localhost/imagename" -## assert-key-is "Unit" "After" "network-online.target" -## assert-key-is "Unit" "Wants" "network-online.target" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" +## assert-key-is-regex "Unit" "Wants" "network-online.target|podman-user-wait-network-online.service" ## assert-key-is "Unit" "RequiresMountsFor" "%t/containers" ## assert-key-is-regex "Service" "WorkingDirectory" "/.*/podman-e2e-.*/subtest-.*/quadlet" ## assert-key-is "Service" "Type" "oneshot" diff --git a/test/e2e/quadlet/basic.container b/test/e2e/quadlet/basic.container index cbceda4e4c..5f7417dbf7 100644 --- a/test/e2e/quadlet/basic.container +++ b/test/e2e/quadlet/basic.container @@ -15,8 +15,8 @@ ## assert-key-is-regex "Service" "ExecStopPost" "-[/S].*/podman rm -v -f -i --cidfile=%t/%N.cid" ## assert-key-is-regex "Service" "ExecStop" ".*/podman rm -v -f -i --cidfile=%t/%N.cid" ## assert-key-is "Service" "Environment" "PODMAN_SYSTEMD_UNIT=%n" -## assert-key-is "Unit" "After" "network-online.target" -## assert-key-is "Unit" "Wants" "network-online.target" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" +## assert-key-is-regex "Unit" "Wants" "network-online.target|podman-user-wait-network-online.service" [Container] Image=localhost/imagename diff --git a/test/e2e/quadlet/basic.image b/test/e2e/quadlet/basic.image index 9a30765e52..cb1bcf34ca 100644 --- a/test/e2e/quadlet/basic.image +++ b/test/e2e/quadlet/basic.image @@ -1,6 +1,6 @@ ## assert-podman-final-args localhost/imagename -## assert-key-is "Unit" "After" "network-online.target" -## assert-key-is "Unit" "Wants" "network-online.target" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" +## assert-key-is-regex "Unit" "Wants" "network-online.target|podman-user-wait-network-online.service" ## assert-key-is "Unit" "RequiresMountsFor" "%t/containers" ## assert-key-is "Service" "Type" "oneshot" ## assert-key-is "Service" "RemainAfterExit" "yes" diff --git a/test/e2e/quadlet/mount.container b/test/e2e/quadlet/mount.container index bd156dc72b..615fe58631 100644 --- a/test/e2e/quadlet/mount.container +++ b/test/e2e/quadlet/mount.container @@ -10,7 +10,7 @@ Mount=type=bind,src=/path/on/host,dst=/path/in/container,relabel=shared,U=true Mount=type=volume,source=vol1,destination=/path/in/container,ro=true ## assert-podman-args-key-val "--mount" "," "type=volume,source=systemd-basic,destination=/path/in/container,ro=true" ## assert-key-is "Unit" "Requires" "basic-volume.service" -## assert-key-is "Unit" "After" "network-online.target" "basic-volume.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic-volume.service" Mount=type=volume,source=basic.volume,destination=/path/in/container,ro=true ## assert-podman-args-key-val "--mount" "," "type=tmpfs,tmpfs-size=512M,destination=/path/in/container" Mount=type=tmpfs,tmpfs-size=512M,destination=/path/in/container diff --git a/test/e2e/quadlet/mount.servicename.container b/test/e2e/quadlet/mount.servicename.container index 95be8f82af..00a80a5af8 100644 --- a/test/e2e/quadlet/mount.servicename.container +++ b/test/e2e/quadlet/mount.servicename.container @@ -2,5 +2,5 @@ Image=localhost/imagename ## assert-podman-args-key-val "--mount" "," "type=volume,source=test-volume,destination=/path/in/container,ro=true" ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "network-online.target" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" Mount=type=volume,source=service-name.volume,destination=/path/in/container,ro=true diff --git a/test/e2e/quadlet/network.quadlet.build b/test/e2e/quadlet/network.quadlet.build index eb755dcedd..f38c820d21 100644 --- a/test/e2e/quadlet/network.quadlet.build +++ b/test/e2e/quadlet/network.quadlet.build @@ -1,6 +1,6 @@ ## assert-podman-args "--network" "systemd-basic" ## assert-key-is "Unit" "Requires" "basic-network.service" -## assert-key-is "Unit" "After" "network-online.target" "basic-network.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic-network.service" [Build] ImageTag=localhost/imagename diff --git a/test/e2e/quadlet/network.quadlet.container b/test/e2e/quadlet/network.quadlet.container index 7811cad10c..ba805e3273 100644 --- a/test/e2e/quadlet/network.quadlet.container +++ b/test/e2e/quadlet/network.quadlet.container @@ -1,6 +1,6 @@ ## assert-podman-args "--network" "systemd-basic" ## assert-key-is "Unit" "Requires" "basic-network.service" -## assert-key-is "Unit" "After" "network-online.target" "basic-network.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic-network.service" [Container] Image=localhost/imagename diff --git a/test/e2e/quadlet/network.quadlet.servicename.build b/test/e2e/quadlet/network.quadlet.servicename.build index a06c030ebd..95137f673d 100644 --- a/test/e2e/quadlet/network.quadlet.servicename.build +++ b/test/e2e/quadlet/network.quadlet.servicename.build @@ -1,6 +1,6 @@ ## assert-podman-args "--network" "test-network" ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "network-online.target" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" [Build] ImageTag=localhost/imagename diff --git a/test/e2e/quadlet/network.quadlet.servicename.container b/test/e2e/quadlet/network.quadlet.servicename.container index 54c74fd1ea..d28791b463 100644 --- a/test/e2e/quadlet/network.quadlet.servicename.container +++ b/test/e2e/quadlet/network.quadlet.servicename.container @@ -1,6 +1,6 @@ ## assert-podman-args "--network" "test-network" ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "network-online.target" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" [Container] Image=localhost/imagename diff --git a/test/e2e/quadlet/network.reuse.container b/test/e2e/quadlet/network.reuse.container index e26546ba44..f9a6f6b142 100644 --- a/test/e2e/quadlet/network.reuse.container +++ b/test/e2e/quadlet/network.reuse.container @@ -1,6 +1,6 @@ ## assert-podman-args "--network" "container:systemd-basic" ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "network-online.target" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" [Container] Image=localhost/imagename diff --git a/test/e2e/quadlet/network.reuse.name.container b/test/e2e/quadlet/network.reuse.name.container index 49fef56267..2927e6fea0 100644 --- a/test/e2e/quadlet/network.reuse.name.container +++ b/test/e2e/quadlet/network.reuse.name.container @@ -1,6 +1,6 @@ ## assert-podman-args "--network" "container:foobar" ## assert-key-is "Unit" "Requires" "name.service" -## assert-key-is "Unit" "After" "network-online.target" "name.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "name.service" [Container] Image=localhost/imagename diff --git a/test/e2e/quadlet/volume.quadlet.build b/test/e2e/quadlet/volume.quadlet.build index 6cb57bda13..08ede62f3e 100644 --- a/test/e2e/quadlet/volume.quadlet.build +++ b/test/e2e/quadlet/volume.quadlet.build @@ -1,6 +1,6 @@ ## assert-podman-args "-v" "systemd-basic:/volume/basic" ## assert-key-is "Unit" "Requires" "basic-volume.service" -## assert-key-is "Unit" "After" "network-online.target" "basic-volume.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic-volume.service" [Build] ImageTag=localhost/imagename diff --git a/test/e2e/quadlet/volume.quadlet.servicename.build b/test/e2e/quadlet/volume.quadlet.servicename.build index d33df93335..4034d2b4c1 100644 --- a/test/e2e/quadlet/volume.quadlet.servicename.build +++ b/test/e2e/quadlet/volume.quadlet.servicename.build @@ -1,6 +1,6 @@ ## assert-podman-args "-v" "test-volume:/volume/basic" ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "network-online.target" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" [Build] ImageTag=localhost/imagename diff --git a/test/e2e/quadlet/volume.servicename.container b/test/e2e/quadlet/volume.servicename.container index dece6a4af3..aeb7bb7644 100644 --- a/test/e2e/quadlet/volume.servicename.container +++ b/test/e2e/quadlet/volume.servicename.container @@ -1,6 +1,6 @@ [Container] Image=localhost/imagename ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "network-online.target" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" ## assert-podman-args -v test-volume:/container/quadlet Volume=service-name.volume:/container/quadlet diff --git a/test/system/252-quadlet.bats b/test/system/252-quadlet.bats index c7a80277e1..b91030e111 100644 --- a/test/system/252-quadlet.bats +++ b/test/system/252-quadlet.bats @@ -201,6 +201,15 @@ EOF run_quadlet "$quadlet_file" service_setup $QUADLET_SERVICE_NAME + run -0 systemctl show --property=Wants --property=After "$QUADLET_SERVICE_NAME" + service="network-online.target" + if is_rootless; then + service="podman-user-wait-network-online.service" + fi + assert "${lines[0]}" == "Wants=$service" "quadlet unit Wants network dependency" + # Note systemd adds some other default services to After= so no exact match possible + assert "${lines[1]}" =~ "After=.*$service.*" "quadlet unit After network dependency" + # Check that we can read the logs from the container with podman logs even # with the `passthrough` driver. The log may need a short period of time # to bubble up into the journal logs, so wait for it. From 67e0fa8b89086f9be352a63620a8b7aa1a34e68f Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Fri, 18 Oct 2024 11:52:59 +0200 Subject: [PATCH 6/6] quadlet: add default network dependencies to all units There is no good reason for the special case, kube and pod units definitely need it. Volume and network units maybe not but for consistency we add it there as well. This makes the docs much easier to write and understand for users as the behavior will not differ. Signed-off-by: Paul Holzinger --- cmd/quadlet/main.go | 4 ++-- docs/source/markdown/podman-systemd.unit.5.md | 11 +++-------- pkg/systemd/quadlet/quadlet.go | 12 ++++++++++-- test/e2e/quadlet/build.quadlet.servicename.volume | 2 +- test/e2e/quadlet/build.quadlet.volume | 2 +- test/e2e/quadlet/image.quadlet.servicename.volume | 2 +- test/e2e/quadlet/image.quadlet.volume | 2 +- test/e2e/quadlet/network.quadlet.kube | 2 +- test/e2e/quadlet/network.quadlet.pod | 2 +- test/e2e/quadlet/network.quadlet.servicename.kube | 2 +- test/e2e/quadlet/network.servicename.quadlet.pod | 2 +- test/e2e/quadlet/volume.servicename.pod | 2 +- test/e2e/quadlet_test.go | 2 ++ 13 files changed, 26 insertions(+), 21 deletions(-) diff --git a/cmd/quadlet/main.go b/cmd/quadlet/main.go index 49efe103f2..e8ea99ed47 100644 --- a/cmd/quadlet/main.go +++ b/cmd/quadlet/main.go @@ -732,11 +732,11 @@ func process() error { service, err = quadlet.ConvertContainer(unit, isUserFlag, unitsInfoMap) case strings.HasSuffix(unit.Filename, ".volume"): warnIfAmbiguousName(unit, quadlet.VolumeGroup) - service, err = quadlet.ConvertVolume(unit, unit.Filename, unitsInfoMap) + service, err = quadlet.ConvertVolume(unit, unit.Filename, unitsInfoMap, isUserFlag) case strings.HasSuffix(unit.Filename, ".kube"): service, err = quadlet.ConvertKube(unit, unitsInfoMap, isUserFlag) case strings.HasSuffix(unit.Filename, ".network"): - service, err = quadlet.ConvertNetwork(unit, unit.Filename, unitsInfoMap) + service, err = quadlet.ConvertNetwork(unit, unit.Filename, unitsInfoMap, isUserFlag) case strings.HasSuffix(unit.Filename, ".image"): warnIfAmbiguousName(unit, quadlet.ImageGroup) service, err = quadlet.ConvertImage(unit, unitsInfoMap, isUserFlag) diff --git a/docs/source/markdown/podman-systemd.unit.5.md b/docs/source/markdown/podman-systemd.unit.5.md index 47d7dda91a..e2cafd9b55 100644 --- a/docs/source/markdown/podman-systemd.unit.5.md +++ b/docs/source/markdown/podman-systemd.unit.5.md @@ -238,9 +238,9 @@ that limit the output to only the units you are debugging. ### Implicit network dependencies -In the case of Container, Image and Build units, Quadlet will add dependencies on the `network-online.target` (as root) -or `podman-user-wait-network-online.service` (as user) by adding `After=` and `Wants=` properties to the unit. -This is to ensure that the network is reachable if an image needs to be pulled and by the time the container is started. +Quadlet will add dependencies on the `network-online.target` (as root) or `podman-user-wait-network-online.service` +(as user) by adding `After=` and `Wants=` properties to the unit. This is to ensure that the network is reachable +if an image needs to be pulled and by the time the container is started. The special case `podman-user-wait-network-online.service` unit is needed as user because user units are unable to wait for system (root) units so `network-online.target` doesn't do anything there and is instead ignored. As this caused @@ -1796,11 +1796,6 @@ exists on the host, pulling it if needed. Using image units allows containers and volumes to depend on images being automatically pulled. This is particularly interesting when using special options to control image pulls. -Note: The generated service have a dependency on `network-online.target` or -`podman-user-wait-network-online.service` assuring the network is reachable if an image needs to be pulled. -If the image service needs to run without available network (e.g. early in boot), this behavior -can be disabled by adding `DefaultDependencies=false` in the `Quadlet` section. - Valid options for `[Image]` are listed below: | **[Image] options** | **podman image pull equivalent** | diff --git a/pkg/systemd/quadlet/quadlet.go b/pkg/systemd/quadlet/quadlet.go index 611b510143..3e957200de 100644 --- a/pkg/systemd/quadlet/quadlet.go +++ b/pkg/systemd/quadlet/quadlet.go @@ -882,7 +882,7 @@ func ConvertContainer(container *parser.UnitFile, isUser bool, unitsInfoMap map[ // The original Network group is kept around as X-Network. // Also returns the canonical network name, either auto-generated or user-defined via the // NetworkName key-value. -func ConvertNetwork(network *parser.UnitFile, name string, unitsInfoMap map[string]*UnitInfo) (*parser.UnitFile, error) { +func ConvertNetwork(network *parser.UnitFile, name string, unitsInfoMap map[string]*UnitInfo, isUser bool) (*parser.UnitFile, error) { unitInfo, ok := unitsInfoMap[network.Filename] if !ok { return nil, fmt.Errorf("internal error while processing network %s", network.Filename) @@ -891,6 +891,8 @@ func ConvertNetwork(network *parser.UnitFile, name string, unitsInfoMap map[stri service := network.Dup() service.Filename = unitInfo.ServiceFileName() + addDefaultDependencies(service, isUser) + if network.Path != "" { service.Add(UnitGroup, "SourcePath", network.Path) } @@ -992,7 +994,7 @@ func ConvertNetwork(network *parser.UnitFile, name string, unitsInfoMap map[stri // The original Volume group is kept around as X-Volume. // Also returns the canonical volume name, either auto-generated or user-defined via the VolumeName // key-value. -func ConvertVolume(volume *parser.UnitFile, name string, unitsInfoMap map[string]*UnitInfo) (*parser.UnitFile, error) { +func ConvertVolume(volume *parser.UnitFile, name string, unitsInfoMap map[string]*UnitInfo, isUser bool) (*parser.UnitFile, error) { unitInfo, ok := unitsInfoMap[volume.Filename] if !ok { return nil, fmt.Errorf("internal error while processing network %s", volume.Filename) @@ -1001,6 +1003,8 @@ func ConvertVolume(volume *parser.UnitFile, name string, unitsInfoMap map[string service := volume.Dup() service.Filename = unitInfo.ServiceFileName() + addDefaultDependencies(service, isUser) + if volume.Path != "" { service.Add(UnitGroup, "SourcePath", volume.Path) } @@ -1142,6 +1146,8 @@ func ConvertKube(kube *parser.UnitFile, unitsInfoMap map[string]*UnitInfo, isUse service := kube.Dup() service.Filename = unitInfo.ServiceFileName() + addDefaultDependencies(service, isUser) + if kube.Path != "" { service.Add(UnitGroup, "SourcePath", kube.Path) } @@ -1532,6 +1538,8 @@ func ConvertPod(podUnit *parser.UnitFile, name string, unitsInfoMap map[string]* service := podUnit.Dup() service.Filename = unitInfo.ServiceFileName() + addDefaultDependencies(service, isUser) + if podUnit.Path != "" { service.Add(UnitGroup, "SourcePath", podUnit.Path) } diff --git a/test/e2e/quadlet/build.quadlet.servicename.volume b/test/e2e/quadlet/build.quadlet.servicename.volume index a253ec0871..881a614d03 100644 --- a/test/e2e/quadlet/build.quadlet.servicename.volume +++ b/test/e2e/quadlet/build.quadlet.servicename.volume @@ -1,7 +1,7 @@ ## assert-podman-args --driver image ## assert-podman-args --opt image=localhost/imagename ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" [Volume] Driver=image diff --git a/test/e2e/quadlet/build.quadlet.volume b/test/e2e/quadlet/build.quadlet.volume index b5daa92c0b..4a7ceabe60 100644 --- a/test/e2e/quadlet/build.quadlet.volume +++ b/test/e2e/quadlet/build.quadlet.volume @@ -1,7 +1,7 @@ ## assert-podman-args --driver image ## assert-podman-args --opt image=localhost/imagename ## assert-key-is "Unit" "Requires" "basic-build.service" -## assert-key-is "Unit" "After" "basic-build.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic-build.service" [Volume] Driver=image diff --git a/test/e2e/quadlet/image.quadlet.servicename.volume b/test/e2e/quadlet/image.quadlet.servicename.volume index e7b4d21127..9507e7f0d2 100644 --- a/test/e2e/quadlet/image.quadlet.servicename.volume +++ b/test/e2e/quadlet/image.quadlet.servicename.volume @@ -1,7 +1,7 @@ ## assert-podman-args --driver image ## assert-podman-args --opt image=localhost/imagename ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" [Volume] Driver=image diff --git a/test/e2e/quadlet/image.quadlet.volume b/test/e2e/quadlet/image.quadlet.volume index 5cd4922cae..963830d491 100644 --- a/test/e2e/quadlet/image.quadlet.volume +++ b/test/e2e/quadlet/image.quadlet.volume @@ -1,7 +1,7 @@ ## assert-podman-args --driver image ## assert-podman-args --opt image=localhost/imagename ## assert-key-is "Unit" "Requires" "basic-image.service" -## assert-key-is "Unit" "After" "basic-image.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic-image.service" [Volume] Driver=image diff --git a/test/e2e/quadlet/network.quadlet.kube b/test/e2e/quadlet/network.quadlet.kube index 5a3f367d92..8cbf1d6a22 100644 --- a/test/e2e/quadlet/network.quadlet.kube +++ b/test/e2e/quadlet/network.quadlet.kube @@ -1,6 +1,6 @@ ## assert-podman-args "--network" "systemd-basic" ## assert-key-is "Unit" "Requires" "basic-network.service" -## assert-key-is "Unit" "After" "basic-network.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic-network.service" [Kube] diff --git a/test/e2e/quadlet/network.quadlet.pod b/test/e2e/quadlet/network.quadlet.pod index f08079de2b..0eecbe1893 100644 --- a/test/e2e/quadlet/network.quadlet.pod +++ b/test/e2e/quadlet/network.quadlet.pod @@ -1,6 +1,6 @@ ## assert-podman-pre-args "--network" "systemd-basic" ## assert-key-is "Unit" "Requires" "basic-network.service" -## assert-key-is "Unit" "After" "basic-network.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic-network.service" [Pod] Network=basic.network diff --git a/test/e2e/quadlet/network.quadlet.servicename.kube b/test/e2e/quadlet/network.quadlet.servicename.kube index 16eccc37be..533bfb9540 100644 --- a/test/e2e/quadlet/network.quadlet.servicename.kube +++ b/test/e2e/quadlet/network.quadlet.servicename.kube @@ -1,6 +1,6 @@ ## assert-podman-args "--network" "test-network" ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" [Kube] diff --git a/test/e2e/quadlet/network.servicename.quadlet.pod b/test/e2e/quadlet/network.servicename.quadlet.pod index 88d7edfead..b9affeb1cb 100644 --- a/test/e2e/quadlet/network.servicename.quadlet.pod +++ b/test/e2e/quadlet/network.servicename.quadlet.pod @@ -1,6 +1,6 @@ ## assert-podman-pre-args "--network" "test-network" ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" [Pod] Network=service-name.network diff --git a/test/e2e/quadlet/volume.servicename.pod b/test/e2e/quadlet/volume.servicename.pod index 07e64c4539..b5b7306915 100644 --- a/test/e2e/quadlet/volume.servicename.pod +++ b/test/e2e/quadlet/volume.servicename.pod @@ -1,6 +1,6 @@ ## assert-podman-pre-args -v test-volume:/container/quadlet ## assert-key-is "Unit" "Requires" "basic.service" -## assert-key-is "Unit" "After" "basic.service" +## assert-key-is-regex "Unit" "After" "network-online.target|podman-user-wait-network-online.service" "basic.service" [Pod] Volume=service-name.volume:/container/quadlet diff --git a/test/e2e/quadlet_test.go b/test/e2e/quadlet_test.go index cba32c4481..ffed49a8a2 100644 --- a/test/e2e/quadlet_test.go +++ b/test/e2e/quadlet_test.go @@ -818,6 +818,8 @@ BOGUS=foo "[X-Kube]", "Yaml=deployment.yml", "[Unit]", + "Wants=network-online.target", + "After=network-online.target", fmt.Sprintf("SourcePath=%s/basic.kube", quadletDir), "RequiresMountsFor=%t/containers", "[Service]",