Systemd service file doesn't read the environmentFile
I am trying to start etcd
service and I have a environment variable file that I am referring by the systemd
file.
First time it works fine and in the next time when I try to stop the service and do the same steps, it doesn't read the environmentFile
and update the values.
Here's my /etc/etcd.conf
where I put environment variables
INTERNAL_IP=$(ip -o route get to 8.8.8.8 | sed -n 's/.*src \([0-9.]\+\).*/\1/p')
cat << EOF > /etc/etcd.conf
#SELF_IP is the IP of the node where this file resides.
SELF_IP=$INTERNAL_IP
# IP of Node 1
NODE_1_IP=10.128.15.225
#IP of Node 2
NODE_2_IP=10.128.15.226
NODE_3_IP=10.128.15.227
EOF
This is my /etc/systemd/system/etcd3.service
file
cat << EOF > /etc/systemd/system/etcd3.service
[Unit]
Description=etcd
Documentation=https://github.com/coreos/etcd
Conflicts=etcd.service
Conflicts=etcd2.service
[Service]
Type=notify
Restart=always
RestartSec=25s
LimitNOFILE=40000
TimeoutStartSec=1s
EnvironmentFile=/etc/etcd.conf
ExecStart=/bin/bash -c "/usr/local/bin/etcd --name etcd-${SELF_IP} --data-dir /var/lib/etcd --quota-backend-bytes 8589934592 --auto-compaction-retention 3 --listen-client-urls http://${SELF_IP}:2379,http://localhost:2379 --advertise-client-urls http://${SELF_IP}:2379,http://localhost:2379 --listen-peer-urls http://${SELF_IP}:2380 --initial-advertise-peer-urls http://${SELF_IP}:2380 --initial-cluster 'etcd-${NODE_1_IP}=http://${NODE_1_IP}:2380,etcd-${NODE_2_IP}=http://${NODE_2_IP}:2380,etcd-${NODE_3_IP}=http://${NODE_3_IP}:2380' --initial-cluster-token my-etcd-token --initial-cluster-state new"
[Install]
WantedBy=multi-user.target
EOF
Why this is working for the first time and not afterwards?
How can i stop the service successfully and try to create the /etc/etcd.conf
with some additional values and start the same service
because it gives the below error:
-- Subject: Unit etcd3.service has begun start-up
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit etcd3.service has begun starting up.
Nov 19 15:08:59 etcd-1 etcd[2341]: error verifying flags, expected IP in URL for binding (http://:2380). See 'etcd --help'.
Nov 19 15:08:59 etcd-1 systemd[1]: etcd3.service: main process exited, code=exited, status=1/FAILURE
Nov 19 15:08:59 etcd-1 systemd[1]: Failed to start etcd.
-- Subject: Unit etcd3.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit etcd3.service has failed.
--
-- The result is failed.
and when I try to cat /etc/systemd/system/etcd3.service
after the first time (i.e second time after executing the same commands), the values I have passed are not really shown their, instead it shows empty values, such as --name etcd-
There are 2 problems with the shell variables like ${SELF_IP}
in the ExecStart=
line.
One is that
cat << EOF > /etc/systemd/system/etcd3.service
does variable interpolation, so the etcd3.service
file will replace ${SELF_IP}
by whatever its current value is, perhaps empty. The fix for this is to quote the EOF
as in cat <<'EOF'
for example.
The next problem will then be that systemd also interpolates variables of the form ${...}
in the ExecStart=
line, even when inside single or double quotes. So they will again be replaced by the current value for systemd (which uses the EnvironmentFile
when running the command, not when parsing the line), so probably empty.
The fix for this is to double the $
signs on this line, eg $${SELF_IP}
. If you use /bin/bash -cv
as the command you should be able to see what command is passed to bash, and whether the variables have survived that far.