I want to delay the start of a service if a file exists (instead of fail the service if the file exist, as with ConditionPathExists=) but did not find anything in unit documentation
Is it technically possible with systemd ? How ?
I want to delay the start of a service if a file exists (instead of fail the service if the file exist, as with ConditionPathExists=) but did not find anything in unit documentation
Is it technically possible with systemd ? How ?
As far as I can tell ConditionPathExists= does not put the unit into a "failed" state. ConditionPathExists= only skips the unit.
Unit files may also include a number of Condition…= and Assert…= settings. Before the unit is started, systemd will verify that the specified conditions are true. If not, the starting of the unit will be (mostly silently) skipped. Failing conditions will not result in the unit being moved into the "failed" state.
One way I found to delay the start of a unit, based on the existence of a file, is to test for the file with ExecStartPre=, then Restart=on-failure and RestartSec=. This does put the unit into a failure state, but it will keep retrying until success. For example:
[Service]
# Should cause failure if file exists
ExecStartPre=/usr/bin/test ! -f afile
ExecStart=mycommand
# Restart on failure. Keep trying to create backup.
RestartSec=10m
Restart=on-failure
Put TimeoutStartSec=infinity in the unit file and configure ExecStart= with a script like
#! /bin/bash
TIMEOUT=1000
test -f /path/to/testfile && sleep "$TIMEOUT"
exec /path/to/service/binary plus arguments
This cannot be done (in a useful way) with ExecStartPre=, see man systemd.service:
Note that ExecStartPre= may not be used to start long-running processes. All processes forked off by processes invoked via ExecStartPre= will be killed before the next service process is run.
If you want to do this with systemd "alone" then you can create a helper unit check_and_wait.service. This one gets the entries:
# check_and_wait.service
[Service]
TimeoutStartSec=infinity
ConditionPathExists=/path/to/testfile
ExecStart=/usr/bin/sleep 1000
RemainAfterExit=yes
The main unit gets these entries:
[Unit]
Wants=check_and_wait.target
After=check_and_wait.target
ExecStartPre, just move binary into ExecStart. What goes wrong?
[Service]
ExecStartPre=bash -c "while [ -f /path/to/file ]; do sleep 1; done"
ExecStart=your_command