ansible-taler-exchange

Ansible playbook to deploy a production Taler Exchange
Log | Files | Refs | README | LICENSE

borg-backup.sh (3659B)


      1 #!/bin/bash
      2 
      3 export BORG_REPO={{ borg_repo | quote }}
      4 export BORG_PASSPHRASE={{ borg_passphrase | quote }}
      5 export BORG_RSH='ssh -F /root/.ssh/borg-config'
      6 
      7 umask 077
      8 info() { printf "\n%s %s\n\n" "$(date)" "$*" >&2; }
      9 
     10 # Acquire the lock before changing any dump files or installing cleanup traps.
     11 # A competing cron/manual/reboot run must not touch the owner's snapshot.
     12 exec 9>/run/taler-borg-backup.lock || exit 2
     13 if ! flock --exclusive --nonblock 9; then
     14     info "Another backup is running; this run made no changes"
     15     exit 75
     16 fi
     17 cd /root || exit 2
     18 cleanup() {
     19     rm -f -- postgres-backup.sql postgres-backup.sql.gz
     20 }
     21 trap cleanup EXIT
     22 trap 'exit 2' HUP INT TERM
     23 
     24 info "Dumping database"
     25 
     26 # The root-owned output is intentionally opened by this shell.
     27 # shellcheck disable=SC2024
     28 sudo -u postgres pg_dumpall > postgres-backup.sql
     29 db_exit=$?
     30 
     31 if [[ $db_exit -ne 0 ]]; then
     32     info "DB export failed, exit status $db_exit"
     33     exit 1
     34 fi
     35 
     36 # Note: I actually benchmarked (!) this on *our* SQL data.
     37 # zstd was fastest, but gzip was smallest
     38 # (tested: gzip, bzip, zstd, lzip, xz)
     39 # -f so that a snapshot left behind by an interrupted run does not
     40 # block every future backup.
     41 gzip -f postgres-backup.sql || exit 1
     42 
     43 echo "Database snapshot created:"
     44 ls -al postgres-backup.sql.gz
     45 
     46 info "Starting backup"
     47 
     48 # Backup the most important directories into an archive named after
     49 # the machine this script is currently running on:
     50 
     51 borg create                         \
     52     --verbose                       \
     53     --filter AME                    \
     54     --list                          \
     55     --stats                         \
     56     --show-rc                       \
     57     --compression lz4               \
     58     --exclude-caches                \
     59     --exclude 'home/*/.cache/*'     \
     60     --exclude 'var/tmp/*'           \
     61     --exclude 'var/lib/taler-exchange/secmod-*/*' \
     62                                     \
     63     ::'{hostname}-{now}'            \
     64     /etc                            \
     65     /root                           \
     66     /var/lib/libeufin-nexus         \
     67     /var/lib/taler-exchange
     68 
     69 backup_exit=$?
     70 
     71 info "Removing database dump"
     72 
     73 rm -f -- postgres-backup.sql.gz || exit 2
     74 
     75 if [[ $backup_exit -ne 0 ]]; then
     76     info "Backup did not complete cleanly, exit status $backup_exit; not pruning"
     77     exit $backup_exit
     78 fi
     79 
     80 info "Pruning repository"
     81 
     82 # Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
     83 # archives of THIS machine. The '{hostname}-*' matching is very important to
     84 # limit prune's operation to this machine's archives and not apply to
     85 # other machines' archives also:
     86 
     87 borg prune                          \
     88     --list                          \
     89     --glob-archives '{hostname}-*'  \
     90     --show-rc                       \
     91     --keep-daily    7               \
     92     --keep-weekly   4               \
     93     --keep-monthly  6
     94 
     95 prune_exit=$?
     96 if [[ $prune_exit -ne 0 ]]; then
     97     info "Prune did not complete cleanly, exit status $prune_exit; not compacting"
     98     exit "$prune_exit"
     99 fi
    100 
    101 # actually free repo disk space by compacting segments
    102 
    103 info "Compacting repository"
    104 
    105 borg compact
    106 
    107 compact_exit=$?
    108 
    109 # use highest exit code as global exit code
    110 global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
    111 global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit ))
    112 global_exit=$(( db_exit > global_exit ? db_exit : global_exit ))
    113 
    114 if [ ${global_exit} -eq 0 ]; then
    115     info "Backup, Prune, and Compact finished successfully"
    116 elif [ ${global_exit} -eq 1 ]; then
    117     info "Backup, Prune, and/or Compact finished with warnings"
    118 else
    119     info "Backup, Prune, and/or Compact finished with errors"
    120 fi
    121 
    122 exit ${global_exit}