#!/usr/bin/env bash # {{ ansible_managed }} # This file is to cleanup your backup archive and move some snapshots to a external storage. {% if restic_archiver__cache_config | bool %} {% include 'includes/restic_cache.sh.j2' %} {% endif %} {% if restic_archiver__mail_on_error | bool %} {% include 'includes/set_send_mail_on_error_variable.sh.j2' %} {% endif %} {% if restic_archiver__mail_report | default(false) %} {% include 'includes/mail_report_header.sh.j2' %} {% endif %} {% for repo in restic_archiver__repos %} {# define macro: how fast should we delete snapshots? Variables are defined via defaults! #} {% macro retention_pattern(repo) -%} {% if repo.keep_last is defined and repo.keep_last != None -%} --keep-last {{ repo.keep_last }} {%- else -%} --keep-last {{ restic_archiver__keep }} {%- endif %} \ {% if repo.keep_hourly is defined and repo.keep_hourly != None -%} --keep-hourly {{ repo.keep_hourly }} {%- else -%} --keep-hourly {{ restic_archiver__keep_hourly }} {%- endif %} \ {% if repo.keep_daily is defined and repo.keep_daily != None -%} --keep-daily {{ repo.keep_daily }} {%- else -%} --keep-daily {{ restic_archiver__keep_daily }} {%- endif %} \ {% if repo.keep_weekly is defined and repo.keep_weekly != None -%} --keep-weekly {{ repo.keep_weekly }} {%- else -%} --keep-weekly {{ restic_archiver__keep_weekly }} {%- endif %} \ {% if repo.keep_monthly is defined and repo.keep_monthly != None -%} --keep-monthly {{ repo.keep_monthly }} {%- else -%} --keep-monthly {{ restic_archiver__keep_monthly }} {%- endif %} \ {% if repo.keep_yearly is defined and repo.keep_yearly != None -%} --keep-yearly {{ repo.keep_yearly }} {%- else -%} --keep-yearly {{ restic_archiver__keep_yearly }} {%- endif -%} {% if repo.keep_within is defined and repo.keep_within != None %} \ --keep-within {{ repo.keep_within }} {% endif -%} {%- if repo.prune|default(restic_archiver__prune) %} \ --prune {% endif %} {%- endmacro %} {# START DOING STUFF INSIDE THE RESTIC REPO FOR LOOP #} { # try {% if restic_archiver__mount_required %} {% include 'includes/mounting.sh.j2' %} {% endif %} # Settings for Server {{ repo['name'] | string }} export RESTIC_REPOSITORY="{{ repo['location'] }}" export RESTIC_PASSWORD='{{ repo['password'] | regex_replace('\'', '\'\\\'\'') }}' 2>/dev/null BACKUP_NAME="{{ repo.name }}" {% if restic_archiver__mail_report | default(false) %} # collect info about last snapshot for mail report restic {{ restic_archiver__default_opt }} stats latest | grep Total {% endif %} echo "init $BACKUP_NAME" restic {{ restic_archiver__default_opt }} forget {{ retention_pattern(repo) }} echo "restic forget done" {%- if repo.prune|default(restic_archiver__prune) %} restic {{ restic_archiver__default_opt }} prune echo "restic prune done" {% endif %} {% if restic_archiver__mail_report | default(false) %} cat <> /tmp/mailcontent

{{ repo.name }}

$(restic {{ restic_archiver__default_opt }} check --quiet 2>/dev/null)

Latest Snapshots

$(restic --quiet snapshots --latest 1 --json | jq -c '.[]' | while read i; do echo -e "$i" | python3 -c "import sys, json; jsondata=json.load(sys.stdin); print('\n\n\n\n\n')" ; done)
Hostname latest backup Path
', jsondata['hostname'], '', jsondata['time'], '', str(jsondata['paths'][0]), '
$(restic --quiet stats --json | python3 -c "import sys, json; jsondata=json.load(sys.stdin); print('\n')") EOT {% else %} restic {{ restic_archiver__default_opt }} check {% endif %} {% if repo.archive|default(false) %} # ARCHIVE Settings for Server "{{ repo['name'] | string }}" export RESTIC_REPOSITORY="{{ repo['archive_location'] }}" export RESTIC_PASSWORD='{{ repo['archive_password'] | regex_replace('\'', '\'\\\'\'') }}' 2>/dev/null BACKUP_NAME="{{ repo.name }}_archive" echo "init $BACKUP_NAME" {% if restic_archiver__mount_required %} {% include 'includes/mounting.sh.j2' %} fi {% endif %} # init repo if it does not exist if ([ -z "$(restic cat config)" ]) 2>/dev/null; then restic {{ restic_archiver__default_opt }} init --copy-chunker-params fi # ARCHIVE Settings for Server "{{ repo['name'] | string }}" export RESTIC_REPOSITORY2="{{ repo['archive_location'] }}" export RESTIC_PASSWORD2='{{ repo['archive_password'] | regex_replace('\'', '\'\\\'\'') }}' 2>/dev/null export RESTIC_REPOSITORY="{{ repo['location'] }}" export RESTIC_PASSWORD='{{ repo['password'] | regex_replace('\'', '\'\\\'\'') }}' 2>/dev/null {% if restic_archiver__mount_required %} {% include 'includes/mounting.sh.j2' %} {% endif %} # transfer snapshots to archive restic {{ restic_archiver__default_opt }} copy {% if repo.archive_cleanup %} # ARCHIVE CLEANUP Settings for Server "{{ repo['name'] | string }}" export RESTIC_REPOSITORY="{{ repo['archive_location'] }}" export RESTIC_PASSWORD='{{ repo['archive_password'] | regex_replace('\'', '\'\\\'\'') }}' 2>/dev/null BACKUP_NAME="{{ repo.name }}_archive" restic {{ restic_archiver__default_opt }} forget {{ retention_pattern(repo) }} {%- if repo.prune|default(restic_archiver__prune) %} restic {{ restic_archiver__default_opt }} prune echo "restic ARCHIVE prune done" {% endif %} {% endif %} {% if restic_archiver__mail_report | default(false) %} restic --quiet stats --json | python3 -c "import sys, json; jsondata=json.load(sys.stdin); print('\n\n\n\n\n')" >> /tmp/mailcontent {% endif %} echo -e "
name total size total files
snapshots', str(int(jsondata['total_size'] / 1024 / 1024 / 1024 * 1000 )/1000 ), 'GB ', str(jsondata['total_file_count']), ' Files
external_archive', str(int(jsondata['total_size'] / 1024 / 1024 / 1024 * 1000 )/1000 ), 'GB ', str(jsondata['total_file_count']), ' Files.
\n

" >> /tmp/mailcontent restic {{ restic_archiver__default_opt }} check --quiet >> /tmp/mailcontent {% else %} restic {{ restic_archiver__default_opt }} check {% endif %} } || { # catch echo -e "

ALARM, ALARM

\n

SOMETING IN $RESTIC_REPOSITORY went wrong

" >> /tmp/mailcontent awk 'NR==3{print "

ALARM, ALARM

\n

SOMETING IN $RESTIC_REPOSITORY went wrong

"}1' /tmp/mailcontent >> /tmp/mailcontentx mv /tmp/mailcontentx /tmp/mailcontent found_error=true {% if restic_archiver__mail_on_error | bool %} restic_archiver__send_mail_on_error=true {% endif %} } {% endfor %} sync {% if restic_archiver__mail_report | default(false) %} cat <> /tmp/mailcontent








$(df -h)
EOT mail -a "Content-type: text/html" -s "restic backup report" {{ restic_archiver__mailaddress }} < /tmp/mailcontent {% endif %} {% if restic_archiver__mail_on_error | bool %} if [ "$restic_archiver__send_mail_on_error" == true ]; then mail -s "[ERROR] restic backup report" {{ restic_archiver__mailaddress }} <<< 'Something went wrong while running restic backup archiver at {{ ansible_hostname }}' fi {% endif %} {% if restic_archiver__umount_after_usage %} umount {{ restic_archiver__mount_disk }} {% endif %}