La configuración de una ruta estática cada arranque con launchd / plist está fallando

Espero usar launchd para establecer una ruta estática en un servidor en el momento del arranque, ya que no he encontrado una mejor manera de configurar este tipo de red en un servidor.

Mi problema es que el comando parece estar ejecutándose antes de que se configure la pila de red, por lo que estoy buscando consejos sobre cómo cambiar mi plist para que de alguna manera dependa de la configuración del enrutamiento del sistema antes de que se ejecute.

16 de enero 14:39:45 servidor com.company.route.legacy_printer[149]: ruta: escribiendo en el socket de enrutamiento: la red es inalcanzable

16 de enero 14:39:45 servidor com.company.route.legacy_printer[149]: agregar red 10.1.1.1: puerta de enlace 10.0.1.2: no se puede acceder a la red

Recibo este error después de un reinicio, pero cargar la misma plist como root una vez que la Mac ha arrancado funciona bien, así que espero que sea un ajuste fácil o que alguien me indique una mejor manera de obtener una ruta estática de manera confiable después de cada arranque.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.company.route.legacy_printer</string>
    <key>ProgramArguments</key>
    <array>
        <string>/sbin/route</string>
        <string>-n</string>
        <string>add</string>
        <string>-net</string>
        <string>10.1.1.1</string>
        <string>10.0.1.2</string>
        <string>255.255.255.0</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
    <key>AbandonProcessGroup</key>
    <true/>
</dict>
</plist>

Revisé Ejecutar un comando cada vez que Mac se inicia con launchctl/plist y ¿Cómo puedo ejecutar/detener/reiniciar una aplicación automáticamente, en el inicio/inicio de sesión/en otro momento? para llegar tan lejos, pero necesita un empujón adicional para encontrar la dependencia correcta para obtener el momento adecuado para el comando de ruta.

Si puede permitírselo, la solución más fácil podría ser simplemente agregar un par de segundos de retraso.
Estoy tentado a poner 60 segundos de suspensión y una canalización desde que launchd no programa necesariamente los trabajos en el mismo orden. No debería ser un gran problema retrasar las cosas, solo menos limpio que saber cómo construir el activador correcto.

Respuestas (1)

Una breve llamada a scutil debería ayudar a probar si la red está preparada para una interfaz específica en IPv4, lo que debería ser suficiente para determinar cuándo puede agregar una ruta IPv4. El siguiente comando devolverá un 0 si la primera conexión Ethernet tiene una dirección IPv4 viable dentro del período de tiempo de espera predeterminado de 15 segundos.

  • /usr/sbin/scutil -w State:/Network/Interface/en0/IPv4

En su lugar, podría llamar a un script para realizar las pruebas y el enrutamiento, tal vez usando el comando -t para ajustar el tiempo de espera si es necesario. No conozco una forma de sobrecargar los argumentos de lanzamiento para tener todo contenido, pero debería estar bien haber iniciado un script en el sistema de archivos local para realizar esta tarea. Tenga cuidado si no está utilizando en0 para su IPv4 o si desea tener enrutamiento en una interfaz de red diferente a la predeterminada.

Esa secuencia de comandos puede verificar si hay errores, tal vez verificar otras interfaces, así como registrar el éxito y el fracaso usando el loggercomando.

Esa llamada no funcionará en un escenario solo inalámbrico, ya que esos dispositivos generalmente son en1. Solo más énfasis en "[…] probar si la red está preparada para una interfaz específica en IPv4".
Cuando me enfrento a múltiples pasos para iniciar plists, generalmente encuentro que escribir un script y usar el plist para llamar al script funciona mejor.
Buen punto @afragen: las interfaces unidas y los adaptadores Thunderbolt pueden hacer que en0 no sea el nombre de red elegido.