Commit Graph
14682 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5.5 81e2be2204 fix(dev-python): hand requires-python to the remote script with a valid backreference
76adaeb9e8 wrote the regex_search group reference as '\1' inside the folded
task scalar. Jinja unescapes string literals, so the filter received \x01,
rejected it as an unknown argument and failed the dev-python task on every
remote host. The literal is now '\\1', and the unit test renders the task's
environment expression the way Ansible does instead of only checking that
the variable is named.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 15:55:22 +01:00
kevinveenbirkenbachandClaude Opus 5.5 76adaeb9e8 fix(dev-python): take the supported Python range from requires-python
bf9c5be173 capped the bootstrap at 3.14 with constants inside install.sh, a
second copy of the range pyproject.toml already declares. requires-python is
now the single source (>=3.11,<3.15): install.sh derives its floor and cap
from it, in the repository or, on a remote host where the script runs alone,
from INFINITO_PYTHON_REQUIRES that the dev-python role reads from the same
file; any other form fails loudly. The Dockerfile copies pyproject.toml
before the bootstrap, and pip now refuses 3.15 for the package as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 15:42:34 +01:00
kevinveenbirkenbachandClaude Opus 5.5 bf9c5be173 fix(dev-python): cap the bootstrap Python at the newest minor ansible-core supports
Fedora 45 defaults to Python 3.15. ansible-core 2.21, which the unpinned
`ansible` extra still resolves to (ansible 14.5.0 pins ~=2.21.5), calls
dataclasses._is_type, which 3.15 removed, so the Workspace (fedora:latest)
job died before the first playbook (run 41491308729).

install.sh now picks and installs the highest Python between
PYTHON_MIN_MINOR and PYTHON_MAX_MINOR (3.11 to 3.14) on apt, rpm and
pick_python_bin, and fails loudly when only newer interpreters exist. On
Fedora 45 it installs python3.14. Raise PYTHON_MAX_MINOR once ansible ships
ansible-core 2.22.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 15:06:41 +01:00
kevinveenbirkenbach d807d1b6b4 Merge pull request #1343 from infinito-nexus/update/docker-image-versions-web-app-matrix-20261102-0d5ec80
update(images): update Docker image versions (web-app-matrix)
2026-11-02 18:27:01 +01:00
kevinveenbirkenbach 9d92726412 Merge pull request #1344 from infinito-nexus/update/docker-image-versions-web-app-seaweedfs-20261102-1736cb5
update(images): update Docker image versions (web-app-seaweedfs)
2026-11-02 18:26:43 +01:00
infinito-nexus-updater[bot] a90fe6a5de update(images): update Docker image versions (web-app-seaweedfs) 2026-11-02 17:16:11 +00:00
infinito-nexus-updater[bot] c59c723eca update(images): update Docker image versions (web-app-matrix) 2026-11-02 17:16:05 +00:00
kevinveenbirkenbach ca21cdd2fd Merge pull request #1339 from infinito-nexus/update/docker-image-versions-web-app-socialhome-20261102-feb553b
update(images): update Docker image versions (web-app-socialhome)
2026-11-02 17:51:46 +01:00
kevinveenbirkenbach f96b5aabba Merge pull request #1342 from infinito-nexus/update/version-sources-web-app-zammad-20261102-2de8475
update(versions): update pins with a declared source (web-app-zammad)
2026-11-02 15:02:47 +01:00
kevinveenbirkenbach 9e49c1d67e Merge pull request #1341 from infinito-nexus/update/version-sources-web-app-stalwart-20261102-6da48bb
update(versions): update pins with a declared source (web-app-stalwart)
2026-11-02 15:02:20 +01:00
kevinveenbirkenbach f6a378b35b Merge branch 'main' into update/version-sources-web-app-stalwart-20261102-6da48bb 2026-11-02 15:02:07 +01:00
kevinveenbirkenbach fd3e0b9a33 Merge pull request #1340 from infinito-nexus/update/docker-image-versions-web-app-stalwart-20261102-48eb899
update(images): update Docker image versions (web-app-stalwart)
2026-11-02 15:01:19 +01:00
kevinveenbirkenbach f707036771 Merge pull request #1338 from infinito-nexus/update/docker-image-versions-web-app-gitea-20261102-96944f8
update(images): update Docker image versions (web-app-gitea)
2026-11-02 15:00:53 +01:00
kevinveenbirkenbach cb905638a2 Merge pull request #1337 from infinito-nexus/update/repository-refs-pkgmgr-20261102-da915bf
update(repos): bump git refs to latest semver tags (pkgmgr)
2026-11-02 15:00:36 +01:00
infinito-nexus-updater[bot] aaaa26474a update(versions): update pins with a declared source (web-app-zammad) 2026-11-02 13:47:12 +00:00
infinito-nexus-updater[bot] ed8a0b660b update(versions): update pins with a declared source (web-app-stalwart) 2026-11-02 13:47:06 +00:00
infinito-nexus-updater[bot] dff2e91592 update(images): update Docker image versions (web-app-stalwart) 2026-11-02 13:47:01 +00:00
infinito-nexus-updater[bot] e6032b3e37 update(images): update Docker image versions (web-app-socialhome) 2026-11-02 13:46:56 +00:00
infinito-nexus-updater[bot] 75cf9d7f41 update(images): update Docker image versions (web-app-gitea) 2026-11-02 13:46:49 +00:00
infinito-nexus-updater[bot] 67b18ee3a8 update(repos): bump git refs to latest semver tags (pkgmgr) 2026-11-02 13:46:46 +00:00
kevinveenbirkenbach 562052a032 Merge pull request #1330 from infinito-nexus/fix/ci/runner-disk-nvme/1329
fix(ci): put containerd, Docker and swap on the runner's empty spare disk
2026-11-02 14:46:11 +01:00
kevinveenbirkenbachandClaude Opus 5.5 2d7bf740b0 fix(ci): put containerd, Docker and swap on the runner's empty spare disk
The small GitHub runner shape (AWS, 72G root) ran out of disk in swarm and compose rows (#1329: WordPress#2 of run 41261531965, Nextcloud#6 and #7 of run 41262286962) while an empty instance-store disk nvme1n1 sat unused. mount_spare_disk.sh formats and mounts it at /mnt, but only on a GitHub-hosted runner outside act, and only a whole unpartitioned disk without any signature, mount or swap use of at least 75G; every decline leaves a notice. relocate_docker_dataroot.sh then bind-mounts /var/lib/containerd from the spare disk and moves the Docker data-root to /mnt/docker-host (not /mnt/docker, which is the nested daemon's volume that dedicated.sh wipes). It refuses before stopping anything when images, volumes, build cache, foreign containerd namespaces or shims exist or daemon.json is unreadable, and rolls back the bind mount and daemon.json on any later failure or cancel. Swap goes on / once containerd lives on /mnt, dump_state.sh logs disk size, model and free space per storage root, and the swarm watchdog samples / and /var/lib/containerd every 10 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:31:02 +01:00
kevinveenbirkenbach 076eea636b Merge pull request #1328 from infinito-nexus/update/repository-refs-pkgmgr-20261101-99cab09
update(repos): bump git refs to latest semver tags (pkgmgr)
2026-11-01 02:43:47 +01:00
infinito-nexus-updater[bot] ddda63edb6 update(repos): bump git refs to latest semver tags (pkgmgr) 2026-11-01 01:41:17 +00:00
kevinveenbirkenbach 35fd939957 Merge pull request #1327 from infinito-nexus/fix/dotenv-smoke/real-env-untouched/1188
fix(tests): keep the dotenv smoke test out of the repository .env
2026-11-01 02:34:16 +01:00
kevinveenbirkenbachandClaude Opus 5.5 16de8ed3a0 fix(tests): keep the dotenv smoke test out of the repository .env
TestDotenvSmoke ran `python -m cli.meta.env` with cwd=PROJECT_ROOT and no
--output, so every make test rewrote the real .env with defaults: as root
inside the container, with a fresh INFINITO_CACHE_PACKAGE_ADMIN_PASSWORD
and possibly another INFINITO_DOMAIN.

The test now writes to --output <tempdir>/.env and asserts that the
repository .env keeps its inode and mtime. A marker line in a worktree .env
vanished on every run of the old test and survives the new one; without
--output the new assertion fails with "The smoke run replaced the
repository .env".

Fixes #1188

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 02:26:03 +01:00
kevinveenbirkenbach bc4f6a4106 Merge pull request #1323 from infinito-nexus/update/repository-refs-pkgmgr-20261031-82d6480
update(repos): bump git refs to latest semver tags (pkgmgr)
2026-10-31 17:28:47 +01:00
infinito-nexus-updater[bot] 1354f277ae update(repos): bump git refs to latest semver tags (pkgmgr) 2026-10-31 16:24:19 +00:00
kevinveenbirkenbach 3a72ef96cc Merge pull request #1322 from infinito-nexus/fix/sys-svc-webserver-core/access-log-no-tokens/1192
fix(sys-svc-webserver-core): keep URL tokens out of the openresty access log
2026-10-31 17:23:27 +01:00
kevinveenbirkenbach 1cd9fef208 Merge remote-tracking branch 'origin/main' into fix/sys-svc-webserver-core/access-log-no-tokens/1192 2026-10-31 14:33:11 +01:00
kevinveenbirkenbach df5689d70d Merge pull request #1320 from infinito-nexus/update/docker-image-versions-web-app-socialhome-20261031-b84d86f
update(images): update Docker image versions (web-app-socialhome)
2026-10-31 14:29:26 +01:00
kevinveenbirkenbachandClaude Opus 5.5 8d6040948c fix(sys-svc-webserver-core): match token routes on the decoded path
The access-log map read $request_uri, which keeps percent-encoding and
repeated slashes. A request such as /%70assword/reset/<token>,
/password%2Freset/<token> or //password//reset/<token> missed the
token-route expression, fell through to the plain-path branch and was
logged with the token in plain text, while the backend still decoded it
to its reset handler.

The map now reads $uri: decoded, slash-merged (merge_slashes is not
overridden anywhere) and without the query string, so the existing
expressions match every spelling of a token route. Trade-off: after an
internal redirect the log shows the internal URI; with the generic
vhost's error_page (ws_generic.conf.j2) a 5xx line now carries
/500.html instead of the client's path, with the status unchanged.
Nothing in the repository parses the proxy access log.

The unit test resolves the map against the variable it reads, modelling
$uri as nginx builds it, and adds the three encoded spellings above.
Negative control: with the map back on $request_uri, exactly those three
cases fail (3 failed, 8 passed).

Reported by CodeRabbit on #1322.

Part of #1192

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 12:46:31 +01:00
kevinveenbirkenbach dbcc78e376 Merge remote-tracking branch 'origin/main' into fix/sys-svc-webserver-core/access-log-no-tokens/1192 2026-10-31 10:40:44 +01:00
kevinveenbirkenbachandClaude Opus 5.5 10d2b11cc9 fix(sys-svc-webserver-core): keep URL tokens out of the openresty access log
The front proxy logged the full request line: production had no
access_log, so nginx fell back to `combined` ($request, Referer,
$remote_user), and the debug format logged $request and the Referer.
Query-string tokens (?access_token=, ?key=, ?token=) and token routes
such as /password/reset/{token} and /i/confirm-email/{user}/{random}
ended up in plain text in the container log.

nginx.conf.j2 now declares a map from $request_uri to
$infinito_access_log_path:

- the path is written without the query string;
- the segments after a known token route (password/reset,
  password-reset, reset-password, confirm-email,
  lostpassword/reset/form, email-login, activate-account; matched
  case-insensitively at any depth) are written as [redacted], so the
  request, its status and timings stay visible without the token.

Both modes write an explicit access_log to /dev/stdout:

- production uses the new `redacted` format, laid out like `combined`
  (remote address, time, "method path protocol", status, bytes,
  user agent) with Referer and basic-auth user written as "-", so
  combined-style parsers keep working;
- debug keeps its fields (host, timings, upstream time, lengths,
  X-Forwarded-For, scheme, server name) but logs
  "method path protocol" instead of $request and drops the Referer.

The path comes from $request_uri instead of $uri so internal rewrites
(error_page, try_files) do not replace the path the client requested.
Nothing in the repository parses the proxy access log (Wazuh, the
health checks and the Prometheus log_by_lua metrics do not read it),
so no consumer needs to change. The error log still carries
`request:` and `referrer:` on error-level entries; that is outside
this change.

A unit test renders nginx.conf.j2 in both modes and asserts that every
access_log uses a format declared there, that no format references
$request, $request_uri, $args, $query_string, $is_args, $arg_*,
$http_referer or $remote_user, and, by resolving the map as nginx does,
that query strings are dropped, token routes are redacted and
lookalike paths stay unchanged.

Verified live with web-svc-html in production mode (deploy failed=0, so
openresty accepted the config). A probe request to
/password/reset/<probe>?token=<probe> was logged as
"GET /password/reset/[redacted] HTTP/1.1" 404 62 "-" "curl/8.14.1",
and /plain/page as "GET /plain/page HTTP/1.1". Negative control: the
same request against the previous config logged the probe path token
and the query token in plain text. The debug format with the fix is
covered by the unit test only.

Closes #1192

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 10:40:40 +01:00
kevinveenbirkenbach 9008b4435e Merge pull request #1321 from infinito-nexus/update/docker-image-versions-web-svc-logout-20261031-b634bf4
update(images): update Docker image versions (web-svc-logout)
2026-10-31 10:39:45 +01:00
infinito-nexus-updater[bot] c471346ea1 update(images): update Docker image versions (web-svc-logout) 2026-10-31 09:14:06 +00:00
infinito-nexus-updater[bot] c7d964e803 update(images): update Docker image versions (web-app-socialhome) 2026-10-31 09:14:02 +00:00
kevinveenbirkenbach 0a4fd11e7e Merge pull request #1319 from infinito-nexus/fix/svc-prx-openresty/worker-connections/1300
fix(svc-prx-openresty): size worker_connections independently of pids_limit
2026-10-31 10:09:54 +01:00
kevinveenbirkenbach c37190495b Merge remote-tracking branch 'origin/main' into fix/svc-prx-openresty/worker-connections/1300 2026-10-31 03:00:09 +01:00
kevinveenbirkenbachandClaude Opus 5.5 f52da1c875 fix(svc-prx-openresty): size worker_connections independently of pids_limit
The shared proxy's nginx.conf derived worker_connections from the
openresty container's pids_limit. pids_limit caps processes and threads,
worker_connections caps simultaneous sockets per worker (client and
upstream), so with pids_limit 256 and one worker the whole host's proxy
held about 256 sockets, roughly 128 proxied requests in flight across
every vhost. Raising pids_limit to buy connections would loosen the
fork-bomb guard.

svc-prx-openresty now declares services.openresty.worker_connections
(4096 per worker, the common nginx production range, enough for several
chunk-heavy apps such as OpenWebUI at ~150-170 requests per page load).
WEBSERVER_PROXY_WORKER_CONNECTIONS reads it through lookup('config'),
without a default, so a missing key fails loudly. pids_limit stays 256.

WEBSERVER_PROXY_WORKER_RLIMIT_NOFILE is derived as 2x worker_connections
(8192), one descriptor for each client and upstream socket of a proxied
request, and nginx.conf renders it as worker_rlimit_nofile. The openresty
container pins its nofile ulimit (soft and hard) to the same value:
workers call setrlimit as root without CAP_SYS_RESOURCE, so they can only
lower the hard limit, and the inherited hard limit depends on the host
daemon (Docker >= 25 defaults to 1024:524288, DiD nests whatever the
outer container has). An explicit ulimit makes the rlimit succeed on
every host instead of logging a setrlimit alert.

The unit test pins worker_connections 4096, worker_rlimit_nofile 8192 and
the container ulimit, and fails when worker_connections follows
pids_limit again.

Live proof (compose deploy of web-svc-html, both plays failed=0): the
deployed nginx.conf renders worker_rlimit_nofile 8192 and
worker_connections 4096; openresty's master, worker and cache manager
run with "Max open files 8192 8192"; the openresty log carries no
setrlimit or "worker_connections are not enough" line.

Closes #1300

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 03:00:03 +01:00
kevinveenbirkenbach 73b0eceed8 Merge pull request #1315 from infinito-nexus/update/docker-image-versions-web-app-pihole-20261031-d252fb3
update(images): update Docker image versions (web-app-pihole)
2026-10-31 02:20:41 +01:00
kevinveenbirkenbach ee503bbbeb Merge pull request #1317 from infinito-nexus/fix/tests/worker-limits-carrier-isolation
test(lookup): restore sys.modules after loading the sso plugins fresh
2026-10-31 02:20:16 +01:00
kevinveenbirkenbach fe04755517 Merge pull request #1316 from infinito-nexus/update/docker-image-versions-web-svc-logout-20261031-63df524
update(images): update Docker image versions (web-svc-logout)
2026-10-31 02:20:03 +01:00
kevinveenbirkenbachandClaude Opus 5.5 9aa56b71e9 test(lookup): restore sys.modules after loading the sso plugins fresh
test_sso.py, test_sso_oidc_plugin.py and test_sso_proxy_consumers.py
evict utils, utils.cache, utils.cache.applications and the roles
packages from sys.modules to import their plugin against fresh modules,
and never put the originals back. Ansible's plugin loader keeps the
applications lookup it loaded earlier in sys.modules, so that lookup
stayed bound to the evicted utils.cache.applications, whose
_MERGED_APPLICATIONS_CACHE utils.cache._reset_cache_for_tests() no
longer reaches.

On main this turned test_webserver_worker_limits red whenever one xdist
worker ran a test that loads the applications lookup through Ansible,
then one of these sso tests, then the worker-limits test: the stale
cache served the cpus 0.5 payload of test_a_sub_cpu_proxy_still_runs_one_worker,
so the later methods rendered worker_processes 1 instead of 4 (main run
41139196554, Workspace centos and fedora, second make test on gw1).

_load_module now runs inside mock.patch.dict(sys.modules): the plugin
keeps the fresh modules it was built against, and sys.modules returns to
its prior state afterwards. This is the change store-i18n carries since
ec0fde6561, ported unchanged so both lines stay identical.

Evidence:
- Before: pytest -n 0 test_tor_ports.py test_sso_oidc_plugin.py
  test_webserver_worker_limits.py -> "3 failed, 33 passed", the CI
  failure set ('1' != '4' twice, worker_processes 1 vs 4).
- After: test_tor_ports.py, the four sso test files and
  test_webserver_worker_limits.py -> "68 passed".

(cherry picked from commit ec0fde6561)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 02:17:21 +01:00
infinito-nexus-updater[bot] 5fdb311936 update(images): update Docker image versions (web-svc-logout) 2026-10-31 01:17:20 +00:00
infinito-nexus-updater[bot] d526936660 update(images): update Docker image versions (web-app-pihole) 2026-10-31 01:17:15 +00:00
kevinveenbirkenbach 8ad0a0e434 Merge pull request #1314 from infinito-nexus/fix/web-app-shopware/php-8.3.36
fix(web-app-shopware): move PHP base to docker-base 8.3.36-caddy
2026-10-31 00:53:21 +01:00
kevinveenbirkenbach f59484b710 Merge remote-tracking branch 'origin/main' into fix/web-app-shopware/php-8.3.36 2026-10-31 00:45:21 +01:00
kevinveenbirkenbachandClaude Opus 5.5 2348d48110 fix(web-app-shopware): move PHP base to docker-base 8.3.36-caddy
The bare ghcr.io/shopware/docker-base:8.3 tag is frozen. Its digest
sha256:14826eb9 is the same as 8.3.25, built 2025-09-05, and carries
PHP_VERSION=8.3.25. Upstream has published only flavoured tags since
8.3.26. 8.3.36-caddy (sha256:b1fdca6e, built 2026-10-30, also the
current 8.3-caddy) carries PHP_VERSION=8.3.36. It has the same
supervisord entrypoint, www-data user and exposed ports 8000/9000 as
the bare tag. That clears the 8.3.36 security floor that hlth-runtime
reports for shopware-web, -worker and -scheduler.

The flavoured tag needs two follow-ups:

- SHOPWARE_COMPOSER_PLATFORM_PHP drops the "-<flavor>" suffix before it
  pads major.minor. Without that, composer gets platform.php
  "8.3.36-caddy". It now renders 8.3.36, and 8.3 still renders 8.3.0.
- shopware/docker 6ae1717 ("feat: remove default env vars") removed
  SHOPWARE_ES_ENABLED=0, SHOPWARE_ES_INDEXING_ENABLED=0 and
  SHOPWARE_ES_INDEX_PREFIX= from the image. Shopware 6.7.13.0 reads
  them through %env()% with no container default, so env.j2 now sets
  the values the old image shipped. SHOPWARE_HTTP_DEFAULT_TTL keeps its
  7200 default from core services.xml. Nothing in Shopware reads
  DATABASE_PORT, and the role uses DATABASE_URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 00:45:19 +01:00
kevinveenbirkenbach ba4c06b943 Merge pull request #1309 from infinito-nexus/update/docker-image-versions-web-svc-logout-20261030-c8885e1
update(images): update Docker image versions (web-svc-logout)
2026-10-30 23:35:58 +01:00