Refactor alarm compose service and systemctl templates

- Fixed bug where not both alarm services (email + telegram) were triggered.
- Removed direct OnFailure references for email and telegram,
  now handled by unified compose service.
- Introduced 01_core.yml in sys-ctl-alm-compose to structure
  role execution (subservices → core service → test run).
- Added configurable variables SYSTEMCTL_ALARM_COMPOSER_SUBSERVICES
  and SYSTEMCTL_ALARM_COMPOSER_DUMMY_MESSAGE.
- Replaced dedicated @.service template with generic systemctl template
  using systemctl_tpl_* variables for flexibility.
- Updated script.sh.j2 to collect exit codes and print clear errors.
- Fixed typos and streamlined vars in sys-systemctl.

See conversation: https://chatgpt.com/share/68a46172-7c3c-800f-a69c-0cb9edd6839f
This commit is contained in:
Kevin Veen-Birkenbach 2025-08-19 13:35:39 +02:00
parent b1e8339283
commit b49fdc509e
No known key found for this signature in database
GPG Key ID: 44D8F11FD62F878E
8 changed files with 55 additions and 30 deletions

View File

@ -17,8 +17,6 @@ SYS_SERVICE_UPDATE_DOCKER: "{{ 'update-docker' | get_servic
## On Failure
SYS_SERVICE_ON_FAILURE_COMPOSE: "{{ 'sys-ctl-alm-compose' | get_service_name(SOFTWARE_NAME,'%i.service') }}"
SYS_SERVICE_ON_FAILURE_EMAIL: "{{ 'sys-ctl-alm-email' | get_service_name(SOFTWARE_NAME,'%i.service') }}"
SYS_SERVICE_ON_FAILURE_TELEGRAM: "{{ 'sys-ctl-alm-telegram' | get_service_name(SOFTWARE_NAME,'%i.service') }}"
## Groups
SYS_SERVICE_GROUP_BACKUPS: >

View File

@ -0,0 +1,25 @@
- name: "Include dependent services for '{{ systemctl_id }}'"
include_role:
name: '{{ item }}'
loop:
- sys-ctl-alm-telegram
- sys-ctl-alm-email
vars:
flush_handlers: true
systemctl_timer_enabled: false
systemctl_copy_files: true
- name: "Include core service for '{{ systemctl_id }}'"
include_role:
name: sys-systemctl
vars:
flush_handlers: true
systemctl_timer_enabled: false
systemctl_copy_files: true
systemctl_tpl_exec_start: "{{ systemctl_script_exec }} %i"
systemctl_tpl_on_failure: "" # No on failure needed, because it's anyhow the default on failure procedure
- name: "Send message to test service."
systemd:
name: "sys-ctl-alm-compose@{{ SYSTEMCTL_ALARM_COMPOSER_DUMMY_MESSAGE }}.service"
state: started

View File

@ -1,14 +1,4 @@
- block:
- name: "Include '{{ systemctl_id }}'"
include_role:
name: '{{ item }}'
loop:
- sys-ctl-alm-telegram
- sys-ctl-alm-email
- sys-systemctl
vars:
flush_handlers: true
systemctl_timer_enabled: false
systemctl_copy_files: false
- include_tasks: 01_core.yml
- include_tasks: utils/run_once.yml
when: run_once_sys_ctl_alm_compose is not defined

View File

@ -0,0 +1,11 @@
#!/bin/bash
err=0
set -u
{% for alarm_service in SYSTEMCTL_ALARM_COMPOSER_SUBSERVICES %}
{% set alarm_service_full_name = alarm_service | get_service_name(SOFTWARE_NAME, '"$1".service') %}
if ! /usr/bin/systemctl start {{ alarm_service_full_name }}; then
echo "ERROR: Failed to start {{ alarm_service_full_name }}" >&2
err=1
fi
{% endfor %}
exit $err

View File

@ -1,10 +0,0 @@
[Unit]
Description={{ SOFTWARE_NAME }} - Alarm Notifier for %i
[Service]
Type=oneshot
{% for alarm_service in [ SYS_SERVICE_ON_FAILURE_EMAIL, SYS_SERVICE_ON_FAILURE_TELEGRAM ] %}
ExecStart=/usr/bin/systemctl start {{ alarm_service }}
{% endfor %}
User=root
Group=systemd-journal

View File

@ -1 +1,7 @@
systemctl_id: sys-ctl-alm-compose@
systemctl_id: sys-ctl-alm-compose@
SYSTEMCTL_ALARM_COMPOSER_SUBSERVICES:
- 'sys-ctl-alm-email'
- 'sys-ctl-alm-telegram'
SYSTEMCTL_ALARM_COMPOSER_DUMMY_MESSAGE: "[Info] Dummy Message: No Failure; Ansible is initializing {{ SOFTWARE_NAME }} on {{ inventory_hostname }}."

View File

@ -1,7 +1,7 @@
[Unit]
Description=Service for {{ SOFTWARE_NAME }} role '{{ systemctl_id }}' (DEFAULT TEMPLATE)
OnFailure={{ SYS_SERVICE_ON_FAILURE_COMPOSE }}
Description={{ SOFTWARE_NAME }} - Service for role '{{ systemctl_id }}'
OnFailure={{ systemctl_tpl_on_failure }}
[Service]
Type=oneshot
ExecStart={{ systemctl_script_exec }}
Type={{ systemctl_tpl_type }}
ExecStart={{ systemctl_tpl_exec_start }}

View File

@ -7,11 +7,16 @@ systemctl_script_dir: "{{ [ PATH_SYSTEMCTL_SCRIPTS, systemctl_id ] | path_jo
## Settings
systemctl_copy_files: true # When set to false file copying will be skipped
systemctl_timer_enabled: false # When set to true timmer will be loaded
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 ) }}"
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 }}"