我们有一个单元文件,其:
用途ExecStartPre
生成一个配置文件
ExecStart
使用配置文件来启动一个服务
ExecStartPost
,删除由创建的文件ExecStartPre
。(该文件有硬编码的密码,我们不想将其保存在磁盘上。所以它必须只在服务启动或重新启动时存在。
如果服务启动成功,则应删除配置文件,如果服务启动失败,则也应删除该文件。
这是 systemd 文件:
[Unit]
Description=Prometheus Server
Documentation=https://prometheus.io/docs/introduction/overview/
After=network-online.target
[Service]
User=prommgr
Group=secapm
Restart=on-failure
ExecStartPre=/usr/bin/python2 /prom/config/anon_yml.py
ExecStart=/bin/sh -c "/prom/appl/prometheus/prometheus --config.file=/prom/config/prometheus.yml --storage.tsdb.path=/prom/data --web.listen-address=127.0.0.1:9090 --storage.tsdb.retention.time=1825d &>>/prom/logs/prometheus.log"
ExecStartPost=/usr/bin/python2 anon_yml.py --delete
[Install]
WantedBy=multi-user.target
有问题的配置文件是 prometheus.yml,脚本anon_yml.py
将从 jinja 模板创建文件,并使用所需的密码填充它。
ExecStart
然后将启动服务
理论上,ExecStartPost
ExecStart 完成后将从磁盘中删除 prometheus.yml 文件,但是当重新启动服务时,我遇到配置文件丢失的错误。这仅意味着 ExecStartPost 没有等到 ExecStart 完成。
如何确保仅在进程重新启动后才删除配置文件?
答案1
执行速度过快的原因ExecStartPost=
是您的服务是Type=simple
(默认ExecStart=
的 指定但Type=
被省略)。在这种情况下,ExecStartPost=
会在 进程ExecStart=
启动后立即执行。
如果您只想ExecStartPost=
在最后一个ExecStart=
进程成功退出后执行,那么您需要将服务更改为Type=oneshot
:
[Service]
Type=oneshot
...
答案2
用作标志来检查您的 Post 操作是否可以执行。
- 附加到 ExecStart cmd:
&& touch /tmp/flag
- 将 ExecStartPost 替换为:
timeout 10 bash -c -- 'while test ! -f /tmp/flag; do /usr/bin/python2 anon_yml.py --delete && rm -f /tmp/flag ; sleep 1; done'
它看起来有点脏但应该能用......