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
This commit is contained in:
Kevin Veen-Birkenbach 2025-08-19 15:00:44 +02:00
parent b49fdc509e
commit 26b392ea76
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
104 changed files with 377 additions and 334 deletions

View File

@ -3,8 +3,6 @@
## Meta ## Meta
SYS_SERVICE_SUFFIX: ".{{ SOFTWARE_NAME | lower }}.service" SYS_SERVICE_SUFFIX: ".{{ SOFTWARE_NAME | lower }}.service"
SYS_SERVICE_ALL_ENABLED: "{{ not MODE_DEBUG }}" # Flush all services
SYS_SERVICE_DEFAULT_STATE: "{{ 'restarted' if MODE_DEBUG else omit }}"
## Names ## Names
SYS_SERVICE_CLEANUP_BACKUPS_OLD: "{{ 'sys-ctl-cln-bkps' | get_service_name(SOFTWARE_NAME) }}" SYS_SERVICE_CLEANUP_BACKUPS_OLD: "{{ 'sys-ctl-cln-bkps' | get_service_name(SOFTWARE_NAME) }}"

View File

@ -7,8 +7,8 @@ SYS_TIMER_ALL_ENABLED: "{{ not MODE_DEBUG }}" # Runtime Variables for Process
## Server Tact Variables ## Server Tact Variables
HOURS_SERVER_AWAKE: "0..23" # Ours in which the server is "awake" (100% working). Rest of the time is reserved for maintanance HOURS_SERVER_AWAKE: "0..23" # Ours in which the server is "awake" (100% working). Rest of the time is reserved for maintanance
RANDOMIZED_DELAY_SEC: "5min" # Random delay for systemd timers to avoid peak loads. RANDOMIZED_DELAY_SEC: "5min" # Random delay for systemd timers to avoid peak loads.
## Timeouts for all services ## Timeouts for all services
SYS_TIMEOUT_CLEANUP_SERVICES: "15min" SYS_TIMEOUT_CLEANUP_SERVICES: "15min"

View File

@ -23,4 +23,4 @@
to nonempty values in your configuration file. to nonempty values in your configuration file.
- include_role: - include_role:
name: sys-systemctl name: sys-service

View File

@ -5,7 +5,7 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart={{ systemctl_script_exec }} {{ BACKUP_TO_USB_SOURCE }} {{ BACKUP_TO_USB_DESTINATION }} ExecStart={{ system_service_script_exec }} {{ BACKUP_TO_USB_SOURCE }} {{ BACKUP_TO_USB_DESTINATION }}
ExecStartPost=/bin/systemctl start {{ SYS_SERVICE_CLEANUP_BACKUPS_OLD }} ExecStartPost=/bin/systemctl start {{ SYS_SERVICE_CLEANUP_BACKUPS_OLD }}
[Install] [Install]

View File

@ -1,5 +1,5 @@
application_id: "svc-bkp-loc-2-usb" application_id: "svc-bkp-loc-2-usb"
systemctl_id: "{{ application_id }}" system_service_id: "{{ application_id }}"
BACKUP_TO_USB_DESTINATION: '{{ BACKUP_TO_USB_MOUNT}}{{ BACKUP_TO_USB_TARGET }}' BACKUP_TO_USB_DESTINATION: '{{ BACKUP_TO_USB_MOUNT}}{{ BACKUP_TO_USB_TARGET }}'
BACKUPS_SERVICE_MNT_NAME: '{{ BACKUP_TO_USB_MOUNT | trim(''/'') | replace(''/'',''-'') }}.mount' BACKUPS_SERVICE_MNT_NAME: '{{ BACKUP_TO_USB_MOUNT | trim(''/'') | replace(''/'',''-'') }}.mount'

View File

@ -23,8 +23,8 @@
mode: "0755" mode: "0755"
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_timer_enabled: true system_service_timer_enabled: true
systemctl_on_calendar: "{{ SYS_SCHEDULE_BACKUP_REMOTE_TO_LOCAL }}" system_service_on_calendar: "{{ SYS_SCHEDULE_BACKUP_REMOTE_TO_LOCAL }}"

View File

@ -5,5 +5,5 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }} {{ SYS_SERVICE_CLEANUP_BACKUPS_FA
[Service] [Service]
Type=oneshot Type=oneshot
ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_BACKUPS| join(' ') }} --timeout "{{ SYS_TIMEOUT_BACKUP_SERVICES }}" ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_BACKUPS| join(' ') }} --timeout "{{ SYS_TIMEOUT_BACKUP_SERVICES }}"
ExecStart={{ systemctl_script_exec }} ExecStart={{ system_service_script_exec }}
ExecStartPost=/bin/systemctl start {{ SYS_SERVICE_CLEANUP_BACKUPS_OLD }} ExecStartPost=/bin/systemctl start {{ SYS_SERVICE_CLEANUP_BACKUPS_OLD }}

View File

@ -1,5 +1,5 @@
application_id: svc-bkp-rmt-2-loc application_id: svc-bkp-rmt-2-loc
systemctl_id: "{{ application_id }}" system_service_id: "{{ application_id }}"
DOCKER_BACKUP_REMOTE_2_LOCAL_DIR: '{{ PATH_ADMINISTRATOR_SCRIPTS }}{{ application_id }}/' DOCKER_BACKUP_REMOTE_2_LOCAL_DIR: '{{ PATH_ADMINISTRATOR_SCRIPTS }}{{ application_id }}/'
DOCKER_BACKUP_REMOTE_2_LOCAL_SCRIPT: "{{ DOCKER_BACKUP_REMOTE_2_LOCAL_DIR }}svc-bkp-rmt-2-loc.sh" DOCKER_BACKUP_REMOTE_2_LOCAL_SCRIPT: "{{ DOCKER_BACKUP_REMOTE_2_LOCAL_DIR }}svc-bkp-rmt-2-loc.sh"
DOCKER_BACKUP_REMOTE_2_LOCAL_BACKUP_PROVIDERS: "{{ applications | get_app_conf(application_id, 'backup_providers') }}" DOCKER_BACKUP_REMOTE_2_LOCAL_BACKUP_PROVIDERS: "{{ applications | get_app_conf(application_id, 'backup_providers') }}"

View File

@ -1,2 +1,2 @@
- include_role: - include_role:
name: sys-systemctl name: sys-service

View File

@ -4,7 +4,7 @@ Before=wg-quick@wg0.service
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart={{ systemctl_script_exec }} ExecStart={{ system_service_script_exec }}
[Install] [Install]
RequiredBy=wg-quick@wg0.service RequiredBy=wg-quick@wg0.service

View File

@ -1,2 +1,2 @@
application_id: svc-net-wireguard-plain application_id: svc-net-wireguard-plain
systemctl_id: "{{ application_id }}" system_service_id: "{{ application_id }}"

View File

@ -11,8 +11,8 @@
- msi-perkeyrgb - msi-perkeyrgb
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_on_calendar: "{{ SYS_SCHEDULE_ANIMATION_KEYBOARD_COLOR }}" system_service_on_calendar: "{{ SYS_SCHEDULE_ANIMATION_KEYBOARD_COLOR }}"
systemctl_timer_enabled: true system_service_timer_enabled: true
persistent: true persistent: true

View File

@ -4,4 +4,4 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart={{ systemctl_script_exec }} {{ vendor_and_product_id }} ExecStart={{ system_service_script_exec }} {{ vendor_and_product_id }}

View File

@ -1,3 +1,3 @@
application_id: svc-opt-keyboard-color application_id: svc-opt-keyboard-color
systemctl_id: "{{ application_id }}" system_service_id: "{{ application_id }}"
vendor_and_product_id: "{{ applications | get_app_conf(application_id, 'vendor_and_product_id') }}" vendor_and_product_id: "{{ applications | get_app_conf(application_id, 'vendor_and_product_id') }}"

View File

@ -1,2 +1,2 @@
- include_role: - include_role:
name: sys-systemctl name: sys-service

View File

@ -5,4 +5,4 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service] [Service]
Type=oneshot Type=oneshot
ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_OPTIMIZE_DRIVE }} {{ SYS_SERVICE_BACKUP_RMT_2_LOC }} --timeout "{{ SYS_TIMEOUT_STORAGE_OPTIMIZER }}" ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_OPTIMIZE_DRIVE }} {{ SYS_SERVICE_BACKUP_RMT_2_LOC }} --timeout "{{ SYS_TIMEOUT_STORAGE_OPTIMIZER }}"
ExecStart={{ systemctl_script_exec }} --mass-storage-path {{ OPT_DRIVE_MASS_STORAGE_PATH }} ExecStart={{ system_service_script_exec }} --mass-storage-path {{ OPT_DRIVE_MASS_STORAGE_PATH }}

View File

@ -1,4 +1,4 @@
application_id: svc-opt-ssd-hdd application_id: svc-opt-ssd-hdd
systemctl_id: "{{ application_id }}" system_service_id: "{{ application_id }}"
OPT_DRIVE_RAPID_STORAGE_PATH: "{{ applications | get_app_conf(application_id, 'volumes.rapid_storage') }}" OPT_DRIVE_RAPID_STORAGE_PATH: "{{ applications | get_app_conf(application_id, 'volumes.rapid_storage') }}"
OPT_DRIVE_MASS_STORAGE_PATH: "{{ applications | get_app_conf(application_id, 'volumes.mass_storage') }}" OPT_DRIVE_MASS_STORAGE_PATH: "{{ applications | get_app_conf(application_id, 'volumes.mass_storage') }}"

View File

@ -1,4 +1,4 @@
- name: "Include dependent services for '{{ systemctl_id }}'" - name: "Include dependent services for '{{ system_service_id }}'"
include_role: include_role:
name: '{{ item }}' name: '{{ item }}'
loop: loop:
@ -9,14 +9,14 @@
systemctl_timer_enabled: false systemctl_timer_enabled: false
systemctl_copy_files: true systemctl_copy_files: true
- name: "Include core service for '{{ systemctl_id }}'" - name: "Include core service for '{{ system_service_id }}'"
include_role: include_role:
name: sys-systemctl name: sys-service
vars: vars:
flush_handlers: true flush_handlers: true
systemctl_timer_enabled: false systemctl_timer_enabled: false
systemctl_copy_files: true systemctl_copy_files: true
systemctl_tpl_exec_start: "{{ systemctl_script_exec }} %i" systemctl_tpl_exec_start: "{{ system_service_script_exec }} %i"
systemctl_tpl_on_failure: "" # No on failure needed, because it's anyhow the default on failure procedure systemctl_tpl_on_failure: "" # No on failure needed, because it's anyhow the default on failure procedure
- name: "Send message to test service." - name: "Send message to test service."

View File

@ -1,4 +1,4 @@
systemctl_id: sys-ctl-alm-compose@ system_service_id: sys-ctl-alm-compose@
SYSTEMCTL_ALARM_COMPOSER_SUBSERVICES: SYSTEMCTL_ALARM_COMPOSER_SUBSERVICES:
- 'sys-ctl-alm-email' - 'sys-ctl-alm-email'

View File

@ -2,7 +2,7 @@
## Description ## Description
This role installs and configures the necessary components for sending email notifications via systemd when a service fails. It sets up the `{{ systemctl_id }}` service and configures email parameters and templates using msmtp. This role installs and configures the necessary components for sending email notifications via systemd when a service fails. It sets up the `{{ system_service_id }}` service and configures email parameters and templates using msmtp.
## Overview ## Overview

View File

@ -5,8 +5,8 @@
- sys-svc-msmtp - sys-svc-msmtp
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_copy_files: true system_service_copy_files: true

View File

@ -3,6 +3,6 @@ Description=status email for %i to user
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart={{ systemctl_script_exec }} %i ExecStart={{ system_service_script_exec }} %i
User=root User=root
Group=systemd-journal Group=systemd-journal

View File

@ -1 +1 @@
systemctl_id: sys-ctl-alm-email@ system_service_id: sys-ctl-alm-email@

View File

@ -10,9 +10,9 @@
- telegram_chat_id # The Telegram chat ID to send messages to - telegram_chat_id # The Telegram chat ID to send messages to
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_copy_files: true system_service_copy_files: true
- name: install curl - name: install curl
community.general.pacman: community.general.pacman:

View File

@ -3,6 +3,6 @@ Description=status Telegram message for %i to user
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart={{ systemctl_script_exec }} %i ExecStart={{ system_service_script_exec }} %i
User=root User=root
Group=systemd-journal Group=systemd-journal

View File

@ -1 +1 @@
systemctl_id: sys-ctl-alm-telegram@ system_service_id: sys-ctl-alm-telegram@

View File

@ -15,8 +15,8 @@
when: MODE_RESET | bool when: MODE_RESET | bool
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_copy_files: false system_service_copy_files: false
systemctl_timer_enabled: false system_service_timer_enabled: false
systemctl_on_calendar: "{{ SYS_SCHEDULE_BACKUP_DOCKER_TO_LOCAL }}" system_service_on_calendar: "{{ SYS_SCHEDULE_BACKUP_DOCKER_TO_LOCAL }}"

View File

@ -5,7 +5,7 @@
# - BKP_DOCKER_2_LOC_DISABLED: All images where backup.disabled is set (for --images-no-backup-required) # - BKP_DOCKER_2_LOC_DISABLED: All images where backup.disabled is set (for --images-no-backup-required)
# CLI-ready variables render these lists as argument strings. # CLI-ready variables render these lists as argument strings.
systemctl_id: sys-ctl-bkp-docker-2-loc system_service_id: sys-ctl-bkp-docker-2-loc
# Verify if DB is enabled # Verify if DB is enabled
BKP_DOCKER_2_LOC_DB_ENABLED: "{{ database_type | default('') | bool }}" BKP_DOCKER_2_LOC_DB_ENABLED: "{{ database_type | default('') | bool }}"

View File

@ -14,4 +14,4 @@
state: present state: present
- include_role: - include_role:
name: sys-systemctl name: sys-service

View File

@ -5,4 +5,4 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service] [Service]
Type=oneshot Type=oneshot
ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP | join(' ') }} --timeout "{{ SYS_TIMEOUT_BACKUP_SERVICES }}" ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP | join(' ') }} --timeout "{{ SYS_TIMEOUT_BACKUP_SERVICES }}"
ExecStart={{ systemctl_script_exec }} --backups-folder-path {{ BACKUPS_FOLDER_PATH }} --maximum-backup-size-percent {{SIZE_PERCENT_MAXIMUM_BACKUP}} ExecStart={{ system_service_script_exec }} --backups-folder-path {{ BACKUPS_FOLDER_PATH }} --maximum-backup-size-percent {{SIZE_PERCENT_MAXIMUM_BACKUP}}

View File

@ -1 +1 @@
systemctl_id: "sys-ctl-cln-bkps" system_service_id: "sys-ctl-cln-bkps"

View File

@ -12,8 +12,8 @@
package_name: certreap package_name: certreap
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_timer_enabled: true system_service_timer_enabled: true
systemctl_on_calendar: "{{ SYS_SCHEDULE_CLEANUP_CERTS }}" system_service_on_calendar: "{{ SYS_SCHEDULE_CLEANUP_CERTS }}"
systemctl_copy_files: false system_service_copy_files: false

View File

@ -1 +1 @@
systemctl_id: sys-ctl-cln-certs system_service_id: sys-ctl-cln-certs

View File

@ -6,7 +6,7 @@
- sys-lock - sys-lock
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_timer_enabled: true system_service_timer_enabled: true
systemctl_on_calendar: "{{SYS_SCHEDULE_CLEANUP_DISC_SPACE}}" system_service_on_calendar: "{{SYS_SCHEDULE_CLEANUP_DISC_SPACE}}"

View File

@ -5,4 +5,4 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service] [Service]
Type=oneshot Type=oneshot
ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP| join(' ') }} --timeout "{{ SYS_TIMEOUT_BACKUP_SERVICES }}" ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP| join(' ') }} --timeout "{{ SYS_TIMEOUT_BACKUP_SERVICES }}"
ExecStart={{ systemctl_script_exec }} {{ SIZE_PERCENT_CLEANUP_DISC_SPACE }} ExecStart={{ system_service_script_exec }} {{ SIZE_PERCENT_CLEANUP_DISC_SPACE }}

View File

@ -1 +1 @@
systemctl_id: "sys-ctl-cln-disc-space" system_service_id: "sys-ctl-cln-disc-space"

View File

@ -24,8 +24,8 @@
changed_when: false changed_when: false
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_timer_enabled: true system_service_timer_enabled: true
systemctl_on_calendar: "{{SYS_SCHEDULE_CLEANUP_FAILED_BACKUPS}}" system_service_on_calendar: "{{SYS_SCHEDULE_CLEANUP_FAILED_BACKUPS}}"
systemctl_copy_files: false system_service_copy_files: false

View File

@ -1,2 +1,2 @@
systemctl_id: sys-ctl-cln-faild-bkps system_service_id: sys-ctl-cln-faild-bkps
CLN_FAILED_DOCKER_BACKUPS_PKG: cleanup-failed-docker-backups CLN_FAILED_DOCKER_BACKUPS_PKG: cleanup-failed-docker-backups

View File

@ -4,7 +4,7 @@
when: run_once_sys_ctl_alm_compose is not defined when: run_once_sys_ctl_alm_compose is not defined
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_on_calendar: "{{SYS_SCHEDULE_HEALTH_BTRFS}}" system_service_on_calendar: "{{SYS_SCHEDULE_HEALTH_BTRFS}}"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -1 +1 @@
systemctl_id: sys-ctl-hlth-btrfs system_service_id: sys-ctl-hlth-btrfs

View File

@ -11,7 +11,7 @@
package_notify: rebuild checkcsp docker image package_notify: rebuild checkcsp docker image
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_on_calendar: "{{ SYS_SCHEDULE_HEALTH_CSP_CRAWLER }}" system_service_on_calendar: "{{ SYS_SCHEDULE_HEALTH_CSP_CRAWLER }}"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -4,4 +4,4 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart={{ systemctl_script_exec }} --nginx-config-dir={{ NGINX.DIRECTORIES.HTTP.SERVERS }} ExecStart={{ system_service_script_exec }} --nginx-config-dir={{ NGINX.DIRECTORIES.HTTP.SERVERS }}

View File

@ -1 +1 @@
systemctl_id: sys-ctl-hlth-csp system_service_id: sys-ctl-hlth-csp

View File

@ -7,7 +7,7 @@
when: run_once_sys_ctl_hlth_disc_space is not defined when: run_once_sys_ctl_hlth_disc_space is not defined
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_on_calendar: "{{ SYS_SCHEDULE_HEALTH_DISC_SPACE }}" system_service_on_calendar: "{{ SYS_SCHEDULE_HEALTH_DISC_SPACE }}"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -1 +1 @@
systemctl_id: sys-ctl-hlth-disc-space system_service_id: sys-ctl-hlth-disc-space

View File

@ -4,7 +4,7 @@
when: run_once_sys_ctl_alm_compose is not defined when: run_once_sys_ctl_alm_compose is not defined
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_timer_enabled: true system_service_timer_enabled: true
systemctl_on_calendar: "{{ SYS_SCHEDULE_HEALTH_DOCKER_CONTAINER }}" system_service_on_calendar: "{{ SYS_SCHEDULE_HEALTH_DOCKER_CONTAINER }}"

View File

@ -1 +1 @@
systemctl_id: sys-ctl-hlth-docker-container system_service_id: sys-ctl-hlth-docker-container

View File

@ -4,7 +4,7 @@
when: run_once_sys_ctl_alm_compose is not defined when: run_once_sys_ctl_alm_compose is not defined
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_on_calendar: "{{SYS_SCHEDULE_HEALTH_DOCKER_VOLUMES}}" system_service_on_calendar: "{{SYS_SCHEDULE_HEALTH_DOCKER_VOLUMES}}"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -4,4 +4,4 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart={{ systemctl_script_exec }} "{{ DOCKER_WHITELISTET_ANON_VOLUMES | join(' ') }}" ExecStart={{ system_service_script_exec }} "{{ DOCKER_WHITELISTET_ANON_VOLUMES | join(' ') }}"

View File

@ -1 +1 @@
systemctl_id: sys-ctl-hlth-docker-volumes system_service_id: sys-ctl-hlth-docker-volumes

View File

@ -4,7 +4,7 @@
when: run_once_sys_ctl_alm_compose is not defined when: run_once_sys_ctl_alm_compose is not defined
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_on_calendar: "{{SYS_SCHEDULE_HEALTH_JOURNALCTL}}" system_service_on_calendar: "{{SYS_SCHEDULE_HEALTH_JOURNALCTL}}"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -1 +1 @@
systemctl_id: sys-ctl-hlth-journalctl system_service_id: sys-ctl-hlth-journalctl

View File

@ -4,7 +4,7 @@
when: run_once_sys_ctl_alm_telegram is not defined when: run_once_sys_ctl_alm_telegram is not defined
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_on_calendar: "{{ SYS_SCHEDULE_HEALTH_MSMTP }}" system_service_on_calendar: "{{ SYS_SCHEDULE_HEALTH_MSMTP }}"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -1,2 +1,2 @@
systemctl_id: sys-ctl-hlth-msmtp system_service_id: sys-ctl-hlth-msmtp

View File

@ -14,7 +14,7 @@
state: present state: present
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_on_calendar: "{{SYS_SCHEDULE_HEALTH_NGINX}}" system_service_on_calendar: "{{SYS_SCHEDULE_HEALTH_NGINX}}"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -1 +1 @@
systemctl_id: sys-ctl-hlth-webserver system_service_id: sys-ctl-hlth-webserver

View File

@ -4,9 +4,9 @@
when: run_once_sys_ctl_alm_compose is not defined when: run_once_sys_ctl_alm_compose is not defined
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_state: restarted system_service_state: restarted
systemctl_on_calendar: "{{ SYS_SCHEDULE_MAINTANANCE_LETSENCRYPT_DEPLOY }}" system_service_on_calendar: "{{ SYS_SCHEDULE_MAINTANANCE_LETSENCRYPT_DEPLOY }}"
persistent: "true" persistent: "true"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -4,4 +4,4 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service] [Service]
Type=oneshot Type=oneshot
ExecStart={{ systemctl_script_exec }} {{ ssl_cert_folder }} {{ docker_compose.directories.instance }} {{ LETSENCRYPT_LIVE_PATH }} ExecStart={{ system_service_script_exec }} {{ ssl_cert_folder }} {{ docker_compose.directories.instance }} {{ LETSENCRYPT_LIVE_PATH }}

View File

@ -1 +1 @@
systemctl_id: "sys-ctl-mtn-cert-deploy" system_service_id: "sys-ctl-mtn-cert-deploy"

View File

@ -13,9 +13,9 @@
state: present state: present
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_copy_files: false system_service_copy_files: false
systemctl_on_calendar: "{{ SYS_SCHEDULE_MAINTANANCE_LETSENCRYPT_RENEW }}" system_service_on_calendar: "{{ SYS_SCHEDULE_MAINTANANCE_LETSENCRYPT_RENEW }}"
persistent: true persistent: true
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -1 +1 @@
systemctl_id: sys-ctl-mtn-cert-renew system_service_id: sys-ctl-mtn-cert-renew

View File

@ -10,8 +10,8 @@
package_name: btrfs-auto-balancer package_name: btrfs-auto-balancer
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_copy_files: false system_service_copy_files: false
systemctl_on_calendar: "{{SYS_SCHEDULE_REPAIR_BTRFS_AUTO_BALANCER}}" system_service_on_calendar: "{{SYS_SCHEDULE_REPAIR_BTRFS_AUTO_BALANCER}}"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -1 +1 @@
systemctl_id: sys-ctl-rpr-btrfs-balancer system_service_id: sys-ctl-rpr-btrfs-balancer

View File

@ -4,7 +4,7 @@
when: run_once_sys_lock is not defined when: run_once_sys_lock is not defined
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_on_calendar: "{{SYS_SCHEDULE_REPAIR_DOCKER_HARD}}" system_service_on_calendar: "{{SYS_SCHEDULE_REPAIR_DOCKER_HARD}}"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -5,4 +5,4 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service] [Service]
Type=oneshot Type=oneshot
ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP | join(' ') }} {{ SYS_SERVICE_REPAIR_DOCKER_HARD }} --timeout "{{ SYS_TIMEOUT_RESTART_DOCKER }}" ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP | join(' ') }} {{ SYS_SERVICE_REPAIR_DOCKER_HARD }} --timeout "{{ SYS_TIMEOUT_RESTART_DOCKER }}"
ExecStart={{ systemctl_script_exec }} ExecStart={{ system_service_script_exec }}

View File

@ -1,2 +1,2 @@
systemctl_id: sys-ctl-rpr-docker-hard system_service_id: sys-ctl-rpr-docker-hard

View File

@ -4,7 +4,7 @@
when: run_once_sys_lock is not defined when: run_once_sys_lock is not defined
- include_role: - include_role:
name: sys-systemctl name: sys-service
vars: vars:
systemctl_on_calendar: "{{SYS_SCHEDULE_REPAIR_DOCKER_SOFT}}" system_service_on_calendar: "{{SYS_SCHEDULE_REPAIR_DOCKER_SOFT}}"
systemctl_timer_enabled: true system_service_timer_enabled: true

View File

@ -5,4 +5,4 @@ OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
[Service] [Service]
Type=oneshot Type=oneshot
ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP| join(' ') }} {{ SYS_SERVICE_REPAIR_DOCKER_SOFT }} --timeout "{{ SYS_TIMEOUT_HEAL_DOCKER }}" ExecStartPre=/usr/bin/python {{ PATH_SYSTEM_LOCK_SCRIPT }} {{ SYS_SERVICE_GROUP_MANIPULATION | join(' ') }} --ignore {{ SYS_SERVICE_GROUP_CLEANUP| join(' ') }} {{ SYS_SERVICE_REPAIR_DOCKER_SOFT }} --timeout "{{ SYS_TIMEOUT_HEAL_DOCKER }}"
ExecStart=/bin/sh -c '{{ systemctl_script_exec }} {{ PATH_DOCKER_COMPOSE_INSTANCES }}' ExecStart=/bin/sh -c '{{ system_service_script_exec }} {{ PATH_DOCKER_COMPOSE_INSTANCES }}'

View File

@ -1 +1 @@
systemctl_id: sys-ctl-rpr-docker-soft system_service_id: sys-ctl-rpr-docker-soft

View File

@ -1,44 +1,26 @@
# Core Daemon Reset # sys-daemon
## Description ## Description
This role resets and cleans up all **Infinito.Nexus** core daemon `systemd` service units that match the configured suffix (`SYS_SERVICE_SUFFIX`). Role to reset and configure the **systemd manager** for Infinito.Nexus.
It is primarily used in maintenance or reset scenarios when a full service cleanup is required. It ensures a clean state of the manager configuration and applies default timeout values.
## Overview ## Overview
When the `MODE_RESET` flag is enabled, the role will: - Purges the systemd manager drop-in directory if requested.
- Validates all active unit files before reload/reexec.
1. **Run Once Per Play:** Guarded by `run_once_sys_daemon` to avoid duplicate execution. - Applies default timeout values for systemd manager behavior.
2. **Identify Service Units:** Finds all `/etc/systemd/system/*{{ SYS_SERVICE_SUFFIX }}` units. - Provides handler-based reload/reexec for systemd.
3. **Stop and Disable Services:** Gracefully stops and disables matching services.
4. **Remove Unit Files:** Deletes the corresponding unit files from the system.
5. **Reload systemd:** Ensures the service manager state is updated after cleanup.
## Purpose
The main goal of this role is to ensure a clean and consistent state for core daemon services by removing obsolete or stale systemd units.
This is particularly useful when re-deploying or performing a full environment reset.
## Features ## Features
- **Automated Cleanup:** Stops, disables, and removes targeted systemd units. - **Drop-in Purge:** Optionally remove `/etc/systemd/system.conf.d` contents.
- **Idempotent Execution:** Runs only once per playbook run. - **Manager Defaults:** Deploys custom timeouts via `timeouts.conf`.
- **Configurable Targeting:** Matches services using `SYS_SERVICE_SUFFIX`. - **Validation:** Uses `systemd-analyze verify` before reload.
- **Systemd Integration:** Reloads daemon state after changes. - **Integration:** Triggers `daemon-reload` or `daemon-reexec` safely.
## Further Resources ## Further Resources
- [systemd Service Management](https://www.freedesktop.org/software/systemd/man/systemctl.html) - [systemd - Manager Configuration](https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html)
- [Infinito.Nexus License](https://s.infinito.nexus/license) - [systemd-analyze](https://www.freedesktop.org/software/systemd/man/systemd-analyze.html)
- [systemctl](https://www.freedesktop.org/software/systemd/man/systemctl.html)
## License
This role is released under the Infinito.Nexus NonCommercial License.
See [license details](https://s.infinito.nexus/license)
## Author Information
Kevin Veen-Birkenbach
Consulting & Coaching Solutions
[https://www.veen.world](https://www.veen.world)

View File

@ -0,0 +1,8 @@
# General
SYSTEMD_MANAGER_CONF_DIR: "/etc/systemd/system.conf.d"
# Defaults
SYSTEMD_DEFAULT_TIMEOUT_START: "90s" # Maximum time a service is allowed to reach the 'active' state during startup
SYSTEMD_DEFAULT_TIMEOUT_STOP: "90s" # Maximum time a service is allowed to stop gracefully before being killed
SYSTEMD_DEFAULT_TIMEOUT_ABORT: "90s" # Additional grace period after Stop timeout before systemd sends SIGKILL

View File

@ -1,4 +1,49 @@
- name: "reload system daemon" - name: collect systemd unit files
shell: |
shopt -s nullglob
files=({{ PATH_SYSTEM_SERVICE_DIR }}*.service {{ PATH_SYSTEM_SERVICE_DIR }}*.timer)
printf "%s\n" "${files[@]}"
args:
executable: /bin/bash
register: _unit_files
changed_when: false
failed_when: false
become: true
listen:
- reload system daemon
- reexec systemd manager
- name: validate systemd units
shell: |
systemd-analyze verify {{ _unit_files.stdout_lines | join(' ') }}
register: _verify_units
changed_when: false
failed_when: _unit_files.stdout | length > 0 and _verify_units.rc != 0
become: true
when: _unit_files.stdout | length > 0
listen:
- reload system daemon
- reexec systemd manager
- name: show merged manager config
command: systemd-analyze cat-config systemd/system.conf
register: _catcfg
changed_when: false
become: true
listen:
- reload system daemon
- reexec systemd manager
- name: reload system daemon
command: systemctl daemon-reload command: systemctl daemon-reload
become: true
listen: reload system daemon
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"
- name: reexec systemd manager
command: systemctl daemon-reexec
become: true
listen: reexec systemd manager
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"

View File

@ -1,19 +1,19 @@
---
galaxy_info: galaxy_info:
author: "Kevin Veen-Birkenbach" author: "Kevin Veen-Birkenbach"
description: "Role to reset and clean up Infinito.Nexus systemd service units for the core daemon." description: "Role to reset and configure the systemd manager (drop-ins, defaults, validation)."
company: | license: "Infinito.Nexus NonCommercial License"
license_url: "https://s.infinito.nexus/license"
company: |
Kevin Veen-Birkenbach Kevin Veen-Birkenbach
Consulting & Coaching Solutions Consulting & Coaching Solutions
https://www.veen.world https://www.veen.world
license: "Infinito.Nexus NonCommercial License"
license_url: "https://s.infinito.nexus/license"
min_ansible_version: "2.9"
galaxy_tags: galaxy_tags:
- systemd - systemd
- cleanup
- infinito - infinito
- daemon
- cleanup
repository: "https://s.infinito.nexus/code" repository: "https://s.infinito.nexus/code"
issue_tracker_url: "https://s.infinito.nexus/issues" issue_tracker_url: "https://s.infinito.nexus/issues"
documentation: "https://s.infinito.nexus/code/#sys-daemon-role" documentation: "https://www.freedesktop.org/software/systemd/man/systemd-system.conf.html"
dependencies: [] dependencies: []

View File

@ -0,0 +1,16 @@
- name: reload system daemon
command: /bin/true
notify: "reload system daemon"
- name: "Sanity check SYSTEMD_MANAGER_CONF_DIR"
assert:
that:
- SYSTEMD_MANAGER_CONF_DIR | regex_search('^/etc/systemd/system\.conf\.d/?$')
fail_msg: "SYSTEMD_MANAGER_CONF_DIR must be /etc/systemd/system.conf.d"
when: SYSTEMD_MANAGER_RESET_PURGE | bool
- name: "Purge manager drop-in directory (remove)"
file:
path: "{{ SYSTEMD_MANAGER_CONF_DIR }}"
state: absent
notify: reexec systemd manager

View File

@ -0,0 +1,12 @@
- name: "Ensure {{ SYSTEMD_MANAGER_CONF_DIR }} exists"
file:
path: "{{ SYSTEMD_MANAGER_CONF_DIR }}"
state: directory
mode: "0755"
- name: Deploy systemd manager default timeout settings
template:
src: timeouts.conf.j2
dest: "{{ SYSTEMD_MANAGER_CONF_DIR }}/timeouts.conf"
mode: "0644"
notify: reexec systemd manager

View File

@ -1,8 +1,8 @@
- name: "reset (if enabled)" - block:
include_tasks: reset.yml - name: "reset (if enabled)"
when: MODE_RESET | bool and run_once_sys_daemon is not defined include_tasks: 01_reset.yml
when: MODE_RESET | bool and run_once_sys_daemon is not defined
- name: run {{ role_name }} once - name: Apply systemd manager defaults
set_fact: include_tasks: 02_defaults.yml
run_once_sys_daemon: true - include_tasks: utils/run_once.yml
when: run_once_sys_daemon is not defined when: run_once_sys_daemon is not defined

View File

@ -1,3 +0,0 @@
- name: reload system daemon
command: /bin/true
notify: "reload system daemon"

View File

@ -0,0 +1,4 @@
[Manager]
DefaultTimeoutStartSec={{ SYSTEMD_DEFAULT_TIMEOUT_START }}
DefaultTimeoutStopSec={{ SYSTEMD_DEFAULT_TIMEOUT_STOP }}
DefaultTimeoutAbortSec={{ SYSTEMD_DEFAULT_TIMEOUT_ABORT }}

View File

@ -0,0 +1,27 @@
# sys-service
## Description
Role to manage **systemd service units** for Infinito.Nexus software stacks.
It installs or removes unit files, configures runtime behavior, and ensures services are properly deployed.
## Overview
- Resets service units by removing old or obsolete definitions.
- Deploys new service unit files and service scripts.
- Optionally sets up timers linked to the services.
- Ensures correct reload/restart behavior across the stack.
## Features
- **Unit Cleanup:** Automated removal of old service units.
- **Custom Templates:** Supports both `systemctl.service.j2` and `systemctl@.service.j2`.
- **Timers:** Integrates with `sys-timer` for scheduled execution.
- **Runtime Limits:** Configurable `RuntimeMaxSec` per service.
- **Handlers:** Automatic reload/restart of services when definitions change.
## Further Resources
- [systemd - Service Units](https://www.freedesktop.org/software/systemd/man/systemd.service.html)
- [systemd - Timer Units](https://www.freedesktop.org/software/systemd/man/systemd.timer.html)
- [systemctl](https://www.freedesktop.org/software/systemd/man/systemctl.html)

View File

@ -0,0 +1,3 @@
SYS_SERVICE_ALL_ENABLED: "{{ not MODE_DEBUG }}"
SYS_SERVICE_DEFAULT_STATE: "{{ 'restarted' if MODE_DEBUG else omit }}"
SYS_SERVICE_DEFAULT_RUNTIME: "86400s" # Maximum total runtime a service is allowed to run before being stopped

View File

@ -1,8 +1,8 @@
- name: "refresh systemctl service" - name: "refresh systemctl service"
systemd: systemd:
name: "{{ systemctl_id | get_service_name(SOFTWARE_NAME) }}" name: "{{ system_service_id | get_service_name(SOFTWARE_NAME) }}"
daemon_reload: yes daemon_reload: yes
enabled: yes enabled: yes
state: "{{ systemctl_state }}" state: "{{ system_service_state }}"
async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}"
poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}"

View File

@ -1,10 +1,10 @@
--- ---
galaxy_info: galaxy_info:
author: "Kevin Veen-Birkenbach" author: "Kevin Veen-Birkenbach"
description: "Utility role to reset/clean up systemd units for a given software stack." description: "Role to manage systemd service units, including cleanup, deployment, and runtime configuration."
license: "Infinito.Nexus NonCommercial License" license: "Infinito.Nexus NonCommercial License"
license_url: "https://s.infinito.nexus/license" license_url: "https://s.infinito.nexus/license"
company: | company: |
Kevin Veen-Birkenbach Kevin Veen-Birkenbach
Consulting & Coaching Solutions Consulting & Coaching Solutions
https://www.veen.world https://www.veen.world
@ -16,9 +16,9 @@ galaxy_info:
galaxy_tags: galaxy_tags:
- systemd - systemd
- services - services
- cleanup
- reset
- automation - automation
- infinito
repository: "https://s.infinito.nexus/code" repository: "https://s.infinito.nexus/code"
issue_tracker_url: "https://s.infinito.nexus/issues" issue_tracker_url: "https://s.infinito.nexus/issues"
documentation: "https://docs.infinito.nexus" documentation: "https://www.freedesktop.org/software/systemd/man/systemd.service.html"
dependencies: []

View File

@ -1,7 +1,6 @@
# roles/sys-systemctl/tasks/03_base.yml
- name: "find best matching source for service script" - name: "find best matching source for service script"
set_fact: set_fact:
systemctl_script_src: >- system_service_script_src: >-
{{ lookup('first_found', {{ lookup('first_found',
{ {
'files': [ 'files': [
@ -10,21 +9,21 @@
'files/script.sh', 'files/script.sh',
'files/script.py' 'files/script.py'
], ],
'paths': [ systemctl_role_dir ] 'paths': [ system_service_role_dir ]
}, },
errors='strict' errors='strict'
) }} ) }}
when: systemctl_copy_files | bool when: system_service_copy_files | bool
- name: "Load file logic for '{{ systemctl_id }}'" - name: "Load file logic for '{{ system_service_id }}'"
include_tasks: 04_files.yml include_tasks: 04_files.yml
when: when:
- systemctl_copy_files | bool - system_service_copy_files | bool
- systemctl_script_src - system_service_script_src
- name: "Load systemctl logic for '{{ systemctl_id }}'" - name: "Load systemctl logic for '{{ system_service_id }}'"
include_tasks: 05_service.yml include_tasks: 05_service.yml
- name: "Load timer logic for '{{ systemctl_id }}'" - name: "Load timer logic for '{{ system_service_id }}'"
include_tasks: 06_timer.yml include_tasks: 06_timer.yml
when: systemctl_timer_enabled | bool when: system_service_timer_enabled | bool

View File

@ -0,0 +1,23 @@
- name: "create {{ system_service_script_dir }}"
file:
path: "{{ system_service_script_dir }}"
state: directory
mode: "0755"
- name: "template or copy script"
block:
- name: "render template"
template:
src: "{{ system_service_script_src }}"
dest: "{{ [system_service_script_dir, (system_service_script_src | basename | regex_replace('\\.j2$', ''))] | path_join }}"
mode: "0755"
when: system_service_script_src.endswith('.j2')
- name: "copy raw file"
copy:
src: "{{ system_service_script_src }}"
dest: "{{ [system_service_script_dir, (system_service_script_src | basename)] | path_join }}"
mode: "0755"
when: not system_service_script_src.endswith('.j2')
when: system_service_copy_files | bool

View File

@ -1,7 +1,7 @@
# 1) Find the template (prefer target role, then fall back to this role) # 1) Find the template (prefer target role, then fall back to this role)
- name: Resolve systemctl template source - name: Resolve systemctl template source
set_fact: set_fact:
systemctl_template_src: >- system_service_template_src: >-
{{ lookup( {{ lookup(
'first_found', 'first_found',
{ {
@ -10,7 +10,7 @@
'templates/systemctl.service.j2' 'templates/systemctl.service.j2'
], ],
'paths': [ 'paths': [
systemctl_role_dir, system_service_role_dir,
role_path role_path
] ]
}, },
@ -20,22 +20,22 @@
# Optional: sanity check with a clear error if truly nothing found # Optional: sanity check with a clear error if truly nothing found
- name: Ensure a systemctl template was found - name: Ensure a systemctl template was found
assert: assert:
that: systemctl_template_src | length > 0 that: system_service_template_src | length > 0
fail_msg: >- fail_msg: >-
Could not resolve any systemctl template. Looked in: Could not resolve any systemctl template. Looked in:
{{ systemctl_role_dir }}/templates/ and {{ role_path }}/templates/. {{ system_service_role_dir }}/templates/ and {{ role_path }}/templates/.
# 2) Now we may safely derive whether its the “@” variant # 2) Now we may safely derive whether its the “@” variant
- name: Flag whether @-template is used - name: Flag whether @-template is used
set_fact: set_fact:
systemctl_uses_at: "{{ (systemctl_template_src | basename) is search('@\\.service\\.j2$') }}" system_service_uses_at: "{{ (system_service_template_src | basename) is search('@\\.service\\.j2$') }}"
# 3) Use it # 3) Use it
- name: "setup systemctl '{{ systemctl_id }}'" - name: "setup systemctl '{{ system_service_id }}'"
template: template:
src: "{{ systemctl_template_src }}" src: "{{ system_service_template_src }}"
dest: "{{ [ PATH_SYSTEM_SERVICE_DIR, systemctl_id | get_service_name(SOFTWARE_NAME) ] | path_join }}" dest: "{{ [ PATH_SYSTEM_SERVICE_DIR, system_service_id | get_service_name(SOFTWARE_NAME) ] | path_join }}"
notify: "{{ 'reload system daemon' if systemctl_uses_at else 'refresh systemctl service' }}" notify: "{{ 'reload system daemon' if system_service_uses_at else 'refresh systemctl service' }}"
- name: refresh systemctl service when SYS_SERVICE_ALL_ENABLED - name: refresh systemctl service when SYS_SERVICE_ALL_ENABLED
command: /bin/true command: /bin/true
@ -44,4 +44,4 @@
- refresh systemctl service - refresh systemctl service
when: when:
- SYS_SERVICE_ALL_ENABLED | bool - SYS_SERVICE_ALL_ENABLED | bool
- not systemctl_uses_at - not system_service_uses_at

View File

@ -0,0 +1,13 @@
- name: Fail if system_service_id contains "@"
assert:
that:
- "'@' not in system_service_id"
fail_msg: "Invalid system_service_id '{{ system_service_id }}' → must not contain '@'."
- name: "Make '{{ system_service_id }}' available for sys-timer"
set_fact:
system_service_timer_service: "{{ system_service_id }}"
- name: "include role for sys-timer for {{ system_service_timer_service }}"
include_role:
name: sys-timer

View File

@ -1,14 +1,14 @@
- block: - block:
- include_tasks: 01_core.yml - include_tasks: 01_core.yml
- include_tasks: utils/run_once.yml - include_tasks: utils/run_once.yml
when: run_once_sys_systemctl is not defined when: run_once_sys_service is not defined
- name: "Execute service routines for '{{ systemctl_id }}'" - name: "Execute service routines for '{{ system_service_id }}'"
block: block:
- name: "Load base routine for '{{ systemctl_id }}'" - name: "Load base routine for '{{ system_service_id }}'"
include_tasks: 03_base.yml include_tasks: 03_base.yml
- include_tasks: utils/run_once.yml - include_tasks: utils/run_once.yml
vars: vars:
# Necessary to flush after every service which uses an 'systemctl_id' otherwise wrong one will be used # Necessary to flush after every service which uses an 'system_service_id' otherwise wrong one will be used
flush_handlers: true flush_handlers: true
when: systemctl_id is defined when: system_service_id is defined

View File

@ -0,0 +1,10 @@
[Unit]
Description={{ SOFTWARE_NAME }} - Service for role '{{ system_service_id }}'
OnFailure={{ system_service_tpl_on_failure }}
[Service]
Type={{ system_service_tpl_type }}
ExecStart={{ system_service_tpl_exec_start }}
{% if system_service_tpl_runtime |length > 0 %}
RuntimeMaxSec={{ system_service_tpl_runtime }}
{% endif %}

View File

@ -0,0 +1,23 @@
UNIT_SUFFIX_REMOVER_PACKAGE: "unsure"
## Paths
system_service_role_name: "{{ system_service_id | regex_replace('@','') }}"
system_service_role_dir: "{{ [ playbook_dir, 'roles', system_service_role_name ] | path_join }}"
system_service_script_dir: "{{ [ PATH_SYSTEMCTL_SCRIPTS, system_service_id ] | path_join }}"
## Settings
system_service_copy_files: true # When set to false file copying will be skipped
system_service_timer_enabled: false # When set to true timer will be loaded
system_service_state: "{{ SYS_SERVICE_DEFAULT_STATE }}"
# Dynamic Loaded ( Just available when dependencies are loaded )
system_service_script_base: "{{ system_service_script_src | basename | regex_replace('\\.j2$', '') }}"
system_service_script_type: "{{ system_service_script_base | filetype }}"
system_service_script_inter: "/bin/{{ 'bash' if system_service_script_type == 'sh' else 'python3'}}"
system_service_script_exec: "{{ system_service_script_inter }} {{ system_service_id | get_service_script_path( system_service_script_type ) }}"
# Service template
system_service_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
system_service_tpl_type: "oneshot"
system_service_tpl_exec_start: "{{ system_service_script_exec }}"
system_service_tpl_runtime: "{{ SYS_SERVICE_DEFAULT_RUNTIME }}"

View File

@ -1,52 +0,0 @@
# sys-systemctl
Utility role to reset/clean up **systemd** units for a given software stack.
It can install a unit-file remover tool, delete units that match a configured suffix, and reload the systemd daemon. The role is designed to run **once per play** and is commonly included by other roles (e.g., timer/service roles) to ensure a clean state before (re)deployment.
## Overview
When `MODE_RESET` is enabled, the role will:
1. Install the configured remover tool/package (via `pkgmgr-install`).
2. Remove all unit files that match the configured suffix for the current software.
3. Reload the systemd daemon to apply changes.
A run-once guard (`run_once_sys_systemctl`) prevents repeated execution within the same play run.
## Features
- **Idempotent cleanup** of systemd unit files based on a suffix.
- **Pluggable remover tool** via `UNIT_SUFFIX_REMOVER_PACKAGE`.
- **Daemon reload** to immediately apply changes.
- **Run-once safety** across the play to avoid redundant work.
## Variables
| Variable | Type | Default | Description |
|-----------------------------|---------|-------------|---------------------------------------------------------------------------------------------|
| `MODE_RESET` | bool | `false` | If `true`, executes the reset/cleanup tasks. |
| `SYS_SERVICE_SUFFIX` | string | *required* | Suffix used to identify unit files belonging to the software stack (e.g., `.infinito.nexus`). |
| `SOFTWARE_NAME` | string | *required* | Logical software identifier passed to the remover tool. |
| `UNIT_SUFFIX_REMOVER_PACKAGE` | string| `"unsure"` | Package/command used to remove the unit files. Must provide a CLI compatible with `-s`. |
> **Note:** The role expects the remover tool to support a command pattern like:
> ```
> <UNIT_SUFFIX_REMOVER_PACKAGE> -s '<SOFTWARE_NAME>'
> ```
> Replace `UNIT_SUFFIX_REMOVER_PACKAGE` with your actual utility (or wrapper script) that removes all matching unit files.
## Tasks Flow
- `tasks/main.yml`
- Includes `tasks/01_reset.yml` **only when** `MODE_RESET` is `true`.
- Loads `utils/run_once.yml` once to set `run_once_sys_systemctl`.
- `tasks/01_reset.yml`
- Installs `UNIT_SUFFIX_REMOVER_PACKAGE` via `pkgmgr-install`.
- Executes the remover command to purge unit files for `SOFTWARE_NAME` / `SYS_SERVICE_SUFFIX`.
- Runs `systemctl daemon-reload`.
## Dependencies
- `pkgmgr-install` (role): used to install `UNIT_SUFFIX_REMOVER_PACKAGE`.

View File

@ -1,23 +0,0 @@
- name: "create {{ systemctl_script_dir }}"
file:
path: "{{ systemctl_script_dir }}"
state: directory
mode: "0755"
- name: "template or copy script"
block:
- name: "render template"
template:
src: "{{ systemctl_script_src }}"
dest: "{{ [systemctl_script_dir, (systemctl_script_src | basename | regex_replace('\\.j2$', ''))] | path_join }}"
mode: "0755"
when: systemctl_script_src.endswith('.j2')
- name: "copy raw file"
copy:
src: "{{ systemctl_script_src }}"
dest: "{{ [systemctl_script_dir, (systemctl_script_src | basename)] | path_join }}"
mode: "0755"
when: not systemctl_script_src.endswith('.j2')
when: systemctl_copy_files | bool

View File

@ -1,13 +0,0 @@
- name: Fail if systemctl_id contains "@"
assert:
that:
- "'@' not in systemctl_id"
fail_msg: "Invalid systemctl_id '{{ systemctl_id }}' → must not contain '@'."
- name: "Make '{{ systemctl_id }}' available for sys-timer"
set_fact:
systemctl_timer_service: "{{ systemctl_id }}"
- name: "include role for sys-timer for {{ systemctl_timer_service }}"
include_role:
name: sys-timer

View File

@ -1,7 +0,0 @@
[Unit]
Description={{ SOFTWARE_NAME }} - Service for role '{{ systemctl_id }}'
OnFailure={{ systemctl_tpl_on_failure }}
[Service]
Type={{ systemctl_tpl_type }}
ExecStart={{ systemctl_tpl_exec_start }}

View File

@ -1,22 +0,0 @@
UNIT_SUFFIX_REMOVER_PACKAGE: "unsure"
## Paths
systemctl_role_name: "{{ systemctl_id | regex_replace('@','') }}"
systemctl_role_dir: "{{ [ playbook_dir, 'roles', systemctl_role_name ] | path_join }}"
systemctl_script_dir: "{{ [ PATH_SYSTEMCTL_SCRIPTS, systemctl_id ] | path_join }}"
## Settings
systemctl_copy_files: true # When set to false file copying will be skipped
systemctl_timer_enabled: false # When set to true timer will be loaded
systemctl_state: "{{ SYS_SERVICE_DEFAULT_STATE }}"
# Dynamic Loaded ( Just available when dependencies are loaded )
systemctl_script_base: "{{ systemctl_script_src | basename | regex_replace('\\.j2$', '') }}"
systemctl_script_type: "{{ systemctl_script_base | filetype }}"
systemctl_script_inter: "/bin/{{ 'bash' if systemctl_script_type == 'sh' else 'python3'}}"
systemctl_script_exec: "{{ systemctl_script_inter }} {{ systemctl_id | get_service_script_path( systemctl_script_type ) }}"
# Service template
systemctl_tpl_on_failure: "{{ SYS_SERVICE_ON_FAILURE_COMPOSE }}"
systemctl_tpl_type: "oneshot"
systemctl_tpl_exec_start: "{{ systemctl_script_exec }}"

View File

@ -6,12 +6,12 @@
vars: vars:
flush_handlers: true flush_handlers: true
- name: set systemctl_timer_service to sys-ctl-cln-bkps - name: set system_service_timer_service to sys-ctl-cln-bkps
set_fact: set_fact:
systemctl_timer_service: "sys-ctl-cln-bkps" system_service_timer_service: "sys-ctl-cln-bkps"
- name: "include role for sys-timer for {{ systemctl_timer_service }}" - name: "include role for sys-timer for {{ system_service_timer_service }}"
include_role: include_role:
name: sys-timer name: sys-timer
vars: vars:
systemctl_on_calendar: "{{ SYS_SCHEDULE_CLEANUP_BACKUPS }}" system_service_on_calendar: "{{ SYS_SCHEDULE_CLEANUP_BACKUPS }}"

View File

@ -7,9 +7,9 @@ This role configures a systemd timer to periodically start a corresponding servi
## Overview ## Overview
Optimized for automated task scheduling in a [systemd](https://en.wikipedia.org/wiki/Systemd) environment, this role: Optimized for automated task scheduling in a [systemd](https://en.wikipedia.org/wiki/Systemd) environment, this role:
- Generates a timer unit file for a given service (using the `systemctl_timer_service` variable). - Generates a timer unit file for a given service (using the `system_service_timer_service` variable).
- Reloads and restarts the timer using systemd to ensure that changes take effect. - Reloads and restarts the timer using systemd to ensure that changes take effect.
- Supports dynamic configuration of scheduling parameters via variables like `systemctl_on_calendar` and `RANDOMIZED_DELAY_SEC`. - Supports dynamic configuration of scheduling parameters via variables like `system_service_on_calendar` and `RANDOMIZED_DELAY_SEC`.
## Purpose ## Purpose

View File

@ -1,8 +1,8 @@
[Unit] [Unit]
Description=Timer to start {{ systemctl_timer_service }}{{ SYS_SERVICE_SUFFIX }} Description=Timer to start {{ system_service_timer_service }}{{ SYS_SERVICE_SUFFIX }}
[Timer] [Timer]
OnCalendar={{ systemctl_on_calendar }} OnCalendar={{ system_service_on_calendar }}
RandomizedDelaySec={{ RANDOMIZED_DELAY_SEC }} RandomizedDelaySec={{ RANDOMIZED_DELAY_SEC }}
Persistent={{ persistent | default('false') }} Persistent={{ persistent | default('false') }}

Some files were not shown because too many files have changed in this diff Show More