From 9c7586c7c3a235672ec6490d1a8bc44a222ce5d1 Mon Sep 17 00:00:00 2001 From: Colin Wilk Date: Tue, 1 Sep 2026 21:01:05 +0200 Subject: Add borg prune and compact jobs Run repository retention either after a successful backup or from a dedicated systemd timer. Clean up script generation with templates and expand molecule test coverage. BREAKING CHANGE: Aggregate backup scripts are no longer managed, and state=preset now requires at least one readable included directory. --- tasks/client_setup.yml | 135 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 94 insertions(+), 41 deletions(-) (limited to 'tasks/client_setup.yml') diff --git a/tasks/client_setup.yml b/tasks/client_setup.yml index ab09926..2a1389a 100644 --- a/tasks/client_setup.yml +++ b/tasks/client_setup.yml @@ -1,37 +1,3 @@ ---- -- name: Ensure borg_client_user exists - ansible.builtin.getent: - database: passwd - key: "{{ borg_client_user }}" - become: true - -- name: Compute borg_client_user_home if not set - ansible.builtin.set_fact: - borg_client_user_home: "{{ ansible_facts.getent_passwd[borg_client_user][4] }}" - when: borg_client_user_home is not defined - -- name: Validate borg_client_user home exists - ansible.builtin.stat: - path: "{{ borg_client_user_home }}" - register: user_home_stat - become: true - -- name: Fail if borg_client_user home missing - ansible.builtin.fail: - msg: | - Home directory {{ borg_client_user_home }} for user {{ borg_client_user }} does not exist. - Please ensure the user has a valid home directory before running this role. - when: not user_home_stat.stat.exists - -- name: Check readability of included paths - ansible.builtin.stat: - path: "{{ item }}" - loop: "{{ borg_included_dirs }}" - register: included_paths_stat - become: true - become_user: "{{ borg_client_user }}" - when: borg_included_dirs | length > 0 - - name: Compute SSH key identifier ansible.builtin.set_fact: borg_ssh_key_identifier: "{{ (borg_server_host_url ~ '_' ~ borg_repo_name) | regex_replace('[^a-zA-Z0-9]', '_') }}" @@ -230,13 +196,24 @@ delegate_to: localhost become: false -- name: Create backup scripts - ansible.builtin.include_tasks: client_create_scripts_each.yml - loop: - - "{{ borg_backup_script_location }}" - - "{{ borg_backup_script_location }}{{ '@' if borg_backup_argument != '' else '' }}{{ borg_backup_argument }}" - loop_control: - loop_var: script_location +- name: Create repository-specific backup script + ansible.builtin.template: + src: borg_backup_script.j2 + dest: "{{ borg_backup_script_location }}{{ '@' if borg_backup_argument != '' else '' }}{{ borg_backup_argument }}" + owner: "{{ borg_client_user }}" + group: "{{ borg_client_user }}" + mode: "0711" + become: true + +- name: Create repository-specific prune script + ansible.builtin.template: + src: borg_prune_script.j2 + dest: "{{ borg_prune_script_location }}{{ '@' if borg_backup_argument != '' else '' }}{{ borg_backup_argument }}" + owner: "{{ borg_client_user }}" + group: "{{ borg_client_user }}" + mode: "0711" + become: true + when: borg_prune_enabled - name: Configure systemd borg_backup service ansible.builtin.template: @@ -258,6 +235,72 @@ notify: Reload systemd become: true +- name: Configure systemd borg_prune service + ansible.builtin.template: + src: borg_prune.service.j2 + dest: /etc/systemd/system/{{ borg_prune_service_name }}{{ "@" if borg_backup_argument != "" }}{{ borg_backup_argument }}.service + mode: "0644" + owner: root + group: root + notify: Reload systemd + become: true + when: borg_prune_enabled + +- name: Configure systemd borg_prune timer + ansible.builtin.template: + src: borg_prune.timer.j2 + dest: /etc/systemd/system/{{ borg_prune_timer_name }}{{ "@" if borg_backup_argument != "" }}{{ borg_backup_argument }}.timer + mode: "0644" + owner: root + group: root + notify: Reload systemd + become: true + when: + - borg_prune_enabled + - borg_prune_trigger == 'timer' + +- name: Check if stale borg_prune timer exists + ansible.builtin.stat: + path: /etc/systemd/system/{{ borg_prune_timer_name }}{{ "@" if borg_backup_argument != "" }}{{ borg_backup_argument }}.timer + register: stale_prune_timer_stat + become: true + when: not (borg_prune_enabled and borg_prune_trigger == 'timer') + +- name: Disable stale borg_prune timer + ansible.builtin.systemd: + name: "{{ borg_prune_timer_name }}{{ '@' if borg_backup_argument != '' else '' }}{{ borg_backup_argument }}.timer" + state: stopped + enabled: false + become: true + when: + - not (borg_prune_enabled and borg_prune_trigger == 'timer') + - stale_prune_timer_stat.stat.exists + +- name: Remove stale borg_prune timer file + ansible.builtin.file: + path: /etc/systemd/system/{{ borg_prune_timer_name }}{{ "@" if borg_backup_argument != "" }}{{ borg_backup_argument }}.timer + state: absent + notify: Reload systemd + become: true + when: not (borg_prune_enabled and borg_prune_trigger == 'timer') + +- name: Remove stale borg_prune service file + ansible.builtin.file: + path: /etc/systemd/system/{{ borg_prune_service_name }}{{ "@" if borg_backup_argument != "" }}{{ borg_backup_argument }}.service + state: absent + notify: Reload systemd + become: true + when: not borg_prune_enabled + +- name: Remove stale repository-specific prune script + ansible.builtin.file: + path: "{{ borg_prune_script_location }}{{ '@' if borg_backup_argument != '' else '' }}{{ borg_backup_argument }}" + state: absent + become: true + when: + - not borg_prune_enabled + - borg_prune_script_location | length > 0 + - name: Reload systemd now before enabling services ansible.builtin.meta: flush_handlers @@ -267,3 +310,13 @@ state: started enabled: true become: true + +- name: Enable borg_prune systemd timer + ansible.builtin.systemd: + name: "{{ borg_prune_timer_name }}{{ '@' if borg_backup_argument != '' else '' }}{{ borg_backup_argument }}.timer" + state: started + enabled: true + become: true + when: + - borg_prune_enabled + - borg_prune_trigger == 'timer' -- cgit v1.2.3