GNU/Linux >> Tutoriales Linux >  >> Linux

¿Por qué se ejecuta una secuencia de comandos después de que se haya iniciado la red?

Soy relativamente nuevo en systemd y estoy aprendiendo su arquitectura.

En este momento, estoy tratando de descubrir cómo hacer que se ejecute un script de shell personalizado. Este script debe ejecutarse después la capa de red se ha iniciado.

Estoy ejecutando Arch, usando systemd y netctl.

Para probar, escribí un script simple que simplemente ejecuta ip addr list > /tmp/ip.txt . Creé el siguiente archivo de servicio para este script.

(/etc/systemd/system/test.service)
[Unit]
Description=test service

[Service]
ExecStart=/root/test.script

[Install]
WantedBy=multi-user.target

Luego habilité el script con,

systemctl enable test

Al reiniciar, el script sí se ejecuta, pero se ejecuta antes de que se inicie la red. En otras palabras, la salida en ip.txt no muestra ninguna dirección IPv4 asignada a la interfaz principal. En el momento en que inicio sesión, la dirección IPv4 ya se ha asignado y la red está activa.

Supongo que podría alterar el punto en el que se ejecuta el script jugando con WantedBy parámetro, pero no estoy seguro de cómo hacerlo.

¿Podría alguien indicarme la dirección correcta?

Respuesta aceptada:

Sobre las dependencias de configuración de la red systemd

Es muy fácil afectar el orden de las unidades de systemd. Por otro lado, debe tener cuidado con lo que garantiza una unidad completa.

Configura tu servicio

En los sistemas actuales,
ordenar después de network.target solo garantiza que el servicio de red se haya iniciado, no que haya alguna configuración real. Debe realizar el pedido después de network-online.target y jálelo para lograrlo.

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

Para compatibilidad con sistemas más antiguos, es posible que también deba realizar un pedido después de network.target.

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

Eso es para el archivo de unidad de su servicio y para systemd.

Implementación en versiones actuales de software

Ahora debe asegurarse de que network-online.target funciona como se esperaba (o que al menos puede usar network.target ).

La versión actual de NetworkManager ofrece el NetworkManager-wait-online.service que es atraído por network-online.target y así por vuestro servicio. Este servicio especial garantiza que su servicio esperará hasta que todas las conexiones configuradas para iniciarse automáticamente se realicen correctamente, fallen o se agote el tiempo de espera.

La versión actual de systemd-networkd bloquea su servicio hasta que todos los dispositivos estén configurados según lo solicitado. Es más fácil porque actualmente solo admite configuraciones que se aplican en el momento del arranque (más específicamente, en el momento del inicio de `systemd-networkd.service).

En aras de la exhaustividad, /etc/init.d/network El servicio en Fedora, tal como lo interpretan las versiones actuales de systemd, bloquea network.target y por lo tanto bloquea indirectamente network-online.target y su servicio. Es un ejemplo de una implementación basada en script.

Si su implementación, ya sea basada en un demonio o en un script, se comporta como uno de los servicios de administración de red anteriores, retrasará el inicio de su servicio hasta que la configuración de la red se complete con éxito, falle por una buena razón o se agote el tiempo después de un tiempo razonable. marco para completar.

Relacionado:¿Buscar archivos cuyos nombres de ruta contengan varias palabras sin un orden específico entre ellas?

Es posible que desee comprobar si netctl funciona de la misma manera y esa información sería una valiosa adición a esta respuesta.

Implementaciones en versiones anteriores de software

No creo que vea una versión lo suficientemente antigua de systemd donde esto no funcione bien. Pero puede verificar que al menos network-online.target existe y que se ordena después de network.target .

Anteriormente NetworkManager solo garantizó que se aplicaría al menos una conexión. E incluso para que eso funcione, tendría que habilitar el NetworkManager-wait-online.service explícitamente. Esto se solucionó durante mucho tiempo en Fedora, pero solo se aplicó recientemente en sentido ascendente.

systemctl enable NetworkManager-wait-online.service

Notas sobre las implementaciones network.target y network-online.target

Nunca debería necesitar hacer que su software dependa de NetworkManager.service o NetworkManager-wait-online.service ni ningún otro servicio específico. En su lugar, todos los servicios de administración de red deben ordenarse antes de network.target y opcionalmente network-online.target .

Un servicio de administración de red basado en un script simple debe finalizar la configuración de la red antes de salir y debe ordenarse antes de network.target y así indirectamente antes de network-online.target .

[Unit]
Before=network.target

[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes

Un servicio de administración de red basado en daemon también debe ordenarse a sí mismo antes de network.target aunque no es muy útil.

[Unit]
Before=network.target

[Service]
Type=simple
ExecStart=...

Un servicio que espera a que finalice el daemon debe ordenarse después del servicio específico y antes de network-online.target . Debería usar Requisite en el servicio daemon para que falle inmediatamente si no se utiliza el servicio de administración de red respectivo.

[Unit]
Requisite=...
After=...
Before=network-online.target

[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes

El paquete debe instalar un enlace simbólico al servicio de espera en wants directorio para network-online.target para que lo atraigan los servicios que quieren esperar a que la red esté configurada.

ln -s /usr/lib/systemd/system/... /usr/lib/systemd/system/network-online.target.wants/

Documentación relacionada

  • http://www.freedesktop.org/software/systemd/man/systemd.special.html#network-online.target
  • http://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/

Notas finales

Espero no solo haber ayudado a responder a su pregunta en el momento en que la hizo, sino que también contribuí a mejorar la situación en las distribuciones ascendentes y de Linux, de modo que ahora pueda dar una respuesta mejor de lo que era posible en el momento de escribir la original. .


Linux
  1. Ejecute el script php como proceso daemon

  2. Ruby script como servicio

  3. Ejecutar script bash desde URL

  4. Ejecutar secuencia de comandos de Python a través de crontab

  5. No puedo demandar al usuario jenkins después de instalar Jenkins

Primeros pasos con systemctl

Cómo ejecutar Shell Script como servicio SystemD en Linux

¿Cómo ejecutar un comando en un script de Shell?

Centos 7:Primeros pasos

¿Cómo ejecutar un script bash?

Systemd:cómo ejecutar el script solo al apagar (no al reiniciar)