如何建立保證在其他兩個作業開始之前完成的單執行 Upstart 作業?

如何建立保證在其他兩個作業開始之前完成的單執行 Upstart 作業?

如何編寫一個保證運行的 Upstart 任務只有一次每次啟動後,但也保證在至少兩個其他作業之一開始運行之前運行完成。我不想更改另外兩個作業的 Upstart 初始化文件,因為它們不屬於我。重新啟動這兩個作業中的任何一個都不會導致所需的任務再次執行。

情況是所需的任務必須對本機檔案系統中的某些檔案進行一些修改,而其他作業都需要這些檔案。

我對 Upstart 完全陌生,發現它的學習曲線比我預期的要陡峭,因此需要接受有關為什麼解決方案的效果將與解決方案本身一樣有價值。

答案1

我相信我對自己的問題有一個答案CameronNemo 的部分解決方案馬克·拉塞爾的回答一個相關但有些不同的問題。

需要兩個 Upstart 設定檔。第一個是本機檔案系統可用時立即啟動的作業,作為預啟動腳本執行所需的檔案修改,然後永遠處於空閒運行狀態:

# 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

第二個設定檔是一個 Upstart 任務,它會延遲可能依賴我們嘗試修改的檔案的所有其他作業的啟動。它為每個依賴作業產生一個自身實例:

# 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線解釋了它在無限睡眠期間被殺死的可能性。我們需要該task行來阻止 jobA 和 joB 直到達到停止狀態。modify-files如果尚未啟動,則先執行的執行個體將啟動。

由於modify-files永遠不會達到停止狀態,因此無論 jobA 或 jobB 是否重新啟動,它都不會重新運行。

這個解決方案似乎有效,但我歡迎任何批評或改進。

答案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

為了不修改其他兩個作業的 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在這些事件上啟動。

答案3

start on starting jobA or starting jobB

instance $JOB

pre-start exec /path/to/script

起始位元阻止作業在其生命週期中繼續前進,直到該作業完成。

實例位的作用是,兩個啟動事件(jobA 和 jobB)都被禁止,而不僅僅是一個,如果您沒有實例節,就會發生這種情況。

使用預啟動exec/script(取代常規exec/script)的目的是,當腳本/執行的命令完成時,作業仍將被視為正在運行,而使用傳統的exec/script 時,作業將被視為正在運行。

使用任務正是使作業執行兩次的原因(例如,如果您重新啟動了作業),因此我們將其排除在外。

相關內容