Commit Graph
14682 Commits
Author SHA1 Message Date
kevinveenbirkenbach bc928de445 Merge pull request #341 from infinito-nexus/update/docker-image-versions-20260624-b65a611
update(images): update Docker image versions
2026-06-25 01:00:21 +02:00
kevinveenbirkenbach 3856981b0b Update services.yml 2026-06-25 01:00:01 +02:00
kevinveenbirkenbach 33ca228a78 Merge pull request #340 from infinito-nexus/update/docker-image-versions-20260624-c93ed59
update(images): update Docker image versions
2026-06-25 00:59:11 +02:00
kevinveenbirkenbachandClaude Opus 4.8 f5564144c0 fix(web-app-matomo): pin matomo to 5.3.2 to match the bootstrap installer
The Playwright bootstrap installer (ghcr.io/kevinveenbirkenbach/matomo-bootstrap:1.1.13, the latest tag) scripts the install wizard against matomo 5.3.2 (its e2e compose). The role ran matomo:latest (currently 5.11.2), whose first-website wizard step changed, so the installer timed out ('first website form submit did not progress to tracking code') after 7 retries and failed the deploy. Pin matomo to 5.3.2 to stop the :latest drift.

Verified: a fresh matomo deploy completes, the bootstrap obtains its token with no installer timeout, and the matomo admin Playwright spec passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 00:34:26 +02:00
kevinveenbirkenbachandClaude Opus 4.8 dba4b2a5d1 test(web-app-nextcloud): harden integration_discourse spec timeouts for deploy-load
When the spec runs during a full variant-3/4 deploy the host is under heavy provisioning load, so the Discourse Vue components render slowly and the cumulative test exceeded its 120s budget at the instance-address field. Raise the overall timeout to 240s and the URL-field and connect waits to 60s. Idle the spec passes in ~24s; this only adds margin for the loaded path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 00:34:26 +02:00
kevinveenbirkenbachandClaude Opus 4.8 6344b33201 fix(web-app-nextcloud): store integration OAuth credentials NC-encrypted via ICrypto
The shared OAuth-credential writer stored the RAW value via IAppConfig::setValueString(..., sensitive: true), but the integration apps (gitlab/openproject/suitecrm/zammad) read back via getValueString(lazy) + ICrypto->decrypt and expect an ICrypto ciphertext. The mismatch made decrypt throw 'Authenticated ciphertext could not be decoded' while rendering the GitLab Personal section, which 500'd the shared connected-accounts page and cascaded into the integration_discourse spec timing out on the missing #discourse_prefs mount. Encrypt each value with ICrypto and store it lazy + non-sensitive, mirroring the apps' own setEncryptedAppValue.

Verified in-container: getAdminClientId() now succeeds, a fresh variant-3 provision no longer returns a 500, and the integration_discourse spec passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 00:34:25 +02:00
kevinveenbirkenbachandClaude Opus 4.8 7b7e99fa8a fix(test-swarm): skip worker-drain chaos for manager-pinned roles
The chaos phase (09 seed -> 10 drain -> 11 assert) assumes the app runs on a
worker it can drain. A role declaring `default_placement: manager` (single-node
DBs, the edge proxy, ...) only ever runs on the manager, so
09_seed_content.sh's `NODE=$(... | grep -vx "$MGR" | head -1)` matched nothing
and, under `set -o pipefail`, killed the script with a silent exit 1 before its
own `[ -z NODE ]` handler could report it.

_context.sh now derives DEFAULT_PLACEMENT_MANAGER from the role's
meta/services.yml and exposes skip_chaos_if_manager_pinned(); 09/10/11 call it
and exit 0 (chaos not applicable) for those roles. 09 also appends `|| true` to
the NODE pipeline so a genuinely-absent worker task on a non-pinned role reaches
the honest failure handler instead of dying silently.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:55:39 +02:00
kevinveenbirkenbachandClaude Opus 4.8 845408045e style(web-app-pihole): yamllint-normalize meta/server.yml
Add the document-start marker and indent the canonical-domains list entry to
match the project's yamllint profile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:55:39 +02:00
kevinveenbirkenbachandClaude Opus 4.8 c768bbf019 fix(env): register INFINITO_DEPLOY_MODE in the static env registry
scripts/meta/resolve/apps.sh reads INFINITO_DEPLOY_MODE (added with the
per-mode skip feature) but the key had no registry entry, failing
tests.lint.filesystem.env.test_used_keys_declared. Add an empty default
to default.env and the key to the static-passthrough STATIC_KEYS so the
CI workflows' compose/swarm value passes through; empty disables the
per-mode skip filtering locally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:55:39 +02:00
kevinveenbirkenbachandClaude Opus 4.8 b82e8cee78 fix(svc-bkp-local-2-device): test the USB backup via a config variant
Replace the empty-config compose deploy failure (assert
BACKUP_TO_USB_MOUNT != "") with a working test path:

- meta/variants.yml: pin non-empty mount/target/source so the CI matrix
  (which applies variants) deploys the plug-triggered backup service. No
  device appears in CI, so the .mount unit only waits and the oneshot
  backup never fires.
- tasks/main.yml: fix the assert typo BACKUP_TO_USB_target -> ..._TARGET.
  The lowercase name was undefined, so the assert would still error even
  with the variant config present.
- vars/main.yml: derive entity_name via get_entity_name and build the
  config lookup path from it instead of hardcoding 'local-2-device'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:55:39 +02:00
kevinveenbirkenbachandClaude Opus 4.8 b12842610c fix(test-deploy): surface python-resolution errors in roundtrip + run.sh
Drop the `2>/dev/null || true` that swallowed the roundtrip skip-check (a failed
get_role_skip silently became "no skip"), and replace `${PYTHON:-python3}` with
strict `${PYTHON}` in roundtrip.sh and run.sh. Both source
scripts/meta/env/load.sh (which sources python.sh, always setting PYTHON or
failing) before the usage, so the fallback was dead code that only masked a
PYTHON-unset setup error as a confusing system-python failure. Now such a
failure aborts loudly under set -euo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:55:39 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9e732ac9fe feat(test-deploy): declarative per-mode skip to opt apps out of discovery
Add a `skip: [compose, swarm]` field on a role's meta/services.yml primary entity
so an app can opt out of the test-deploy matrix per deploy mode, replacing the
hardcoded exclude regex in apps.sh (the "TODO: Remove exclude condition"). The
filter threads through both discovery paths: the CI workflows pass
INFINITO_DEPLOY_MODE -> apps.sh -> `cli meta roles applications type
--skip-mode`, and roundtrip.sh honours the same get_role_skip SPOT per app/mode.

Apply skip: [compose, swarm] to svc-storage-nfs-server and svc-storage-nfs-client
(NFS storage is swarm-only and set up via the cluster inventory, not the matrix)
and web-opt-rdr-www (the previously regex-excluded app).

Covered by get_role_skip and skip_mode-filter unit tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:55:38 +02:00
Alejandro Roman 7890785a6e fix(svc-runner): mkdir /opt/src needs --user root for container cp 2026-06-24 21:14:13 +02:00
kevinveenbirkenbachandClaude Opus 4.8 036b645978 Merge main into feature/026-unified-addon-syntax
Resolve pihole meta conflicts toward the branch: keep the bond:1 service flags and the YAML normalization; merged main carried no unique pihole content (only pre-normalization formatting and the absence of the bond lines). bookwyrm meta auto-merged from main.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 21:10:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 f4fa58c761 style(web-app-pihole): normalize meta YAML (document-start, wrap long description, fix galaxy_tags indentation)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 20:57:47 +02:00
kevinveenbirkenbachandClaude Opus 4.8 5221c9e4d5 fix(web-app-odoo): scope native-login submit to the login form to avoid the navbar search button
The Playwright native-login helper clicked the first match of a broad 'form button[type=submit]' selector, which on the website login page non-deterministically resolved to the navbar search button (oe_search_button, type=submit) instead of the Log in button — an unstable element the click waited on until the 180s timeout, making the admin-login addon specs (account/contacts/crm/project/sale_management) flaky. Scope the selector to the login form (form:has(input[name=login])) and target the Log in button by role (getByRole button, name /log in/i).

Diagnosed from the CI error-context page snapshot (navbar search button before the login form) and the run's flaky pass/fail pattern with all failures at the login step; not yet re-run against a live Odoo deploy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 20:54:01 +02:00
kevinveenbirkenbachandClaude Opus 4.8 bb3d68caa0 fix(web-app-nextcloud): probe integration partners with container inspect instead of exec true
The gitlab/openproject/suitecrm/zammad integration tasks gated their partner-running check on 'container exec <partner> true' (rc==0), which returns rc 127 on partner images lacking a true binary, wrongly skipping the integration. Switch to 'container inspect -f {{.State.Running}}' gated on stdout-trimmed == 'true' — the same probe already shipped for the mattermost integration in 8023e4b8b. inspect never enters the container, so the in-container PATH lookup that broke the old probe is irrelevant.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 20:46:57 +02:00
kevinveenbirkenbachandClaude Opus 4.8 8023e4b8b2 fix(web-app-mattermost): repair nextcloud OAuth coupling probe and gate user-access-tokens on nextcloud presence
The nextcloud->mattermost OAuth provisioning failed because the partner-running probe used 'container exec <mm> true' (rc 127 — no true binary in the mattermost image), which gated provisioning off and left the OAuth app unprovisioned (spec failed on oauth_instance_url=null). Replace it with 'container inspect -f {{.State.Running}}' gated on stdout-trimmed == true, provision the OAuth app via a controller-run script using a short-lived admin PAT, and rewrite the spec as a behavioral connect-redirect check.

Mattermost personal access tokens are now enabled only when the consumer web-app-nextcloud is deployed (services.mattermost.user_access_token_enabled renders from 'web-app-nextcloud' in group_names) instead of being hardcoded on.

Verified: probe live in the DiD stack (inspect running -> rc0, missing -> graceful skip); the user-access-token chain renders True/False via a real Templar (nextcloud present -> True, absent -> False); service-flag integration tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 20:41:19 +02:00
kevinveenbirkenbachandClaude Opus 4.8 593712b501 chore(ci): rename compose-deploy discover job to "Navigate compositions"
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 19:16:19 +02:00
kevinveenbirkenbachandClaude Opus 4.8 24923130ea fix(test-swarm): wire INFINITO_SWARM_TEST_LABEL into the swarm topology env
Every test-deploy-swarm matrix job died at 01_start_nfs.sh with
`INFINITO_SWARM_TEST_LABEL: unbound variable`: the label (consumed by
01_start_nfs.sh, 02_start_swarm_nodes.sh and clean_all.sh) was added to
default.env but never sourced by 00_topology.sh nor exported to the job env.
Broaden the 00_topology.sh source filter to `^INFINITO_SWARM_[A-Z0-9_]+=` (every
swarm key, future-proof) and export INFINITO_SWARM_TEST_LABEL from the
"Load swarm topology SPOT into job env" step.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 19:16:19 +02:00
kevinveenbirkenbachandClaude Opus 4.8 6122213ed2 feat(web-app-matrix): migrate dead mautrix-facebook/instagram to mautrix-meta + gate bridge specs by deployed addon
Legacy mautrix-python facebook/instagram bridges are EOL and fail at runtime (appservice bot masquerade 403). Replace both with the bridgev2 mautrix-meta addon: config, schema credential, variant-2 wiring, and a profile spec with a positive @metabot probe plus an un-bridged-MXID negative control.

playwright.env.j2 now emits MAUTRIX_<bridge>_ADDON_ENABLED only for bridges that are actually deployed, so each bridge spec runs iff its bridge is up (closes the skip-as-green gap) and is telegram-drop aware.

Verified: compose variant-2 deploy failed=0; @metabot registers on the live Synapse; bridge suite green (meta/signal/whatsapp/slack), telegram skips (no API creds).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:45:58 +02:00
kevinveenbirkenbachandClaude Opus 4.8 e8c00c5dca chore(claude): record WebFetch(deepwiki.com) permission
Auto-recorded while a research agent fetched deepwiki.com; added in sorted
position in permissions.allow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 faca8835ea style(web-app-pihole): yamllint-normalize meta and tasks
Pure formatter pass, no behaviour change: add the `---` document marker, indent
the run_after list item, normalize a quote style and drop over-aligned key
padding in 01_core.yml.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 76fac1fbfe fix(lint): filesystem-lint compliance for default.env, Makefile, clean_all.sh
Pre-existing test-lint failures surfaced while greening the suite:
- default.env: move the INFINITO_SWARM_* block into ASC order (it sat before
  INFINITO_LIMIT/LINT instead of after INFINITO_SUBNET) and trim the
  INFINITO_SWARM_TEST_LABEL comment under the 140-char cap.
- Makefile: order act-swarm-clean before act-swarm-down and fold the
  act-swarm-clean comment block to one description line plus Note: markers.
- scripts/tests/deploy/swarm/clean_all.sh: add the executable bit.
- tests/unit/plugins/filter/test_ruby.py: autoformat reflow.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 72aa792db3 style(cli-meta): satisfy ruff in complexity model/render
Two pre-existing ruff findings in the complexity reporter (from an earlier
refactor) blocked `make autoformat` / `make test`: model.py used a bare
hashlib.sha1 for a non-security cache key (S324) and render.py built a list with
a for-append loop (PERF401). Pass usedforsecurity=False and switch to
list.extend.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 8ea4a81ae1 fix(web-app-keycloak): mark 05_realm_import/compose.yml include-gated
The compose-flavour realm-import file runs `compose stop/run/up` and chdirs into
directories.instance, but it is only ever included via the DEPLOYMENT_MODE-driven
`05_realm_import/{{ DEPLOYMENT_MODE }}.yml` switch, so those compose-only calls
never reach a swarm host. Add the
`# include-gated: when: DEPLOYMENT_MODE == "compose"` file-header marker so the
compose-verb / compose-chdir lints treat the file as exempt; it was missing since
the 05_realm_import flavour split.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 5687643b46 style(deployment-mode): positive == 'compose' gates + enforce via lint
DEPLOYMENT_MODE is binary (swarm / compose), so a negated `!= 'swarm'` gate
always means `== 'compose'`. Replace every negated gate across roles/ and
group_vars with the positive form for readability, and add a lint
(tests/lint/ansible/variables/test_no_deployment_mode_negation.py) that forbids
`DEPLOYMENT_MODE !=` in .yml/.yaml/.j2 with a `# nocheck:
deployment-mode-negation` escape.

The compose-verb / chdir / jinja-gate lint guidance messages now suggest the
positive form too; the gate matcher (utils/annotations/task_gate.py) and its
test inputs keep recognising the legacy `!= 'swarm'` so a nocheck-marked
exception is still detected as compose-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 6a0ab683df fix(web-app-gitlab): fold GITLAB_OMNIBUS_CONFIG to one line for the swarm env-file
A swarm docker stack deploy env-file value must be a single physical line; the
multi-line GITLAB_OMNIBUS_CONFIG was read as separate whitespace-named env
entries and aborted the deploy. Add a depth-aware ruby_single_line filter that
collapses the Ruby program to one line (statement-boundary newlines at bracket
depth 0 become ';', newlines inside an open bracket or a string become a space
so hash/array literals like the OIDC omniauth_providers stay valid) and apply it
on the swarm branch only; compose keeps the multi-line value unchanged.

Covered by tests/unit/plugins/filter/test_ruby.py (10 cases incl. a realistic
omnibus config, escaped quotes and nested literals).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 bf512834f8 fix(web-app-erpnext): scale stateless services + widen overlay to /24
In swarm the default replicas=node-count made erpnext's 7 services overflow its
per-stack /28 overlay (16 IPs), so swarm rejected tasks with "ip addresses may
be exhausted". Rather than pin everything to one replica, let the stateless
services scale and size the overlay to fit:

- backend (gunicorn), queue-short/queue-long (RQ workers) and the nginx frontend
  scale to node-count: state lives in MariaDB + Redis, jobs are claimed
  atomically from Redis, and swarm reaches each service via its overlay VIP (the
  published port is ingress, so DOCKER_BIND_HOST binding does not pin them).
- websocket (no socket.io redis adapter, needs sticky sessions), scheduler
  (singleton, else duplicate scheduled jobs) and configurator (one-shot) stay at
  one replica via a single service_replicas = 1 above those blocks.
- widen the erpnext overlay from the packed 192.168.105.176/28 to a fresh
  192.168.214.0/24 (4 scalable x node-count + 3 singletons + VIPs exceed a /28).

Also relocate the configurator to the end of the template: its
{% set docker_restart_policy = 'no' %} is template-scoped and was leaking
restart:no / swarm condition:none onto every long-running service. With it last
the one-shot policy stays scoped to the configurator; depends_on is by name so
file order is safe, and compose is unaffected (compose_replicas emits nothing in
compose mode).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 5101ded6c1 fix(web-app-bluesky): swarm front-proxy routing via service key + internal port
In swarm the bluesky api/web/view vhosts proxied to the wrong upstream: the
front proxy used the app entity name as the service key and resolve_upstream
hard-failed without an internal port (bluesky has no
services.bluesky.ports.internal). Pass the swarm service keys (pds /
bluesky-broker / view) and the internal ports (added to
services.{api,web,view,broker}) per mode, and freeze + re-pass
proxy_internal_port in sys-stk-front-proxy so it survives the nested role loads
and reaches html.conf.j2 (mirrors the existing front_proxy_service_key freeze).

The sys-stk-front-proxy change is compose-neutral (resolve_upstream ignores
internal_port in compose) and a no-op for the 9 non-passing apps (internal_port
stays ''); it also co-fixes web-svc-coturn, whose deliberate
proxy_internal_port: 80 was being lost (coturn has no
services.coturn.ports.internal, so swarm resolve_upstream hard-failed).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 e297e244cb fix(web-app-decidim): swarm-port the rails setup via resolved host node + CID
The setup execs ran 'container exec {{ DECIDIM_CONTAINER }}' (a compose-only
container name) and probed health via community.docker.docker_container_info,
which returns undefined in swarm and broke the until-expr with "object of type
has no len()". Resolve the hosting node + the local container ID per mode
(01_setup/{swarm,compose}.yml, selected by a DEPLOYMENT_MODE-driven include) and
run every exec/inspect delegated to that node against the resolved CID, mirroring
the web-app-matomo resolve pattern. The six rails steps
(migrate/seed/org-host/admin-user/oidc) are logically unchanged; only the
container targeting moved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 70d6c36422 fix(web-app-discourse): skip the compose-style network-connect handler in swarm
The shared-DB 'container network connect' handler attaches discourse to the DB's local container by name, which only exists in compose. In swarm the DB is a service reachable via its overlay alias, so the by-name connect aborts. Gate the handler with DEPLOYMENT_MODE == 'compose'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 870d353fb9 refactor(web-app-keycloak): split realm-import into mode flavors + orchestrator
05_realm_import.yml becomes a thin orchestrator: probe whether the realm exists, then (when import is enabled and the realm is missing) include the per-mode body 05_realm_import/{{ DEPLOYMENT_MODE }}.yml and re-run 04_login. The compose path (stop/import/restart) moves verbatim to 05_realm_import/compose.yml; the swarm scale path moves to 05_realm_import/swarm.yml (was 05b_realm_import_swarm.yml); 05a_realm_import_run.yml is absorbed and removed. Pure structural move, no behavior change; ansible-lint clean (production profile).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 ac63feeea7 fix(web-app-keycloak): re-resolve live CID on swarm reschedule (kcadm TOCTOU)
The role cached keycloak's swarm container ID into KEYCLOAK_LOCAL_CID and reused it for every 'container exec <CID> kcadm.sh'. In swarm the realm-import scale-up reschedules keycloak, so the cached CID dies mid-block; the next kcadm exec aborts with 'No such container' and the module falls into the create branch, surfacing as 'Failed to create Keycloak object' on Update Client settings (15 swarm apps).

Make kcadm resilient: keycloak_kcadm_update.py re-resolves a fresh healthy CID via the swarm service label and retries on 'No such container' (bounded). Quiesce churn first: 05b waits for replicas X/X stable across 3 consecutive polls before re-resolving (stability poll extracted to files/wait_replicas_stable.sh). Add --filter health=healthy to CID resolution in 04_login and 05b. The 26.6.3 pin is unrelated. Swarm-gated; compose runs the module exactly once as before.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 975438dc46 fix(web-app-matomo): self-healing swarm bootstrap + restructure bootstrap tasks
Swarm bootstrap fix: the single 'container service update --force' plus one-shot log-poll aborted on a flaky installer (restart_policy:no never re-runs it). Merge force-update and token-poll into one retried block (each attempt re-forces a fresh installer task, 2-3 attempts); the poll loop lives in files/bootstrap_swarm_poll.sh (script module, vars passed as env).

Restructure: split the bootstrap into mode flavors (05_bootstrap/flavors/{swarm,compose}.yml) and per-mode debug (05_bootstrap/debug/{swarm,compose}.yml), both selected by one DEPLOYMENT_MODE-driven include; renumber 07-10 to 06-09. Swarm-only behavior changes; compose paths unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 72c4a31d05 fix(web-svc-collabora): wait for swarm task to converge before coolconfig exec
In swarm the coolconfig post-deploy exec fired while the task was still Preparing (the shared-service deferred flush skips the convergence gate), so the container id resolved empty and container exec failed with 'invalid container name or ID: value is empty'. Add a swarm-gated wait on the task reaching Running before the exec, mirroring web-app-matomo/tasks/10_resolve_host_cid.yml. Compose unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 8547a800ed refactor(ci): unify deploy tests to compose+swarm, retire INFINITO_DEPLOY_TYPE
Delete the per-deploy-type workflows (test-deploy-local/universal/
workstation) and the redundant act-all/act-app runner scripts (replaced
by make act-workflow). Only compose and swarm deploy tests remain.

Both now discover the full application matrix (every deployment type,
lifecycle-filtered to alpha/beta/rc/stable) instead of just the server/
web-* scope, via apps.sh resolving applications.type without --type.

Retire INFINITO_DEPLOY_TYPE entirely: discovery is now unconditional and
the deploy step never read it. Removed from apps.sh, ci/all.sh, the local
deploy scripts, the two workflows, default.env, the env passthrough list,
the dotenv generator test, the Makefile compose-deploy target, and docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 18:31:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 4698c65ce0 fix(test-e2e-playwright): bound networkidle waits with a 15s timeout
Unbounded `page.waitForLoadState("networkidle")` in the shared admin/seaweedfs
personas and the dashboard simpleicons-card test waited the long default before
the existing `.catch` swallowed it, so apps that never go network-idle
(websocket/long-poll: mailu admin, matomo) made the Playwright run exceed its
1200s task timeout. The result was already discarded, so capping each wait at
15s only bounds it; it matches the timeout already used elsewhere
(web-app-mailu playwright.spec.js, pihole, bluesky).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9dd49283b7 fix(svc-dns-unbound): gate host :53 publish off under DinD
The compose template published the resolver on {{ DOCKER_BIND_HOST }}:53. Under
DinD DOCKER_BIND_HOST is 0.0.0.0 and the host already binds :53 (its own
systemd-resolved), so `compose up` failed with "address already in use". Since
5dad81d3f made svc-dns-unbound required, unbound now deploys in every
mailu-bearing compose stack, turning that latent clash into the dominant
compose CI failure. Consumers reach unbound at UNBOUND_RESOLVER_IP on the
overlay and the readiness probe runs container-internal, so the host publish is
unused under DinD: gate it to non-DinD hosts only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 38784fbd17 chore(claude): allow WebFetch for cdn01.quay.io
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 18:31:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 bc1184dd10 refactor(complexity-cli): split modules, add base/siblings + --unique
Split the single complexity __main__.py into graph (discovery + BFS),
model (ComplexityRow + scoring), render (table/json/string) and cli
(argparse + main); __main__ stays a thin entry point.

Add a 'base' column (sha1 of the role's name unioned with its embedded
services, sorted) so roles in the same mutual-embedding cluster share a
key, and a 'siblings' column listing the rest of that cluster. --unique
keeps one role per base. roundtrip's default app list now passes
--unique to skip redundant same-cluster deploys.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 18:31:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 3a55877a39 refactor(swarm-test): SPOT topology naming in default.env + add act-swarm-clean
Hoist the swarm-test node, network and NFS-export-base names out of the shell
harness (00_topology.sh) into default.env (INFINITO_SWARM_*), so the shell
harness and the Python harness (extend_inventory, write_extras) read one source
instead of each hardcoding the suffixes. 00_topology.sh, extend_inventory.py,
write_extras.py and 01/09/11 now read the SPOT; passthrough.py exports the keys
into the generated .env. 00_topology.sh reads default.env directly (not .env)
because the workflow sources it before make dotenv runs.

Rename topology.sh -> 00_topology.sh (sorts ahead of 01_/02_, the order it is
sourced in) and update all 10 references.

Add scripts/tests/deploy/swarm/clean_all.sh + make act-swarm-clean to reclaim
wedged act-swarm state between runs, label-scoped via INFINITO_SWARM_TEST_LABEL
so it never touches unrelated containers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 18:31:34 +02:00
Alejandro Roman b4cf5a4389 refactor code and best pracites 2026-06-24 18:31:23 +02:00
Alejandro Roman a77b596271 remove async pass in local 2026-06-24 18:31:23 +02:00
Alejandro Roman 1e0ff3706f change test to local.sh approach 2026-06-24 18:31:22 +02:00
Alejandro Roman 114e2338fc tunr test to locally run 2026-06-24 18:31:22 +02:00
Alejandro Roman b1fc2bd64e cache refresh resilient 2026-06-24 18:31:21 +02:00
Alejandro Roman dc26196ec6 remove helper log to fins issue 2026-06-24 18:31:21 +02:00
Alejandro Roman e19cf7276b fix conflicts order with svc 2026-06-24 18:31:21 +02:00
Alejandro Roman 18772ba39f add outputs to find recurrent issue 2026-06-24 18:31:20 +02:00