I have Python script with works as a systemd daemon in CentOS 7. The daemon gets executed by the version of python I created in a virtualenv. I am trying to tweak the script to be able to set the virtualenv path in an environment variable so I can easily switch to a different virtualenv by changing paths via the one variable and restarting the service. I have created my systemd scripts to be able to initialize multiple instances of the daemon and this works great. When I try to use an environment variable to point to my python parser things break. Here is what I have so far.
/etc/systemd/system/[email protected]:
[Unit]
Description=pipeline remove tickets worker instances as a service, instance %i
Requires=pipeline-remove.service
Before=pipeline-remove.service
BindsTo=pipeline-remove.service
[Service]
PermissionsStartOnly=true
Type=idle
User=root
ExecStart=/path/to/venv/bin/python /pipeline/python/daemons/remove_tickets.py
Restart=always
TimeoutStartSec=10
RestartSec=10
[Install]
WantedBy=pipeline-remove.service
/etc/systemd/system/pipeline-remove.service (to start all instances):
[Unit]
Description=manages pipeline remove tickets worker instances as a service, instance
[Service]
Type=oneshot
ExecStart=/usr/bin/sh /usr/bin/pipeline-remove-start.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
pipeline-remove-start.sh:
#!/bin/bash
systemctl start pipeline-remove@{1..2}
This works great for me, but things break when I try to set the python dir the following way:
/etc/profile.d/pipeline_envvars.sh:
PIPELINE_VIRTUALENV=/path/to/venv
/etc/systemd/system/[email protected]:
[Unit]
Description=pipeline remove tickets worker instances as a service, instance %i
Requires=pipeline-remove.service
Before=pipeline-remove.service
BindsTo=pipeline-remove.service
[Service]
PermissionsStartOnly=true
Type=idle
User=root
EnvironmentFile=/etc/profile.d/pipeline_envvars.sh
ExecStart=/${PIPELINE_VIRTUALENV}/bin/python /pipeline/python/daemons/remove_tickets.py
Restart=always
TimeoutStartSec=10
RestartSec=10
[Install]
WantedBy=pipeline-remove.service
I then try to start it:
sudo systemctl daemon-reload
sudo systemctl restart pipeline-remove@{1..1}
sudo systemctl status pipeline-remove@{1..1}
The status shows the following exit code 203 which means executable not found:
● [email protected] - pipeline remove tickets worker instances as a service, instance 1
Loaded: loaded (/etc/systemd/system/[email protected]; disabled; vendor preset: disabled)
Active: activating (auto-restart) (Result: exit-code) since Fri 2018-01-26 15:04:50 UTC; 6s ago
Process: 11716 ExecStart=/${PIPELINE_VIRTUALENV}/bin/python /pipeline/python/daemons/remove_tickets.py (code=exited, status=203/EXEC)
Main PID: 11716 (code=exited, status=203/EXEC)
Jan 26 15:04:50 dev systemd[1]: [email protected]: main process exited, code=exited, status=203/EXEC
Jan 26 15:04:50 dev systemd[1]: Unit [email protected] entered failed state.
Jan 26 15:04:50 dev systemd[1]: [email protected] failed.
Found the exec code here. Also found this in syslog, /var/log/messages:
Jan 26 15:07:13 dev systemd: Starting pipeline remove tickets worker instances as a service, instance 1...
Jan 26 15:07:13 dev systemd: Failed at step EXEC spawning /${PIPELINE_VIRTUALENV}/bin/python: No such file or directory
Jan 26 15:07:13 dev systemd: [email protected]: main process exited, code=exited, status=203/EXEC
Jan 26 15:07:13 dev systemd: Unit [email protected] entered failed state.
Jan 26 15:07:13 dev systemd: [email protected] failed.
Jan 26 15:07:23 dev systemd: [email protected] holdoff time over, scheduling restart.
Jan 26 15:07:23 dev systemd: Started pipeline remove tickets worker instances as a service, instance 1.
When I try to drop the leading / in ExecStart I get a relative path error even though my env var does contain an absolute path:
Failed to start [email protected]: Unit is not loaded properly:
Invalid argument.
See system logs and 'systemctl status [email protected]' for
details.
And status shows the following:
vagrant@dev:~$ sudo systemctl status pipeline-remove@{1..1}
● [email protected] - pipeline remove tickets worker instances as a service, instance 1
Loaded: error (Reason: Invalid argument)
Active: inactive (dead)
Jan 26 15:11:39 dev systemd[1]: [email protected] failed.
Jan 26 15:11:42 dev systemd[1]: Stopped pipeline remove tickets worker instances as a service, instance 1.
Jan 26 15:11:42 dev systemd[1]: [/etc/systemd/system/[email protected]:12] Executable path is not absolute, ignoring: ${PIPELINE_VIRTUALENV}/bin/python /pipel...e_tickets.py
Jan 26 15:11:42 dev systemd[1]: [email protected] lacks both ExecStart= and ExecStop= setting. Refusing.
I used this guide to help me get started but now I'm stuck. How can I get my python daemon to come up while setting the python executable path from an environment variable?