Как создать однострочное задание Upstart, которое должно завершиться до начала двух других заданий?

5

Как написать одну задачу Upstart, которая гарантированно будет запускать только один раз после каждого запуска, но также гарантированно будет завершена до того, как начнется запуск хотя бы одного из двух других заданий. Я не хочу изменять файлы инициализации Upstart для этих двух других заданий, поскольку они не принадлежат мне. Перезапуск любого из этих двух других заданий не должен приводить к повторной работе требуемой задачи.

Ситуация заключается в том, что желаемая задача должна внести некоторые изменения в некоторые файлы в локальной файловой системе, которые потребуются для обоих других заданий.

Я совершенно новичок в Upstart и считаю, что это более крутая кривая обучения, чем я ожидал, поэтому образование в why для решения будет столь же ценным, как и само решение.

    
задан froage 07.10.2014 в 11:41
источник

3 ответа

3

Я считаю, что у меня есть ответ на мой собственный вопрос, который использует частичное решение 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 перезапущены.

Это решение работает, но я приветствую любые критические замечания или улучшения.

    
ответ дан froage 10.10.2014 в 10:13
источник
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

Чтобы не изменять сценарий выскочки двух других заданий, вы должны переопределить файлы . > , которые позволяют изменять способ запуска и остановки задания путем изменения начала и завершения условий.

Следуя моим примерам, я создал простой 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 запускается в этих событиях.

    
ответ дан Lety 09.10.2014 в 01:22
1
start on starting jobA or starting jobB

instance $JOB

pre-start exec /path/to/script

Начальный бит предотвращает переход заданий в жизненный цикл до завершения этого задания.

Бит экземпляра так, что оба стартовых события (для jobA и jobB) заблокированы, а не только один, как это было бы, если бы у вас не было строфы экземпляра.

Использование pre-start exec / script (вместо обычного exec / script) заключается в том, что когда команда сценария / выполнения завершается, задание все равно будет считаться запущенным, тогда как с традиционным exec / script работа считается остановленным при выходе из сценария exec / script.

Использование задачи будет именно тем, что заставляет задание запускаться дважды (например, если перезагруженные задания), поэтому мы оставляем это.

    
ответ дан CameronNemo 08.10.2014 в 03:07