From b84afb3abfcc62186d5b48be7966d1c3843cdaa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20=C5=BD=C3=A1=C4=8Dek?= Date: Sat, 30 May 2026 20:53:27 +0200 Subject: [PATCH] Manage own borgmatic systemd service and timer Ship borgmatic.service and borgmatic.timer from the backup role instead of relying on the package-provided units. The units are deployed to /etc/systemd/system (overriding the package units), with a configurable schedule via role defaults. Co-Authored-By: Claude Opus 4.8 (1M context) --- roles/backup/defaults/main.yml | 10 +++++++++ roles/backup/tasks/main.yml | 23 +++++++++++++++++++++ roles/backup/templates/borgmatic.service.j2 | 21 +++++++++++++++++++ roles/backup/templates/borgmatic.timer.j2 | 11 ++++++++++ 4 files changed, 65 insertions(+) create mode 100644 roles/backup/defaults/main.yml create mode 100644 roles/backup/templates/borgmatic.service.j2 create mode 100644 roles/backup/templates/borgmatic.timer.j2 diff --git a/roles/backup/defaults/main.yml b/roles/backup/defaults/main.yml new file mode 100644 index 0000000..996a9d3 --- /dev/null +++ b/roles/backup/defaults/main.yml @@ -0,0 +1,10 @@ +--- +# Schedule for our own borgmatic.timer (overrides the package-shipped unit). +# OnCalendar uses systemd.time(7) syntax. RandomizedDelaySec spreads load so +# every host doesn't hit the borg server at the same instant. +borgmatic_oncalendar: "*-*-* 03:00:00" +borgmatic_randomized_delay_sec: 3h +borgmatic_persistent: true + +# Extra flags passed to the borgmatic invocation in our borgmatic.service. +borgmatic_verbosity_args: "--verbosity -1 --syslog-verbosity 1" diff --git a/roles/backup/tasks/main.yml b/roles/backup/tasks/main.yml index 1fa88b2..c9aff83 100644 --- a/roles/backup/tasks/main.yml +++ b/roles/backup/tasks/main.yml @@ -75,6 +75,29 @@ group: root mode: '0640' + - name: Deploy borgmatic systemd service (overrides package unit) + ansible.builtin.template: + src: borgmatic.service.j2 + dest: /etc/systemd/system/borgmatic.service + owner: root + group: root + mode: '0644' + register: _borgmatic_service_unit + + - name: Deploy borgmatic systemd timer (overrides package unit) + ansible.builtin.template: + src: borgmatic.timer.j2 + dest: /etc/systemd/system/borgmatic.timer + owner: root + group: root + mode: '0644' + register: _borgmatic_timer_unit + + - name: Reload systemd if units changed + ansible.builtin.systemd: + daemon_reload: true + when: _borgmatic_service_unit is changed or _borgmatic_timer_unit is changed + - name: Enable and start borgmatic timer ansible.builtin.systemd: name: borgmatic.timer diff --git a/roles/backup/templates/borgmatic.service.j2 b/roles/backup/templates/borgmatic.service.j2 new file mode 100644 index 0000000..35bf691 --- /dev/null +++ b/roles/backup/templates/borgmatic.service.j2 @@ -0,0 +1,21 @@ +# Managed by Ansible — do not edit by hand. +[Unit] +Description=borgmatic backup +Wants=network-online.target +After=network-online.target +# Don't run on battery power. +ConditionACPower=true + +[Service] +Type=oneshot +# Lower priority so backups don't starve foreground work. +Nice=19 +CPUSchedulingPolicy=batch +IOSchedulingClass=best-effort +IOSchedulingPriority=7 +IOWeight=100 +Restart=no +# Prevent rate limiting of borgmatic log events. +LogRateLimitIntervalSec=0 +# Delay start by a random amount handled in the timer; keep the service simple. +ExecStart=systemd-inhibit --who="borgmatic" --what="sleep:shutdown" --why="Prevent interrupting scheduled backup" /usr/bin/borgmatic {{ borgmatic_verbosity_args }} diff --git a/roles/backup/templates/borgmatic.timer.j2 b/roles/backup/templates/borgmatic.timer.j2 new file mode 100644 index 0000000..f25c1f3 --- /dev/null +++ b/roles/backup/templates/borgmatic.timer.j2 @@ -0,0 +1,11 @@ +# Managed by Ansible — do not edit by hand. +[Unit] +Description=Run borgmatic backup + +[Timer] +OnCalendar={{ borgmatic_oncalendar }} +RandomizedDelaySec={{ borgmatic_randomized_delay_sec }} +Persistent={{ borgmatic_persistent | bool | lower }} + +[Install] +WantedBy=timers.target -- 2.52.0