Systemd:如果“ oneshot”服务第一次失败,如何确保重试该服务?


18

我已经阅读了几次systemd服务联机帮助页,但是仍然无法弄清基本的systemd模式:

我想在启动时运行一次启动过程(例如docker容器或格式化驱动器),成功完成。但是,如果为此使用Type = oneshot,则无法使用Restart = on-failure,并且如果失败,则不会重试该工作。我在这里错过明显的东西吗?

我还尝试将Type = simple设置为Restart = on-failure,但是在很多情况下,我需要oneshot服务提供以下行为(从联机帮助页中):

oneshot的行为类似于简单。但是,可以预期该过程必须在systemd启动后续单元之前退出。

更新:


我使用的一种解决方法是省略Restart和包装my_cmdExecStart=/bin/sh -c 'while ! my_cmd; do sleep 1; done',以及一些合理的TimeoutStartSec值。
rozcietrzewiacz

你看过FailureAction =吗?Restart=通过设置FailureAction=[self.unit](将[self.unit]替换为设备名称),可能会实现相同的目的。这有点骇人听闻,但至少很明确而且很容易遵循。
Centimane

@Centimane FailureAction使用与相同的值StartLimitAction,除了none触发某种关闭外,所有其他值都一样。
jpkotta

Answers:


5

我正在尝试的一种可能的解决方法是

  [Unit]
    Description=Tags instance and EBS vols
    After=docker.service
    Requires=docker.service

    [Service]
    ExecStartPre=/usr/bin/docker run --rm -v /opt/tag.sh:/tag.sh -v /opt:/ack --entrypoint=/bin/sh alpine /tag.sh
    ExecStartPre=/usr/bin/sh -c '[[ -e /opt/TAG_SUCCESS ]]'
    ExecStart=/usr/bin/rm /opt/TAG_SUCCESS
    Restart=on-failure
    RestartSec=30

脚本tag.shtouch /ack/TAG_SUCCESS在执行结束时所在的位置。我相信这将非常接近所需的行为,因为ExecStartPre它将顺序执行,在调用之前等待成功完成,ExecStart并且仅考虑Starting一次调用该单元ExecStart,此时我们确定已完成启动任务。

但这仍然感觉像是一个巨大的黑客吗?


这对我来说效果很好,除了我还必须使RemainAfterExit=yes该单元保持“活动”状态,以便其他单元可以依赖它。
古斯
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.