¿Cómo creo un trabajo Upstart de ejecución única que se garantiza que se completará antes de que comiencen otros dos trabajos?

¿Cómo creo un trabajo Upstart de ejecución única que se garantiza que se completará antes de que comiencen otros dos trabajos?

¿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-waituna vez que modify-filesesté inactivo en su estado de ejecución. Esa normal exitlínea da cuenta de la posibilidad de morir durante su sueño infinito. Necesitamos la tasklí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-filesnunca 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.confcomo 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 firstJobcomenzará myEventgenerado por mainJoby 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 mainJobcomiencen 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.

información relacionada