Commit Graph
14145 Commits
Author SHA1 Message Date
kevinveenbirkenbach e2501cb1de Release version 16.2.0 v16.2.0 2026-10-20 21:11:50 +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 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] 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
kevinveenbirkenbach d0698daa5e Merge pull request #414 from pragepani/feature/web-app-wazuh/add-role
feat(web-app-wazuh): add Wazuh SIEM role with OIDC/LDAP RBAC
2026-10-19 14:35:24 +02:00
infinito-nexus-updater[bot] 628f835d86 update(images): update Docker image versions (web-app-pixelfed) 2026-10-19 11:36:40 +00:00
kevinveenbirkenbach 32216cc199 Merge pull request #999 from infinito-nexus/fix/compose/primary-net-ip-range
fix(compose): keep dynamic addresses off the stack's static IPs
2026-10-19 13:34:52 +02:00
kevinveenbirkenbachandClaude Opus 5.5 ad70e3de1e fix(svc-storage-nfs-client): keep swarm backups node-local
On swarm nodes /var/lib/infinito is the ganesha NFSv4.2 state share, so
every backup repository landed on it. ganesha 6.5 refuses user.* extended
attributes, and baudolo 7.1.x copies volumes with `rsync -aHAX`, so the
volume backup of OpenCloud (user.oc.* metadata) failed with
`fsetxattr(... "user.oc.id") failed: Operation not supported (95)`.

After the state mount the client role now binds the node's own
/var/lib/infinito-backup over /var/lib/infinito/backup. Every consumer
keeps its path; the data stays on local disk with its attributes, and the
backup host pulls each provider over ssh as before. The bind carries
_netdev: without it, systemd-fstab-generator puts the bind into
local-fs.target below its NFS parent in remote-fs.target, and the boot
transaction cycles. The DR drill remounts the bind after its lazy remount
of the state share, because `umount -l` on the parent detaches it.

Closes #1012

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 13:28:45 +02:00
kevinveenbirkenbach d014c8dab1 Merge pull request #1018 from infinito-nexus/fix/ci/sudo-rs-preserve-env
fix(ci): keep main green on ubuntu-26.04 runners (sudo-rs env, fedora iptables-nft)
2026-10-19 13:16:44 +02:00
kevinveenbirkenbach 97a03a1194 Merge remote-tracking branch 'origin/main' into fix/compose/primary-net-ip-range 2026-10-19 13:07:26 +02:00
kevinveenbirkenbachandClaude Opus 5.5 c4f340d7b4 fix(sys-svc-container): install iptables-nft with docker on RedHat
On Fedora 44, dnf satisfies docker-ce's `(iptables-nft or iptables)`
requirement with iptables-legacy. The legacy backend needs the ip_tables
module, which ubuntu-26.04 runners no longer have loaded, and the compose
container cannot load it because it mounts no /lib/modules. The MSS clamp
task then failed with `modprobe: FATAL: Module ip_tables not found` and
`can't initialize iptables table 'mangle'` (Nextcloud#10, Gitea#0,
Jellyfin#0 on fedora). CentOS 10 already resolves to iptables-nft from the
same plan and deploys green on the same image.

Naming iptables-nft in the docker transaction makes Fedora use the
nf_tables backend as well.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 13:07:18 +02:00
kevinveenbirkenbachandClaude Opus 5.5 281a9cce9b fix(ci): name the preserved environment for sudo-rs runners
ubuntu-latest is rolling over to ubuntu-26.04, whose sudo is sudo-rs. It
ignores `-E` ("preserving the entire environment is not supported") and
hands the child only the explicit `env` assignments, so the swarm matrix
died at import with `KeyError: 'INFINITO_SRC_DIR'` before any inventory
existed (PR #1009, Nextcloud#0). Jobs that landed on ubuntu-24.04 kept
passing.

Every `sudo -E` now passes the caller's exported names through
`--preserve-env="$(compgen -e | paste -sd, -)"`, which both classic sudo
and sudo-rs honour. A lint rejects `sudo -E` and bare `--preserve-env`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-19 13:07:18 +02:00
kevinveenbirkenbach 4018a2114c Merge pull request #1016 from infinito-nexus/update/docker-image-versions-web-app-stalwart-20261019-4598c08
update(images): update Docker image versions (web-app-stalwart)
2026-10-19 12:15:37 +02:00
infinito-nexus-updater[bot] 1d98616895 update(images): update Docker image versions (web-app-stalwart) 2026-10-19 09:11:08 +00:00
kevinveenbirkenbach 3705615000 Merge pull request #1014 from infinito-nexus/update/repository-refs-pkgmgr-20261019-3a9100b
update(repos): bump git refs to latest semver tags (pkgmgr)
2026-10-19 10:33:54 +02:00
kevinveenbirkenbach 847054928e Merge pull request #1015 from infinito-nexus/update/docker-image-versions-web-app-semaphore-20261019-393ca71
update(images): update Docker image versions (web-app-semaphore)
2026-10-19 10:33:13 +02:00
infinito-nexus-updater[bot] 3647788374 update(images): update Docker image versions (web-app-semaphore) 2026-10-19 08:15:51 +00:00