我正在创建一个foo启动/关闭上游包的包bar。关系应该是:
bar 可以在不影响的情况下启动、停止或重新加载 foo如果/lib/systemd/system/bar.service看起来像这样:
[Unit]
Description=Bar
[Service]
ExecStart=/bin/sleep infinity
Restart=on-failure
Run Code Online (Sandbox Code Playgroud)
那么“正常”解决方案是添加WantedBy和PartOf关系到bar:
[Unit]
Description=Bar
PartOf=foo.service
[Service]
ExecStart=/bin/sleep infinity
Restart=on-failure
[Install]
WantedBy=foo.service
Run Code Online (Sandbox Code Playgroud)
但是,bar是一个上游包,我认为强制bar了解foo或修补是不太正确的bar。
我认为一个完美的解决方案是这样创建foo.service:
[Unit]
Description=Foo
Wants=bar.service
ConsistsOf=bar.service
[Service]
Type=oneshot
ExecStart=/bin/true
RemainAfterExit=yes
Run Code Online (Sandbox Code Playgroud)
但是我的 journalctl 说:
“单位”部分中的未知左值“ConsistsOf”
和手册页说:
当 PartOf=b.service 用于 a.service 时,此依赖项将在 b.service 的属性列表中显示为 ConsistsOf=a.service。ConsistsOf= 依赖项不能直接指定。
我不确定为什么 ConsistsOf=不能直接指定,但是有没有我没有考虑的替代方案?
修改上游/外部 bar.service 以包含PartOf=与另一个单元的关系的适当方法是使用“插入式”覆盖配置,这是一个 systemd 功能,允许您修改现有单元而无需接触原始文件。
从systemd.unit手册页:
与单元文件一起
foo.service,foo.service.d/可能存在“插入”目录。.conf解析单元文件本身后,将解析该目录中所有带有后缀“ ”的文件。这对于更改或添加单元的配置设置很有用,而无需修改单元文件。
在您的特定情况下,您应该创建一个/etc/systemd/system/bar.service.d/partof-foo.conf包含内容的插件,例如:
[Unit]
PartOf=foo.service
Run Code Online (Sandbox Code Playgroud)
(名称partof-foo.conf只是一个建议,任何带有.conf后缀的都应该有效。)
然后使用systemctl daemon-reload.
完成后,您可以使用 来检查单元systemctl cat bar,这将清楚地显示正在考虑覆盖。此外,现在,systemctl show foo将显示与 的ConsistsOf=关系,bar.service并且该关系的影响将随之而来(停止foo将导致bar停止。)
对于第二部分(foo具有Wants=bar.service),我建议将该指令直接添加到 ,foo.service而不是[Install]在bar.service.
首先,该[Install]部分必须使用systemctl enable bar命令激活,因此在某种程度上更难维护。(另外,我已经看到[Install]了不尊重“插入”的错误。我相信这些已经修复,但可能仍然存在于您的发行版 systemd 中。)
此外,您可能希望使用更强的Requires=关系,而不是Wants=,因为foo.service如果bar.service无法启动,这将导致失败。(还考虑添加一个排序依赖项,例如After=bar.servicefrom foo.service,因此foo实际上会等到barup 后再进行自己的启动。)
由于foo.service是您控制的文件,只需将其直接包含在那里:
[Unit]
Description=Foo
Requires=bar.service
After=bar.service
Run Code Online (Sandbox Code Playgroud)
假设您也需要排序依赖项,如果不这样做,可以安全地省略它。
这应该照顾一切。