¿Cómo puedo asegurarme de que un trabajo de Upstart comience antes que otros trabajos de Upstart?

33

Esta es una pregunta general de Upstart, pero déjame usar un caso específico:

Centrify es una puerta de enlace NIS a ActiveDirectory. Debe cargarse antes de cualquier servicio que dependa del servicio de autenticación que proporciona, por ejemplo, autofs, cron, nis, et al.

Esto ha resultado ser bastante difícil de lograr, incluso cuando trato de cambiar las dependencias de los otros servicios (lo cual no creo que debamos hacer de todos modos, no quiero tocar los otros trabajos de Upstart si es posible) .

Sugerencias?

Mark Russell
fuente

Respuestas:

29

La solución es abordar el problema desde la otra dirección: para satisfacer los criterios de inicio de Centrify, no es necesario hacer que los servicios existentes dependan del nuevo servicio Centrify, sino que el nuevo servicio Centrify dependa de los servicios existentes.

Por ejemplo, un archivo de configuración de Upstart /etc/init/centrify.confpodría decir:

comenzar en (iniciar cron o iniciar autofs o iniciar nis)

Al convertir esto al inglés, esto se traduciría como:

inicie el servicio Centrify justo antes de iniciar cron, autofs o nis (lo que comience primero).

El orden en que se inician cron, autofs o nis es irrelevante: Upstart se asegurará de que Centrify se inicie antes del servicio que se inicie primero, lo que garantiza que Centrify se esté ejecutando antes de que cualquiera de esos servicios comience.

Tenga en cuenta también que Upstart bloqueará el inicio del primer servicio que desea iniciarse hasta que Centrify haya comenzado a ejecutarse.

Muy elegante y simple una vez que te acostumbras a pensar de esta manera.

James Hunt
fuente
44
Esto me parece totalmente al revés. ¿Por qué debería modificarse el script conf para un servicio cuando otras cosas dependen de él ?
ben w
3
@benw Para que no tenga que modificar la configuración existente de servicios que no posee.
Paccc
1
@Paccc cuando escribo un nuevo script que depende de nginx, tengo que modificar el script conf para nginx ... que no tengo.
ben w
2
@benw ¿Por qué no puedes usarlo start on (started nginx)en tu nuevo script?
Paccc
2
@Paccc no realmente. start on (started nginx)significa "iniciar mi servicio después de nginx". Lo cual no es lo mismo que "iniciar nginx antes de mi servicio porque lo necesita".
sickill
12

La respuesta de James funciona para una dependencia 1 a 1. Para un 1 a muchos, es decir, para asegurarse de que el servicio A comience antes que los servicios B, C y D, debe adoptar otro enfoque. Puede consultar los scripts de portmap actuales como referencia, pero este es el enfoque general: cree un script de espera.

Escenario: desea que su Servicio A se ejecute siempre antes del servicio-b, el servicio-c y el servicio-d.

Solución: cree un script de espera para el Servicio A. Llámelo "/etc/init/service-a-wait.conf"

# service-a-wait

start on (starting service-b 
    or starting service-c
    or starting service-d)
stop on (started service-a or stopped service-a)

# We know that we have more than one job that needs to wait for service-a and
# will make use of this service, so we need to instantiate.
instance $JOB

# Needed to make starting the job successful despite being killed
normal exit 2
task

script

    status service-a | grep -q "start/running" && exit 0
    start service-a || true

    # Waiting forever is ok.. upstart will kill this job when
    # the service-a we tried to start above either starts or stops
    while sleep 3600 ; do :; done

end script

Lo que esto significa en inglés simple es: cuando el servicio b, c o d indica que desean comenzar, deben esperar para comenzar hasta que se ejecute el servicio a. El trabajo service-a-wait está diseñado para ejecutarse hasta que service-a haya comenzado. Una vez que finaliza el servicio de espera, ahora los servicios b, cyd son libres de continuar y ejecutarse.

Esto asegurará que el servicio-a esté en funcionamiento antes de que cualquiera de sus dependencias inversas intente iniciarse.

Nota: la línea "instancia $ TRABAJO" es importante en este escenario "comenzar en ... o ... o ...". De lo contrario, solo bloqueará lo que B, C o D dispare primero.

(La instanciación merece una mejor explicación honestamente. Por ahora, solo hazlo.;)

Mark Russell
fuente
3
No entiendo esto ... ¿qué impide que una condición de carrera entre el inicio del servicio A y el servicio B continúe comenzando? No veo cómo advenedizo sabrá que el guión ha completado "iniciar servicio-a" ... (culpe esto a la documentación de mala calidad de
advenedizo
@ Mark Russell: ¿No debería ser esa normal exit 2línea en su normal exit 0 2lugar? La primera línea en la scriptsección claramente puede exit 0.
froage