CluPilotCloud/docker/provisioning-worker.sh

52 lines
2.0 KiB
Bash
Executable File

#!/bin/sh
# Der Tunnel und der Arbeiter, die sich einen Container teilen — aber nicht
# mehr ein Schicksal.
#
# Bis hierher war `php artisan queue:work` der Prozess 1 dieses Containers.
# Damit hing wg0 an seinem Leben: jedes Mal, wenn der Arbeiter endete, endete
# der Container, und mit ihm der Netz-Namensraum, in dem der Tunnel steht.
#
# Ein Arbeiter endet oefter, als man denkt. `--timeout=2100` beendet ihn, wenn
# ein Provisionierungs-Schritt zu lange braucht. Ein fataler Fehler beendet ihn.
# Ein ueberschrittenes Speicherlimit beendet ihn. `queue:restart` beendet ihn
# absichtlich. In allen vier Faellen fielen bisher saemtliche WireGuard-Sitzungen
# mit — die des Betreibers am Telefon genauso wie die jedes Hosts. Von aussen sah
# das aus wie „das VPN ist unzuverlaessig", und die Ursache stand in einer Zeile
# docker-compose.yml, die von Warteschlangen handelt.
#
# Deshalb: wg0 einmal hochziehen, und danach den Arbeiter in einer Schleife
# halten. Faellt er, kommt er wieder — der Tunnel merkt nichts davon.
#
# Der Container endet dann nur noch, wenn Docker ihn beendet. Das ist Absicht:
# ein Arbeiter, der nicht startet, ist ein Fall fuers Protokoll, kein Grund,
# jedem Host die Verbindung abzuschneiden.
set -u
wg-quick up wg0 2>/dev/null || true
# SIGTERM sauber weiterreichen: sonst wartet `docker compose stop` zehn Sekunden
# und schlaegt dann mit SIGKILL zu — mitten in einem Provisionierungs-Schritt.
child=''
stop() {
[ -n "$child" ] && kill -TERM "$child" 2>/dev/null
exit 0
}
trap stop TERM INT
while true; do
php artisan queue:work provisioning \
--queue=provisioning \
--tries=1 \
--timeout=2100 \
--sleep=3 &
child=$!
wait "$child"
code=$?
# Ins Protokoll, nicht ins Nichts: ein Arbeiter, der staendig neu startet,
# ist ein eigenes Problem — es soll nur nicht mehr das Problem des Tunnels
# sein.
echo "[provisioning] Arbeiter beendet (Code ${code}) — wg0 bleibt oben, Neustart in 2 s" >&2
sleep 2
done