Commit Graph
8 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5 972c8764fe fix(integrations): probe the node-local port, not the public domain
Four readiness probes waited on lookup('domain', <app>) port 80 -- a
publication identity used as a machine address. With svc-net-tor deployed
that name is onion-only, because exclusive: true replaces the clearnet
domain rather than adding to it (utils/cache/domains.py).

Nextcloud 5 then burned its full 600s on zammad.helpdesk.<onion>:80. The task
carries no delegate_to but inherits apply: delegate_to: NEXTCLOUD_HOST_NODE
from 02_manager_ops.yml:46-50, which propagates through nested includes, so it
ran on a worker. svc-net-tor is placement: manager, so that worker had no
.onion split-DNS, no TransPort redirect and no :80 listener. wait_for swallows
socket.gaierror in a bare except and retries, so an unresolvable name is
indistinguishable from a slow service -- it just burns the timeout.

Point the probes at DOCKER_REACH_HOST and the service's own
ports.local.http instead. No name resolution, so the onion replacement cannot
reach it; node-local, so the inherited delegation stops mattering; and it hits
the service's own listener rather than the shared front proxy, which is what
the probe was supposed to measure in the first place.

Verified on the failing run's artifacts that this is node-independent in
swarm: zammad_railsserver.1 ran only on mgr-01, yet dockerd listens on *:8077
on all three nodes -- the ingress mesh. Only svc-prx-openresty and svc-net-tor
publish with mode: host; every other role, these four included, goes through
ingress.

Same swap for openproject, suitecrm and wordpress->discourse, which had the
identical construct.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 13:39:05 +02:00
kevinveenbirkenbachandClaude Opus 5 31c3a84eac refactor(web-app-wordpress): group the install task files under a shared directory
The structure lint requires files sharing a name prefix to live in a
directory of that name. tasks/utils/install_plugin.yml and
tasks/utils/install_mu_plugin.yml violated that from the moment they
landed in 4d9bf6da3; move both into tasks/utils/install/ and repoint the
three includes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 02:13:27 +02:00
kevinveenbirkenbachandClaude Opus 5 2f7cd543ad fix(web-app-wordpress): run every addon through its declaration
The deploy died in the drill's second pass on `wp plugin install activitypub
--activate`: the first pass had installed it, the DR restore put the tree back,
and wp-cli refuses to unpack onto an occupied directory. `--force` would have
made that green by overwriting whatever the restore produced - on a branch about
NFS-backed volumes, the worst possible place to paper over a restore. The probe
keeps it red instead: `wp plugin is-installed` answers from `get_plugins()`
alone (verified in the pinned wp-cli phar: `Fetchers\Plugin::get()` iterates
`get_plugins()` and nothing else), so a tree WordPress cannot parse still
reaches the install and still fails on folder_exists.

Activation moves into its own step. Chained to `install --activate`, wp-cli sets
chained_command and skips the result check, so an activation failure returns 0
today.

The same install path now serves both call sites; the addon hook carried its own
copy, which is why one defect needed fixing twice.

mu-plugins follow the declaration the way discourse already does. The loop reads
`mechanism: mu_plugin` from meta/addons/ instead of spelling two filenames, which
is how `infinito-http-ca-trust` shipped undeclared while `infinito-oidc-rbac-mapper`
carried a `required: true` that nothing evaluated. Both install paths honour that
field now - a required addon aborts the play, an optional one warns and is
skipped - which is the first place in the repo to read it.

Three guards, because the loop replaced two guaranteed literals: an assert that
every required addon is claimed by some install path, a lint pairing each
vendored addon with its shipped file in both directions, and the spec the addon
contract demands.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 02:13:25 +02:00
kevinveenbirkenbachandClaude Fable 5 f5911e1ec4 fix(web-app-wordpress): repair discourse addon exec and gate keycloak env on sso
Three defects broke the wordpress jobs in both modes:

The wp-discourse shell tasks used folded scalars whose continuation
lines were indented deeper than the first, so YAML preserved the
newlines and the shell ran three separate commands instead of one
(--path=... reached the host shell as its own command). Align the
continuations so the fold collapses to a single line.

The discourse exec address came from container_address, which expands
to a resolve subshell under swarm; the argv-form command task passed it
verbatim to docker as a container name. Discourse is launcher-based and
its container is literally named 'discourse' in both modes, so use the
services.discourse.name config lookup instead.

The playwright env rendered keycloak credential lookups uncondition-
ally, crashing the sso-disabled variant; gate them on
lookup('service','sso').required like the sibling flags, and drop
narration comments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 15:34:28 +02:00
kevinveenbirkenbachandClaude Opus 4.8 96aa7784b6 feat(sys-svc-compose): scale all task timeouts via TIMEOUT_FACTOR lookup
Add a 'timeout' lookup plugin that returns round(base * TIMEOUT_FACTOR)
(group_vars default 1, so value-identical to the old literals). One knob
in group_vars stretches every wait in the stack for a slow uplink:
TIMEOUT_FACTOR: 2 doubles them all.

- plugins/lookup/timeout.py + unit tests (identity, factor scaling,
  string coercion, error paths).
- group_vars/all/17_resource.yml: TIMEOUT_FACTOR: 1.
- Convert all 34 literal 'timeout:' task keywords / module args across 25
  task+handler files to "{{ lookup('timeout', <base>) | int }}".
- tests/lint/repository/yaml/test_timeout_uses_lookup.py enforces the
  lookup in every task/handler timeout (opt-out: # nocheck: timeout-lookup).
- swarm.yml pre-deploy build handler: add the missing timeout (same
  network-build hang vector as compose.yml's Build compose).
- Drop 13 pre-existing narration comments in the touched files (comment
  lint enforces whole-file on any edited file).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-03 13:57:30 +02:00
kevinveenbirkenbachandClaude Opus 4.8 cddb0dc59b feat(lint): require emoji-prefixed task/step/job names + convert existing
Add tests/lint/repository/test_name_emoji_and_length.py: every Ansible task
name and GitHub Actions workflow/job/step name must start with an emoji (first
char not 0-9/A-Za-z) and be <= 80 chars.

- emit emoji names at the source: cli/build/include generator now writes
  "🔧 setup <app>" / "🚿 flush handlers after <app>" so generated
  tasks/groups/*-roles.yml satisfy the convention too
- convert existing task/step/job/workflow names to emoji-prefixed, choosing a
  task-fitting icon per action (📦 install, ✅ ensure, 🔍 probe, 🥾 bootstrap,
  🚀 deploy, 🧩 service-module load, ⬇️ checkout, 📂 include-routines, ...)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 22:45:06 +02:00
kevinveenbirkenbachandClaude Opus 4.8 36ebf34b64 Merge branch 'main' into feature/swarm-nfs
Resolve 69 conflicts across ~70 files: union main's image-version bumps and new service fields (bond, resource limits) with the swarm branch's default_placement / NFS / IS_STACK_HOST config; retire the three per-deploy-type test workflows main still edited (consolidated into compose+swarm); adopt main's run-once 01_core dispatchers while re-applying each role's swarm guard. Fix the post-merge lint surfaced by main's stricter rules: bond + resource-budget keys, container-exec stack-host gating + resolver routing, leaky/dead proxy vars, suitecrm once-flag, xwiki variant nocheck, nextcloud oversized-block to gated include, matrix-mdad capped at 3g. make autoformat clean, make test green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 17:13:55 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9a4701370a refactor(addons): move wordpress addon tasks to tasks/addons; remove bogus xwiki matomo addon
Relocate the wordpress per-addon task files from tasks/plugins/ to tasks/addons/ (pure renames) and repoint tasks/main.yml, giving every role a uniform tasks/addons/ layout. Remove roles/web-app-xwiki/meta/addons/matomo.yml: matomo is provided as a service via services.matomo, not an Extension-Manager extension, and the org.xwiki.contrib:matomo extension does not exist in the nexus catalog (install plan failed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 00:16:54 +02:00