I seem to have a blind spot when searching the systemd docs for the (very common?) pattern of managing the life cycle of resources which have init, renew, quit phases. Here is an example of using upnp to configure your home modem/router (IGD) with a NAT entry:

Description="Configure the IGD's NAT for VOIP"
Type=oneshot
ExecStart="upnpc -a ..."
ExecStop="upnpc -d ..."
RemainActiveAfterExit=yes

Now it is easy to use systemd to start and stop the service. However, upnp also requires renewing the NAT entry periodically. The semantically correct way would be to create a "partOf" timer which will start and stop along with the service:

Description="BAD TIMER"
PartOf=configure-the-igd.service
OnUnitActiveSec = "1hr";

The ExecStart script is fine for renewal, but unfortunately RemainActiveAfterExit prevents timers from recurring.

The answer seems to be to create a second service for renewal. This second unit has no RemainActiveAfterExit so it will repeat:

Description="Renew the IGD's NAT for VOIP"
Type=oneshot
ExecStart="upnpc -a ..."

Now the timer is part of the first service, but triggers the second:

Description="BETTER TIMER"
PartOf=configure-the-igd.service
OnUnitActiveSec = "1hr";
Unit=renew-the-igd.service

My question: Is it really necessary to use two service units for this pattern, or am I missing some obvious common pattern that everyone else knows about?

Warning: That was untested code above, and my unit file syntax might be slightly wrong, since I generally use nix expressions to create unit files.

--
Anthony Carrico

Reply via email to