mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-10 12:47:04 +00:00
`web-app-mailu/tasks/03_manage_user.yml` and `03b_create_user_token.yml` run `compose exec admin flask mailu user <...>` and `compose exec admin curl http://localhost:8080/api/v1/token` immediately after the existing wait blocks in `02_wait_for_database.yml` (mariadb domain table + admin flask CLI ready). Under CI load the Mailu admin container is reachable on the compose network, but two further runtime preconditions are not guaranteed when those tasks fire: 1. The flask CLI imports succeed (`flask routes` returns 0) before Mailu's admin code has finished establishing the lazy Redis connection that `flask mailu user` needs to commit the user. Symptom (run 26480944120 job 77980186049, infinito-nexus/core run 26480946718 job 77980074367, web-app-suitecrm): redis/connection.py:639 ConnectionRefusedError: [Errno 111] during `flask mailu user no-reply infinito.example -- <pw>`. 2. The admin gunicorn HTTP server on :8080 is not yet listening when `03b_create_user_token.yml` curls `http://localhost:8080/api/v1/ token`. Symptom (run 26480946718 job 77980074254, web-app-fediwall): curl: (7) Failed to connect to localhost port 8080 after 0 ms. Add two further wait blocks after the existing flask-routes wait, both following the same probe/rescue pattern (300-line container log dump on timeout) the file already establishes: * Redis: `compose exec -T redis redis-cli ping` until stdout contains "PONG". Matches Mailu's own healthcheck command verbatim (svc-db-redis/templates/service.yml.j2 line 24) and depends on no extra auth -- Mailu's env.j2 declares no REDIS_PASSWORD and the injected svc-db-redis service runs with no `--requirepass`. * Admin HTTP: `compose exec -T admin curl -sS -o /dev/null -w '%{http_code}' http://localhost:8080/sso/login` until rc=0 and the captured status code matches `^[1-5][0-9][0-9]$`. Any HTTP response (200 / 302 / 404 / 5xx) proves gunicorn is bound; the regex form makes the check robust against an upstream rename of the SSO endpoint. Restructure for clarity: * Split the original `02_wait_for_database.yml` into `02_wait_for_mariadb.yml` (mariadb domain table + flask CLI ready; flask init touches the DB) and `03_wait_for_redis.yml` (Redis PING + admin HTTP :8080; the HTTP API requires Redis-backed sessions). * Bump every subsequent task file by one step (03_manage_user -> 04_manage_user, 04_generate-... -> 05_..., etc.) so the directory order still encodes execution order at a glance. * Update the cross-`include_tasks` references in `01_core.yml`, `04_manage_user.yml` and `04a_manage_user_token.yml`. Also bump the trailing comment in `01_core.yml` that pointed at `03_manage_user.yml` to the new `04_manage_user.yml`. * Hoist the recurring `lookup('container', application_id, 'directories.instance')` (12 occurrences plus a 6x indirection via a per-include `MAILU_DOCKER_DIR` alias previously defined in `01_core.yml`) into a single `MAILU_INSTANCE_DIR` constant in `vars/main.yml`, matching the existing `MAILU_VOLUMES_DIR` shape. All `chdir:` values now resolve to the same string with no extra indirection. `make autoformat` and `make test` (188 tests, 158s) pass on the restructured tree. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>