#!/bin/bash # Managed by Ansible (role restic_backup). # # restic-backup run hooks, then backup + forget to every repository # restic-backup init create the repositories that do not exist yet # restic-backup plain restic against one repository, e.g. # restic-backup hel1 snapshots # restic-backup fsn1 restore latest --target /tmp/r # # Repositories: {{ restic_repositories.keys() | join(', ') }} set -uo pipefail set -a; . /etc/restic/env; set +a export RESTIC_CACHE_DIR=/var/cache/restic STAGE={{ restic_stage_dir }} declare -A REPOS=( {% for name, url in restic_repositories.items() %} [{{ name }}]="{{ url }}" {% endfor %} ) log() { echo "restic-backup: $*"; } # Last good backup per repository, for Prometheus (node_exporter textfile) metric() { local f={{ monitoring_textfile_dir }}/restic_$1.prom printf '# HELP restic_backup_last_success_timestamp_seconds Last successful restic backup.\n# TYPE restic_backup_last_success_timestamp_seconds gauge\nrestic_backup_last_success_timestamp_seconds{repo="%s"} %s\n' "$1" "$(date +%s)" > "$f.tmp" && mv "$f.tmp" "$f" } case "${1:-}" in init) for name in "${!REPOS[@]}"; do if RESTIC_REPOSITORY="${REPOS[$name]}" restic cat config >/dev/null 2>&1; then log "$name: exists" else RESTIC_REPOSITORY="${REPOS[$name]}" restic init || exit 1 log "$name: created" fi done ;; run) failed=0 rm -rf "$STAGE"; install -d -m 700 "$STAGE" export STAGE {% for hook in restic_pre_hooks %} log "hook {{ loop.index }}/{{ restic_pre_hooks | length }}" ( set -e; {{ hook }} ) || { log "hook failed"; failed=1; } {% endfor %} for name in "${!REPOS[@]}"; do export RESTIC_REPOSITORY="${REPOS[$name]}" log "$name: backup" restic backup --host {{ inventory_hostname }} --one-file-system --exclude-caches \ {% for e in restic_excludes %} --exclude '{{ e }}' \ {% endfor %} {{ (restic_paths + [restic_stage_dir]) | join(' ') }} || { failed=1; continue; } prune="" [ "$(date +%a)" = "{{ restic_prune_weekday }}" ] && prune="--prune" log "$name: forget $prune" restic forget --host {{ inventory_hostname }} {{ restic_keep }} $prune || failed=1 metric "$name" done rm -rf "$STAGE" exit $failed ;; *) [ -n "${1:-}" ] && [ -n "${REPOS[$1]:-}" ] || { sed -n '4,10p' "$0"; exit 2; } export RESTIC_REPOSITORY="${REPOS[$1]}"; shift exec restic "$@" ;; esac