Writing nested Systemd Scripts

The trick here is to use a dummy program to start the wrapper and hold them active after the program was terminated.

dummy-master.service

[Unit]
Description=Dummy Master Service

[Service]
# The dummy program will exit
Type=oneshot
# Execute a dummy program
ExecStart=/bin/true
# This service shall be considered active after start
RemainAfterExit=yes

[Install]
# Components of this application should be started at boot time
WantedBy=multi-user.target

dummy-db.service

[Unit]
Description=Dummy Database
# When systemd stops or restarts the dummy-master.service, the action is propagated to this unit
PartOf=dummy-master.service
# Start this unit after the dummy-master.service start
After=dummy-master.service

[Service]
User=dummyuser
Type=forking
# Pretend that the component is running
ExecStart=/usr/local/database.sh start
ExecStop=/usr/local/database.sh stop
# Restart the service on non-zero exit code when terminated by a signal other than SIGHUP, SIGINT, SIGTERM or SIGPIPE
Restart=on-failure

[Install]
# This unit should start when app.service is starting
WantedBy=dummy-master.service

dummy-listener.service

[Unit]
Description=Dummy Listener
# When systemd stops or restarts the dummy-master.service, the action is propagated to this unit
PartOf=dummy-master.service
# Start this unit after the dummy-master.service start
After=dummy-master.service
After=dummy-db.service

[Service]
User=dummyuser
Type=forking
# Pretend that the component is running
ExecStart=/usr/local/listener.sh start
ExecStop=/usr/local/listener.sh stop
# Restart the service on non-zero exit code when terminated by a signal other than SIGHUP, SIGINT, SIGTERM or SIGPIPE
Restart=on-failure

[Install]
# This unit should start when dummy-master.service is starting
WantedBy=dummy-master.service

dummy-cron.service

[Unit]
Description=Dummy Cron
# When systemd stops or restarts the dummy-master.service, the action is propagated to this unit
PartOf=dummy-master.service
# Start this unit after the dummy-master.service start
After=dummy-master.service
After=dummy-listener.service

[Service]
User=dummyuser
Type=forking
# Pretend that the component is running
ExecStart=/usr/local/cron.sh start
ExecStop=/usr/local/cron.sh stop
# Restart the service on non-zero exit code when terminated by a signal other than SIGHUP, SIGINT, SIGTERM or SIGPIPE
Restart=on-failure
RemainAfterExit=yes

[Install]
# This unit should start when dummy-master.service is starting
WantedBy=dummy-master.service

After defining the related services, you have to enable all of them.

systemctl enable dummy-master dummy-db dummy-listener dummy-cron

Now you can control the whole workflow with one systemd script:

systemctl start|stop|status dummy-master

Leave a Reply

Your email address will not be published. Required fields are marked *