aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorColin Wilk <colin@wilk.cx>2026-09-01 21:01:05 +0200
committerColin Wilk <colin@wilk.cx>2026-09-01 21:43:57 +0200
commit9c7586c7c3a235672ec6490d1a8bc44a222ce5d1 (patch)
tree8b36c5ee3105da2ae769c0d9cd96683d213c949d /README.md
parentfa137a92e1084a07608a4008ec0cb891baa76774 (diff)
downloadansible-role-borgbackup-9c7586c7c3a235672ec6490d1a8bc44a222ce5d1.tar.gz
ansible-role-borgbackup-9c7586c7c3a235672ec6490d1a8bc44a222ce5d1.zip
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.
Diffstat (limited to 'README.md')
-rw-r--r--README.md124
1 files changed, 71 insertions, 53 deletions
diff --git a/README.md b/README.md
index 1eab45d..f5690f5 100644
--- a/README.md
+++ b/README.md
@@ -160,7 +160,8 @@ your Borg backups, but it is not used by default.
<!-- TODO: Include keyfile backup mode -->
`borg_included_dirs` and `borg_excluded_dirs` finally picks what directories
-will be backed up by Borg.
+will be backed up by Borg. `borg_included_dirs` must not be empty when
+`state: present`.
```yaml
borg_compression: zstd # -C argument
@@ -182,6 +183,66 @@ borg_create_additional_arguments: "--stats --list --filter=AME"
borg_create_additional_arguments: "--one-file-system --exclude-caches"
```
+### Prune and Compact Configuration
+
+The role can manage Borg retention with `borg prune` and optionally run `borg
+compact` afterwards to actually free repository disk space.
+
+Enable pruning with `borg_prune_enabled`. Pruning always runs in a dedicated
+systemd service. By default, `borg_prune_trigger` is `after_backup`, so a
+successful backup service starts the prune service. The backup script itself
+only runs `borg create`; the prune script runs `borg prune` and optionally
+`borg compact`.
+
+If you want prune on its own schedule, set `borg_prune_trigger: timer`. That
+creates a dedicated prune timer using `borg_prune_timer_name`,
+`borg_prune_systemd_oncalendar`, and `borg_prune_systemd_accuracysec` to start
+the same prune service.
+
+You can set an archive filter via `borg_prune_glob_archives` so prune only
+touches the archive series for this backup job.
+
+```yaml
+borg_prune_enabled: true
+borg_prune_trigger: after_backup
+borg_prune_glob_archives: "{hostname}-*"
+
+borg_prune_keep_daily: "7"
+borg_prune_keep_weekly: "4"
+borg_prune_keep_monthly: "6"
+borg_prune_keep_yearly: "1"
+
+borg_prune_compact_enabled: true
+borg_compact_threshold: 10
+```
+
+Example with a separate weekly prune timer:
+
+```yaml
+borg_prune_enabled: true
+borg_prune_trigger: timer
+borg_prune_systemd_oncalendar: "Sun *-*-* 04:00:00"
+borg_prune_systemd_accuracysec: 60min
+borg_prune_glob_archives: "{hostname}-*"
+borg_prune_keep_daily: "7"
+borg_prune_keep_weekly: "8"
+borg_prune_keep_monthly: "12"
+borg_prune_compact_enabled: true
+borg_compact_threshold: 1
+```
+
+For the full list of supported variables, see:
+[`defaults/main.yml`](defaults/main.yml) as well as the relevant Borg
+documentation:
+
+- <https://borgbackup.readthedocs.io/en/stable/usage/prune.html>
+- <https://borgbackup.readthedocs.io/en/stable/usage/compact.html>
+
+> [!INFO]
+> Prune and compact are not compatible with append-only repositories from the
+> client side. The role will fail early if you enable both
+> `borg_prune_enabled: true` and `borg_mode_append_only: true`.
+
To decrypt your backups without the client, we store the decryption keys in a
YAML file in your Ansible repository. You require the decryption keys as well as
access to the repository files on the Borg server to access the backups.
@@ -211,10 +272,12 @@ The names of the systemd service and timer are:
`{{ borg_backup_timer_name }}{{ borg_backup_argument }}.service` and
`{{ borg_backup_timer_name }}{{ borg_backup_argument }}.timer`.
-For the backup scripts we add `{{ borg_backup_script_location }}` for creating a
-backup on all specified targets and
-`{{ borg_backup_script_location }}{{ borg_backup_argument }}` for backing up to
-each target.
+Each target gets exactly one repository-specific backup script at
+`{{ borg_backup_script_location }}@{{ borg_backup_argument }}`. Systemd executes
+that script, and the same script can be called manually. The role does not
+create an aggregate script that runs all configured targets. If
+`borg_backup_argument` is empty, the script uses the unsuffixed
+`borg_backup_script_location` path.
To configure the backup schedule, we offer `borg_systemd_oncalendar` and
`borg_systemd_accuracysec`, which map to the corresponding systemd options,
@@ -523,66 +586,21 @@ To remove a specific repository (applies to both single and multi-instance setup
rm /usr/local/bin/run_borg_backup@ARGUMENT
```
-3. _(Multi-instance only)_ Edit the base backup script to remove the repository block:
-
- ```bash
- # Edit /usr/local/bin/run_borg_backup
- # Remove the ANSIBLE MANAGED BLOCK for the deleted repository
- ```
-
-4. _(If other repositories remain)_ Update `authorized_keys` on the Borg server
+3. _(If other repositories remain)_ Update `authorized_keys` on the Borg server
to remove the repository restriction. Edit `/opt/borg/.ssh/authorized_keys`
and remove the `--restrict-to-repository /opt/borg/REPONAME` from the
appropriate line.
If this is the last repository for the host, remove the entire line instead.
-5. Delete the repository on the Borg server:
+4. Delete the repository on the Borg server:
```bash
ssh borg@SERVER "borg delete /opt/borg/REPONAME"
# Or simply: ssh borg@SERVER "rm -rf /opt/borg/REPONAME"
```
-6. Remove the decryption key entry from your `decryption_keys.yml`.
-
-## Deprovisioning a Complete Host
-
-To remove all backup configuration for a host:
-
-1. Stop and disable all systemd timers and services:
-
- ```bash
- systemctl list-units --type=timer --all | grep borg_backup
- # For each relevant timer:
- systemctl stop borg_backup@*.timer
- systemctl disable borg_backup@*.timer
- ```
-
-2. Remove all backup scripts:
-
- ```bash
- rm -f /usr/local/bin/run_borg_backup*
- ```
-
-3. Remove the SSH key from the Borg server's `authorized_keys`:
-
- ```bash
- # On the Borg server, edit /opt/borg/.ssh/authorized_keys
- # Remove the line containing root@HOSTNAME
- ```
-
-4. Delete all repositories for the host on the Borg server:
-
- ```bash
- ssh borg@SERVER "rm -rf /opt/borg/HOSTNAME"
- # For multi-instance:
- ssh borg@SERVER "rm -rf /opt/borg/HOSTNAME_repo1"
- ssh borg@SERVER "rm -rf /opt/borg/HOSTNAME_repo2"
- ```
-
-5. Remove all decryption key entries for the host from your
- `decryption_keys.yml`.
+5. Remove the decryption key entry from your `decryption_keys.yml`.
## Dependencies