web-dev-qa-db-ja.com

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

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

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

私はUpstartに完全に慣れていないので、予想以上に急な学習曲線を見つけるので、whyソリューションの動作に関する教育は、ソリューション自体と同じくらい価値があります。

5
froage

CameronNemoの部分解 および Mark Russellの解答 を、関連するが多少異なる質問に活用する私自身の質問に対する答えがあると思います。

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

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

modify-filesは停止状態に到達しないため、jobAまたはjobBの再起動に関係なく、新たに実行されることはありません。

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

3
froage

選択したイベントで開始し、スクリプトを実行し、最後にイベントを発行して他の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スクリプトを変更しないようにするには、 override files を使用します。開始条件と停止条件を変更して、ジョブを開始および停止する。

私の例に従って、次のような簡単な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

firstJobmyEventで生成され、mainJobで生成され、runlevel [016]で停止します

Lubuntu 12.04でこれらのジョブをテストし、再起動後に/var/log/upstart/firstJob.logで見つけました:

  (startTask) firstJob -- myEvent

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

2
Lety
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が終了すると停止します。

Taskを使用することで、ジョブが2回実行されるようになります(たとえば、ジョブを再起動した場合)。

1
CameronNemo