是否可以使用systemd根据文件的存在来启动和停止服务?


9

到目前为止,我的配置是:

foo.path

[Path] 
PathExists=/tmp/foo.path

[Install] 
WantedBy=multi.user.target

foo.service

[Unit]
Description=Matt Test
BindsTo=foo.path

[Service]
ExecStart=/bin/sh /home/mpekar/bin/foo.sh 
PIDFile=/run/foo.pid

这在启动时工作正常,但是在删除/tmp/foo.path时foo.service不会被杀死。有什么方法可以使systemd做到这一点,还是它不是适合该工作的工具?


Answers:


4

我会尝试的。使用PathChanged创建附加服务:

foo-stop.path

[Path] 
PathChanged=/tmp/foo.path

[Install] 
WantedBy=multi.user.target

然后创建:foo-stop.service

进行“ ExecStart”脚本检查以查看是否/tmp/foo.path已删除(因为PathChanged也可能触发其他更改)。如果路径已删除,请执行脚本调用/bin/systemctl stop foo


1
我要继续接受它,直到systemd提供一个明确的选项来执行相同的操作。
mpr

0

如果在删除/tmp/foo.path时可以杀死绑定到PIDFile(/run/foo.pid)的进程(例如,这两个动作都作为服务关闭脚本中的动作),则可以。

我是在运行<= RHEL-7.7的Tomcat上使用派生服务实现的,该服务包含一个ExecStartPost操作,该操作将应用程序pidfile(catalina.pid)的内容记录到服务PIDFile路径中。相应的.path文件中的“ PathExists”跟踪该catalina.pid上出现的内容,以便在用户(在我的情况下,为非特权)调用启动脚本时挂接systemd服务。当用户启动关闭操作时,将删除应用程序pidfile,PID(同样也是非特权的)正常死掉,而systemd将停止该服务,这是systemd pid监督的结果。

poc.service:

[nouser@nohost system]# cat poc.service
# . . .
[Unit]
After=network.target
After=%p.path
Wants=%p.path
# . . . 
[Service]
Type=forking
Environment="%p_APPLICATION_PID_FILE=/opt/%p/logs/catalina.pid"
PIDFile=/var/run/%p.pid
ExecStart=/bin/sh -c '/path/to/tomcat/control/script/invoked/with/su/hypen start'
ExecStartPost=/bin/sh -c 'cat ${%p_APPLICATION_PID_FILE} > $(systemctl show %n -p PIDFile|cut -f2- -d"=")'
ExecStop=/bin/sh -c '/path/to/tomcat/control/script/invoked/with/su/hypen stop'
# . . .

poc.path:

[nouser@nohost system]# cat poc.path
# . . .
[Path]
PathExists=/opt/%p/logs/catalina.pid
# . . .

这种方式也对Spring Boot应用程序有用。但是当他们出生于bash进程时,我不得不立即杀死该父进程,以强制PID 1成为应用程序的父进程。否则,journalctl会显示一条消息“ * .service:监督进程XXXXX,它不是我们的孩子。我们很可能不会注意到它退出的时间。”,最后,系统服务不会在用户关闭操作时停止。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.