El servicio de la Unidad Systemd se reinicia si otro servicio se inicia o vuelve a cargar

16

Me gustaría saber si hay una manera Systemdde reiniciar A.service( After) cuando B.servicese inicia o se vuelve a cargar (solo recargar la configuración), si es posible sin editar el sistema B.serviceque instala y actualiza.

A.servicedebe comenzar incluso si B.serviceno está instalado, deshabilitado o detenido.

A.service:

[Unit]
After = B.service network-online.target
Wants = B.service

[Service]
Type=oneshot
ExecStart = /script.sh start
ExecStop = /script.sh stop
RemainAfterExit=yes

[Install]
WantedBy = network-online.target

B.service:

[Unit]
After=syslog.target network.target

[Service]
Type=forking
ExecStart=/cmd start
ExecStop=/cmd stop
ExecReload=/cmd reload
PIDFile=/var/run/cmd.pid

[Install]
WantedBy=multi-user.target
Alex
fuente

Respuestas:

12

Puedes usar PartOfen la [Unit]sección.

Ejemplo: PartOf=B.service

Desde la página del manual,

PartOf =

Configura dependencias similares a Requiere =, pero limitadas a detener y reiniciar unidades. Cuando systemd detiene o reinicia las unidades enumeradas aquí, la acción se propaga a esta unidad. Tenga en cuenta que esta es una dependencia unidireccional: los cambios en esta unidad no afectan a las unidades enumeradas.

Thushi
fuente
Gracias, estaba investigando, Overriding vendor settingspero esto parece aún más fácil y prometedor, solo la excitación es que no quiero Aparar si me Bdetengo, solo A.restartsi B.start, de todos modos, haré alguna prueba pronto y veré si hay alguna forma de manejarlo, entonces te lo haré saber
Alex
@ Alex: ¿Qué pasa si usa PartOfy Restart=alwaysjuntos?
Thushi
Estoy mirando la Restart=documentación, no estoy seguro de cuál es el comportamiento con los oneshotservicios, pero de todos modos: When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restartedsi entiendo correctamente, detener manualmente B detendría A
Alex
Bueno, ahora, la recompensa se asignó automáticamente para su vencimiento, @Thushi Agradezco su esfuerzo y la sugerencia, pero PartOfno es una solución para la pregunta, disfrute de todos modos.
Alex
@Alex: Bueno, los puntos no son importantes para mí. Hay muchas otras formas en que puedo ganar puntos. Solo quiero saber si la solución proporcionada resuelve su problema. Si no, trabajaremos más en ello. ¿Qué hay de usar PartOfcon Restart=always? ¿Intentaste eso?
Thushi
3

No tenía control sobre stopcon PartOf=, y Ano debe parar con B, por lo que terminé usando la configuración de proveedores Anulación , parece que funciona.

/etc/systemd/system/B.service.d/override.conf

[Service]
ExecStart=
ExecStart=/bin/sh -c '/cmd start || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'
ExecReload=
ExecReload=/bin/sh -c '/cmd reload || exit $?; sleep 5; [ -x /script.sh ] && /script.sh start; exit 0'

/cmdla implementación es asíncrona y accedo a un recurso que también /script.shnecesita acceder, no encontré nada mejor (por ahora) para dormir unos segundos.

Traté de usar systemctl [--no-block] try-restartantes de usar /script.shdirectamente pero no funcionó.

Alex
fuente
También estoy buscando una solución para este escenario. ¿Podría explicar esta solución un poco más? o proporcione un enlace a algunos documentos para leer y comprender lo que ha hecho.
zappy 01 de
Hola @zappy, busca el manual man systemd.unit(o búscalo en línea si no está instalado) y busca el capítulo "Anulación de la configuración del proveedor".
Alex
Gracias por su aporte. Entiendo que elige el método anterior solo porque el servicio B es específico del proveedor y no desea editar ese archivo de servicio. Pero en mi caso, tanto el servicio A como el B no son entregados por el proveedor. Siento que anularlo puede agregar complejidad al sistema. ¿Tenemos alguna otra opción?
zappy
La pregunta tiene un par de años, ¿revisó la documentación? Tal vez este escenario ha sido cubierto desde entonces. En ese momento tenía prisa pero, al tener tiempo, buscaba la lista de correo oficial del sistema y preguntaba allí, eventualmente abría un problema
Alex
1

Por el momento, systemd no cubre este senario. No puede lograr esta funcionalidad solo a través de los archivos de servicio. Una posibilidad es secuestrar systemctl a través de un script de shell con el mismo nombre y en esa verificación para ver si B.service está a punto de reiniciarse o recargarse, realizar la acción apropiada con A.service también y, si es necesario, actualizar el rc.local para llegar al estado correcto en el arranque también. Tengo este problema con docker.service y networking.service, pero siempre los reinicio juntos:

systemctl restart docker.service networking.service

Obviamente, esto no sería efectivo si systemd manipula internamente B.service (por ejemplo, a través de otros archivos de servicio).

kaveh minooie
fuente