4

I have an application that should be started during boot and terminated gracefully during shutdown. The problem is that I cannot ensure that the application is started/stopped using systemd, it's quite a complex app that might sometimes need to be started "partially" using manual commands so there is therefore no real good way for systemd to keep track of the actual state of the application.

So, I've arrived at the conclusion that I need a "stupid" systemd unit that will simply always run a certain script at startup and another one at shutdown, no matter the state of the service. And this is what I'm having difficulties to accomplish. Here's what I use for testing:

[Unit]
Description=My Test application
Wants=network-online.target 
After=network-online.target

[Service]
Type=oneshot
ExecStart=/home/user/tmp/systemd-test/script.sh start
ExecStop=/home/user/tmp/systemd-test/script.sh stop
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

The problem with above is that I cannot make it run "stop" if start hasn't been previously run and the other way around:

$ systemctl start test  # Start script is run
$ systemctl start test  # Nothing happens
$ systemctl stop test   # Stop script is run
$ systemctl stop test   # Nothing happens
$ systemctl stop test   # Nothing happens

So imagine the start script failing for whatever reason during boot, the app admin going in and starting things manually. Then the stop script will not be run during shutdown because it was never started properly as far as systemd is concerned.

My question is therefore, is there a way to make a "stupid" systemd service that doesn't care about state, or will I have to separate it into two different units?

Edit: To explain a bit more why I cannot really use systemd state as intended: Starting the application first involves starting a "server" process, and once that is up and running to start a "launcher" process that in turn spins up ~20 different processes for different types of processing. And everything is started asynchronously (i.e. non-blocking) with no way to know when things are actually up except for grepping the logs or invoking a custom binary for listing processes. So there is really no way for systemd to find out if one of these 20 processess failed to start.

1
  • More likely you need to start the app with multiple "smart" systemd units. Commented Dec 13, 2020 at 1:34

1 Answer 1

5

My question is therefore, is there a way to make a "stupid" systemd service that doesn't care about state

You could try this (mind the dash before the executable):

ExecStart=-/home/user/tmp/systemd-test/script.sh start

or

the app admin going in and starting things manually

You could make them start the script exclusively via systemd, by e.g. checking for an environment variable:

test -z "$INVOCATION_ID" && echo "This script must be run via systemd" && exit
5
  • A bit like Debian sysvinit scripts automatically detect if they're started outside systemd (and systemd is running), print "Starting $prog (via systemctl)", and do it for you.
    – sourcejedi
    Commented Dec 12, 2020 at 16:45
  • @sourcejedi I have a similar problem and would be interested in more details around the Debian sysvinit scripts.
    – Jeff Schaller
    Commented Dec 12, 2020 at 19:59
  • @JeffSchaller they check if [ $PPID -ne 1 ]. (init scripts would only be run from systemd system instances, not systemd user instances).
    – sourcejedi
    Commented Dec 12, 2020 at 20:15
  • Thanks, @sourcejedi! Glad to hear that others have come up with a similar solution!
    – Jeff Schaller
    Commented Dec 12, 2020 at 20:18
  • 1
    That's pretty clever @Artem. That way as long as no one goes in and runs start/stop commands manually it should work OK. The second alternative would absolutely make sense if that script was the only way to start the application, but unfortunately that really isn't the case. It sometimes needs some manual care, starting individual pieces indenendently of each other, so there's really no way of using systemd the way it's intended here.
    – yzfr1
    Commented Dec 13, 2020 at 11:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .