diff --git a/src/roles/foreman/defaults/main.yaml b/src/roles/foreman/defaults/main.yaml index 1aee8039..b9fbe5c7 100644 --- a/src/roles/foreman/defaults/main.yaml +++ b/src/roles/foreman/defaults/main.yaml @@ -16,3 +16,30 @@ foreman_url: "http://{{ ansible_facts['fqdn'] }}:3000" # CPU based calculation is based on https://github.com/puma/puma/blob/master/docs/deployment.md#mri # Memory based calculation is based on https://docs.gitlab.com/ee/install/requirements.html#puma-settings foreman_puma_workers: "{{ [32, ansible_facts['processor_nproc'] * 1.5, (ansible_facts['memtotal_mb'] / 1024) - 1.5] | min | int }}" + +foreman_recurring_tasks_enabled: true +foreman_recurring_tasks: + - instance: reports-daily + rake: "reports:daily" + schedule: "daily" + - instance: db-sessions-clear + rake: "db:sessions:clear" + schedule: "daily" + - instance: reports-expire + rake: "reports:expire" + schedule: "daily" + - instance: audits-expire + rake: "audits:expire" + schedule: "daily" + - instance: reports-weekly + rake: "reports:weekly" + schedule: "weekly" + - instance: reports-monthly + rake: "reports:monthly" + schedule: "monthly" + - instance: notifications-clean + rake: "notifications:clean" + schedule: "weekly" + - instance: ldap-refresh_usergroups + rake: "ldap:refresh_usergroups" + schedule: "*-*-* *:00,30:00" diff --git a/src/roles/foreman/tasks/main.yaml b/src/roles/foreman/tasks/main.yaml index f08bdb17..b772d2c5 100644 --- a/src/roles/foreman/tasks/main.yaml +++ b/src/roles/foreman/tasks/main.yaml @@ -161,6 +161,53 @@ - worker - worker-hosts-queue +- name: Define templated Quadlet for recurring Foreman rake tasks + when: foreman_recurring_tasks_enabled + loop: "{{ foreman_recurring_tasks }}" + loop_control: + label: "{{ item.instance }}" + containers.podman.podman_container: + name: "foreman-recurring-{{ item.instance }}" + quadlet_filename: "foreman-recurring@{{ item.instance }}" + state: quadlet + image: "{{ foreman_container_image }}:{{ foreman_container_tag }}" + sdnotify: false + network: host + hostname: "{{ ansible_facts['fqdn'] }}" + command: "foreman-rake {{ item.rake }}" + volume: + - 'foreman-data-run:/var/run/foreman:z' + secrets: + - 'foreman-database-url,type=env,target=DATABASE_URL' + - 'foreman-seed-admin-user,type=env,target=SEED_ADMIN_USER' + - 'foreman-seed-admin-password,type=env,target=SEED_ADMIN_PASSWORD' + - 'foreman-settings-yaml,type=mount,target=/etc/foreman/settings.yaml' + - 'foreman-katello-yaml,type=mount,target=/etc/foreman/plugins/katello.yaml' + - 'foreman-ca-cert,type=mount,target=/etc/foreman/katello-default-ca.crt' + - 'foreman-client-cert,type=mount,target=/etc/foreman/client_cert.pem' + - 'foreman-client-key,type=mount,target=/etc/foreman/client_key.pem' + quadlet_options: + - | + [Unit] + PartOf=foreman.target + StartLimitIntervalSec=0 + - | + [Service] + TimeoutStartSec=30m + TimeoutStopSec=2m + KillMode=mixed + SyslogIdentifier=foreman-recurring-%i + +- name: Render timers for recurring tasks + when: foreman_recurring_tasks_enabled + ansible.builtin.template: + src: foreman-recurring@.timer.j2 + dest: "/etc/systemd/system/foreman-recurring@{{ item.instance }}.timer" + mode: "0644" + loop: "{{ foreman_recurring_tasks }}" + loop_control: + label: "{{ item.instance }}" + - name: Run daemon reload to make Quadlet create the service files ansible.builtin.systemd: daemon_reload: true @@ -207,6 +254,16 @@ delay: 5 register: foreman_status +- name: Enable & start recurring timers + when: foreman_recurring_tasks_enabled + ansible.builtin.systemd: + name: "foreman-recurring@{{ item.instance }}.timer" + enabled: true + state: started + loop: "{{ foreman_recurring_tasks }}" + loop_control: + label: "{{ item.instance }}" + - name: Wait for Foreman tasks to be ready ansible.builtin.uri: url: '{{ foreman_url }}/api/v2/ping' diff --git a/src/roles/foreman/templates/foreman-recurring@.timer.j2 b/src/roles/foreman/templates/foreman-recurring@.timer.j2 new file mode 100644 index 00000000..c696d969 --- /dev/null +++ b/src/roles/foreman/templates/foreman-recurring@.timer.j2 @@ -0,0 +1,13 @@ +[Unit] +Description=Timer for Foreman recurring: {{ item.rake }} +PartOf=foreman.target + +[Timer] +Unit=foreman-recurring@{{ item.instance }}.service +OnCalendar={{ item.schedule }} +Persistent=true +RandomizedDelaySec=120 +AccuracySec=1min + +[Install] +WantedBy=timers.target foreman.target diff --git a/tests/foreman_test.py b/tests/foreman_test.py index ba0e80fe..40c467c4 100644 --- a/tests/foreman_test.py +++ b/tests/foreman_test.py @@ -5,6 +5,16 @@ FOREMAN_HOST = 'localhost' FOREMAN_PORT = 3000 +RECURRING_INSTANCES = [ + "reports-daily", + "db-sessions-clear", + "reports-expire", + "audits-expire", + "reports-weekly", + "reports-monthly", + "notifications-clean", + "ldap-refresh_usergroups", +] @pytest.fixture(scope="module") @@ -59,3 +69,16 @@ def test_foreman_dynflow_container_instances(server, dynflow_instance): def test_foreman_dynflow_service_instances(server, dynflow_instance): service = server.service(f"dynflow-sidekiq@{dynflow_instance}") assert service.is_running + + +@pytest.mark.parametrize("instance", RECURRING_INSTANCES) +def test_foreman_recurring_timers_enabled_and_running(server, instance): + timer = server.service(f"foreman-recurring@{instance}.timer") + assert timer.is_enabled + assert timer.is_running + + +@pytest.mark.parametrize("instance", RECURRING_INSTANCES) +def test_foreman_recurring_services_exist(server, instance): + service = server.service(f"foreman-recurring@{instance}.service") + assert service.exists