it-swarm.com.de

Wie erstelle ich einen Upstart-Job mit einer Ausführung, der garantiert abgeschlossen wird, bevor zwei andere Jobs beginnen?

Wie schreibt man eine Upstart-Task, die garantiert ausgeführt wird nur einmal nach jedem Start, aber auch garantiert vollständig ausgeführt wird, bevor einer von mindestens zwei anderen Jobs ausgeführt wird? Ich möchte die Upstart-Init-Dateien für diese beiden anderen Jobs nicht ändern, da sie nicht zu mir gehören. Wenn Sie einen dieser beiden anderen Jobs neu starten, wird die gewünschte Task möglicherweise nicht erneut ausgeführt.

Die Situation ist, dass die gewünschte Aufgabe einige Änderungen an einigen Dateien im lokalen Dateisystem vornehmen muss, die für beide anderen Jobs erforderlich sind.

Ich bin völlig neu in Upstart und finde, dass es eine steilere Lernkurve als erwartet gibt. Daher ist eine Schulung zu warum der Lösung genauso wertvoll wie die Lösung selbst.

5
froage

Ich glaube, ich habe eine Antwort auf meine eigene Frage, die CameronNemos Teillösung und Mark Russells Antwort auf eine verwandte, aber etwas andere Frage nutzt.

Es sind zwei Upstart-Konfigurationsdateien erforderlich. Der erste Job wird gestartet, sobald das lokale Dateisystem verfügbar ist, führt die gewünschten Dateiänderungen als Pre-Start-Skript durch und befindet sich dann für immer im Leerlaufzustand:

# modify-files - Single-execution file modification job

start on local-filesystems

console log

pre-start script
  echo "$(date --rfc-3339=ns) $(hostname) $UPSTART_JOB"
  exec /path/to/your/script
end script

Die zweite Konfigurationsdatei ist eine Upstart-Task, die den Start aller anderen Jobs verzögert, die möglicherweise von den Dateien abhängen, die wir ändern möchten. Pro abhängigem Job wird eine Instanz von sich selbst erstellt:

# modify-files-wait - Helper task for modify-files

start on (starting jobA or jobB)
stop on (started modify-files or stopped modify-files)

instance $JOB

console log
normal exit 0 2
task

script
  echo "$(date --rfc-3339=ns) $(hostname) $UPSTART_JOB ($UPSTART_INSTANCE)"
  status modify-files | grep -q "start/running" && exit 0
  start modify-files || true
  sleep infinity
end script

Upstart beendet alle Instanzen von modify-files-wait, sobald modify-files im Leerlauf ist. Diese normal exit -Zeile erklärt die Möglichkeit, im unendlichen Schlaf getötet zu werden. Wir brauchen die task -Zeile, um jobA und joB zu blockieren, bis der gestoppte Zustand erreicht ist. Die zuerst ausgeführte Instanz startet modify-files, sofern sie noch nicht gestartet wurde.

Da modify-files nie seinen Stoppzustand erreicht, wird es nie wieder ausgeführt, unabhängig davon, ob JobA oder JobB neu gestartet wird.

Diese Lösung scheint zu funktionieren, aber ich begrüße jede Kritik oder Verbesserung.

3
froage

Sie können einen einfachen Task-Job definieren, der bei einem Ereignis Ihrer Wahl startet, Ihr Skript ausführen und am Ende ein Ereignis ausgeben, um die beiden anderen Jobs zu starten.

Zum Beispiel:

# mainJob - 
#
# This service emit myEvent to run firstJob 
description "emit myEvent to run firstJob"
start on runlevel [2345]
task
console log
script
     echo "(startTask) $UPSTART_JOB -- $UPSTART_EVENTS" 
     exec /path/to/your/script
     initctl emit -n myEvent
end script

Um das Startskript der beiden anderen Jobs nicht zu ändern, sollten Sie Dateien überschreiben , mit denen Sie die Art und Weise ändern können in dem ein Job gestartet und gestoppt wird, indem die Bedingungen für das Starten und Stoppen geändert werden.

Nach meinen Beispielen habe ich einen einfachen firstJob.conf wie folgt erstellt:

# firstJob - 
#
# This service print environment variable 
description "print environment variable"
start on runlevel [2345]
stop on runlevel [016]
task
console log
script
if [ "$RUNLEVEL" = "0" -o "$RUNLEVEL" = "1" -o "$RUNLEVEL" = "6" ]; then
     exec  echo "(stopTask) $UPSTART_JOB -- $UPSTART_EVENTS"  
else
     exec  echo "(startTask) $UPSTART_JOB -- $UPSTART_EVENTS" 
fi
end script

Und dann überschreibe ich start unter der Bedingung, dass eine Überschreibungsdatei erstellt wird:

echo "start on myEvent" > /etc/init/firstJob.override

Also startet firstJob mit myEvent, generiert von mainJob und stoppt mit runlevel [016]

Ich habe diese Jobs auf Lubuntu 12.04 getestet und nach dem Neustart in /var/log/upstart/firstJob.log gefunden:

  (startTask) firstJob -- myEvent

Sie sollten überprüfen, ob für "die anderen beiden Jobs" eine bestimmte Ereignisbedingung zum Starten erforderlich ist, und sicherstellen, dass mainJob bei diesen Ereignissen gestartet wird.

2
Lety
start on starting jobA or starting jobB

instance $JOB

pre-start exec /path/to/script

Das Startbit verhindert, dass die Jobs in ihrem Lebenszyklus weiterlaufen, bis dieser Job abgeschlossen ist.

Das Instanzbit ist so, dass beide Startereignisse (für jobA und jobB) gesperrt sind, nicht nur eines, wie dies der Fall wäre, wenn Sie keine Instanzzeilengruppe hätten.

Die Verwendung von Exec/Script vor dem Start (anstelle eines regulären Exec/Script) bewirkt, dass der Job nach Abschluss des Script/Executed-Befehls weiterhin als ausgeführt betrachtet wird, wohingegen bei einem herkömmlichen Exec/Script der Job als ausgeführt betrachtet wird wird beim Beenden von exec/script gestoppt.

Die Verwendung von task bewirkt genau, dass der Job zweimal ausgeführt wird (z. B. wenn die Jobs, die Sie haben, neu gestartet werden), sodass wir ihn weglassen.

1
CameronNemo