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