systemd execstart python守护进程使用virtualenv from环境变量动态启动
我在CentOS 7中使用Python脚本作为systemd守护进程。守护进程由我在virtualenv中创建的python版本执行。我正在尝试调整脚本,以便能够在环境变量中设置virtualenv路径,以便通过一个变量更改路径并重新启动服务,轻松切换到不同的virtualenv。我已经创建了我的systemd脚本,以便能够初始化守护进程的多个实例,这非常有效。当我试图使用一个环境变量来指向我的python解析器时,情况就不一样了。这是我到目前为止所拥有的 /etc/系统D/系统/管道-remove@.service:systemd execstart python守护进程使用virtualenv from环境变量动态启动,python,virtualenv,systemd,Python,Virtualenv,Systemd,我在CentOS 7中使用Python脚本作为systemd守护进程。守护进程由我在virtualenv中创建的python版本执行。我正在尝试调整脚本,以便能够在环境变量中设置virtualenv路径,以便通过一个变量更改路径并重新启动服务,轻松切换到不同的virtualenv。我已经创建了我的systemd脚本,以便能够初始化守护进程的多个实例,这非常有效。当我试图使用一个环境变量来指向我的python解析器时,情况就不一样了。这是我到目前为止所拥有的 /etc/系统D/系统/管道-remo
[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
[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
/etc/systemd/system/pipeline-remove.service(启动所有实例):
pipeline-remove-start.sh:
#!/bin/bash
systemctl start pipeline-remove@{1..2}
这对我来说非常有用,但当我尝试按以下方式设置python目录时,情况就不一样了:
/etc/profile.d/pipeline_envvars.sh:
PIPELINE_VIRTUALENV=/path/to/venv
/etc/系统D/系统/管道-remove@.service:
[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
[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
然后我尝试启动它:
sudo systemctl daemon-reload
sudo systemctl restart pipeline-remove@{1..1}
sudo systemctl status pipeline-remove@{1..1}
状态显示以下退出代码203,表示未找到可执行文件:
● pipeline-remove@1.service - pipeline remove tickets worker instances as a service, instance 1
Loaded: loaded (/etc/systemd/system/pipeline-remove@.service; 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]: pipeline-remove@1.service: main process exited, code=exited, status=203/EXEC
Jan 26 15:04:50 dev systemd[1]: Unit pipeline-remove@1.service entered failed state.
Jan 26 15:04:50 dev systemd[1]: pipeline-remove@1.service failed.
找到了exec代码。在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: pipeline-remove@1.service: main process exited, code=exited, status=203/EXEC
Jan 26 15:07:13 dev systemd: Unit pipeline-remove@1.service entered failed state.
Jan 26 15:07:13 dev systemd: pipeline-remove@1.service failed.
Jan 26 15:07:23 dev systemd: pipeline-remove@1.service holdoff time over, scheduling restart.
Jan 26 15:07:23 dev systemd: Started pipeline remove tickets worker instances as a service, instance 1.
当我尝试在ExecStart
中删除前导的/
时,即使我的环境变量包含绝对路径,我也会得到一个相对路径错误:
Failed to start pipeline-remove@1.service: Unit is not loaded properly:
Invalid argument.
See system logs and 'systemctl status pipeline-remove@1.service' for
details.
状态显示如下:
vagrant@dev:~$ sudo systemctl status pipeline-remove@{1..1}
● pipeline-remove@1.service - 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]: pipeline-remove@1.service 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/pipeline-remove@.service:12] Executable path is not absolute, ignoring: ${PIPELINE_VIRTUALENV}/bin/python /pipel...e_tickets.py
Jan 26 15:11:42 dev systemd[1]: pipeline-remove@1.service lacks both ExecStart= and ExecStop= setting. Refusing.
我用指南来帮助我开始,但现在我被卡住了。如何在从环境变量设置python可执行路径时启动python守护进程?在进一步阅读之后,我偶然发现了答案。问题是
ExecStart
的第一个参数必须是文本:
ExecStart=执行此操作时执行的命令及其参数
服务已启动。对于每个指定的命令,第一个
参数必须是可执行文件的绝对文本路径
进一步阅读ExecStart,它说:
在展开时其值未知的变量被视为
空字符串请注意,第一个参数(即
执行)可能不是变量
我最后也遇到了同样的问题。最后,这是有效的:用shell包装整个东西以运行:
[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=/bin/sh -c '${PIPELINE_VIRTUALENV}/bin/python /pipeline/python/daemons/remove_tickets.py'
Restart=always
TimeoutStartSec=10
RestartSec=10
[Install]
WantedBy=pipeline-remove.service
因此
ExecStart=/bin/sh-c'
节省了时间,现在我可以为我的环境变量指定python解释器路径。我将保留答案,希望能为其他人节省一些时间。再读几遍后,我无意中找到了答案。问题是ExecStart
的第一个参数必须是文本:
ExecStart=执行此操作时执行的命令及其参数
服务已启动。对于每个指定的命令,第一个
参数必须是可执行文件的绝对文本路径
进一步阅读ExecStart,它说:
在展开时其值未知的变量被视为
空字符串请注意,第一个参数(即
执行)可能不是变量
我最后也遇到了同样的问题。最后,这是有效的:用shell包装整个东西以运行:
[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=/bin/sh -c '${PIPELINE_VIRTUALENV}/bin/python /pipeline/python/daemons/remove_tickets.py'
Restart=always
TimeoutStartSec=10
RestartSec=10
[Install]
WantedBy=pipeline-remove.service
因此ExecStart=/bin/sh-c'
节省了时间,现在我可以为我的环境变量指定python解释器路径。将保留答案,希望能为其他人节省一些时间