Linux – systemd oneshot Requirement to execute only once

linuxstartupsystemd

I have multiple systemd services that require a generated EnvironmentFile. I have a shell script which generates this Environment file, but since I need that environment file before any Exec… commands execute, I cannot use ExecStartPre=generate_env_file.sh . Therefore, I have another service (generate_env_file.service) set to run that script as a oneshot:

[Service]
Type=oneshot
ExecStartPre=/usr/bin/touch /path/to/config.ini
ExecStart=/path/to/generate_env_file.sh

and I have multiple other service files which have:

[Unit]
Requires=generate_env_file.service
After=generate_env_file.service

How can I guarantee that two or more dependent services (which require generate_env_file.service) will not run in parallel and spawn two parallel executions of generate_env_file.service?

I've looked at using RemainAfterExit=true or possibly StartLimitIntervalSec= and StartLimitBurst= to ensure that only one copy will execute at a time during some period but I'm not sure the best way to go about doing this.

Best Answer

RemainAfterExit=true is the way to go. In this case Systemd starts the service and Systemd considers it as started and live. However this doesn't cover the use case of executing systemctl restart generate_env_file.service. In this case systemd will re-execute your service. To solve this, you could create a marker file in the run file system in ExecStartPost= and add ConditionFileExists= directive to check the existence of file.

Related Question