Commit Graph
14682 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Fable 5 62a46e472f Merge branch 'feature/swarm-nfs' into feature/svc-net-tor
Resolves the runner Dockerfile to the lint-standard Acquire::Retries=3
and keeps the collabora TODO wording; hardens the merged tree for the
stricter lints (apt retries in the tor Dockerfile, shell-or-true
markers, comment cleanup).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 16:27:25 +02:00
kevinveenbirkenbachandClaude Fable 5 3125c5ac03 docs: regenerate role catalogs with the tor onion wiring
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:49:50 +02:00
kevinveenbirkenbachandClaude Fable 5 38fabe226c chore(lint): pathlib + safe-loader noqa for the quality gate
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:48:23 +02:00
kevinveenbirkenbachandClaude Fable 5 d6ed25545d fix(mailu): include cert-deploy unconditionally
The role self-gates on tls.enabled and books itself as executed either
way; the TLS guard at the include suppressed that bookkeeping, so the
required_by verifier failed onion deployments with 'did not execute'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:47:00 +02:00
kevinveenbirkenbachandClaude Fable 5 a881ec26b9 fix(mirror): read the CSP whitelist from its post-merge location
The server.yml split hoisted csp to the top level; the filter kept
reading server.csp.whitelist and silently returned no mirrorable asset
hosts, leaving the mirror vhost whitelist and body rewrite empty.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:43:39 +02:00
kevinveenbirkenbachandClaude Fable 5 56f4dc6400 fix(hlth-webserver): probe domains from the stack host only
Workers have no tor egress resolver (onion probes NXDOMAIN, exit 12)
and serve no clearnet vhosts (ingress answers 404); the check belongs
to OpenResty, which is placed on the manager.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:42:18 +02:00
kevinveenbirkenbachandClaude Fable 5 86ca0fc5f4 fix(msmtp): route swarm infra nodes through the manager ingress
Nodes outside the mesh (nfs, backup) can neither resolve the onion
mail host (no tor resolver) nor reach a locally published SMTP port;
hlth-msmtp died with status=68/NOHOST. The manager's ingress publishes
the mail ports on every node IP.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:39:02 +02:00
kevinveenbirkenbachandClaude Fable 5 f4e8930579 fix(svc-db): give the onion credential tests tor's 120s window
A cold onion connect alone measured 15.7s and tor holds SOCKS streams
up to 120s while fetching the descriptor; the 30s caps cut cold
circuits mid-handshake across all three forwarders and DB clients.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:37:19 +02:00
kevinveenbirkenbachandClaude Fable 5 b2440a7180 fix(swarm-test): deterministic lab networking and lifecycle
Pin node hostnames to their lab-net IPs (dual-homed nodes let Docker
DNS hand workers the cache-net IP while the registry binds only the
lab IP), quiesce the CI compose tor before bootstrap (it publishes the
same onion identity as the cluster), and reap wedged nodes with a
retried SIGKILL so leftovers cannot starve later phases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:35:47 +02:00
kevinveenbirkenbachandClaude Fable 5 f2defbe69f fix(test-e2e-cli): install DB client modules into the PATH python
test.sh spawns its SOCKS forwarders with the bare python3 from PATH -
the baked /opt/venvs/infinito venv on swarm nodes - which neither
sys-pip-install (targets ansible_python_interpreter) nor the system pip
reaches. python3 -m pip hits exactly the interpreter test.sh sees;
--break-system-packages keeps the compose CI system python accepting it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:30:47 +02:00
kevinveenbirkenbachandClaude Fable 5 0bf4397759 fix(test-e2e-playwright): harden the onion wait and retry flaked suites
Cold onion probes need curl to outlive tor's internal 120s descriptor
wait; the recreate path must force-update the tor_tor service in swarm
instead of spawning a competing compose publisher; and a degraded Tor
circuit fails single suites with pure timeouts, so failed roles get one
retry on rotated circuits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:26:56 +02:00
kevinveenbirkenbachandClaude Fable 5 fa2f6eb7e3 fix(sso): pin the onion OIDC issuer via host-gateway in swarm too
The compose-only guard left swarm sso-proxies resolving auth.<onion>
through the embedded DNS, which races container startup and
intermittently hands back a loopback that dead-ends in the task netns
(token exchange refused). The static extra_hosts entry wins in both
modes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:24:08 +02:00
kevinveenbirkenbachandClaude Fable 5 9ae0c7eff6 fix(svc-net-tor): run the node onion natively in swarm
Pin tor to the manager (host-published SOCKS/DNS live on the stack
host), forward HiddenServicePorts and the dnsmasq onion fast path to
the node address instead of loopback (dead-ends in task netns),
tolerate an empty clearnet-upstream capture, detect foreign dnsmasq
drop-ins before claiming the listener, and transfer onion_self_reach
to remote targets via script.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:19:52 +02:00
Alejandro Roman 1915ec115b Merge kevinveenbirkenbach/feature/swarm-nfs into stalwart integration branch 2026-07-22 12:16:40 +02:00
Alejandro Roman 321ca12c60 fix db issues with new implementation 2026-07-22 11:20:15 +02:00
kevinveenbirkenbachandClaude Opus 4.8 f75e93d8ad fix(nextcloud): expand the swarm container resolver through a shell
In swarm mode NEXTCLOUD_CONTAINER_ADDRESS is a subshell expression that resolves the live container id, but the additional-config loader task called container exec via command/argv, which passes the expression literally and fails with 'No such container'. Run it through the shell like every occ task does, and convert the encrypted-appconfig task that carried the same latent argv pattern.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 00:47:09 +02:00
kevinveenbirkenbachandClaude Opus 4.8 0b2d081daf fix(nextcloud): deliver extra config via a native additional-config file
The infinito config loader was appended to the occ-managed config.php with a shell printf while the image entrypoint was still in its post-install write phase; the entrypoint read config.php before the append and wrote it back after, clobbering the loader, so /var/www/infinito extras (oidc_login_provider_url among them) never reached Nextcloud and /apps/oidc_login/oidc answered 500 in the compose e2e job. Install the loader as config/zzz-infinito.config.php after occ reports installed instead: Nextcloud merges config/*.config.php on every read, occ never rewrites those files, and the entrypoint rsync excludes /config/, so no clobber path remains. A file mount was rejected because a non-empty config/ suppresses the entrypoint's base-config copy on first install. The loader now declares $CONFIG directly (additional config files load after unset($CONFIG)), cron gets the /var/www/infinito bind it silently lacked, and the dead include-path vars and host render go away.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 23:22:48 +02:00
kevinveenbirkenbachandClaude Opus 4.8 d2cea2dec3 fix(nextcloud): reach mattermost via DOCKER_REACH_HOST, not localhost
On the DinD swarm nodes glibc resolves localhost to ::1 first and the IPv6 connect to the ingress-published port hangs until timeout, so the mattermost HTTP gate burned 30 attempts while 127.0.0.1 through the ingress DNAT answers fine (measured on an identically shaped node). Point nextcloud_mm_local_url at DOCKER_REACH_HOST, the repo's established reach pattern (gitea, shopware, nextcloud's own config wait), which the DinD nodes override to the bridge gateway; compose keeps 127.0.0.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 23:22:48 +02:00
kevinveenbirkenbachandClaude Opus 4.8 fb78b17901 fix(guide): resolve *.localhost inside the host-mode boot container
The hlth-webserver health service HEAD-requests the deploy's *.infinito.localhost vhosts, but the guide boot container has no resolver mapping for them (no CoreDNS sidecar, no dev-flow dns setup), so the service failed every start and burned 25x60s retries. Install libnss-myhostname on the apt branch and ensure the myhostname NSS module is listed in nsswitch.conf on every distro; it resolves any *.localhost name to loopback where the openresty vhosts answer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 23:22:48 +02:00
kevinveenbirkenbachandClaude Opus 4.8 671a1894f3 fix(user-backup): gate POSIX ACLs on the runtime filesystem type
The ACL include was gated on declared intent (storage.backend != 'nfs'), but the host-mode CI deploy NFSv4-mounts /var/lib/infinito via the nfs-server controller mount while storage.backend stays at its 'local' default, so setfacl ran against nfs4 and failed with EOPNOTSUPP (the Linux NFSv4 client exposes no POSIX ACL xattrs). Probe the fstype of the backups root with findmnt and skip ACLs on any nfs*; the existing chown backup:backup + 0700 already enforce the same posture there.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 23:22:47 +02:00
kevinveenbirkenbachandClaude Opus 4.8 c08040f0e1 fix(nextcloud): gate mattermost OAuth provisioning on the HTTP API
Every readiness signal before the OAuth provisioning (mmctl local mode, the container healthcheck) probes Mattermost's local-mode unix socket, never the HTTP listener, and the provisioning curl was the deploy's first request against :8065, one-shot and unretried. On swarm the ingress-published port can transiently swallow that single request after a concurrent stack deploy reprograms the mesh (observed as curl 28, 30s, 0 bytes). Wait for /api/v4/system/ping on the delegate node before provisioning and retry the provisioning itself.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 19:08:09 +02:00
kevinveenbirkenbachandClaude Opus 4.8 c0ae7109f7 fix(nfs-server): back the export base with ext4 on overlay CI hosts
ganesha FSAL_VFS cannot initialise export roots on overlayfs (name_to_handle_at returns EOPNOTSUPP in init_export_root) and cannot claim tmpfs either (resolve_posix_filesystem ENOENT), so on CI/DinD nodes whose /srv/nfs sits on overlay every client mount fails with 'No such file or directory'. On overlay hosts inside the dev/act/github runtime, mount a 2G ext4 loopback image on the export base before rendering exports; refuse to mount over a non-empty base. Real hosts (RUNTIME=host) are never touched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 19:08:09 +02:00
kevinveenbirkenbachandClaude Opus 4.8 8cc0371116 fix(provision): generate policy-compliant become passwords
The provisioned become password doubles as the Keycloak administrator realm password (user-administrator/meta/users.yml) and the guide flow generated it 64-char alphanumeric, so kcadm set-password failed the realm passwordPolicy specialChars(1) on every fresh single-app deploy. Delegate generate_random_password to ValueGenerator.generate_strong_password, the same class-guaranteeing generator every other realm user already gets via the strong_password filter; the realm policy stays strict. Also drop the commented-out Trusted Hosts block from the realm template.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 19:08:09 +02:00
kevinveenbirkenbachandClaude Opus 4.8 509cd19985 ci(guide): install pyyaml + gettext-base/jq on the Act runner
The catthehacker Act runner image lacks the project's pyyaml plus gettext-base/jq that GitHub's ubuntu-latest ships, so guide_select and the compose deploy step fail under act. Install them in an ACT-gated step (no-op on real CI).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 19:08:09 +02:00
kevinveenbirkenbachandClaude Opus 4.8 aba932b5fa chore(claude): ignore all of .claude except settings.json and .gitignore
Invert the .claude ignore from a per-file denylist to an allowlist so new tool state never leaks into the repo; only settings.json and .gitignore stay tracked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 19:08:09 +02:00
kevinveenbirkenbachandClaude Opus 4.8 cb27ea746e fix(keycloak): default OIDC.CLIENT.SECRET to a generated credential
Guide-provisioned single SSO apps left OIDC.CLIENT.SECRET undefined, so the Keycloak realm client render raised "object of type 'dict' has no attribute 'SECRET'" under ansible-core 2.21. Add an oidc_client_secret credential to the Keycloak schema (auto-generated like administrator_password) and default defaults_oidc.CLIENT.SECRET to it via lookup('config', 'web-app-keycloak', 'credentials.oidc_client_secret', ''); an inventory OIDC.CLIENT.SECRET still overrides through the recursive combine at tasks/stages/01_constructor.yml.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 19:08:08 +02:00
kevinveenbirkenbachandClaude Opus 4.8 ea9ebe0de3 refactor(inventory): rename prod inventory to production
Standardize the private inventory dir on the fully spelled "production" (matching inventories/development). Update the role README template (SPOT) and regenerate 153 role READMEs plus the admin deploy guide; add inventories/production/ to .gitignore, propagated to .dockerignore via make fix-dockerignore.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 19:08:08 +02:00
kevinveenbirkenbachandClaude Opus 4.8 a1f5494f2c refactor(lifecycle): single-source the CI-tested lifecycle envelope
Read INFINITO_LIFECYCLES from default.env via a new tested_lifecycles() helper; derive TESTED_LIFECYCLES, the README overview envelope, the guide-select role filter, and the invokable-lifecycle lint from it. Add "maintained" to the envelope and drop the redundant hardcoded "alpha beta rc stable" strings from workflows, CLI help, and docs.

Guide selection now skips pre-alpha/eol roles (153 -> 117 testable).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 19:08:08 +02:00
kevinveenbirkenbachandClaude Opus 4.8 2ac6c0878d fix(yaml): tolerate ansible-vault tags in the shared loader
The cached YAML loader crashed on the !vault tag with a ConstructorError,
so any lint test that walks the tree and parses every .yml (yaml-syntax,
role/group-vars usage, ...) failed as soon as a vault-encrypted inventory
was present. Register a !vault constructor on SafeLoader that loads the
ciphertext as a plain scalar, mirroring the existing !override/!reset
handling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 12:05:40 +02:00
kevinveenbirkenbachandClaude Opus 4.8 ff463b7b6a fix(ci): pass GHA repo owner into the DNS DinD env generation
Removing the baked .env forces cli.meta.env to regenerate inside the
container; with GITHUB_ACTIONS=true its on-GHA guard aborts (exit 2) unless
GITHUB_REPOSITORY_OWNER / GITHUB_REPOSITORY is set, so .env is never written
and compose-up dies with KeyError: INFINITO_CONTAINER. Forward the owner and
repository (already resolved on the runner) into each per-distro container.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 12:05:39 +02:00
kevinveenbirkenbachandClaude Opus 4.8 43d23ef696 refactor(agents): reorganize operator workflows into i8- skills
Move the operator cheatsheet's copy-paste prompts into per-workflow i8- skills
that each route to their authoritative procedure doc, and reduce the cheatsheet
to a table index plus a usage paragraph, enforced by a new lint. Add skills for
develop, test, quality, refactor, the debug and requirement flows, and
commit / pull-request / push-trigger-pull; rename the iteration skills to
i8-iterate-* and rename the index to i8-help. Wire the active-listening,
dialectic, and robot skills into the flows for clarification, uncertain root
causes, and autonomous execution. Drop the Infinito-specific agent aliases
(alias.md, INFINITO_ALIAS_MD, the make alias agent section, and the two alias
tests); terminal aliases stay.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 11:14:44 +02:00
kevinveenbirkenbachandClaude Opus 4.8 04f424bcb3 fix(ci): regenerate .env per distro inside the DNS DinD
The prebuilt CI image ships a .env generated at build time with the debian
default, and load.sh only regenerates when it is missing, so every distro's
DinD ran with debian's INFINITO_CONTAINER and config regardless of the image.
Remove the baked .env before make compose-up so it is regenerated from the
container's INFINITO_DISTRO, restoring the per-distro behaviour the old
matrix flow had on a fresh checkout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 11:14:44 +02:00
kevinveenbirkenbachandClaude Opus 4.8 34669658ef fix(guide): install systemd in the initless pkgmgr image before booting it
The host-mode guide booted the pkgmgr distro image with --entrypoint
/sbin/init, but that image ships no init at all (it is a package-manager CLI
tool), so runc rejected the container with exit 127. Install systemd in a
throwaway container, commit an image that carries /sbin/init, and boot that
instead. Also read the post-loop readiness state into a variable so a
degraded systemd is not masked by pipefail.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 11:14:44 +02:00
kevinveenbirkenbachandClaude Opus 4.8 36e4d67df2 fix(dns-test): accept a degraded systemd instead of failing under pipefail
The readiness check piped systemctl is-system-running into grep. Because
is-system-running exits non-zero on a degraded system (only running returns
0) and the script runs under set -o pipefail, the pipeline propagated that
non-zero even when grep matched, so the loop never broke and centos, which
settles at degraded with one failed unit, always exited 1 regardless of the
timeout. Read the state into a variable and match it, so a degraded system
is accepted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 11:14:44 +02:00
kevinveenbirkenbachandClaude Opus 4.8 3c81d4ea26 fix(web-app-openproject): run cross-node container exec on the web node in swarm
The db:migrate and settings tasks, and the nextcloud to openproject OAuth
provisioning, ran container exec into the openproject web container from the
manager. In swarm the web replica is scheduled on a worker, so the
manager-resolved container id is not local and the exec fails. Resolve the
web service's hosting node and node-local container id via resolve_host_cid
and delegate every exec to that node, matching the pattern the role's own
03_admin.yml and the mattermost integration already use. The nextcloud
running probe is dropped in favour of the convergence wait.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 11:14:43 +02:00
Alejandro Roman ac101d2efa Merge kevinveenbirkenbach/feature/swarm-nfs into stalwart integration branch 2026-07-21 10:00:17 +02:00
kevinveenbirkenbachandClaude Opus 4.8 b2dd244678 ci(test-guide): upload rescue diagnostics on deploy failure
The guide job had no failure diagnostics, so an unhealthy container such as
decidim failed the deploy with no logs to inspect. Run the recursive
container.py rescue collector on failure and upload the snapshot, mirroring
the deploy-swarm and deploy-compose jobs. In compose mode the collector
descends into the persisted INFINITO_CONTAINER and captures the nested app
containers' logs, inspect and health status.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:59:51 +02:00
kevinveenbirkenbachandClaude Opus 4.8 138d40ac92 fix(ci): use fuse-overlayfs for the DNS DinD inner daemon
The per-distro DNS Docker-in-Docker container runs on an overlay rootfs, so
the inner daemon's default overlayfs snapshotter fails to mount overlay on
overlay ("invalid argument") and docker compose up never brings coredns and
infinito up. Install fuse-overlayfs and write /etc/docker/daemon.json with
storage-driver fuse-overlayfs plus containerd-snapshotter disabled before
starting docker, mirroring the swarm node daemon.json that already runs this
way in CI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:59:51 +02:00
kevinveenbirkenbachandClaude Opus 4.8 52c497a90e docs(web-app-nextcloud): correct the mattermost provisioning script location
The OAuth-app provisioning runs host-side on the mattermost node (delegated),
reaching the REST API via the published localhost port, not inside the
container. Fix the now-inaccurate header comment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:59:51 +02:00
kevinveenbirkenbachandClaude Opus 4.8 b44fea8470 fix(web-app-nextcloud): provision the mattermost OAuth coupling on swarm
The Mattermost <-> Nextcloud OAuth provisioning ran its container probe and
mmctl steps on the manager, but in swarm the mattermost task runs on a
worker, so the probe found no container and the whole coupling was skipped.
The connect button then stayed disabled and the integration e2e timed out.

Resolve the mattermost hosting node and node-local container id via
resolve_host_cid and delegate every mmctl step, and the OAuth-app
provisioning, to that node, mirroring the pattern web-app-mattermost's own
role uses. The OAuth-app step keeps running bash on the host because the
image has no shell, but now on the mattermost node so its localhost URL
resolves. Drop the now-unused running probe and the
NEXTCLOUD_MATTERMOST_CONTAINER_ADDRESS var.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 6768591afc refactor(dns-test): drop the redundant INFINITO_PULL_POLICY shell default
parallel.sh already passes INFINITO_PULL_POLICY=always into the DinD
container, so the shell-side "${INFINITO_PULL_POLICY:-always}" default is
redundant and a second source of truth that contradicts default.env's
INFINITO_PULL_POLICY=never. Read the value from the environment; default.env
stays the single default.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 402b949b77 refactor(svc-storage-nfs-server): shorten the NFS default task name
The task name exceeded the 80-character limit; drop the parenthetical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 b556995895 fix(web-app-openproject): justify the pgdata dummy nfs:false
The nfs-false-data-loss lint requires every nfs:false to argue why no data
is lost on a node-local volume. The pgdata dummy holds nothing and is
re-provisioned on redeploy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 68666d72b4 fix(web-app-bigbluebutton): lint-clean the etherpad postgres DB wiring
Quote ETHERPAD_DB_PASSWORD with dotenv_quote so the generated env file is
mode-safe (the passwords lint requires it; compose strips the outer quotes,
swarm passes the value verbatim). Switch the etherpad entrypoint wrapper
mount from a single-file bind to a docker config, which swarm can place on
any node; the meta-volume lint rejects single-file binds as swarm-fragile.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 84d58d71eb fix(web-app-xwiki): wait out the reboot before asserting superadmin auth
After a rolling swarm redeploy xwiki reboots for roughly 356 seconds while
Solr and the extensions initialise. The superadmin auth probe only retried
for about 75 seconds, expiring mid-boot, so the downstream fail block
tripped and the job failed. Retry for up to 600 seconds and gate the loop on
a 200, so the probe waits out the reboot; a genuinely dead superadmin still
fails loudly through the existing fail block.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 e589702fd5 fix(web-app-openproject): make the pgdata dummy a named volume for swarm
The pgdata dummy mount used a host-path bind whose source directory is only
created on the manager. In swarm a worker scheduling the proxy replica finds
no such directory and rejects the task, so the chaos routine sees no worker
task and openproject fails. Use a named docker volume instead; it is
provisioned on whichever node runs the service. nfs: false keeps the
throwaway path off NFS backing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 d5f13b32bb fix(svc-storage-nfs-server): default the mount server to this host when unset
storage.nfs.server defaults to an empty string, so on a single-node or
self-mount deploy nfs_client_src builds the source as ":/srv/nfs/..." and
mount.nfs4 fails with "Failed to resolve server :". Default the server to
this node's own address when unset; the exporter is also the mount target
in that topology. The guard fires only on an empty server, so an explicitly
configured server is never overridden.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 fc1b35e9a7 fix(guide): unmask systemd-logind before enabling root linger
The host-deploy base image ships systemd-logind masked, so loginctl
enable-linger cannot activate org.freedesktop.login1 over D-Bus and the
guide fails after the image pull with "Could not activate remote peer".
Unmask and start logind before enabling linger; it is a no-op where logind
is already active.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 9c25f00cc3 fix(web-app-bigbluebutton): move etherpad DB off churning redis to postgres
Etherpad's ueberdb backend was pinned to the bbb redis service. During a
deploy that redis churns (RestartCount=2), taking etherpad's DB with it, so
etherpad crashes (RestartCount=1) and the health-container job fails. bbb's
own postgres stays stable (RestartCount=0) through the same deploy.

A boot wrapper rewrites settings.json dbType redis to postgres before the
upstream entrypoint runs; env carries the connection values; the etherpad
database is provisioned in the postgres password-sync task; compose adds a
postgres dependency. The ep_redis_publisher pub/sub client stays on redis
(its failures are non-fatal).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00
kevinveenbirkenbachandClaude Opus 4.8 fb731041f4 refactor(ci): extract fork-prereq gate to a script; drop gate jobs
Move the inline fork-prerequisites result assertion out of the
fork-prereqs-ready job into scripts/github/gate/fork_prereqs.sh (result
passed via the RESULT env var; the job now checks out the repo).

The staged diff also drops the code-quality-gate and test-install-gate
aggregator jobs and wires their members (lint, test, security-codeql,
test-install-make, test-install-pkgmgr) directly into the done job's needs,
which still hard-fails on any upstream failure or cancellation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 03:01:35 +02:00