Wie kann ich sicherstellen, dass ein Upstart-Job vor anderen Upstart-Jobs gestartet wird?

33

Dies ist eine allgemeine Upstart-Frage, aber lassen Sie mich einen bestimmten Fall verwenden:

Centrify ist ein NIS-zu-ActiveDirectory-Gateway. Es muss vor jedem Dienst geladen werden, der von dem von ihm bereitgestellten Authentifizierungsdienst abhängt, z. B. autofs, cron, nis, et al.

Es hat sich als ziemlich schwierig erwiesen, dies zu erreichen, selbst wenn versucht wird, die Abhängigkeiten der anderen Dienste zu ändern (was meines Erachtens sowieso nicht der Fall ist, ich möchte die anderen Upstart-Jobs nach Möglichkeit nicht berühren). .

Vorschläge?

Mark Russell
quelle

Antworten:

29

Die Lösung besteht darin, sich dem Problem von der anderen Seite zu nähern: Um die Startkriterien für Centrify zu erfüllen, ist es nicht erforderlich, vorhandene Services von dem neuen Centrify-Service abhängig zu machen, sondern den neuen Centrify-Service von vorhandenen Services abhängig zu machen.

In einer Upstart-Konfigurationsdatei /etc/init/centrify.confkönnte beispielsweise Folgendes stehen:

start on (cron starten oder autofs starten oder nis starten)

Wenn Sie dies in Englisch umwandeln, würde dies folgendermaßen lauten:

Starten Sie den Centrify-Dienst unmittelbar vor dem Start von cron, autofs oder nis (je nachdem, was zuerst gestartet wird).

Die Reihenfolge, in der cron, autofs oder nis gestartet werden, ist irrelevant: Upstart stellt sicher, dass Centrify startet, bevor der Dienst zuerst gestartet wird, und stellt somit sicher, dass Centrify ausgeführt wird, bevor einer dieser Dienste gestartet wird.

Beachten Sie auch, dass Upstart den Start des ersten Dienstes blockiert, der gestartet werden soll, bis Centrify gestartet wurde.

Sehr elegant und einfach, wenn man sich erst einmal daran gewöhnt hat, so zu denken.

James Hunt
quelle
4
Das scheint mir völlig rückständig zu sein. warum soll der conf - Skript für einen Dienst geändert werden , wenn andere Dinge davon ab , es ?
Ben w
3
@benw Damit Sie die vorhandenen Einstellungen von Diensten, die Sie nicht besitzen, nicht ändern müssen.
Paccc
1
@Paccc Wenn ich ein neues Skript schreibe, das von nginx abhängt, muss ich das conf-Skript für nginx ändern ... was ich nicht besitze.
Ben w
2
@benw Warum kannst du nicht start on (started nginx)in deinem neuen Skript verwenden?
Paccc
2
@Paccc eigentlich nicht. start on (started nginx)bedeutet "starte meinen Dienst nach nginx". Das ist nicht dasselbe wie "starte nginx vor meinem Service, weil es es braucht".
Sichel
12

James 'Antwort funktioniert für eine 1: 1-Abhängigkeit. Für eine 1 bis viele, dh um sicherzustellen, dass Dienst A vor den Diensten B, C und D startet, müssen Sie einen anderen Ansatz wählen. Sie können sich die aktuellen Portmap-Skripte als Referenz ansehen, aber hier ist der allgemeine Ansatz: Erstellen Sie ein Warteskript.

Szenario: Sie möchten, dass Service A immer vor Service-B, Service-C und Service-D ausgeführt wird.

Lösung: Erstellen Sie ein Warteskript für Service A. Rufen Sie es "/etc/init/service-a-wait.conf" auf.

# 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

Dies bedeutet im Klartext: Wenn Service b, c oder d signalisiert, dass sie gestartet werden möchten, müssen sie warten, bis Service-a ausgeführt wird. Der Service-a-Wait-Job wird ausgeführt, bis Service-a gestartet wurde. Sobald service-a-wait beendet ist, können die Dienste b, c und d weiter ausgeführt werden.

Dies stellt sicher, dass service-a aktiv ist, bevor eine der umgekehrten Abhängigkeiten gestartet wird.

Hinweis: Die Zeile "instance $ JOB" ist in diesem Szenario "start on ... or .. or .." wichtig. Andernfalls blocken Sie nur für das, was zuerst von B, C oder D ausgelöst wird.

(Die Instanziierung verdient eine ehrlichere Erklärung. Tu es vorerst einfach.;)

Mark Russell
quelle
3
Ich verstehe das nicht… was verhindert, dass ein Rennen zwischen dem Start von Service A und Service B weiterhin startet? Ich sehe nicht , wie Emporkömmling weiß , dass das Skript abgeschlossen ist „Start - Service-a“ ... ( die Schuld dieses auf Upstart der schlampigen Dokumentation vielleicht ...)
Chris Pacejo
@ Mark Russell: Sollte diese normal exit 2Zeile nicht normal exit 0 2stattdessen sein? Die erste Zeile im scriptAbschnitt kann ganz klar exit 0.
Freitag,