¿Cómo se escribe una tarea Upstart que se garantiza su ejecución?sólo una vezdespués de cada inicio, pero también se garantiza que se ejecutará hasta su finalización antes de que comience a ejecutarse uno de al menos otros dos trabajos. No quiero alterar los archivos de inicio de Upstart para esos otros dos trabajos ya que no me pertenecen. Reiniciar cualquiera de esos otros dos trabajos no debería hacer que la tarea deseada se ejecute nuevamente.
La situación es que la tarea deseada debe realizar algunas modificaciones en algunos archivos del sistema de archivos local que necesitarán los otros dos trabajos.
Soy completamente nuevo en Upstart y encuentro que la curva de aprendizaje es más pronunciada de lo que esperaba, por lo que una educación sobrepor quéla solución funciona será tan valiosa como la solución misma.
Respuesta1
Creo que tengo una respuesta a mi propia pregunta que aprovechaLa solución parcial de CameronNemoyLa respuesta de Mark Russell.a una pregunta relacionada pero algo diferente.
Se requieren dos archivos de configuración Upstart. El primero es un trabajo que comienza tan pronto como el sistema de archivos local está disponible, realiza las modificaciones deseadas en el archivo como un script previo al inicio y luego permanece inactivo en estado de ejecución para siempre:
# 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
El segundo archivo de configuración es una tarea Upstart que retrasa el inicio de todos los demás trabajos que podrían depender de los archivos que intentamos modificar. Produce una instancia de sí mismo por trabajo dependiente:
# 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 eliminará todas las instancias de modify-files-wait
una vez que modify-files
esté inactivo en su estado de ejecución. Esa normal exit
línea da cuenta de la posibilidad de morir durante su sueño infinito. Necesitamos la task
línea para bloquear el trabajoA y el trabajoB hasta que se alcance el estado detenido. Se iniciará la instancia que se ejecute primero modify-files
, si aún no se ha iniciado.
Dado que modify-files
nunca llega a su estado detenido, nunca se ejecutará de nuevo, independientemente de si se reinicia el trabajo A o el trabajo B.
Esta solución parece estar funcionando, pero acepto cualquier crítica o mejora.
Respuesta2
Puede definir un trabajo de tarea simple que comience en el evento de su elección, ejecute su script y al final emita el evento para iniciar los otros dos trabajos.
Por ejemplo:
# 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
Para no modificar el script de inicio de los otros dos trabajos, debeanular archivosque le permiten modificar la forma en que un trabajo comienza y se detiene modificando las condiciones de inicio y detención.
Siguiendo mis ejemplos creé un simple firstJob.conf
como este:
# 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
Y luego anulo el inicio con la condición de crear un archivo de anulación:
echo "start on myEvent" > /etc/init/firstJob.override
Entonces firstJob
comenzará myEvent
generado por mainJob
y se detendrárunlevel [016]
Probé estos trabajos en lubuntu 12.04 y después de reiniciar encontré en /var/log/upstart/firstJob.log
:
(startTask) firstJob -- myEvent
Debe verificar si "los otros dos trabajos" necesitan una condición de evento particular para comenzar y asegurarse de que mainJob
comiencen en estos eventos.
Respuesta3
start on starting jobA or starting jobB
instance $JOB
pre-start exec /path/to/script
El bit de inicio evita que los trabajos avancen en su ciclo de vida hasta que se complete el trabajo.
El bit de instancia es para que ambos eventos iniciales (para el trabajoA y el trabajoB) estén inhibidos, no solo uno, como sería el caso si no tuviera una estrofa de instancia.
El uso de un exec/script previo al inicio (en lugar de un exec/script normal) es para que cuando finalice el script/comando ejecutado, el trabajo aún se considere en ejecución, mientras que con un exec/script tradicional el trabajo se considera terminado. se detendrá cuando salga el ejecutable/script.
Usar tarea sería precisamente lo que hace que el trabajo se ejecute dos veces (por ejemplo, si se reinician los trabajos que tienes), por lo que lo omitiremos.