Two bugs kept every mautrix bridge from working: (1) homeserver.yaml.j2 gated app_service_config_files on '{% if MATRIX_BRIDGES | bool %}', but MATRIX_BRIDGES is a list and Ansible's bool filter on a list is always False, so synapse loaded zero appservices and rejected every bridge's as_token (401). Use '| length > 0'. (2) the legacy facebook/instagram bridges interpolated the DB password into the postgres:// URL unencoded; a password with a reserved char crashed mautrix-python with 'Invalid URL: port can't be converted to integer'. URL-encode it like the bridgev2 bridges. Verified by a clean redeploy that recreated the bridge containers and regenerated registrations from the templates: all 5 bridges + synapse healthy.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- keycloak: pin the image from floating 'latest' to 26.6.3 for reproducible deploys.
- sso_proxy: the oauth2-proxy sidecar was pinned to 26.6.3 (the keycloak image
version, mis-copied in 1db235b96), which is not a valid oauth2-proxy tag, so the
CA-trust ca-inject pull failed (manifest unknown) and every sso-proxy-gated app's
compose deploy aborted at the Generate CA trust override handler. Pin to v7.15.3
(live-confirmed pullable).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
web-app-pihole landed on main without the bond importance factor introduced on this branch; the PR merge surfaced 8 enabled+shared services (logout/dashboard/matomo/redis/javascript/prometheus/css/sso) missing bond, failing test_service_bond. Mirror the canonical bond:1 used by every other role's shared services.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
make autoformat output: add YAML document-start marker and normalize
quote/indentation style in meta/info.yml and tasks/01_core.yml. No
semantic change.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Set services.email enabled/shared to literal false in meta/services.yml.
Add corresponding suppressions:
- nocheck: dynamic-flag (flags are now static literals)
- nocheck: email (role has no lookup('email') integration)
Drop the now-static email overrides from meta/variants.yml (a static
base value must not be overridden by a variant) and add javascript
true/false pins to close a pre-existing dynamic-flag variant-coverage
gap that test_coverage flagged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pi-hole v6 returns 308 (HTTP→HTTPS redirect) in addition to the
platform's DEFAULT_OK codes (200, 301, 302). Without 308 in the
accepted status_codes, the webserver health checker would flag
pihole.infinito.example as unhealthy.
- native.spec.js: update button selector from /sign in|login/i to
/log in|sign in/i — Pi-hole v6's submit button text is
'Log in (uses cookie)', not 'Sign in' or 'Login'
- 01_setup.yml: remove pihole setpassword CLI task — Pi-hole v6 blocks
this command when FTLCONF_webserver_api_password is set via env var
('set by environment variable; please unset it to use this function').
Password is now set at container startup via the env var, which is
the v6-idiomatic approach.
Three fixes:
1. guest.spec.js: skip instead of fail when OIDC_ISSUER_URL is unset
(variant-1 has SSO disabled so no Keycloak redirect is expected;
the old expect().toBeTruthy() caused a hard failure instead of skip)
2. playwright.env.j2: only emit OIDC_ISSUER_URL when SSO is proxy-gated
(was unconditionally set, causing native.spec.js to wrongly skip in
variant-1 and oauth2.spec.js/guest.spec.js to fail on missing redirect)
3. compose.yml.j2: Pi-hole v6 compatibility fixes
- Replace WEBPASSWORD with FTLCONF_webserver_api_password (v6 dropped
legacy env vars; WEBPASSWORD is silently ignored in v6)
- Add FTLCONF_webserver_domain={{ domain }} to whitelist the nginx
proxy Host header; Pi-hole v6 FTL returns 403 for unrecognised Host
headers (DNS rebinding protection) — this was causing the baseline
playwright.spec.js to fail with HTTP 403 in variant-1
Playwright's default testMatch only discovers files matching
*.spec.js / *.test.js. test-guest.js, test-oauth2.js, and
test-native.js never matched this pattern and were silently never
executed in any CI variant -- only playwright.spec.js's 2 baseline
tests ever ran (confirmed: 0 occurrences of these files in any
playwright-junit.xml across variant-0/variant-1, sync/async).
Renamed to guest.spec.js, oauth2.spec.js, native.spec.js so the SSO
persona scenarios (Keycloak redirect, admin/biber login, native login)
actually execute and validate the sso-proxy CA trust fix.
oauth2-proxy's singular 'provider-ca-file' flag has a known bug
(oauth2-proxy/oauth2-proxy#2802) and may not be a valid config key on
:latest, causing oauth2-proxy to fail config parsing and crash on
startup. This made nginx's auth_request to sso-proxy return 500 for
every pihole request (HTTP Error 500 on https://pihole.infinito.example/),
blocking even the pre-Playwright readiness check.
provider_ca_files (plural, array of strings) is the documented,
working config key for loading a custom CA for the OIDC provider
connection.
This block was added in an earlier (reverted-in-intent but never
actually removed) attempt and caused a duplicate 'sso-proxy' YAML key
(also defined via sys-svc-compose/base.yml.j2's sso_proxy include),
breaking compose_ca.py's compose config parsing entirely.
The CA trust fix now lives solely in 01_core.yml's lineinfile task,
which patches the rendered oauth2-proxy config file directly -- no
compose.yml changes needed.
- playwright.spec.js: remove duplicated SSO/persona scenarios now
covered by test-guest.js/test-oauth2.js/test-native.js. Reduce to
baseline checks (front page + TLS/HSTS, HTML content-type), matching
the pgadmin pattern.
- meta/main.yml: rewrite description to describe Pi-hole the software
(network-wide DNS sinkhole, DNS/DHCP management, web dashboard)
rather than the role/integration details.
penpot was merged using ports 8041/16506 after our last rebase.
Reassign pihole to 8078 (http) and 16507 (sso) via
infinito contributing network ports suggest.
oauth2-proxy (quay.io/oauth2-proxy/oauth2-proxy) is a distroless image
with no /bin/sh, so the platform's CA-trust wrapper (with-ca-trust.sh,
applied by compose_ca.py for services with a shell) is skipped for this
container. Go binaries ignore SSL_CERT_FILE/REQUESTS_CA_BUNDLE and use
only the OS system cert pool, so on self-signed TLS setups oauth2-proxy
fails OIDC discovery against Keycloak with
'x509: certificate signed by unknown authority'. nginx then falls back
to pihole's native /admin/login instead of redirecting to Keycloak,
breaking SSO entirely in CI and on any self-signed deployment.
Fix: append provider_ca_file to the rendered sso-proxy config after
web-app-keycloak/tasks/sso_proxy.yml renders it and before compose up
runs. oauth2-proxy loads this CA explicitly for the OIDC provider
connection, bypassing the system cert pool entirely.
Scoped to this role: avoids touching the shared
oauth2-proxy-keycloak.cfg.j2 template (would affect every
flavor: oauth2 role platform-wide). No-op on production
(TLS_MODE=letsencrypt).