Services declared as oneshot
are expected to take some action and exit immediatelly (thus, they are not really services,
no running processes remain). A common pattern for these type of service is to be defined by a setup and a teardown action.
Let's create a example foo
service that when started creates a file, and when stopped it deletes it.
Create executable file /opt/foo/setup-foo.sh
:
#!/bin/bash
echo "Setting up foo ..."
touch /tmp/foo-activated
Create executable file /opt/foo/teardown-foo.sh
:
#!/bin/bash
echo "Tearing down foo ..."
if [ -f /tmp/foo-activated ]; then
rm /tmp/foo-activated
else
echo "Doesnt seem to be up: Skipping ..."
fi
Now, we define the systemd unit file as /etc/systemd/system/foo.service
. Note that we must specify RemainAfterExit=true
so that systemd considers the service as active after the setup action is successfully finished.
[Unit]
Description=Setup foo
#After=network.target
[Service]
Type=oneshot
ExecStart=/opt/foo/setup-foo.sh
RemainAfterExit=true
ExecStop=/opt/foo/teardown-foo.sh
StandardOutput=journal
[Install]
WantedBy=multi-user.target
Reload the systemd daemon and start the service as normally (systemctl start foo.service
). Check the status to verify that the correct actions are taking place.
How do you incorporate this script in a target (assuming I wanted to start multiple scripts as a group)?
I created /etc/systemd/system/foo.target with the following contents:
[Unit]
Description=Foo Application Target
Requires=multi-user.target
Wants=foo.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target
AllowIsolate=yes
I also created the foo.target's directory, /etc/systemd/system/foo.target.wants, and a symbolic link to foo.service in that directory.
With this configuration, I'm able to successfully start the target using systemctl start foo.target but I'm unable to stop it properly (using systemctl stop foo.target). When I stop foo.target systemctl looks like it completes but the /tmp/foo-activated file still exists meaning teardown-foo.sh didn't run.
Thanks in advance!
Rob