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 <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger
2024-10-17 14:40:18 +02:00
parent 203ab6573b
commit 57b022782b
18 changed files with 66 additions and 50 deletions

View File

@@ -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"

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.