Mám službu se spuštěným softwarem, který generuje nějaké konfigurační soubory, pokud neexistují, a čte je, pokud existují. Problém, se kterým jsem se potýkal, je, že tyto soubory se někdy poškodí, takže se software nemůže spustit, a tím se služba nezdaří. V tomto případě bych chtěl tyto soubory odstranit a restartovat službu.
Pokusil jsem se vytvořit službu, která by se měla spustit v případě selhání, takto:
[Service]
ExecStart=/bin/run_program
OnFailure=software-fail.service
kde je tato služba:
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=systemctl --user start software.service
Problém je však v tom, že tato služba se nespustí, i když služba selhala.
Zkusil jsem to udělat
systemctl --user enable software-fail.service
ale pak se spustí pokaždé, když se systém spustí, stejně jako jakákoli jiná služba.
Moje dočasné řešení je použít
ExecStopPost=/bin/rm /file/to/delete
ale to není uspokojivý způsob, jak to vyřešit, protože vždy dojde k odstranění souboru při zastavení služby, bez ohledu na to, zda to bylo kvůli selhání nebo ne.
Výstup při selhání:
● software.service - Software
Loaded: loaded (/home/trippelganger/.config/systemd/user/software.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2018-05-04 09:05:26 CEST; 5s ago
Process: 1839 ExecStart=/bin/run_program (code=exited, status=1/FAILURE)
Main PID: 1839 (code=exited, status=1/FAILURE)
May 04 09:05:26 trippelganger systemd[595]: software.service: Main process exited, code=exited, status=1/FAILURE
May 04 09:05:26 trippelganger systemd[595]: software.service: Unit entered failed state.
May 04 09:05:26 trippelganger systemd[595]: software.service: Failed with result 'exit-code'.
Výstup systemctl – stav uživatele software-fail.service
je:
● software-fail.service - Delete corrupt files
Loaded: loaded (/home/trippelganger/.config/systemd/user/software-fail.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Přijatá odpověď:
POZNÁMKA :Pravděpodobně budete chtít použít ExecStopPost=
místo OnFailure=
zde (viz moje další odpověď), ale toto se snaží vyřešit, proč vaše OnFailure=
nastavení nefunguje.
Problém s OnFailure=
nespuštění jednotky může být způsobeno tím, že je v nesprávné sekci, musí být v [Unit]
sekce a nikoli [Service]
.
Místo toho můžete zkusit toto:
# software.service
[Unit]
Description=Software
OnFailure=software-fail.service
[Service]
ExecStart=/bin/run_program
A:
# software-fail.service
[Unit]
Description=Delete corrupt files
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=/bin/systemctl --user start software.service
S tímto nastavením to zvládnu.
Všimněte si však, že pomocí OnFailure=
není zde ideální, protože nemůžete skutečně říct, proč program selhal, a řetězení dalšího jeho spuštění v ExecStop=
voláním /bin/systemctl start
přímo je docela hackery… Řešení pomocí ExecStopPost=
a pohled na výstupní stav je rozhodně lepší.
Pokud definujete OnFailure=
uvnitř [Service]
, systemd (alespoň verze 234 z Fedory 27) si stěžuje:
software.service:6: Unknown lvalue 'OnFailure' in section 'Service'
Nejste si jisti, zda to vidíte ve svých protokolech nebo ne... (Možná to bylo přidáno v nedávném systemd?) To by měl být náznak toho, co se tam děje.
Související:Rozdíl mezi „>“ a „-gt“?