他の 2 つのジョブが開始する前に完了することが保証された単一実行の Upstart ジョブを作成するにはどうすればよいですか?

他の 2 つのジョブが開始する前に完了することが保証された単一実行の Upstart ジョブを作成するにはどうすればよいですか?

確実に実行されるUpstartタスクを書くにはどうすればいいでしょうか?1回だけ各起動後に実行されますが、少なくとも他の 2 つのジョブのいずれかが実行を開始する前に完了することが保証されています。他の 2 つのジョブの Upstart init ファイルは私のものではないため、変更したくありません。他の 2 つのジョブのいずれかを再起動しても、目的のタスクが再度実行されることはありません。

状況としては、目的のタスクが、他の両方のジョブに必要なローカル ファイル システム内の一部のファイルに何らかの変更を加える必要があるということです。

私はUpstartをまったく知らないので、予想以上に学習曲線が急峻だと感じています。なぜ解決策が機能するかどうかは、解決策自体と同じくらい価値があります。

答え1

私は自分自身の質問に対する答えを持っていると信じていますCameronNemoの部分的な解決策そしてマーク・ラッセルの答え関連はあるものの、少し異なる質問です。

2 つの Upstart 構成ファイルが必要です。1 つ目は、ローカル ファイル システムが使用可能になるとすぐに開始され、事前起動スクリプトとして必要なファイル変更を実行し、その後、実行状態で永久にアイドル状態になるジョブです。

# 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

2 番目の設定ファイルは、変更しようとしているファイルに依存する可能性のある他のすべてのジョブの開始を遅らせる Upstart タスクです。依存ジョブごとに 1 つのインスタンスを生成します。

# 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

modify-files-waitUpstart は、実行状態でアイドルmodify-files状態になると、のすべてのインスタンスを強制終了します。このnormal exit行は、無限スリープ中に強制終了される可能性を考慮しています。停止状態に達するまで、jobA と joB をブロックする行が必要です。まだ開始されていない場合は、task最初に実行されるインスタンスが を開始します。modify-files

は停止状態に到達しないためmodify-files、jobA または jobB が再開されても、新たに実行されることはありません。

この解決策は機能しているようですが、批判や改善があれば歓迎します。

答え2

選択したイベントで開始し、スクリプトを実行し、最後にイベントを発行して他の 2 つのジョブを開始する単純なタスク ジョブを定義できます。

例えば:

# 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

他の2つのジョブのupstartスクリプトを変更しないようにするには、ファイルを上書きする開始条件と停止条件を変更することで、ジョブの開始および停止の方法を変更できます。

私の例に従って、firstJob.conf次のようなシンプルなものを作成しました。

# 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

次に、オーバーライド ファイルを作成して、開始条件をオーバーライドします。

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

生成されてからfirstJob始まり、停止しますmyEventmainJobrunlevel [016]

これらのジョブを lubuntu 12.04 でテストしたところ、再起動後に次の結果が見つかりました/var/log/upstart/firstJob.log

  (startTask) firstJob -- myEvent

mainJob「他の 2 つのジョブ」を開始するために特定のイベント条件が必要かどうかを確認し、これらのイベントで開始されることを確認する必要があります。

答え3

start on starting jobA or starting jobB

instance $JOB

pre-start exec /path/to/script

開始ビットは、このジョブが完了するまでジョブがライフ サイクル内で移動しないようにします。

インスタンス ビットは、インスタンス スタンザがない場合のように、1 つの開始イベントだけでなく、両方の開始イベント (jobA と jobB) が禁止されるようにするためのものです。

事前起動 exec/script (通常の exec/script の代わりに) を使用すると、スクリプトまたは実行されたコマンドが終了したときに、ジョブはまだ実行中であると見なされますが、従来の exec/script では、exec/script が終了するとジョブは停止していると見なされます。

タスクを使用すると、ジョブが 2 回実行されることになります (たとえば、ジョブが再開される場合など)。そのため、タスクは省略します。

関連情報