確実に実行される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-wait
Upstart は、実行状態でアイドル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
始まり、停止しますmyEvent
mainJob
runlevel [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 回実行されることになります (たとえば、ジョブが再開される場合など)。そのため、タスクは省略します。