Как создать одноразовое задание 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.
Использование задачи - это именно то, что заставляет задание запускаться дважды (например, если задание перезапускается), поэтому мы его опускаем.