From 42d6c1799b3b1f9ea7605c4e426717ac76a4d533 Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Wed, 20 Aug 2025 12:45:19 +0200 Subject: [PATCH] sys-service: add systemd_directive filter and refactor service template 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 --- .../filter_plugins/systemd_directive.py | 17 +++++++++++++++++ .../templates/systemctl.service.j2 | 19 +++++++++---------- roles/sys-service/vars/main.yml | 11 ++++++----- 3 files changed, 32 insertions(+), 15 deletions(-) create mode 100644 roles/sys-service/filter_plugins/systemd_directive.py diff --git a/roles/sys-service/filter_plugins/systemd_directive.py b/roles/sys-service/filter_plugins/systemd_directive.py new file mode 100644 index 00000000..3a622731 --- /dev/null +++ b/roles/sys-service/filter_plugins/systemd_directive.py @@ -0,0 +1,17 @@ +def systemd_directive(value, key: str) -> str: + """ + Render a single systemd directive line if value is non-empty. + Example: {{ myval | systemd_directive('ExecStart') }} + """ + if value is None: + return "" + sval = str(value).strip() + if not sval: + return "" + return f"{key}={sval}" + +class FilterModule(object): + def filters(self): + return { + "systemd_directive": systemd_directive, + } diff --git a/roles/sys-service/templates/systemctl.service.j2 b/roles/sys-service/templates/systemctl.service.j2 index 2b633a5b..3569e8e4 100644 --- a/roles/sys-service/templates/systemctl.service.j2 +++ b/roles/sys-service/templates/systemctl.service.j2 @@ -1,15 +1,14 @@ [Unit] Description={{ SOFTWARE_NAME }} - Service for role '{{ system_service_id }}' -{% if system_service_tpl_on_failure |length > 0 %} -OnFailure={{ system_service_tpl_on_failure }} -{% endif %} +{{- system_service_tpl_on_failure | systemd_directive('OnFailure') }} [Service] Type={{ system_service_tpl_type }} -{% if system_service_tpl_exec_start_pre |length > 0 %} -ExecStartPre={{ system_service_tpl_exec_start_pre }} -{% endif %} -ExecStart={{ system_service_tpl_exec_start }} -{% if system_service_tpl_runtime |length > 0 %} -RuntimeMaxSec={{ system_service_tpl_runtime }} -{% endif %} +{%- for key, val in [ + ('TimeoutStartSec', system_service_tpl_timeout_start_sec), + ('ExecStartPre', system_service_tpl_exec_start_pre), + ('ExecStart', system_service_tpl_exec_start), + ('RuntimeMaxSec', system_service_tpl_runtime) +] -%} +{{- val | systemd_directive(key) }} +{%- endfor %} diff --git a/roles/sys-service/vars/main.yml b/roles/sys-service/vars/main.yml index 2c64332c..b20f9a34 100644 --- a/roles/sys-service/vars/main.yml +++ b/roles/sys-service/vars/main.yml @@ -17,8 +17,9 @@ system_service_script_inter: "/bin/{{ 'bash' if system_service_script_type == 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 }}" -system_service_tpl_exec_start_pre: "" \ No newline at end of file +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: "{{ '' if system_service_tpl_type == 'oneshot' else SYS_SERVICE_DEFAULT_RUNTIME }}" +system_service_tpl_exec_start_pre: "" +system_service_tpl_timeout_start_sec: "60s" \ No newline at end of file