管理 systemd 模板实例之间的排序依赖关系

管理 systemd 模板实例之间的排序依赖关系

抽象的例子:

我有两个重复任务AB我想将其设置为systemd服务。由于任务彼此非常相似,因此我使用模板[email protected]; A 和 B 将分别作为该模板的实例运行:[email protected][email protected]

# [email protected]
[Unit]
Description= myservice %I

[Service]
Type=oneshot
IOSchedulingClass=idle
ExecStart=bash -c "echo Starting %I; sleep 10; echo Finished %I"
Restart=on-failure

这两个任务的重复要求应通过两个计时器myservice-A.timer和来处理myservice-B.timer。计时器将确保根据配置的时间间隔重复这两个任务,例如A每周和B每天。即使在当时 PC 关闭的情况下,计时器也能保证这一点,在这种情况下,当超过预先配置的重新启动时间时,它们将尽快启动服务。

A然而,最后一种情况可能与之前必须完成的要求相冲突B(如果两者同时启动)。由于我使用的是模板实例,因此我无法在服务本身上使用Before=和选项。After=我可以将它们添加到计时器中,但这似乎并不能解决问题(可能是因为现在计时器只获得排序依赖项,而不是它们正在启动的服务)。

# myservice-A.timer
[Unit]
# The Before= requirement below does not help
Before=myservice-B.timer
Description=weekly execution of myservice

[Timer]
OnCalendar=Monday *-*-* 09:20:00
Persistent=true
[email protected]

[Install]
WantedBy=timers.target
# myservice-B.timer
[Unit]
# the After= requirement below does not help
After=myservice-A.timer
Description=daily execution of myservice

[Timer]
OnCalendar=09:30:00
Persistent=true
[email protected]

[Install]
WantedBy=timers.target

请注意,B不需要执行A,即我不寻找类型的依赖项Requires=。我只讨论这样的情况:当 和 都A通过B计时器启动时,thenA必须在B启动之前完成。

答案1

由于我使用的是模板实例,因此我无法使用服务本身的Before=和选项。After=

但是,您可以在模板的特定实例上设置这些。然而,为了使任何一种关系都能很好地发挥作用,注意:

最重要的是,对于服务单元来说,Before=After=所有配置的启动命令都已被调用并且它们失败或报告启动成功时,启动被视为已完成。

也就是说,[email protected]一旦ExecStart命令开始执行。它不会等待它完成。但是,如果您在ExecStartPre命令中执行这些单元的实际工作,并且可能只使用简单的/bin/truefor ExecStart,那么排序应该有效。也许像这样:

# [email protected]
[Unit]
Description= myservice %I
[email protected]  # Will be skipped for `myservice@A` itself

[Service]
Type=oneshot
IOSchedulingClass=idle
ExecStartPre=/bin/bash -c "echo Starting %I; sleep 10; echo Finished %I"
ExecStart=/bin/true
Restart=on-failure

如果您的命令需要很长时间才能执行,您可能需要配置 setTimeoutStartSec因此。

相关内容