Jak mogę się upewnić, że jedno zadanie Upstart rozpocznie się przed innymi zadaniami Upstart?

33

To jest ogólne pytanie Upstart, ale pozwól mi użyć konkretnego przypadku:

Centrify to brama NIS do ActiveDirectory. Musi się załadować przed jakąkolwiek usługą, która będzie zależeć od świadczonej przez nią usługi uwierzytelniania, np. Autofs, cron, nis i in.

Okazało się to dość trudne do osiągnięcia, nawet przy próbie zmiany zależności innych usług (co nie wydaje mi się, że i tak powinniśmy to robić, nie chcę dotykać innych zadań Upstart, jeśli to w ogóle możliwe) .

Propozycje?

Mark Russell
źródło

Odpowiedzi:

29

Rozwiązaniem jest podejście do problemu z drugiej strony: aby spełnić kryteria początkowe dla Centrify, nie jest konieczne uzależnianie istniejących usług od nowej usługi Centrify, a raczej uzależnienie nowej usługi Centrify od istniejących usług.

Na przykład plik konfiguracyjny Upstart /etc/init/centrify.confmoże powiedzieć:

start on (uruchamianie crona lub uruchamianie autofs lub uruchamianie nis)

Konwertując to na angielski, tłumaczyłoby to jako:

uruchom usługę Centrify tuż przed uruchomieniem crona, autofs lub nis (w zależności od tego, co nastąpi najpierw).

Kolejność uruchamiania cron, autofs lub nis jest nieistotna: Upstart zapewni, że Centrify uruchomi się przed którąkolwiek usługą, zanim zacznie się usługa, zapewniając w ten sposób, że Centrify uruchomi się przed uruchomieniem którejkolwiek z tych usług.

Zauważ też, że Upstart zablokuje uruchomienie pierwszej usługi, która chce się uruchomić, dopóki Centrify nie zacznie działać.

Bardzo elegancki i prosty, gdy przyzwyczaisz się do takiego myślenia.

James Hunt
źródło
4
wydaje mi się to całkowicie odwrócone. dlaczego skrypt conf dla jednej usługi powinien być modyfikowany, gdy inne rzeczy od niego zależą ?
ben w
3
@benw Abyś nie musiał modyfikować istniejących ustawień usług, których nie posiadasz.
Paccc
1
@Paccc, kiedy piszę nowy skrypt, który zależy od nginx, muszę zmodyfikować skrypt conf dla nginx ... którego nie posiadam.
ben w
2
@benw Dlaczego nie możesz użyć start on (started nginx)w nowym skrypcie?
Paccc
2
@Paccc nie bardzo. start on (started nginx)oznacza „uruchom moją usługę po nginx”. Co nie jest tym samym, co „uruchom nginx przed moją usługą, ponieważ jej potrzebuje”.
sickill
12

Odpowiedź Jamesa działa w zależności od 1 do 1. Dla 1 do wielu, tj. Aby upewnić się, że usługa A rozpocznie się przed usługami B, C i D, musisz zastosować inne podejście. Możesz spojrzeć na bieżące skrypty portmap w celach informacyjnych, ale oto ogólne podejście: utwórz skrypt oczekiwania.

Scenariusz: chcesz, aby usługa A zawsze działała przed usługą b, usługą c i usługą d.

Rozwiązanie: utwórz skrypt oczekiwania dla usługi A. Nazwij go „/etc/init/service-a-wait.conf”

# service-a-wait

start on (starting service-b 
    or starting service-c
    or starting service-d)
stop on (started service-a or stopped service-a)

# We know that we have more than one job that needs to wait for service-a and
# will make use of this service, so we need to instantiate.
instance $JOB

# Needed to make starting the job successful despite being killed
normal exit 2
task

script

    status service-a | grep -q "start/running" && exit 0
    start service-a || true

    # Waiting forever is ok.. upstart will kill this job when
    # the service-a we tried to start above either starts or stops
    while sleep 3600 ; do :; done

end script

W zwykłym języku angielskim oznacza to: gdy usługa b, c lub d sygnalizuje, że chce uruchomić, musi poczekać, aż uruchomi się usługa a. Zadanie usługi czekania zostało zaprojektowane do uruchomienia do momentu uruchomienia usługi a. Po zakończeniu usługi Service-a-wait usługi b, c i d mogą nadal działać i działać.

Zapewni to, że usługa a jest uruchomiona przed próbą uruchomienia którejkolwiek z jej odwrotnych zależności.

Uwaga: wiersz „instancja $ JOB” jest ważny w tym scenariuszu „zacznij od ... lub… lub…”. W przeciwnym razie tak naprawdę zablokujesz tylko dla tego, który B, C lub D wystrzeli jako pierwszy.

(tworzenie instancji zasługuje na lepsze wyjaśnienie szczerze. na razie po prostu zrób to;)

Mark Russell
źródło
3
Nie rozumiem tego ... co zapobiega wyścigowi między startem usługi A i usługą B w dalszym ciągu? Nie wiem, jak upstart dowie się, że skrypt zakończył pracę „start service-a”… (może to winę za tandetną dokumentację Upstart…)
Chris Pacejo
@Mark Russell: Czy zamiast tego nie powinna być ta normal exit 2linia normal exit 0 2? Pierwsza linia w scriptsekcji dość wyraźnie może exit 0.
dnia