Commit Graph
37 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 4.8 4039313266 refactor(tasks): enforce and apply a single task-file numbering scheme
Add tests/lint/repository/test_task_file_numbering.py: numbered task
files use exactly two leading digits, a numbered *_core.yml must be
00_core.yml, per directory the numbers are unique/consecutive and start
at 01 (00 with a core file), numbered includes appear in ascending
order, and shared helpers live in tasks/utils/ instead of the numbered
chain.

Apply it across every role: rename NN_core.yml to 00_core.yml with a
consecutive down-shift of the siblings, move letter-suffix children into
a subdirectory named after their parent task, relocate helpers included
from more than one place into tasks/utils/, and update every reference
(include_tasks, path_absolute, .ansible-lint-ignore, requirement docs).
Legacy narration comments in the touched files are deleted; the upstream
xwiki.properties reference block opts out via nocheck. The unused
MAILU_IP6_PUBLIC var (only ever named in now-removed comments) is dropped.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 20:01:31 +02:00
kevinveenbirkenbachandClaude Opus 4.8 ca139756e0 style(cln-bkps): shorten the backups-root task names to the length limit
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 13:03:25 +02:00
kevinveenbirkenbachandClaude Opus 4.8 36d50d604c fix(cln-bkps): run the backup cleanups on every backup-holding host
The inventory gating removed the manager's unconditional volume and secrets backup groups, which had been the only include paths that ever executed the cleanup roles; svc-bkp-nfs-2-local declares both cleanups itself but their IS_STACK_HOST gate silently skipped them on the nfs host, so the required_by validator failed the deploy. The gate becomes the group_vars constant IS_BACKUP_HOST (any svc-bkp-* group membership), which covers every include site since only the five backup roles include the cleanups, and both roles now ensure the backups root exists before installing their timer: cleanback refuses a missing root by design and the size-cleanup script walks it with os.listdir.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 13:03:24 +02:00
kevinveenbirkenbachandClaude Opus 4.8 cddb0dc59b feat(lint): require emoji-prefixed task/step/job names + convert existing
Add tests/lint/repository/test_name_emoji_and_length.py: every Ansible task
name and GitHub Actions workflow/job/step name must start with an emoji (first
char not 0-9/A-Za-z) and be <= 80 chars.

- emit emoji names at the source: cli/build/include generator now writes
  "🔧 setup <app>" / "🚿 flush handlers after <app>" so generated
  tasks/groups/*-roles.yml satisfy the convention too
- convert existing task/step/job/workflow names to emoji-prefixed, choosing a
  task-fitting icon per action (📦 install, ✅ ensure, 🔍 probe, 🥾 bootstrap,
  🚀 deploy, 🧩 service-module load, ⬇️ checkout, 📂 include-routines, ...)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 22:45:06 +02:00
kevinveenbirkenbachandClaude Opus 4.8 569d52a38f fix(swarm-deploy): cross-host, login-shell and quoting deploy bugs
Surfaced by deep-inspecting the swarm matrix CI failures:

- sys-ctl-cln-faild-bkps: the systemd ExecStart resolved cleanback via the
  command_path lookup, which runs on the Ansible controller; the binary is
  pip-installed system-wide on the target node, so shutil.which returned None
  ("command not found in PATH: 'cleanback'"). The ExecStart already runs via
  /bin/sh -c, so use the bare command and let the target shell resolve PATH.
- svc-db-rabbitmq: RABBITMQ_EXEC_SHELL used `sh -lc`; a login shell re-inits
  PATH from /etc/profile and drops the image's /opt/rabbitmq/sbin, so
  rabbitmq-diagnostics was not found (rc 127). Use `sh -c`.
- web-app-friendica: `{{ FRIENDICA_CONTAINER_ADDRESS | quote }}` single-quotes
  the swarm $(resolve-container-id ...) subshell, killing the command
  substitution ("No such container"). Drop the quote, matching 02_manager_ops.
- web-app-gitea: `gitea migrate` ran without `-c {{ GITEA_CONFIG }}` (admin-create
  already has it), so MustInstalled() aborted against the custom app.ini. Add it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 03:30:11 +02:00
kevinveenbirkenbachandClaude Opus 4.7 59c221521c fix(cluster-a): NFS-everywhere for cluster-shared /var/lib/infinito state
Resolves CI swarm rc=69 ("msmtp: needs a password"): controller-side
Ansible lookups (lookup('email').password etc.) couldn't see the
tokens.yml that Mailu writes target-side, because the controller has
its own filesystem in swarm mode.

Mount NFS-shared /var/lib/infinito on every swarm host AND on the
controller during deploy (in-play delegate_to: localhost task at end
of svc-storage-nfs-server role). State subdir exported separately
with no_root_squash + wildcard CIDRs so root-owned writes succeed
and the controller can mount from outside the svc-swarm IP set.

Single-writer guarantee on FILE_TOKENS via delegate_to: STACK_HOST +
run_once on sys-token-store/{01_core,write}.yml. Backup roles
(svc-bkp-container-2-local, sys-ctl-cln-bkps, sys-ctl-cln-faild-bkps,
user-backup/03_permissions_folders, three direct callers of
04_seed-database-to-backup.yml) gated on IS_STACK_HOST to prevent
N-host write races on the shared NFS backup tree.

Fail-fast assertion in svc-storage-nfs-client + 05_controller_mount
when pre-existing local /var/lib/infinito would be hidden by mount-
over. Operator must migrate or wipe before re-deploying.

SPOTs: SWARM_LAB_NETWORK in workflow env block, storage.nfs.state_subdir
in group_vars/all/15_storage.yml, DIR_VAR_LIB unchanged. UPPER_CASE
constants in NFS roles. Cleanup script umounts controller view before
container teardown to prevent stale-mount leak between matrix jobs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 19:02:57 +02:00
kevinveenbirkenbachandClaude Opus 4.7 2a023ca6a1 chore(lint): autoformat strict-failure semantics + claude.sh rename
* scripts/lint/autoformat.sh:
  - rename run_sort_claude_settings worker to run_claude (matches the
    renamed scripts/lint/claude.sh).
  - drop the EXIT trap that wiped status_dir; cleanup happens explicitly
    after `wait` returns, so a parallel worker that interrupts the
    parent never races a vanished status dir.
  - each worker now captures its tool's exit code and writes one of
    OK / SKIP / FAIL. Tolerated `expected violations remain`-style exits
    (markdownlint-cli2 rc≤1, ansible-lint rc≤2) still count as OK; only
    real failures count as FAIL.
  - all workers run to completion regardless of individual tool failures
    (so the user always sees the full picture); after the summary, the
    script exits 1 if any worker reported FAIL.
* scripts/lint/sort_claude_settings.sh -> scripts/lint/claude.sh
  (history preserved via git mv); update test_claude_settings_sorted.py
  fix-hint accordingly.

Plus working-tree drift across roles/, group_vars/, inventories/,
requirements/, and .pre-commit-config.yaml accumulated from the
make-test setup phase regenerating generated artefacts during recent
test runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:30:49 +02:00
kevinveenbirkenbachandClaude Opus 4.7 951f6d36d2 chore(lint): unify autoformat/galaxy parallelism into one PARALLEL env var
* scripts/lint/autoformat.sh: rename AUTOFORMAT_PARALLEL to PARALLEL,
  declare it at file start with default `true`; still env-overridable.
  Reword the worker comment so the literal `# shellcheck` token no
  longer appears at start-of-line and trips SC1072/SC1073.
* scripts/lint/galaxy.sh: drop the GALAXY_FATAL / GALAXY_NAMESPACE /
  GALAXY_PARALLEL env vars (over-engineered for a single repo). Failure
  is always fatal. NAMESPACE is an internal constant. Add the same
  PARALLEL env var (default `true`, env-overridable); falsy demotes the
  xargs fan-out to one worker.
* docs/contributing/environment/variables.md: collapse the four
  AUTOFORMAT_*/GALAXY_* rows into one `PARALLEL` row covering both
  consumers.
* docs/contributing/tools/make.md: refer to `PARALLEL=0` everywhere;
  add the lint-galaxy parallelism note.

Plus working-tree drift across roles/, group_vars/, inventories/, and
tasks/ that accumulated from the make-test setup phase regenerating
generated artefacts during recent test runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 00:59:24 +02:00
kevinveenbirkenbach 8b964be573 fix(sys-lock): avoid hardcoded /usr/bin/python in ExecStartPre 2026-02-23 08:44:25 +01:00
kevinveenbirkenbach 1dc350e9f9 Use command_path lookup for pip-installed CLI binaries 2026-02-22 02:27:40 +01:00
kevinveenbirkenbach e1e1f3eb11 chore(vars): rename PATH_* to DIR_/BIN_/FILE_ conventions
https://chatgpt.com/share/6985cf49-3c74-800f-af97-f68b1969ab01
2026-02-06 12:23:46 +01:00
kevinveenbirkenbach 8a81630391 Added newline at file and POSIX compatible 2026-02-04 19:49:56 +01:00
kevinveenbirkenbach 76d09dbc3f refactor: centralize docker wrappers, CA injection paths, and update tests
Unify compose/run wrappers under PATH_* variables, wire CA trust injection
consistently, extend with NSS/Chromium support, and adapt unit tests to the
new run-based execution model.

https://chatgpt.com/share/697e1f92-bc5c-800f-968d-ad43c50afaea
2026-01-31 17:06:09 +01:00
kevinveenbirkenbach 9e993c338e feat(pip): add global_install flag and fix python-ldap installation for Ansible interpreter
- Add global_install flag to sys-pip-install role (default: false)
- Allow optional system-wide installs via pip3 with --break-system-packages
- Install python-ldap via pip in Ansible interpreter for OpenLDAP role
- Refactor svc-db-openldap tasks into 01_core.yml with run-once gating
- Fix environment handling for conditional global pip installs
- Enable global pip installs for CLI tools (gitcon, ldapsm, backup tools, cleanup tools)

https://chatgpt.com/share/6963dd5d-cae0-800f-b8d7-82a3808be634
2026-01-11 18:26:49 +01:00
kevinveenbirkenbach d7f13d30c6 fix(ci): wait for systemd readiness after compose up
Add a systemd readiness gate to the CI compose wrapper to avoid a race
where systemctl is called before DBus/systemd is fully ready.
This prevents sporadic failures like:
"System has not been booted with systemd as init system (PID 1)".

No Dockerfile or Ansible role changes required.

https://chatgpt.com/share/696045b5-bd08-800f-acd9-e3a4e2e23e52
2026-01-09 01:02:54 +01:00
kevinveenbirkenbach 8297f776e3 feat: make failed-backup cleanup safer and reschedule for low-load hours
- Run failed-backup cleanup at 04:00 to avoid overlap with regular backup jobs
- Add explicit timeout and single-worker defaults for large/slow storage
- Align role defaults with cleanback 1.3.0 safety semantics
- Clarify force-keep behavior and failure handling in role README

https://chatgpt.com/share/695d39c5-3390-800f-81b1-10f0f04e1b42
2026-01-06 17:35:12 +01:00
kevinveenbirkenbach bace99c9c6 Fix pip installation and stabilize cleanback service execution
- Switch sys-pip-install to ansible.builtin.pip with dynamically resolved pip executable
- Remove hardcoded python/pip paths to ensure cross-distro compatibility
- Separate cleanback package pinning from executed command
- Fix systemd ExecStart to call cleanback binary instead of package spec
- Improve robustness against PATH and interpreter mismatches

https://chatgpt.com/share/69554856-3920-800f-995e-8b6948e1d09c
2025-12-31 16:59:12 +01:00
kevinveenbirkenbach 2d691ff933 fix(backup): ensure backup user and root directory are initialized before services
- Move run-once flag execution before dependency includes
- Add user-backup as explicit dependency for backup and cleanup roles
- Ensure backup root directory exists before cleanup services run
- Fix dependency ordering to prevent cleanback failures on missing paths

https://chatgpt.com/share/6954df53-b9d8-800f-b9e7-a1508cf00279
2025-12-31 09:31:12 +01:00
kevinveenbirkenbach d6edf70539 feat(sys): keep recent backups when cleaning failed docker backups
- Add configurable force keep option with default value 3
- Extend systemd cleanup service to skip newest backups
- Update role documentation to explain safe cleanup behavior and configuration

https://chatgpt.com/share/6954d89e-bf08-800f-be4a-5d237d190ddd
2025-12-31 09:09:08 +01:00
kevinveenbirkenbach fa6245b252 feat(cleanup): pass configurable backups root to cleanback service
Use PATH_INFINITO_BACKUP_DIR as --backups-root for the cleanback systemd service and simplify role README to match the actual behavior.

https://chatgpt.com/share/6954d540-199c-800f-9ab3-9512cc686f21
2025-12-31 08:48:10 +01:00
kevinveenbirkenbach 64c3d6cf73 - Remove explicit override of system_service_force_linear_sync in cleanup role
- Rely on SYS_SERVICE_GROUP_MANIPULATION to enforce linear execution order
- Adjust flush logic to disable instant flush when final flush is requested
- Prevent cleanup service from triggering premature service flushes that caused backup failures

https://chatgpt.com/share/695408bb-23f4-800f-9234-0e77c62d9add
2025-12-30 18:15:34 +01:00
kevinveenbirkenbach 735ae59cbb refactor: migrate cleanback installation from pkgmgr to pip
- replace pkgmgr-install with sys-pip-install for cleanback
- install cleanback as a regular pip package
- align roles with pyproject-based distribution
- keep system-wide, non-interactive installation semantics

https://chatgpt.com/share/69517d20-f850-800f-b6ff-6b983247888f
2025-12-28 20:42:12 +01:00
kevinveenbirkenbach 031775c096 Removed redundancies and simplified run_once flag 2025-12-03 18:12:09 +01:00
kevinveenbirkenbach 716ebef33b Refactor task includes and update variable handling for Ansible 2.20 migration
This commit updates multiple roles to ensure compatibility with Ansible 2.20.
Several include paths and task-loading mechanisms required adjustments,
as Ansible 2.20 applies stricter evaluation rules for complex Jinja expressions
and no longer resolves certain relative include paths the way Ansible 2.18 did.

Key changes:
- Replaced legacy once_finalize.yml and once_flag.yml with the new structure
  under tasks/utils/once/finalize.yml and tasks/utils/once/flag.yml.
- Updated all include_tasks statements to use 'path_join' with playbook_dir,
  ensuring deterministic and absolute file resolution across roles.
- Fixed all network helper includes by converting direct relative paths such as
  'roles/docker-compose/tasks/utils/network.yml' to proper Jinja-evaluated paths.
- Normalized MATOMO_* variable names for consistency with the updated variable
  scope behavior in Ansible 2.20.
- Removed deprecated patterns that were implicitly supported in Ansible 2.18
  but break under the more strict variable and path resolution model in 2.20.

These changes are part of the full migration step required to ensure the
infinito-nexus roles remain stable, deterministic, and forward-compatible with
Ansible 2.20.

Details of the discussion and reasoning can be found in this conversation:
https://chatgpt.com/share/69300a8d-24d4-800f-bec0-e895a695618a
2025-12-03 11:02:34 +01:00
kevinveenbirkenbach e09f561f0b Refactor run-once orchestration and bootstrap Mailu/Mastodon in a single deploy
- Replace legacy utils/run_once.yml with the new helpers utils/once_flag.yml and utils/once_finalize.yml
- Introduce utils/compose_up.yml to ensure docker-compose stacks are up and to flush handlers safely without coupling to run-once flags
- Migrate all affected roles (desk-*, dev-*, sys-ctl-*, sys-svc-*, web-app-*, web-svc-*, util-*) to the new run-once helpers
- Rework sys-svc-msmtp to auto-load Mailu once per deploy, check reachability, and reuse the running stack instead of requiring multiple playbook passes
- Adjust web-app-mailu to integrate cert deployment, handler flushing, and run-once handling so Mailu is fully initialized in a single deploy
- Improve Matomo, CDN, logout and CSP/health-check related roles to cooperate with the new compose_up / once_* pattern
- Simplify alarm/backup/timer/service orchestration (sys-ctl-alm-*, sys-bkp-provider, sys-timer-cln-bkps, etc.) by moving run-once logic into dedicated 01_core.yml files
- Update integration tests so utils/once_flag.yml and utils/once_finalize.yml are recognised as valid run-once providers, keeping the global run_once_* guarantees consistent
- Align frontend injection and service dependencies so Mastodon- and Mailu-related services can be brought up coherently within a single deployment cycle rather than several iterations
2025-12-01 13:30:50 +01:00
kevinveenbirkenbach c9f959058b Removed unnecessary blocks 2025-12-01 05:30:41 +01:00
kevinveenbirkenbach 23353ac878 infra(sys-service): centralize async control + pre-deploy backup safeguard
- Added MODE_BACKUP to trigger backup before the rest of the deployment

- sys-ctl-bkp-docker-2-loc: force linear sync and force flush when MODE_BACKUP is true

- Unified name resolution via system_service_name across handlers and tasks

- Introduced system_service_force_linear_sync and system_service_force_flush (rename from system_force_flush)

- Drive async/poll via system_service_async/system_service_poll using omit when disabled

- Propagated per-role overrides (cleanup, repair, cert tasks) for clarity and safety

- Minor formatting and consistency cleanups

Why: Ensure the backup runs before the deployment routine to safeguard data integrity.

Refs: Conversation https://chatgpt.com/share/68de4c41-b6e4-800f-85cd-ce6949097b5e
Signed-off-by: Kevin Veen-Birkenbach <kevin@veen.world>
2025-10-02 11:58:23 +02:00
kevinveenbirkenbach 2806aab89e Removed deathlock between sys-ctl-bkp-docker-2-loc and sys-ctl-cln-faild-bkps - Timer handles now cleanup exclusively 2025-09-19 11:21:18 +02:00
kevinveenbirkenbach 58cf63c040 Removed deathlock and optimized run_once settings for performance 2025-09-11 21:48:56 +02:00
kevinveenbirkenbach 682ea6d7f2 Removed unnecessary --dirval-cmd dirval 2025-09-11 21:16:10 +02:00
kevinveenbirkenbach 486729d57d Removed directory-validator dependencies because it's installed via pkgmgr 2025-09-11 21:01:23 +02:00
kevinveenbirkenbach 5342f70b03 Solved wrong variable bugs :) 2025-09-11 20:58:02 +02:00
kevinveenbirkenbach d40a275d70 feat(sys-ctl-cln-faild-bkps): migrate role to cleanback CLI (systemd oneshot) and derive workers from Ansible facts
- install via pkgmgr (CLEANUP_FAILED_BACKUPS_PKG=cleanback)
- run: cleanback --all --dirval-cmd dirval --workers {{ CLEANUP_FAILED_BACKUPS_WORKERS }} --timeout {{ CLEANBACK_TIMEOUT_SECONDS }} --yes
- remove obsolete systemctl template and path set_fact logic
- keep task variable names intact; no defaults for runtime knobs
- update README to reflect new behavior

Conversation: https://chatgpt.com/share/68c309bf-8818-800f-84d9-c4aa74a4544c
2025-09-11 20:30:29 +02:00
kevinveenbirkenbach 26b392ea76 refactor!: replace sys-systemctl with sys-service, add sys-daemon, and rename systemctl_* → system_service_* across repo
- Swap role includes: sys-systemctl → sys-service in all roles
- Rename variables everywhere: systemctl_* → system_service_* (incl. systemctl_id → system_service_id)
- Templates: ExecStart now uses {{ system_service_script_exec }}; add optional RuntimeMaxSec via SYS_SERVICE_DEFAULT_RUNTIME
- Move SYS_SERVICE defaults into roles/sys-service/defaults (remove SYS_SERVICE_ALL_ENABLED & SYS_SERVICE_DEFAULT_STATE from group_vars/07_services.yml)
- Tidy group_vars/all/08_timer.yml formatting
- Introduce roles/sys-daemon:
  - default manager timeouts (timeouts.conf)
  - optional purge of /etc/systemd/system.conf.d
  - validation via systemd-analyze verify
  - handlers for daemon-reload & daemon-reexec
- Refactor sys-timer to system_service_* variables (docs and templates updated)
- Move filter_plugins/filetype.py under sys-service
- Update meta/README to point to official systemd docs
- Touch many roles (backup/cleanup/health/repair/certs/nginx/csp/wireguard/ssd-hdd/keyboard/update-docker/alarm compose/email/telegram/etc.) to new naming

BREAKING CHANGE:
- Role path/name change: use `sys-service` instead of `sys-systemctl`
- All `systemctl_*` vars are now `system_service_*` (e.g., on_calendar, state, timer_enabled, script_exec, id)
- If you have custom templates, adopt RuntimeMaxSec and new variable names

Chat context: https://chatgpt.com/share/68a47568-312c-800f-af3f-e98575446327
2025-08-19 15:00:44 +02:00
kevinveenbirkenbach 2ba486902f Deactivated file copying for sys-ctl-cln-faild-bkps 2025-08-18 23:34:06 +02:00
kevinveenbirkenbach 2569abc0be Refactor systemctl services and timers
- Unified service templates into generic systemctl templates
- Introduced reusable filter plugins for script path handling
- Updated path variables and service/timer definitions
- Migrated roles (backup, cleanup, repair, etc.) to use systemctl role
- Added sys-daemon role for core systemd cleanup
- Simplified timer handling via sys-timer role

Note: This is a large refactor and some errors may still exist. Further testing and adjustments will be needed.
2025-08-18 21:22:16 +02:00
kevinveenbirkenbach 3a839cfe37 Refactor systemctl services and categories due to alarm bugs
This commit restructures systemctl service definitions and category mappings.

Motivation: Alarm-related bugs revealed inconsistencies in service and role handling.

Preparation step: lays the groundwork for fixing the alarm issues by aligning categories, roles, and service templates.
2025-08-18 13:35:43 +02:00