diff --git a/README.md b/README.md index c50f047..6983153 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,21 @@ You can also use the ``ansible-galaxy`` command on the ``ansible-role-requiremen roles: - role: "systemd_service" systemd_services: + # Normal Service - service_name: ServiceX execstarts: - /path/ServiceX --flag1 + + # Timer Service (AKA CRON) + - service_name: TimerServiceX + execstarts: + - /path/TimerServiceX --flag1 + timer: + state: "started" + options: + OnBootSec: 30min + OnUnitActiveSec: 1h + Persistent: true tags: - servicex-init - ``` diff --git a/defaults/main.yml b/defaults/main.yml index 6da40b0..b95ce6b 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -74,6 +74,15 @@ systemd_default_service_type: simple # `enabled` -- (optional) Set the enabled state of the service. # `state` -- (optional) Set the running state of the service. +# Under the service dictionary the "timer" key can be added which will enable a given service +# as a timer (Legacy cron job). +# `options` -- (optional) This allows any section or key=value pair to be set within the systemd timer file. +# `cron_minute` -- (optional) This allows for "on calendar configuration" (AKA CRON) for the minute segment. +# `cron_hour` -- (optional) This allows for "on calendar configuration" (AKA CRON) for the hour segment. +# `cron_day` -- (optional) This allows for "on calendar configuration" (AKA CRON) for the day segment. +# `cron_weekday` -- (optional) This allows for "on calendar configuration" (AKA CRON) for the weekday segment. +# `cron_month` -- (optional) This allows for "on calendar configuration" (AKA CRON) for the month segment. + # Examples: # systemd_services: # - service_name: ServiceW @@ -109,5 +118,26 @@ systemd_default_service_type: simple # execstops # - /usr/bin/stopcmd1 # - /usr/bin/stopcmd2 - +# +# - service_name: TimerServiceW +# config_overrides: {} # This is used to add in arbitratry unit file options +# execstarts: +# - '/usr/bin/ServiceY' +# restart_changed: no +# timer: +# state: "started" +# options: +# OnBootSec: 30min +# OnUnitActiveSec: 1h +# Persistent: true +# +# - service_name: TimerServiceX +# config_overrides: {} # This is used to add in arbitratry unit file options +# execstarts: +# - '/usr/bin/ServiceY' +# restart_changed: no +# timer: +# state: "started" +# cron_minute: 30 +# cron_hour: 1 systemd_services: [] diff --git a/handlers/main.yml b/handlers/main.yml index 7a18508..56ab471 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -15,7 +15,7 @@ - name: Restart changed services systemd: - name: "{{ item.item.service_name | replace(' ', '_') }}" + name: "{{ item.item.service_name | replace(' ', '_') }}.{{ (item.item.timer is defined) | ternary('timer', 'service') }}" state: restarted listen: systemd service changed with_items: "{{ systemd_services_result.results }}" @@ -23,4 +23,4 @@ - 'item.item.restart_changed | default(systemd_service_restart_changed) | bool' - 'item.item.state is not defined' - 'item.item.enabled | default(systemd_service_enabled) | bool' - - 'item | changed' \ No newline at end of file + - 'item | changed' diff --git a/tasks/main.yml b/tasks/main.yml index 8ad4941..7d69eb4 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -106,6 +106,17 @@ tags: - systemd-service +- name: Check timers + fail: + msg: >- + When using systemd timers the "state" must be defined under the timer key. + when: + - item.timer is defined + - item.timer.state is undefined + with_items: "{{ systemd_services }}" + tags: + - systemd-service + - name: Place the systemd service config_template: src: "systemd-service.j2" @@ -122,17 +133,44 @@ tags: - systemd-service +- name: Place the systemd timer + template: + src: "systemd-timer.j2" + dest: "/etc/systemd/system/{{ item.service_name | replace(' ', '_') }}.timer" + mode: "0644" + owner: "root" + group: "root" + when: + - item.timer is defined + with_items: "{{ systemd_services }}" + notify: + - systemd service changed + register: systemd_timer_result + tags: + - systemd-service + - name: Reload systemd on unit change systemd: daemon_reload: yes when: - - 'systemd_services_result | changed' + - (systemd_services_result | changed) or (systemd_timer_result | changed) - name: Load service systemd: - name: "{{ item.service_name | replace(' ', '_') }}" + name: "{{ item.service_name | replace(' ', '_') }}.service" enabled: "{{ item.enabled | default(systemd_service_enabled) }}" - state: "{{ item.state | default(omit) }}" + state: "{{ (item.timer is defined) | ternary(omit, (item.state | default(omit))) }}" + with_items: "{{ systemd_services }}" + tags: + - systemd-service + +- name: Load timer + systemd: + name: "{{ item.service_name | replace(' ', '_') }}.timer" + enabled: "{{ item.enabled | default(systemd_service_enabled) }}" + state: "{{ item.timer.state | default(omit) }}" + when: + - item.timer is defined with_items: "{{ systemd_services }}" tags: - systemd-service diff --git a/templates/systemd-timer.j2 b/templates/systemd-timer.j2 new file mode 100644 index 0000000..1c1ecd8 --- /dev/null +++ b/templates/systemd-timer.j2 @@ -0,0 +1,25 @@ +# {{ ansible_managed }} + +[Unit] +Description={{ item.service_name }} timer + +[Timer] +{% if item.timer.options is defined %} +{% for key, values in item.timer.options.items() %} +{{ key }}={{ values }} +{% endfor %} +{% else %} +{% set OnCalendar = [] %} +{% set _ = OnCalendar.extend([item.timer.cron_minute | default('*')]) %} +{% set _ = OnCalendar.extend([item.timer.cron_hour | default('*')]) %} +{% set _ = OnCalendar.extend([item.timer.cron_day | default('*')]) %} +{% set _ = OnCalendar.extend([item.timer.cron_weekday | default('*')]) %} +{% set _ = OnCalendar.extend([item.timer.cron_month | default('*')]) %} +OnBootSec=30min +Unit={{ item.service_name }}.service +Persistent=true +OnCalendar={{ OnCalendar | join(' ') }} +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/tests/test.yml b/tests/test.yml index f5d6742..74a5c49 100644 --- a/tests/test.yml +++ b/tests/test.yml @@ -44,6 +44,23 @@ state: started systemd_tempd_prefix: openstack systemd_lock_path: /var/lock/networking + - service_name: "test timer service0" + execstarts: + - "/bin/bash -c 'echo start0'" + timer: + state: "started" + options: + OnBootSec: 30min + OnUnitActiveSec: 1h + Persistent: true + - service_name: "test timer service1" + execstarts: + - "/bin/bash -c 'echo start1'" + timer: + state: "started" + cron_minute: 30 + cron_hour: 1 + post_tasks: - name: Check Services command: systemctl status "{{ item }}" @@ -51,6 +68,8 @@ with_items: - test_simple_service0 - test_oneshot_service0 + - test_timer_service0.timer + - test_timer_service1.timer tags: - skip_ansible_lint