Systemd: Jak zapewnić, że usługa „oneshot” zostanie ponowiona, jeśli zawiedzie po raz pierwszy?

18

Przeczytałem kilka razy stronę systemową usługi, ale nadal nie mogę znaleźć podstawowego wzorca systemowego:

Chcę raz uruchomić proces uruchamiania (np. Kontener Dockera lub sformatować dysk) przy starcie systemu, aby zakończyć. Ale jeśli użyję do tego Type = oneshot, to nie będę mógł użyć Restart = w przypadku awarii, a jeśli się nie powiedzie, to nie spróbuje ponownie wykonać zadania. Czy brakuje mi czegoś oczywistego?

Próbowałem także ustawić Type = simple z Restart = w razie awarii, ale w wielu przypadkach potrzebuję następującego zachowania (z strony podręcznika), które dają usługi oneshot:

Zachowanie oneshota jest podobne do prostego; oczekuje się jednak, że proces musi zakończyć się, zanim systemd rozpocznie jednostki kontrolne.

Aktualizacje:

JKnight
źródło
Jednym z obejść, które zastosowałem, jest pominięcie Restarti zawinięcie w my_cmd ten sposób: ExecStart=/bin/sh -c 'while ! my_cmd; do sleep 1; done'wraz z pewną rozsądną TimeoutStartSecwartością.
rozcietrzewiacz
Czy spojrzałeś na FailureAction = ? Może być w stanie osiągnąć to samo, co Restart=przez ustawienie FailureAction=[self.unit](zamień [self.unit] na nazwę urządzenia). To trochę hacky, ale przynajmniej wyraźne i wystarczająco łatwe do naśladowania.
Centimane
@Centimane FailureActionprzyjmuje te same wartości, co StartLimitActionwszystkie, z wyjątkiem nonepewnego rodzaju wyłączenia.
jpkotta

Odpowiedzi:

5

Jednym z możliwych obejść, których próbuję, jest

  [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

Gdzie skrypt tag.shbędzie touch /ack/TAG_SUCCESSpod koniec wykonywania. Uważam, że zbliża się to do pożądanego zachowania, ponieważ ExecStartPrezostanie wykonane sekwencyjnie, czekając na pomyślne zakończenie przed wywołaniem, ExecStarta jednostka jest rozpatrywana tylko Startingraz, gdy ExecStartzostanie wywołana, w którym momencie jesteśmy pewni, że zakończyliśmy zadanie uruchamiania.

Ale nadal wydaje się to gigantycznym hackem?

JKnight
źródło
RemainAfterExit=yesDziała to dla mnie dobrze, tyle że musiałem również ustawić, aby jednostka pozostała „aktywna”, aby inne jednostki mogły na niej polegać.
Guss