Commit Graph
14158 Commits
Author SHA1 Message Date
kevinveenbirkenbach 66eb3c7082 Release version 16.2.1 v16.2.1 2026-10-20 22:35:05 +02:00
kevinveenbirkenbach dfd25d0561 Merge pull request #1081 from infinito-nexus/update/docker-image-versions-web-app-socialhome-20261020-1c28805
update(images): update Docker image versions (web-app-socialhome)
2026-10-20 22:31:33 +02:00
kevinveenbirkenbach 61ce4e7fc3 Merge pull request #1094 from infinito-nexus/fix/package-cache-frontend/restore-upstreams
fix(package-cache-frontend): restore upstreams.conf from before 16.2.0
2026-10-20 22:31:02 +02:00
kevinveenbirkenbachandClaude Opus 5.5 bc56beb7e9 fix(package-cache-frontend): restore upstreams.conf from before 16.2.0
The 16.2.0 release commit (e2501cb1de) shipped a locally generated
`compose/package-cache-frontend/upstreams.conf`, the output of the cache
generator that only exists on the feature branches (230d9a1e5e). It adds
TLS server blocks for argos-net.com, huggingface.co, index.crates.io,
registry.ollama.ai and static.crates.io, but main's `cert-gen.sh` issues
no certificates for them. nginx then dies on start with

    cannot load certificate "/etc/nginx/certs/argos-net.com.crt"

the frontend stays unhealthy, pypi.org on the runner refuses connections,
and `make install-lint` fails in every workspace job (run 39482585010).

Restore the file byte for byte to its state before the release (blob
b5c5ef08e7), the version every workspace job passed with in run
39443109355.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 22:30:36 +02:00
kevinveenbirkenbach d04a5ed2c2 Merge pull request #1093 from infinito-nexus/fix/web-app-snipe-it/trusted-header-proxy-secret
fix(web-app-snipe-it): bridge the SSO header past v8.8.1's HTTP_ refusal
2026-10-20 22:16:41 +02:00
kevinveenbirkenbachandClaude Opus 5.5 b0856dcf7b fix(web-app-snipe-it): bridge the SSO header past v8.8.1's HTTP_ refusal
Snipe-IT v8.8.1 refuses any `login_remote_user_header_name` matching
`/^HTTP_/i`, so the configured `HTTP_X_FORWARDED_PREFERRED_USERNAME`
stopped minting sessions behind oauth2-proxy.

Apache in the image now copies `X-Forwarded-Preferred-Username` into
the server variable `INFINITO_SSO_USER`, and only when the request also
carries `X-Infinito-Sso-Proxy` equal to the new per-inventory
`sso_proxy_secret`; an empty secret keeps the bridge closed. openresty
sends that header on every proxied request, so a client reaching the
container directly cannot log in by forging the identity header. A
deploy-time check asserts both directions (forged 200, with secret 302).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 22:10:23 +02:00
kevinveenbirkenbach 16ec1d9685 Merge pull request #1092 from infinito-nexus/fix/security/codeql-cleanup
refactor(python): clear the open CodeQL code-quality alerts
2026-10-20 22:00:32 +02:00
kevinveenbirkenbachandClaude Opus 5.5 6e776a5780 refactor(python): clear the open CodeQL code-quality alerts
- Declare `__all__` in every package `__init__.py` whose `PROJECT_ROOT`
  is imported by its modules (163 packages), so the constant counts as
  exported; list every public name where the package defines more.
- Empty the 15 package `__init__.py` files whose `PROJECT_ROOT` no module
  imports.
- Declare the public API of `utils.github.variant.axes` in `__all__`,
  re-exports included, instead of silencing them with `noqa: F401`; the
  list matches the one `feature/store-i18n` already carries.
- Use `import unittest.mock as mock` in `test_applications.py`, as the
  rest of the suite does.
- Spell `_NON_PRINTABLE` in `utils/yaml_bootstrap.py` as the equivalent
  BMP-only positive class; it matches exactly the same 2111 code points
  as the old negated class across U+0000..U+10FFFF.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 21:40:58 +02:00
kevinveenbirkenbach aa91f14f25 Merge pull request #1091 from infinito-nexus/fix/security/clear-text-findings
fix(bcrypt_hash): derive the seeded salt from the seed alone
2026-10-20 21:38:53 +02:00
kevinveenbirkenbachandClaude Opus 5.5 d48f8e9897 fix(bcrypt_hash): derive the seeded salt from the seed alone
The seeded salt was the first 16 bytes of sha256(seed + secret). bcrypt
stores its salt in clear inside the hash, so every seeded hash published
a fast sha256 digest of the password under a seed that is public in the
repository (`web-app-wazuh:indexer-admin`). Anyone holding the hash could
test password guesses at sha256 speed instead of paying bcrypt's cost.

The salt is now sha256(seed)[:16]. The hash stays deterministic for one
password, still changes when the password rotates, and its salt carries
nothing computed from the secret. Existing Wazuh deployments get a new
hash once; `securityadmin.sh` re-applies `internal_users.yml` on every
deploy and the hash still verifies the unchanged password.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 21:35:32 +02:00
kevinveenbirkenbach e2501cb1de Release version 16.2.0 v16.2.0 2026-10-20 21:11:50 +02:00
kevinveenbirkenbach 8306693e61 Merge remote-tracking branch 'origin/main' into update/docker-image-versions-web-app-socialhome-20261020-1c28805 2026-10-20 19:46:37 +02:00
kevinveenbirkenbach 6b6b5b008c Merge pull request #1090 from infinito-nexus/fix/backup/rsync-xattrs/1021
fix(backup): carry hard links, ACLs and xattrs on every backup and recover hop
2026-10-20 18:32:53 +02:00
kevinveenbirkenbachandClaude Opus 5.5 21eba1e88f fix(backup): carry hard links, ACLs and xattrs on every backup and recover hop
baudolo 7.1.x writes volume generations with `rsync -aHAX`, so the
producing host keeps `user.*` extended attributes (OpenCloud keeps its
storage metadata in `user.oc.*`). Every later copy dropped them again,
because none of the other rsync calls passed `-X` (nor `-A`/`-H`):

- NFS export snapshots (svc-bkp-nfs-2-local `script.sh`),
- the backup host's pull (svc-bkp-remote-2-local `pull_specific_host.py`),
- the device sync (svc-bkp-local-2-device `script.py`),
- every recover into a live target (`utils/recovery/base.py`, used by the
  volume, NFS and device recover scripts),
- the `recover full` and `recover remote` tree pulls.

A disaster recovery through the documented chain therefore restored
OpenCloud without `user.oc.*`, silently: the copies succeeded and the
dirval stamp does not cover attributes.

All of these now run `rsync -aHAX` (`-aHAXP` for the device sync). A
target filesystem without xattr support makes rsync exit non-zero as soon
as a source file carries attributes, so the hop fails loudly instead of
dropping them; there is no per-device opt-out. The single-image pull in
`recover remote` keeps `-a`. The provider's ssh-wrapper needs no change:
its glob accepts any server flags and its character guard allows them.

Two tests write a `user.oc.id` attribute and assert it survives the NFS
snapshot and the recover; with the old `-a` both fail with
`OSError: [Errno 61] No data available`.

Closes #1021

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 18:20:46 +02:00
kevinveenbirkenbach 342579e0c6 Merge remote-tracking branch 'origin/main' into update/docker-image-versions-web-app-socialhome-20261020-1c28805 2026-10-20 17:16:34 +02:00
kevinveenbirkenbach fddaecb5ea Merge pull request #1084 from infinito-nexus/fix/svc-storage-nfs-client/ganesha-dir-delegation
fix(svc-storage-nfs-client): stop requesting directory delegations from ganesha < 9.11
2026-10-20 16:51:45 +02:00
kevinveenbirkenbachandClaude Opus 5.5 9b7f25f2fe fix(svc-storage-nfs-client): stop requesting directory delegations from ganesha < 9.11
Every swarm job on ubuntu-26.04 runners (kernel 7.0) died at the NFS
probe write with `[Errno 121] Remote I/O error`. ganesha's NFSv4 debug log
in the rescue bundles shows the cause on every client, the same second as
the failure:

  Request 2: opcode 46 is OP_GET_DIR_DELEGATION
  Status of OP_GET_DIR_DELEGATION in position 2 = NFS4ERR_OP_ILLEGAL

Linux 6.19 added directory delegations: after ACCESS, CREATE, REMOVE or
RENAME the client adds GET_DIR_DELEGATION to the directory's next GETATTR
(`should_request_dir_deleg`, gated per request by the nfsv4 parameter
`directory_delegations`). nfs-ganesha before 9.11 routes op 46 to
`nfs4_op_illegal`, whose reply carries opcode 10044; the client decoder
expects 46 and fails the call with EREMOTEIO. Upstream fixed it in
nfs-ganesha#1385 (98eb77c4, first in V9.11), which answers NOTSUPP; the
client then drops the capability. The distro packages the role installs
predate it: Debian trixie 6.5-5, Ubuntu 26.04 6.5-8.

Every client and the controller now read the server's installed
nfs-ganesha release and, below 9.11, set `directory_delegations=N` right
after the mount and before the first access (the mount itself never sends
op 46), plus `options nfsv4 directory_delegations=N` in /etc/modprobe.d for
later module loads. No ganesha release grants directory delegations, so
the end state equals a fixed server. The parameter is kernel-wide and is
only ever set to N, so clients sharing one kernel cannot flip it back on
each other. Servers on 9.11 or later and the kernel nfsd flavor keep the
client default.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 16:28:52 +02:00
kevinveenbirkenbach 3c3a91c525 Merge pull request #1079 from infinito-nexus/update/docker-image-versions-web-app-pixelfed-20261020-cac5171
update(images): update Docker image versions (web-app-pixelfed)
2026-10-20 15:09:29 +02:00
kevinveenbirkenbach dd7af4b91a Merge pull request #1083 from infinito-nexus/feature/compose/network-recreate
feat(compose): recreate the stack network without losing volumes or worktree stacks
2026-10-20 13:48:34 +02:00
kevinveenbirkenbachandClaude Opus 5.5 310663ae8c feat(compose): recreate the stack network without losing volumes or worktree stacks
When the IPAM config of a compose project's network changes (#999 added
`ip_range`), compose recreates the network on the next `up`. With a
foreign endpoint attached, as every worktree stack is on the primary's
network, compose first stops the project's own containers, then fails
with `error while removing network: ... has active endpoints`, and a
repeated `up` or `up --force-recreate` does not recover. On 2026-10-19
this took the shared registry/package cache and coredns down for every
local session.

`make compose-network-recreate` (alias `i8conere`) runs the sequence that
recovered it: detach every running container of another project from the
network, `docker compose down --remove-orphans` without `-v` so the
caches keep their volumes, the normal `up`, then attach the detached
containers again, which draw addresses from the dynamic pool. If `up`
fails, the still-detached containers are listed instead of reattached.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 13:45:37 +02:00
kevinveenbirkenbach 9fd7b87b5f Merge pull request #1082 from infinito-nexus/update/docker-image-versions-web-app-taiga-20261020-db43a6d
update(images): update Docker image versions (web-app-taiga)
2026-10-20 12:32:45 +02:00
kevinveenbirkenbach 01c1677314 Merge pull request #1080 from infinito-nexus/update/docker-image-versions-web-app-snipe-it-20261020-7ccf379
update(images): update Docker image versions (web-app-snipe-it)
2026-10-20 12:31:53 +02:00
kevinveenbirkenbach f016800d50 Merge pull request #1077 from infinito-nexus/update/docker-image-versions-svc-db-rabbitmq-20261020-633fd88
update(images): update Docker image versions (svc-db-rabbitmq)
2026-10-20 12:31:13 +02:00
kevinveenbirkenbach e8a48f3bb3 Merge pull request #1076 from infinito-nexus/update/version-sources-web-app-n8n-20261020-bcab56d
update(versions): update pins with a declared source (web-app-n8n)
2026-10-20 12:30:45 +02:00
infinito-nexus-updater[bot] 916bc7e025 update(images): update Docker image versions (web-app-taiga) 2026-10-20 10:16:31 +00:00
infinito-nexus-updater[bot] 4353fdbb12 update(images): update Docker image versions (web-app-socialhome) 2026-10-20 10:16:26 +00:00
infinito-nexus-updater[bot] 213d500fe3 update(images): update Docker image versions (web-app-snipe-it) 2026-10-20 10:16:22 +00:00
infinito-nexus-updater[bot] 760d6fee3f update(images): update Docker image versions (web-app-pixelfed) 2026-10-20 10:16:17 +00:00
infinito-nexus-updater[bot] e9e3326e4d update(images): update Docker image versions (svc-db-rabbitmq) 2026-10-20 10:16:09 +00:00
infinito-nexus-updater[bot] 5238ec2b13 update(versions): update pins with a declared source (web-app-n8n) 2026-10-20 10:15:19 +00:00
kevinveenbirkenbach 6cdcdeebbb Merge pull request #1074 from infinito-nexus/dependabot/npm_and_yarn/eslint-10.13.0
chore(deps-dev): bump eslint from 10.12.0 to 10.13.0
2026-10-20 12:14:36 +02:00
kevinveenbirkenbach 827fda83be Merge pull request #1075 from infinito-nexus/fix/system/apparmor-keep-docker-default
fix(apparmor): keep docker-default loaded when tearing AppArmor down
2026-10-20 12:14:16 +02:00
kevinveenbirkenbachandClaude Opus 5.5 a6c3c1cc91 fix(apparmor): keep docker-default loaded when tearing AppArmor down
`security-apparmor-teardown` ran `aa-teardown`, which unloads every
profile including dockerd's in-memory `docker-default`. dockerd only loads
that profile when it starts, so every container start afterwards that
requests it fails until dockerd restarts. Since #1067 runs the teardown on
the GitHub runners, BuildKit failed each RUN of the swarm node image three
times (run 39332343490, 39 of 40 swarm jobs):

    runc run failed: unable to start container process: error during
    container init: unable to apply apparmor profile: apparmor failed to
    apply profile: write .../attr/apparmor/exec: no such file or directory

The teardown now removes each loaded profile by name through securityfs
and skips `docker-default` and child profiles, which leave with their
parent. Dev hosts gain the same: no dockerd restart is needed after
`make environment-bootstrap`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 12:11:14 +02:00
dependabot[bot] af82d6b4bf chore(deps-dev): bump eslint from 10.12.0 to 10.13.0
Bumps [eslint](https://github.com/eslint/eslint) from 10.12.0 to 10.13.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v10.12.0...v10.13.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 10.13.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-10-20 00:19:23 +00:00
kevinveenbirkenbach 0edc8fa470 Merge pull request #1067 from infinito-nexus/fix/ci/runner-apparmor-teardown
fix(ci): tear down host AppArmor profiles on GitHub runners like on dev hosts
2026-10-20 00:04:37 +02:00
kevinveenbirkenbach 3bdbc93e9a Merge remote-tracking branch 'origin/main' into fix/ci/runner-apparmor-teardown 2026-10-19 22:36:59 +02:00
kevinveenbirkenbachandClaude Opus 5.5 fd596cf188 fix(ci): tear down host AppArmor profiles on GitHub runners like on dev hosts
ubuntu-26.04 runner images load per-binary AppArmor profiles (wg-quick,
dig, who, fusermount3, ~150 upstream). Path-based attachment applies to
every unconfined task, so the profiles also attach inside our privileged
`apparmor=unconfined` containers. The upstream wg-quick profile only allows
`/usr/bin/ip`; on CentOS and Fedora nodes `ip` lives at `/usr/sbin/ip`, so
`svc-net-wireguard : Bring 'data' up` failed with rc=126:

    /usr/bin/wg-quick: line 32: /usr/sbin/ip: Permission denied
    apparmor="DENIED" operation="exec" profile="wg-quick" name="/usr/sbin/ip"

(run 39268090162, Fediwall#0, CentOS swarm VPN).

Dev hosts never see this: `environment-bootstrap` runs
`security-apparmor-teardown`. The runners skipped that preparation. The
deploy, workspace and DNS workflows now run the same target on the runner
host before any container starts (skipped under act, whose job container
cannot reach the host's policy), so CI matches the dev-host state for all
profiles, not only the ones seen so far.

A dedicated permissive profile for the containers was rejected: every
AppArmor host without that profile loaded would refuse to start them,
including dev hosts and act.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 22:36:58 +02:00
kevinveenbirkenbach d2b85127cb Merge pull request #1065 from infinito-nexus/feature/ci/runner-label-updater
feat(ci): runner label updater and the move to ubuntu-26.04
2026-10-19 22:22:07 +02:00
kevinveenbirkenbach 03845a8b19 Merge pull request #1023 from infinito-nexus/fix/ci/pin-ubuntu-runner
fix(ci): pin GitHub-hosted runners to ubuntu-24.04
2026-10-19 21:24:13 +02:00
kevinveenbirkenbach 95056e8d33 Merge remote-tracking branch 'origin/main' into feature/ci/runner-label-updater 2026-10-19 16:56:52 +02:00
kevinveenbirkenbachandClaude Opus 5.5 a085427236 chore(svc-storage-nfs-server): capture ganesha's NFSv4 verdicts in debug runs
On ubuntu-26.04 runners the swarm deploy fails at svc-storage-nfs-client's
probe-write, right after a successful probe-mount, on every client node:
`Destination directory /run/svc-storage-nfs-client/probe does not exist`.
The rescue bundles cannot say why: ganesha writes to
/var/log/ganesha/ganesha.log, which the swarm diagnostics never collected,
and its NFS_V4 component logged nothing below EVENT.

Debug runs now log NFS_V4 at DEBUG, and the diagnostics append the tail
of ganesha.log to the nfs-boundary section.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 16:56:52 +02:00
kevinveenbirkenbachandClaude Opus 5.5 b055eece05 feat(ci): keep GitHub-hosted runner labels current through the updater
The workflows pin `runs-on: ubuntu-NN.NN`, so no job moves to a new Ubuntu
release behind our back, but nothing raised the pin either. A sixth job of
`🔄 Update versions` closes that: `utils/update/runner.py` reads the image
table of actions/runner-images, takes the newest x64 Ubuntu label whose
image carries no preview or beta badge, and raises every older bare
`runs-on: ubuntu-NN.NN` to it; arch-suffixed labels stay untouched. The job
opens the change as one PR over `.github/workflows`, so its CI run tests
the new image before it reaches main.

This commit carries the updater's first result: every job now runs on
ubuntu-26.04 (49 `runs-on`).

actionlint 1.7.12, the newest release, does not know `ubuntu-26.04` yet
(rhysd/actionlint#682, fix proposed in rhysd/actionlint#743), so
`.github/actionlint.yaml` declares the label until a release knows it.

act maps each `ubuntu-NN.NN` label the workflows use to the local platform
image, derived from `.github/workflows`, instead of a fixed list that did
not know ubuntu-26.04.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 16:56:52 +02:00
kevinveenbirkenbach e1d7e32889 Release version 16.1.0 v16.1.0 2026-10-19 16:20:32 +02:00
kevinveenbirkenbachandClaude Opus 5.5 52ad8549e0 fix(ci): pin GitHub-hosted runners to ubuntu-24.04
`ubuntu-latest` moved from ubuntu-24.04 to ubuntu-26.04 on its own
schedule, in the middle of run 39166850273, and every job that landed on
the new image met a different OS: sudo-rs instead of sudo, no ip_tables
loaded, and now the NFS probe-write of svc-storage-nfs-client failing on
26.04 swarm nodes. The same branch went red without a code change.

Every `runs-on` now names `ubuntu-24.04`. GitHub still rebuilds that image
weekly, so patches and tool updates keep arriving; only the release jump
becomes a deliberate change of the label. The CodeQL job drops its dead
swift/macos-latest branch, since no swift language is in its matrix. act
already maps ubuntu-24.04 to the local platform image.

A lint rejects any job whose `runs-on` contains a `*-latest` label.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 15:57:12 +02:00
kevinveenbirkenbachandClaude Opus 5.5 155ca9a8a9 fix(web-app-wazuh): declare the empty mesh membership
#414 merged web-app-wazuh with a meta/networks.yml that carries only
`local`, and test_mesh_subnet_pool.py requires every stack role to ship
`meshes: []` so a compose host can join meshes through it. main's
test-lint has been red since d0698daa5e:

    AssertionError: 'meshes' not found in {'local': {'subnet': '192.168.81.0/24'}}

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 15:57:12 +02:00
kevinveenbirkenbach bfd7febe5c Merge pull request #1020 from infinito-nexus/update/docker-image-versions-web-app-pixelfed-20261019-c89532b
update(images): update Docker image versions (web-app-pixelfed)
2026-10-19 15:20:51 +02:00
kevinveenbirkenbach 2520efa3f8 Merge pull request #1019 from infinito-nexus/fix/svc-storage-nfs-client/node-local-backups
fix(svc-storage-nfs-client): keep swarm backups node-local
2026-10-19 15:17:04 +02:00
kevinveenbirkenbach 6cf1c8f95b Merge remote-tracking branch 'origin/main' into fix/svc-storage-nfs-client/node-local-backups 2026-10-19 15:16:06 +02:00
kevinveenbirkenbachandClaude Opus 5.5 13c482cd70 docs(svc-storage-nfs-client): note generations stranded on the share
Generations a swarm node wrote to the NFS share before the node-local
bind stay under the export's backup/ directory, hidden from the nodes,
outside every cleanup and pull. No production swarm install carries any,
so the README states the manual removal instead of migrating.

Refs #1012

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 15:16:06 +02:00
kevinveenbirkenbachandClaude Opus 5.5 c73079613b fix(svc-storage-nfs-client): keep the backup user's access and the state remount
Two holes in the node-local backup bind, both reproduced with the role's
own tasks against a ganesha NFSv4.2 mount:

- The store was created with mode 0700. The role runs twice per deploy
  (constructor svc-storage group, then 02_server), and between the runs
  user-backup and the two cleanup roles converge the same inode to
  root:root 0755. The second run then chmodded it to root:root 0700, the
  backup user lost access (`ls` rc=2), and the backup host's pull would
  list no repositories and exit 0. The store now uses 0755, the mode the
  cleanup roles converge it to, so the second run changes nothing.

- A changed NFS mount line (options, version, server) makes
  ansible.posix.mount fall back from `mount -o remount` to a plain
  `umount`, which the child bind now blocks: `umount.nfs4: device is
  busy`. A check-mode pass detects the pending change and unmounts the
  bind first; the bind task mounts it again afterwards.

Refs #1012

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 15:16:06 +02:00