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

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

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

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

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.

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

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

Например:

# 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 начать на этих событиях.

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.

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

Другие вопросы по тегам