In systemd (v237 on UbuntuLinux 18.04 bionic), I can create a service file (for A.service
), and specify another service Requisite=B.service
. Meaning if I try to start A.service
and B.service
isn't already running, then A.service will not be started. It's a weak version of Requires
, which will start B.service
when I try to start A.service
.
Is there an opposite? Can I say “If B.service is running, then don't start this service” / “If B.service is running, then A.service cannot start”?
The docs say if I do Conflicts=B.service
, then starting A
will stop B and then start A. But I don't want B stopped, I just want A to fail to start. I want something that's to Conflicts
what Requisite
is to Requires
.
I could probably change the ExecStart
to be a shell command that'll fail is systemctl is-active B.service
or some sort of hack. Is there a proper solution?
Generally the way to do this is with an
ExecStartPre
that checks whether the other services is running. If anExecStartPre
command returns an error code then the rest of the startup process is aborted.Something I found later, the best option for this situation is
ExecCondition=
because it will allow you do do a proper error control;ExecStartPre=
will always generate an error if exits with non-zero; whileExecCondition=
will permits to halt the execution without throwing an error, or trowing an error if required. This will be very handy for notifications onExecStartPost=
processing (you can set a trigger to notify that the service did not start because the other was running).The code logic is the same:
The advantage of
ExecCondition=
overExecStartPre=
, is that in this example, it will check if this service instance is the "main" and will exit with a failed status code, so you can easily notice it; also you can use as a trigger forExecStartPost=
andExecStopPost=
.One recommendation is to use many entries of
ExecCondition=
instead running too many commands in a single entry despite permitted; it will enhance troubleshooting and prevent failed state due timeout.