diff options
author | Jonas Gunz <himself@jonasgunz.de> | 2022-01-25 11:01:32 +0100 |
---|---|---|
committer | Jonas Gunz <himself@jonasgunz.de> | 2022-01-25 11:01:32 +0100 |
commit | 9b35f4f8f9253ffb2e7aa8d7ee7526472ab191f2 (patch) | |
tree | 7bbe74ae3924f479ede973e0a9603b5c0646b2f4 /backends | |
parent | b0e2841205ed1f5ce8223c05e90258b30ea88879 (diff) | |
parent | 77a9baea740a49c2204893a022fd4bf25d109c07 (diff) | |
download | minecraft-server-tools-9b35f4f8f9253ffb2e7aa8d7ee7526472ab191f2.tar.gz |
Diffstat (limited to 'backends')
-rw-r--r-- | backends/borg.sh | 84 | ||||
-rw-r--r-- | backends/bup.sh | 71 | ||||
-rw-r--r-- | backends/tar.sh | 73 |
3 files changed, 228 insertions, 0 deletions
diff --git a/backends/borg.sh b/backends/borg.sh new file mode 100644 index 0000000..ec39bc8 --- /dev/null +++ b/backends/borg.sh @@ -0,0 +1,84 @@ +function borg_init() { + local encryption + if [ -z "$BACKUP_PASSCOMMAND" ] ; then + log_info "borg: no password given, repository is not protected" + encryption="none" + else + encryption="repokey-blake2" + fi + + export BORG_PASSCOMMAND="$BACKUP_PASSCOMMAND" + for backup_dir in ${BACKUP_DIRS[*]} + do + log_debug "Initializing repo at $backup_dir " + # borg will check if repo exists + borg init --encryption="$encryption" "$backup_dir" + done +} + +function borg_create_backup() { + export BORG_PASSCOMMAND="$BACKUP_PASSCOMMAND" + local retcode=255 + for backup_dir in ${BACKUP_DIRS[*]} + do + export BORG_REPO="$backup_dir" + + trap 'echo [WARNING] $( date ) Backup interrupted >&2; exit 2' INT TERM + + log_info "borg: backing up to \"$backup_dir\"" + + borg create \ + "${backup_dir}::${BACKUP_NAME}_$(date +'%F_%H-%M-%S')" \ + "$WORLD_NAME" \ + --filter AME \ + --compression lz4 \ + --exclude-caches \ + + local backup_exit=$? + + log_debug "borg: pruning repository at \"$backup_dir\"" + + borg prune \ + --prefix '{hostname}-' \ + --keep-minutely 2 \ + --keep-hourly 24 \ + --keep-daily 7 \ + --keep-weekly 4 \ + --keep-monthly 6 \ + "$backup_dir" + + local prune_exit=$? + + # use highest exit code as global exit code + local global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit )) + retcode=$(( global_exit > retcode ? global_exit : retcode )) + + if [ ${global_exit} -eq 0 ]; then + log_debug "borg: backup and prune finished successfully" + elif [ ${global_exit} -eq 1 ]; then + log_info "borg: backup and/or prune finished with warnings" + else + log_error "borg: backup and/or prune finished with errors" + fi + #exit ${global_exit} + done + return $retcode +} + +# server_restore relies on output format of this function +function borg_ls() { + export BORG_PASSCOMMAND="$BACKUP_PASSCOMMAND" + borg list "$1" | cut -d' ' -f1 | sort -r +} + +function borg_restore() { + export BORG_PASSCOMMAND="$BACKUP_PASSCOMMAND" + local remote="$1" + local snapshot="$2" + local dest="$3" + + export BORG_REPO="$remote" + cd "$dest" + borg extract "${remote}::${snapshot}" + cd - > /dev/null +} diff --git a/backends/bup.sh b/backends/bup.sh new file mode 100644 index 0000000..6aa92b6 --- /dev/null +++ b/backends/bup.sh @@ -0,0 +1,71 @@ +# use first not-remote backup directory as bup's local repository +# defaults to ".bup" +function bup_local() { + for backup_dir in ${BACKUP_DIRS[*]} + do + if [[ $backup_dir != *:* ]]; then + echo "$backup_dir" + return + fi + done + echo ".bup" +} + +function bup_init() { + bup -d "$(bup_local)" index "$WORLD_NAME" + local status=$? + if [ $status -ne 0 ]; then + log_debug "bup: no local repo found, creating..." + bup -d "$(bup_local)" init -r "$(bup_local)" + log_debug "bup: created local repo at $(bup_local)" + fi +} + +function bup_create_backup() { + log_debug "bup: backup started" + + bup -d "$(bup_local)" index "$WORLD_NAME" + + # 0 if saved to at least one non-local repository + # TODO make more strict? + local retcode=1 + for backup_dir in ${BACKUP_DIRS[*]} + do + log_info "bup: backing up to \"$backup_dir\"" + # try to save to remote + bup -d "$(bup_local)" save -r "$backup_dir" -n "$BACKUP_NAME" "$WORLD_NAME" + local status=$? + # if failed - reinit remote and try again + if [ $status -ne 0 ]; then + log_debug "bup: failed backing up to \"$backup_dir\", reinitializing remote..." + bup -d "$(bup_local)" init -r "$backup_dir" + status=$? + if [ $status -eq 0 ]; then + log_debug "bup: created remote at \"$backup_dir\"" + bup -d "$(bup_local)" save -r "$backup_dir" -n "$BACKUP_NAME" "$WORLD_NAME" + else + log_error "bup: failed to make remote at \"$backup_dir\", moving on" + fi + else + if [ ! "$backup_dir" = "$(bup_local)" ]; then + retcode=0 + fi + fi + done + + log_debug "bup: backup finished" + return $retcode +} + +# server_restore relies on output format of this function +function bup_ls() { + local backup_dir="$1" + bup -d "$(bup_local)" ls -r "$backup_dir" "$BACKUP_NAME" | sort -r +} + +function bup_restore() { + local remote="$1" + local snapshot="$2" + local dest="$3" + bup -d "$(bup_local)" restore -r "$remote" --outdir "$dest" "$BACKUP_NAME/$snapshot/$PWD/." +} diff --git a/backends/tar.sh b/backends/tar.sh new file mode 100644 index 0000000..6748ac9 --- /dev/null +++ b/backends/tar.sh @@ -0,0 +1,73 @@ +function tar_init() { + # nothing to do for tar? + : +} + +# TODO: Make default .tar with optional bup +function tar_create_backup() { + log_debug "tar: backing up..." + + local status + + # save world to a temporary archive + local archname="/tmp/${BACKUP_NAME}_`date +%F_%H-%M-%S`.tar.gz" + tar -czf "$archname" "./$WORLD_NAME" + status=$? + if [ $status -ne 0 ]; then + log_error "tar: failed to save the world" + rm "$archname" #remove (probably faulty) archive + return 1 + fi + log_debug "tar: world saved to $archname, pushing it to backup directories..." + + # 0 if could save to at least one backup dir + # TODO: make more strict? + local retcode=1 + for backup_dir in ${BACKUP_DIRS[*]} + do + log_info "tar: backing up to \"$backup_dir\"" + # scp acts as cp for local destination directories + scp "$archname" "$backup_dir/" + status=$? + if [ $status -ne 0 ]; then + log_error "tar: failed pushing to \"$backup_dir\", moving on" + else + retcode=0 + fi + done + + rm "$archname" + + log_debug "tar: backup finished" + + return $retcode +} + +# server_restore relies on output format of this function +function tar_ls() { + local backup_dir="$1" + + if [[ "$backup_dir" == *:* ]]; then + local remote="$(echo "$backup_dir" | cut -d: -f1)" + local remote_dir="$(echo "$backup_dir" | cut -d: -f2)" + ssh "$remote" "ls -1 $remote_dir" | grep "tar.gz" | sort -r + else + ls -1 "$backup_dir" | grep "tar.gz" | sort -r + fi +} + +function tar_restore() { + local remote="$1" + local snapshot="$2" + local dest="$3" + local status + + scp "$remote/$snapshot" "/tmp/" + status=$? + if [ $status -ne 0 ]; then + log_error "tar: failed to get archive from \"$remote/$snapshot\"" + return 1 + fi + + tar -xzf "/tmp/$snapshot" -C "$dest" +} |