Jsem relativně nový v systemd a učím se jeho architektuře.
Právě teď se snažím přijít na to, jak spustit vlastní skript shellu. Tento skript se musí spustit po síťová vrstva se spustila.
Spouštím Arch pomocí systemd a netctl.
Pro testování jsem napsal jednoduchý skript, který jednoduše spustí ip addr list > /tmp/ip.txt
. Pro tento skript jsem vytvořil následující soubor služby.
(/etc/systemd/system/test.service)
[Unit]
Description=test service
[Service]
ExecStart=/root/test.script
[Install]
WantedBy=multi-user.target
Poté jsem povolil skript pomocí,
systemctl enable test
Po restartu se skript skutečně spustí, ale spustí se před spuštěním sítě. Jinými slovy, výstup v ip.txt
nezobrazuje žádnou adresu IPv4 přiřazenou primárnímu rozhraní. V době, kdy se přihlásím, byla adresa IPv4 skutečně přidělena a síť funguje.
Hádám, že bych mohl změnit bod, ve kterém se skript spouští, tím, že bych si pohrál s WantedBy
parametr, ale nejsem si jistý, jak to udělat.
Mohl by mě někdo nasměrovat správným směrem?
Přijatá odpověď:
Na závislosti konfigurace sítě systemd
Je velmi snadné ovlivnit řazení jednotek systemd. Na druhou stranu si musíte dávat pozor na to, co zaručuje dokončená jednotka.
Nakonfigurujte svou službu
Na aktuálních systémech
řazení po network.target
pouze zaručuje, že síťová služba byla spuštěna, nikoli že existuje nějaká skutečná konfigurace. Musíte objednat po network-online.target
a zatáhněte jej, abyste toho dosáhli.
[Unit]
Wants=network-online.target
After=network-online.target
Pro kompatibilitu se staršími systémy možná budete muset objednat i po network.target.
[Unit]
Wants=network-online.target
After=network.target network-online.target
To je pro soubor jednotky vaší služby a pro systemd.
Implementace v aktuálních verzích softwaru
Nyní se musíte ujistit, že network-online.target
funguje podle očekávání (nebo že můžete alespoň použít network.target
).
Aktuální verze NetworkManager nabízí službu NetworkManager-wait-online.service
který je vtažen do network-online.target
a tedy vaší službou. Tato speciální služba zajišťuje, že vaše služba počká, dokud všechna připojení nakonfigurovaná tak, aby se automaticky spouštěla, uspějí, selžou nebo jim vyprší časový limit.
Aktuální verze systemd-networkd zablokuje vaši službu, dokud nebudou všechna zařízení nakonfigurována podle požadavků. Je jednodušší v tom, že v současné době podporuje pouze konfigurace, které se aplikují při spouštění (přesněji dobu spouštění `systemd-networkd.service).
Pro úplnost, /etc/init.d/network
služba ve Fedoře, jak ji interpretují aktuální verze systemd, blokuje network.target
a tím nepřímo blokuje network-online.target
a vaši službu. Je to příklad implementace založené na skriptech.
Pokud se vaše implementace, ať už založená na démonech nebo na skriptech, chová jako jedna z výše uvedených služeb správy sítě, zdrží se spuštění vaší služby, dokud nebude konfigurace sítě buď úspěšně dokončena, selže z dobrého důvodu nebo po přiměřené době vyprší časový limit. rám k dokončení.
Související:Hledat soubory, jejichž cesty obsahují několik slov bez konkrétního pořadí mezi nimi?Možná budete chtít zkontrolovat, zda netctl funguje stejným způsobem a tato informace by byla cenným doplňkem této odpovědi.
Implementace ve starších verzích softwaru
Nemyslím si, že uvidíte dostatečně starou verzi systemd, kde by to nefungovalo dobře. Ale můžete zkontrolovat, že alespoň network-online.target
existuje a že je řazen po network.target
.
Dříve NetworkManager pouze zaručeno, že bude použito alespoň jedno připojení. A aby to fungovalo, museli byste povolit NetworkManager-wait-online.service
výslovně. Toto bylo ve Fedoře již dlouho opraveno, ale teprve nedávno bylo použito upstream.
systemctl enable NetworkManager-wait-online.service
Poznámky k implementacím network.target a network-online.target
Nikdy byste neměli potřebovat, aby byl váš software závislý na NetworkManager.service
nebo NetworkManager-wait-online.service
ani žádné další specifické služby. Místo toho by se všechny služby správy sítě měly řadit před network.target
a volitelně network-online.target
.
Jednoduchá služba správy sítě založená na skriptu by měla dokončit konfiguraci sítě před ukončením a měla by se sama objednat před network.target
a tedy nepřímo před network-online.target
.
[Unit]
Before=network.target
[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes
Služba správy sítě založená na démonech by se také měla řadit před network.target
i když to není příliš užitečné.
[Unit]
Before=network.target
[Service]
Type=simple
ExecStart=...
Služba, která čeká na dokončení démona, by se měla objednat po konkrétní službě a před network-online.target
. Mělo by používat Requisite
na službě démona, takže okamžitě selže, pokud se příslušná služba správy sítě nepoužívá.
[Unit]
Requisite=...
After=...
Before=network-online.target
[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes
Balíček by měl nainstalovat symbolický odkaz na čekající službu v wants
adresář pro network-online.target
aby byl stažen službami, které chtějí čekat na nakonfigurovanou síť.
ln -s /usr/lib/systemd/system/... /usr/lib/systemd/system/network-online.target.wants/
Související dokumentace
- http://www.freedesktop.org/software/systemd/man/systemd.special.html#network-online.target
- http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/
Poznámky na závěr
Doufám, že jsem nejen pomohl zodpovědět vaši otázku v době, kdy jste ji položil, ale také přispěl ke zlepšení situace v upstream a linuxových distribucích, takže nyní mohu poskytnout lepší odpověď, než bylo možné v době psaní původní .