[systemd-devel] Solution for evaluating variables in environment files
Frank Steiner
fsteiner-mail1 at bio.ifi.lmu.de
Wed Oct 7 07:43:51 PDT 2015
Hi,
when switching from system-V to systemd one might run into the problem
that files specified with "EnvironmentFile=..." are not evaluated
(as they were before when e.g. /etc/init.d/apache2 executed
" . /etc/sysconfig.apache") but parsed by systemd itself.
Therefore stuff like
[ -L "/usr/lib64/biojava" ] && export BIOJAVA=/usr/lib64/biojava || export BIOJAVA=/usr/lib/biojava
or
bla="$blu"
or
bla="1"
bla+=" 2"
or
bla="
1
2
"
doesn't work in EnvironmentFiles (which is a real disadvantage of systemd,
by the way!). We have many files in /etc/sysconfig that do more than setting
variables the simple way, e.g. we calculate the include-dirs for apache from
the file system dynamically etc. Some solutions are posted over the net, we
turned them into a little automated version of the
'ExecStart=/bin/bash -c ". /etc/sysconfig/apache2; apache2 blabla'
solution that I'd like to share with those having similar problems. It avoids
creating specific drop-ins or changing the global service files when there
are a lot of services that you need to tweak.
We install two files, eg. /etc/sysconfig/container.start:
#!/bin/bash
service=${1%.service}
[ -n "$service" ] || { echo "no parameter given to $0"; exit 1; }
[ -r /usr/lib/systemd/system/${service}.service ] || { echo "/usr/lib/systemd/system/${service}.service not found by $0"; exit 1; }
# variables set here must be exported (set -a) as the ExecStart command could be
# another shell script that otherwise would not see these values
set -a
for name in `grep "^EnvironmentFile=" /usr/lib/systemd/system/${service}.service |sed 's/EnvironmentFile=//'`
do
. $name
done
set +a
# works only with a single ExecStart line
eval `grep "^ExecStart=" /usr/lib/systemd/system/${service}.service |sed 's/ExecStart=//'`
and /etc/sysconfig/container.conf:
[Service]
# notify like in apache2.service will not work this way
Type=simple
# avoid double execution of shell code in environment files
EnvironmentFile=
ExecStart=
ExecStart=/etc/sysconfig/configuration.start %n
Thus, all you need to do now is creating a link
/etc/systemd/system/apache2.service.d/container.conf -> /etc/sysconfig/container.conf
and then "systemctl start apache2" will evaluate all environment files before
starting apache.
This solution only works for service files with one ExecStart line where no
variables from the environment files are used in e.g. ExecStop (if that's
the case remove the "EnvironmentFile=" from container.conf).
Different versions of container.conf could be created for forking scripts
etc., but this simple version was enough for us to run e.g. apache2 and tomcat.
Maybe this helps someone else :-)
cu,
Frank
--
Dipl.-Inform. Frank Steiner Web: http://www.bio.ifi.lmu.de/~steiner/
Lehrstuhl f. Bioinformatik Mail: http://www.bio.ifi.lmu.de/~steiner/m/
LMU, Amalienstr. 17 Phone: +49 89 2180-4049
80333 Muenchen, Germany Fax: +49 89 2180-99-4049
* Rekursion kann man erst verstehen, wenn man Rekursion verstanden hat. *
More information about the systemd-devel
mailing list