The generic unit template could express neither an ordering dependency nor an Install section, so a role needing either shipped its own templates/systemctl.service.j2 and re-answered the daemon reload, the enable and the flush behaviour by hand.
Add After, Before, Wants, RemainAfterExit and a WantedBy driven Install section, all inert at their defaults, and route the unit path, its owner, become and the systemctl probes through a system_service_scope so a per-login unit lands under the user's own systemd directory.
00_core is gated on the system scope rather than only its prune and lockdown steps: it sets run_once_sys_service, so a user-scope caller running first would otherwise skip the lockdown for every system-scope role behind it in the same play.
Rendering the previous template against the same inputs drops no directive and adds none; the only difference is the blank line an empty directive used to leave behind.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- extended generic systemctl template to support ExecStartPost
- health-docker-volumes: run main script with whitelist, trigger both compose alarm and cleanup on failure
- repair-docker-hard: added ExecStartPre lock, ExecStart, and ExecStartPost to trigger compose alarm always, plus cleanup on failure
- removed obsolete role-specific systemctl.service.j2 templates
- improved consistency across vars and defaults
See: https://chatgpt.com/share/68ad6cb8-c164-800f-96b6-a45c6c7779b3
Introduced custom filter plugin to render optional systemd directives, refactored template to loop over directives, and adjusted default vars (TimeoutStartSec, RuntimeMaxSec handling).
Details: see ChatGPT conversation
https://chatgpt.com/share/68a5a730-6344-800f-b9a3-dc62d5902e9b
- Improved get_service_name filter plugin (clearer suffix handling, consistent var names).
- Added MODE_ASSERT flag to optionally execute validation/assertion tasks.
- Fixed systemd unit handling: consistent use of %I instead of %i, correct escaping of instance names.
- Unified on_failure behavior and alarm composer scripts.
- Cleaned up redundant logging, handlers, and debug config.
- Strengthened sys-service template resolution with assert (only active when MODE_ASSERT).
- Simplified timer and suffix handling with get_service_name filter.
- Hardened sensitive tasks with no_log.
- Added conditional asserts across roles (Keycloak, DNS, Mailu, Discourse, etc.).
These changes improve consistency, safety, and validation across the automation stack.
Conversation: https://chatgpt.com/share/68a4ae28-483c-800f-b2f7-f64c7124c274
- 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