Search code examples
linuxbashsystemd

systemd script - environment file updated by ExecStartPre


I am trying out systemd script along in Docker environment.

Consider this:

command mentioned in ExecStartPre updating environment file and ExecStart actually making use of environment variable mentioned in env. file.? (all in the same systemd file).

like this:

[Unit]
Description=test service
Before=memcached.service

[Service]
Type=oneshot
EnvironmentFile=-/etc/sysconfig/testfile
ExecStartPre=/usr/local/bin/update_sysconfig_testfile.sh
ExecStart=/usr/bin/testmebinary $VOLUMES

[Install]
WantedBy=multi-user.target

Here, $VOLUMES is defined inside testfile and it is updated by update_sysconfig_testfile.sh script.

Will systemd aware about the change made by ExecStartPre (or) it just loads whatever value in testfile?

If there is any better approach, please share.


Solution

  • Since at least systemd 237, you can write an file in ExecStartPre= that's read by EnvironmentFile= before ExecStart= runs as long as you prefix the file path with a dash (EnvironmentFile=-/some/path/.env).

    This appears to due to the timing of when the environment is evaluated. poettering says:

    the env vars are determined only at execution time

    So it's an error if EnvironmentFile= is not defined when ExecStartPre= is executed which is why it needs to be optional, but when the "execution time" of ExecStart= comes, the EnvironmentFile is apparently re-checked and the environment variables set.

    This could be better documented in man systemd.exec.

    You can also use an alternative approach which is suggested in man systemd.exec where Environmentfile= is documented:

    Use one systemd service to write the environment file and a second one to consume it. Using either a Before= or After= relationship in the [Unit] section, you can ensure that the service that writes the environment file is started first in the boot sequence.