From 9c60baf297c31efcacc178f506874e5fe8b7a3dd Mon Sep 17 00:00:00 2001 From: Fabio Sinibaldi Date: Wed, 9 Sep 2026 17:15:18 +0200 Subject: [PATCH] Configure both clients and servers --- .../roles/borg/templates/backup_script.sh.j2 | 86 +++++++++++++++++++ .../borg/templates/borg_backup.service.j2 | 13 +++ 2 files changed, 99 insertions(+) create mode 100644 ansible/playbooks/roles/borg/templates/backup_script.sh.j2 create mode 100644 ansible/playbooks/roles/borg/templates/borg_backup.service.j2 diff --git a/ansible/playbooks/roles/borg/templates/backup_script.sh.j2 b/ansible/playbooks/roles/borg/templates/backup_script.sh.j2 new file mode 100644 index 0000000..12a36b0 --- /dev/null +++ b/ansible/playbooks/roles/borg/templates/backup_script.sh.j2 @@ -0,0 +1,86 @@ +#!/bin/bash +{% for repo_item in borg_repos %} + +# Setting this, so the repo does not need to be given on the commandline: +export BORG_REPO="{{borg_repo_base}}{{repo_item.name}}" + +# See the section "Passphrase notes" for more infos. +export BORG_PASSPHRASE="'{{ repo_item.borg_passphrase }}'" + +# some helpers and error handling: +info() { logger "$*"; } +trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM + +info "Trying to initialize repo. NB returns error if already initialized" +borg init --encryption=repokey + +info "Starting backup for repo {{repo_item.name}}" + +# Backup the most important directories into an archive named after +# the machine this script is currently running on: + +borg create \ + --verbose \ + --filter AME \ + --list \ + --stats \ + --show-rc \ + --compression lz4 \ + --exclude-caches \ + --exclude 'home/*/.cache/*' \ + --exclude 'var/tmp/*' \ + \ + ::"'{{ inventory_hostname }}-{now}'"\ + {% for item in repo_item.paths_to_backup %} + {{ item }}\ + {% endfor %} + +backup_exit=$? + +info "Pruning repository {{ repo_item.name }}" + +# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly +# archives of THIS machine. The '{hostname}-*' matching is very important to +# limit prune's operation to this machine's archives and not apply to +# other machines' archives also: + +borg prune \ + --list \ + --glob-archives "'{{ inventory_hostname }}-*'" \ + --show-rc \ + --keep-daily 7 \ + --keep-weekly 4 \ + --keep-monthly 6 + +prune_exit=$? + +# actually free repo disk space by compacting segments + +info "Compacting repository {{ repo_item.name }}" + +borg compact + +compact_exit=$? + +# use highest exit code as global exit code +global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit )) +global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit )) + +if [ ${global_exit} -eq 0 ]; then + info "Backup, Prune, and Compact finished successfully" +elif [ ${global_exit} -eq 1 ]; then + info "Backup, Prune, and/or Compact finished with warnings" +else + info "Backup, Prune, and/or Compact finished with errors" +fi + + +# end loop for repos + +{% endfor %} + + +exit ${global_exit} + + + diff --git a/ansible/playbooks/roles/borg/templates/borg_backup.service.j2 b/ansible/playbooks/roles/borg/templates/borg_backup.service.j2 new file mode 100644 index 0000000..578173b --- /dev/null +++ b/ansible/playbooks/roles/borg/templates/borg_backup.service.j2 @@ -0,0 +1,13 @@ +[Unit] +Description=Borg Backup + +[Service] +Type=oneshot +User={{ borg_user }} +ExecStart=/home/{{borg_user}}/backup_script.sh + +AmbientCapabilities=CAP_DAC_READ_SEARCH + +StandardOutput=journal +StandardError=journal +SyslogIdentifier=borg \ No newline at end of file