Commit Graph
14682 Commits
Author SHA1 Message Date
kevinveenbirkenbach 68c7555fbe Release 11.5.0 2026-07-04 21:20:44 +02:00
kevinveenbirkenbach 7957eabadc autoformat 2026-07-04 20:29:36 +02:00
kevinveenbirkenbach df1e2041d3 Merge pull request #378 from infinito-nexus/update/docker-image-versions-web-app-semaphore-20260704-91670d7
update(images): update Docker image versions (web-app-semaphore)
2026-07-04 20:09:37 +02:00
infinito-nexus-updater[bot] cf0d0b9047 update(images): update Docker image versions (web-app-semaphore) 2026-07-04 16:50:07 +00:00
kevinveenbirkenbach 2b8edf9011 ruff 2026-07-04 18:24:31 +02:00
kevinveenbirkenbach 9ee4cd0fb9 Merge branch 'main' of github.com:infinito-nexus/core into feature/swarm-nfs
# Conflicts:
#	docs/agents/action/iteration/compose.md
#	roles/svc-db-openldap/vars/main.yml
#	roles/svc-runner/defaults/main.yml
#	roles/svc-runner/tasks/02_cleanup_instance.yml
#	roles/web-app-discourse/meta/server.yml
#	roles/web-app-mailu/tasks/01_core.yml
#	roles/web-app-odoo/tasks/main.yml
2026-07-04 18:16:12 +02:00
kevinveenbirkenbachandClaude Fable 5 63328b488f fix(swarm-tests): carry DOMAIN_PRIMARY into the inventory extras
extend_inventory adds the nfs-server host without host_vars, so the
extras file is its only var source; without the cluster domain it fell
back to the group_vars default and rendered unresolvable
*.infinito.localhost endpoints.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:57 +02:00
kevinveenbirkenbachandClaude Fable 5 f18d909727 fix(service-registry): build the ordered loader list from static role metadata
Per-host rendered applications flip dynamic shared flags with
group_names, so hosts computed divergent ordered lists and Ansible's
result-arrival include registration could deploy consumers before
their engines. The ordered mode now reads the static roles dir; the
per-host when gate in load_service.yml keeps deciding what loads.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:57 +02:00
kevinveenbirkenbachandClaude Fable 5 914ce4054f fix(penpot): make uploaded spec asset bytes unique per run
Penpot dedupes assets by content digest, so re-running the seaweedfs
spec against a persistent bucket wrote no new object and the bucket
check failed. The marker is appended to the PNG bytes after IEND.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:57 +02:00
kevinveenbirkenbachandClaude Fable 5 83c619054b fix(xmpp): fall back to internal auth when ldap is disabled
The no-ldap variant still rendered auth_method: ldap with empty LDAP
bind values, so ejabberd rejected every login. The ldap block is now
gated on services.ldap.enabled with an internal-auth fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:57 +02:00
kevinveenbirkenbachandClaude Fable 5 7d5775ff96 fix(matrix): force compose rendering for the node-local ansible flavor
The ansible flavor deploys matrix as node-local compose even inside a
swarm cluster, but compose_only stripped container_name and friends
because DEPLOYMENT_MODE said swarm, so follow-up exec tasks could not
find the containers. compose_mode_force pins the rendering to compose;
the lookup honors it ahead of the cluster mode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:57 +02:00
kevinveenbirkenbachandClaude Fable 5 371b4f4577 fix(taiga): pre-indent the http healthcheck template
Jinja's indent filter leaves the first line untouched, so the filter
indent(4) wrapper rendered healthcheck: at column 0 and produced
invalid compose YAML. The template now ships pre-indented like its
sibling healthcheck templates; taiga drops the wrapper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 0e644f8599 fix(joomla): stream plugin dir via exec stdin; lint against container cp
container cp needs its source on the node running the docker CLI, so
role_path sources break on swarm workers. The joomla plugin dir now
ships as a controller-side tarball through container exec -i. A new
repository lint forbids docker/container cp in tracked .yml and .sh
files; the six legitimate same-node uses carry justified nochecks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 03ed52eea5 fix(wordpress): ship mu-plugins via exec stdin and unbreak OIDC eval fold
container cp needed the role checkout on the node running the docker
CLI, which does not exist on swarm workers; the mu-plugins now stream
through container exec -i tee with the file read controller-side. The
daggerhart WP-CLI eval line was indented deeper than its folded scalar
block, so YAML kept the newline and bash -lc received no script
argument; realigning the indent folds it back into one command.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 15a8d26ea4 fix(keycloak): move kcadm module and helper to global library paths
Role-local library/ and module_utils/ resolve only inside the owning
role's task scope, so kcadm update tasks invoked from other contexts
in the swarm flow could not find keycloak_kcadm_update. ansible.cfg
already declares ./library and ./utils as the global paths; the filter
plugin and unit tests follow the move. Helper narrows its parse guard
to ValueError.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 de1ac9947b fix(decidim): reach seaweedfs s3 through the public endpoint
Active Storage signs URLs against AWS_ENDPOINT, so it must be the
browser-reachable public endpoint instead of the internal service url.
Compose reaches the canonical s3 api domain via extra_hosts and the
host gateway; swarm resolves it through a new proxy_aliases beacon
field that puts only the canonical domain on the front proxy, keeping
the ambiguous seaweedfs entity alias off shared overlays.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 9e140bef4b fix(moodle): verify password fill before submitting login in specs
Moodle's login page re-renders the form during theme JS init, so the
first fill could land in a discarded DOM node and submit an empty
password. Both specs now retry fill until the field holds the value.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 9cf76e0afa fix(swarm): raise converge retries for jenkins, odoo and pixelfed
First-boot phases (jenkins plugin install, odoo module init, pixelfed
key generation and migrations) exceed the default converge window on
CI runners, so healthy stacks were reported as converge timeouts.
600 retries matches the budget already used by kix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 f82405cc0c refactor(coturn): drop matomo and css service integration entirely
coturn's only web surface is the plaintext gateway health page; there
is never HTML to track or style, so the entries and their variant
overrides were dead configuration. Consumers default to disabled when
the service key is absent, which also supersedes the track: false
opt-out for this role.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 df70060d58 fix(tracking): opt bridgy-fed, coturn and html out of matomo/css injection
These roles serve no injectable HTML (werkzeug 404 without head/body
anchors, plaintext health page), so the playwright tracking check can
never pass; track: false skips the injection expectation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 eeb5e3464f fix(mastodon): resolve hosting node before container health wait
The health wait inspected containers on the deploy host, but swarm can
schedule mastodon services on workers, so the wait always timed out.
Each service now resolves its node and container id via
resolve_host_cid and delegates the inspect loop there; compose passes
the local container id through unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 2bdbd47ab9 fix(espocrm): pin image to 9.3.10 instead of latest
The floating latest tag pulled a broken upstream release mid-run and
made deploys unreproducible; both CI modes failed on the drifted image.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 39de1e4ec5 fix(erpnext): inline gunicorn argv into the backend entrypoint
docker stack deploy does not interpolate $$ back to $, so the swarm
backend received a literal "$$@" and gunicorn never started. Passing
the full command inside the bash -c script removes the interpolation
dependency; compose renders the identical argv as before.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 30afef6bbe fix(resources): entity fallback, short compose service names + SPOT vars
resource_filter now falls back service_name -> entity_name -> hard
default, so entity-level limits keep applying to per-service compose
entries. Compose service names drop the entity prefix (kix, jitsi,
zammad, bluesky); the docker container_name keeps it via compose_only.
A new lint forbids '<entity>-'-prefixed service names.

Service names and internal ports are declared once: vars/main.yml
holds <ROLE>_<SERVICE>_SERVICE constants (container names derived via
entity_name), meta/services.yml declares ports.internal consumed
through config lookups. sso-proxy upstreams stack-qualify the origin
host in swarm because short aliases are ambiguous on shared overlays.
Stale proxy.service_key entries fixed for erpnext/shopware/nextcloud.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 eef3ec316c fix(config): missing-key sentinel must not swallow genuine False leaves
get() signalled a missing key in non-strict mode by returning False, so
every genuinely-False leaf was coerced to the caller's default and
lookup('config', ..., true) could never return False. Moodle's LDAP gate
therefore fired in the ldap-disabled variant round and crashed templating
against never-generated openldap provider credentials. Use a unique
_MISSING sentinel for traversal, keep the default semantics for genuinely
absent keys, and make the moodle gate strict since services.ldap.enabled
is always defined.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 b4badb934c fix(sys-service-loader): keep load order deterministic across hosts
A host-dependent when on the include loop made Ansible register the
included blocks in result-arrival order: workers answering before the
manager pulled their subset (the app's own service, ldap) ahead of the
manager-only engine providers, so consumer stacks deployed before the
engines they converge-wait on (gitea before redis). The condition now
lives inside load_service.yml, every host reports an identical include
set and execution follows the registry order. Hosts that load nothing
also leave the loop with service_loader_preloading reset.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:56 +02:00
kevinveenbirkenbachandClaude Fable 5 6d7bcdf705 fix(swarm-test): mirror the force-shared DB view in the credential closure
derive_includes applies the same shared:true flip as force_shared_db, so
variant rounds that pin a consumer's DB to shared:false keep the central
provider (and its generated credentials) in the include set the deploy
will actually load. extend_inventory derives its manager-placed groups
from the same variant-aware closure instead of a base-config walk, which
re-added pruned provider groups without credentials. matrix.py passes the
round's variant map to the extend step.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 17:05:55 +02:00
kevinveenbirkenbach 3b11c0b259 Merge pull request #358 from kevinveenbirkenbach/feature/web-app-checkmk
feat(web-app-checkmk): add Checkmk role with oauth2-proxy SSO + LDAP
2026-07-04 16:38:34 +02:00
kevinveenbirkenbach fa433d7029 Merge pull request #356 from kevinveenbirkenbach/feature/web-app-semaphore
feat(web-app-semaphore): add Semaphore UI role with OIDC SSO + LDAP
2026-07-04 16:30:43 +02:00
kevinveenbirkenbach 9273895371 Remove variant matrix and bump policy from README
Removed the variant matrix and image bump policy sections from the README.
2026-07-04 11:35:37 +02:00
kevinveenbirkenbach 6dc50af7f3 style(svc-runner): normalize nocheck comment spacing (autoformat) 2026-07-04 11:35:37 +02:00
kevinveenbirkenbachandClaude Opus 4.8 2d485d9bae refactor(web-app-jellyfin): model auth plugins as meta/addons with per-addon specs
Declare the LDAP and SSO auth plugins as proper meta/addons entries
(mechanism/source/version, github-releases update monitoring, url/tag/
md5/guid under config:) and resolve the install parameters in vars from
the addon config instead of hardcoding them.

Move biber's login journeys into the mandated per-addon Playwright specs:
ldap-authentication tests the LDAP manual login, sso-authentication the
OIDC round-trip. Because a Jellyfin user binds to exactly one auth
provider, the LDAP spec skips while SSO is active — the ldap-only matrix
variant owns that path — so a single test user suffices and the specs
stay parallel-safe. playwright.spec.js keeps guest + native admin;
biber's generic persona is opted out via PERSONA_BIBER_BLOCKED.

Also fill the optional meta/info.yml fields (homepage, video, display).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 11:35:37 +02:00
infinito-nexus-updater[bot] bed3e06629 update(images): update Docker image versions (web-app-mediawiki) 2026-07-04 11:35:37 +02:00
infinito-nexus-updater[bot] fb717df691 update(skills): update skills-lock.json to latest versions 2026-07-04 11:35:37 +02:00
infinito-nexus-updater[bot] 4aa9071af1 update(images): update Docker image versions (web-app-erpnext) 2026-07-04 11:35:37 +02:00
infinito-nexus-updater[bot] 7cd5478e86 update(images): update Docker image versions (web-app-opentalk) 2026-07-04 11:35:36 +02:00
infinito-nexus-updater[bot] 2686adfe61 update(images): update Docker image versions (web-app-peertube) 2026-07-04 11:35:36 +02:00
infinito-nexus-updater[bot] 0610838ab6 update(images): update Docker image versions (web-app-prometheus) 2026-07-04 11:35:36 +02:00
dependabot[bot] 47617b6ab2 chore(deps): bump docker/login-action from 4.1.0 to 4.3.0
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.1.0 to 4.3.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/4907a6ddec9925e35a0a9e82d7399ccc52663121...c99871dec2022cc055c062a10cc1a1310835ceb4)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-04 11:35:36 +02:00
dependabot[bot] 99fe8b4b3a chore(deps): bump docker/setup-buildx-action from 4.0.0 to 4.2.0
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 4.0.0 to 4.2.0.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd...bb05f3f5519dd87d3ba754cc423b652a5edd6d2c)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-version: 4.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-04 11:35:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 fc55e325ae docs(agents/role-loop): add hard pre-redeploy verification gate
Before every redeploy that follows a failed deploy, require one explicit
line: either verified-in-container or a named post-deploy-state-exception.
Forbid treating the redeploy itself as the verification, and reject
state-reset friction, logical inference from a prior deploy, and
"looks correct" as reasons to skip. Playwright-spec failures must reset
any polluted state and be green via make compose-playwright first.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 11:35:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 c21245de85 feat(web-app-jellyfin): Jellyfin media server with LDAP + OIDC auth
Bring the full matrix (full-auth / no-auth / ldap-only) green:

- healthcheck: use curl (the image ships no wget)
- install the LDAP plugin from its GitHub release (repo.jellyfin.org is
  unreachable from the deploy network); version/url/md5 live in
  meta/addons/ldap-authentication.yml and reach the script via env
- configure the SSO/OIDC provider through the plugin config API as JSON
  (order-agnostic) instead of hand-written XML, which silently produced
  an empty provider map; set DisablePushedAuthorization + https
  SchemeOverride so Keycloak accepts the redirect_uri
- inject the SSO login button via the branding login-disclaimer + CustomCss
- seed the break-glass admin unconditionally and retry the first-run
  wizard until the admin token resolves (fixes the no-auth variant race)
- Playwright: role-based authenticated-chrome selector for JF 10.11,
  localStorage-clearing logout, and LDAP-before-OIDC ordering (a Jellyfin
  user binds to exactly one auth provider)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 11:35:36 +02:00
kevinveenbirkenbachandClaude Opus 4.8 4bb432db70 feat(web-app-jellyfin): add Jellyfin role with LDAP + OIDC SSO plugins
Implements requirement 030: web-app-jellyfin deploying jellyfin/jellyfin
10.11.11 behind sys-svc-proxy. No external DB (internal SQLite); /config,
/cache, /media named volumes; CPU transcoding. Jellyfin has no native SSO, so
auth is plugin-based (operator chose BOTH): jellyfin-plugin-ldapauth (central
OpenLDAP, all clients incl. native apps) + 9p4/jellyfin-plugin-sso (Keycloak
OIDC, web one-click). files/configure-auth.sh completes the first-run /Startup
wizard (seeds break-glass admin), installs both plugins via Jellyfin's own
/Packages installer, writes the plugin configs, and restarts.

Schemas source-verified against the pinned upstream: Jellyfin v10.11.11, LDAP
plugin v23 (GUID 958aad66-..., flat XmlSerializer config), SSO plugin v4.0.0.3
(OidConfig fields). Honest caveats: the SSO OidConfigs is a SerializableDictionary
(XML shape best-effort), plus plugin ABI compat + the SPA Playwright selectors
are live-deploy-validation items (env-blocked). Each config file is XML-well-
formedness checked before reload.

Validation: make autoformat clean; make test green (lint, test-lint, test-unit,
test-integration 190, test-external).

Refs: docs/requirements/030-web-app-jellyfin.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 11:35:36 +02:00
kevinveenbirkenbach 88f1828908 style(svc-runner): add YAML document start marker (autoformat) 2026-07-04 11:22:12 +02:00
kevinveenbirkenbachandClaude Opus 4.8 02e7584f94 fix(web-app-odoo): restart after auth provisioning so workers drop stale config
The OIDC/LDAP provisioning writes ir.config_parameter rows (web.base.url,
its freeze flag, signup scope) via direct SQL, which the four running
workers never observe: get_param() is ormcached per worker, so a worker
that auto-detected its base url keeps building OAuth redirect_uris that
Keycloak rejects ("Invalid parameter: redirect_uri") while other workers
serve correct links — the partial addon-spec failures in CI. Restart the
container once after provisioning so every worker boots with the frozen
values, and give the web client the same 120s first-render budget that
openModule already documents for cold asset compilation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 11:22:12 +02:00
kevinveenbirkenbachandClaude Opus 4.8 270db0df2f fix(web-app-roulette-wheel): build with npm ci against the app lockfile
The image copied only package.json, so npm install floated transitive
dev dependencies; a new @types/node broke the TypeScript 4.5 build
(ffi.d.ts parse errors) and docker compose build failed the deploy.
Copy package-lock.json and use npm ci for a reproducible graph.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 11:22:12 +02:00
kevinveenbirkenbachandClaude Opus 4.8 ec7f2a4694 fix(web-app-discourse): allow data: script sources in the CSP
Upstream Discourse now loads scripts via data: URIs; without the scheme
in script-src-elem every page load raises securitypolicyviolation events
and the central CSP assertion fails the landing and both OIDC personas
(also failing the coupled nextcloud and wordpress matrix jobs).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 11:22:11 +02:00
kevinveenbirkenbach 0dd5754517 Merge pull request #360 from kevinveenbirkenbach/feature/web-app-jellyfin
feat(web-app-jellyfin): add Jellyfin role with LDAP + OIDC SSO plugins
2026-07-04 10:32:19 +02:00
kevinveenbirkenbach 830fe6476a Remove variant matrix and bump policy from README
Removed the variant matrix and image bump policy sections from the README.
2026-07-04 10:31:43 +02:00
kevinveenbirkenbach 4917e17811 Merge branch 'main' into feature/swarm-nfs 2026-07-04 03:22:09 +02:00