aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/borg.sh44
-rw-r--r--backends/bup.sh54
-rw-r--r--backends/tar.sh70
-rwxr-xr-xserver.sh122
4 files changed, 169 insertions, 121 deletions
diff --git a/backends/borg.sh b/backends/borg.sh
index f5930c8..0b28619 100644
--- a/backends/borg.sh
+++ b/backends/borg.sh
@@ -1,33 +1,33 @@
function borg_init() {
export BORG_PASSCOMMAND="$BACKUP_PASSCOMMAND"
- for BACKUP_DIR in ${BACKUP_DIRS[*]}
+ for backup_dir in ${BACKUP_DIRS[*]}
do
# borg will check if repo exists
- borg init --encryption=repokey-blake2 "$BACKUP_DIR"
+ borg init --encryption=repokey-blake2 "$backup_dir"
done
}
function borg_create_backup() {
export BORG_PASSCOMMAND="$BACKUP_PASSCOMMAND"
- RETCODE=255
- for BACKUP_DIR in ${BACKUP_DIRS[*]}
+ local retcode=255
+ for backup_dir in ${BACKUP_DIRS[*]}
do
- export BORG_REPO="$BACKUP_DIR"
+ export BORG_REPO="$backup_dir"
trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM
- echo "borg: starting backup to \"$BACKUP_DIR\""
+ echo "borg: starting backup to \"$backup_dir\""
borg create \
- "${BACKUP_DIR}::${BACKUP_NAME}_$(date +'%F_%H-%M-%S')" \
+ "${backup_dir}::${BACKUP_NAME}_$(date +'%F_%H-%M-%S')" \
"$WORLD_NAME" \
--filter AME \
--compression lz4 \
--exclude-caches \
- backup_exit=$?
+ local backup_exit=$?
- echo "borg: pruning repository at \"$BACKUP_DIR\""
+ echo "borg: pruning repository at \"$backup_dir\""
borg prune \
--prefix '{hostname}-' \
@@ -36,13 +36,13 @@ function borg_create_backup() {
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
- "$BACKUP_DIR"
+ "$backup_dir"
- prune_exit=$?
+ local prune_exit=$?
# use highest exit code as global exit code
- global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
- RETCODE=$(( global_exit > RETCODE ? global_exit : RETCODE ))
+ local global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
+ retcode=$(( global_exit > retcode ? global_exit : retcode ))
if [ ${global_exit} -eq 0 ]; then
echo "borg: backup and prune finished successfully"
@@ -53,29 +53,29 @@ function borg_create_backup() {
fi
#exit ${global_exit}
done
- return $RETCODE
+ return $retcode
}
# server_restore relies on output format of this function
function borg_ls_dir() {
export BORG_PASSCOMMAND="$BACKUP_PASSCOMMAND"
- borg list "$1" | cut -d' ' -f1
+ borg list "$1" | cut -d' ' -f1 | sort -r
}
function borg_ls_all() {
export BORG_PASSCOMMAND="$BACKUP_PASSCOMMAND"
- for BACKUP_DIR in ${BACKUP_DIRS[*]}
+ for backup_dir in ${BACKUP_DIRS[*]}
do
- echo "borg: backups in \"$BACKUP_DIR\":"
- borg list "$BACKUP_DIR" | cut -d' ' -f1
+ echo "borg: backups in \"$backup_dir\":"
+ borg list "$backup_dir" | cut -d' ' -f1
done
}
function borg_restore() {
export BORG_PASSCOMMAND="$BACKUP_PASSCOMMAND"
- REMOTE="$1"
- SNAPSHOT="$2"
+ local remote="$1"
+ local snapshot="$2"
- export BORG_REPO="$REMOTE"
- borg extract "${REMOTE}::${SNAPSHOT}"
+ export BORG_REPO="$remote"
+ borg extract "${remote}::${snapshot}"
}
diff --git a/backends/bup.sh b/backends/bup.sh
index a5ddb14..b57bd86 100644
--- a/backends/bup.sh
+++ b/backends/bup.sh
@@ -1,19 +1,19 @@
# use first not-remote backup directory as bup's local repository
# defaults to ".bup"
function bup_local() {
- for BACKUP_DIR in ${BACKUP_DIRS[*]}
+ for backup_dir in ${BACKUP_DIRS[*]}
do
- if [[ $BACKUP_DIR != *:* ]]; then
- echo "$BACKUP_DIR"
+ if [[ $backup_dir != *:* ]]; then
+ echo "$backup_dir"
return
fi
done
- echo ".bup"
+ echo ".bup"
}
function bup_init() {
bup -d "$(bup_local)" index "$WORLD_NAME"
- status=$?
+ local status=$?
if [ $status -ne 0 ]; then
echo "bup: no local repo found, creating..."
bup -d "$(bup_local)" init -r "$(bup_local)"
@@ -27,49 +27,51 @@ function bup_create_backup() {
bup -d "$(bup_local)" index "$WORLD_NAME"
# 0 if saved to at least one non-local repository
- RETCODE=1
- for BACKUP_DIR in ${BACKUP_DIRS[*]}
+ # TODO make more strict?
+ local retcode=1
+ for backup_dir in ${BACKUP_DIRS[*]}
do
- echo "bup: backing up to \"$BACKUP_DIR\""
+ echo "bup: backing up to \"$backup_dir\""
# try to save to remote
- bup -d "$(bup_local)" save -r "$BACKUP_DIR" -n "$BACKUP_NAME" "$WORLD_NAME"
+ bup -d "$(bup_local)" save -r "$backup_dir" -n "$BACKUP_NAME" "$WORLD_NAME"
+ local status=$?
# if failed - reinit remote and try again
- if [ ! $? -eq 0 ]; then
- echo "bup: failed backing up to \"$BACKUP_DIR\", reinitializing remote..."
- bup -d "$(bup_local)" init -r "$BACKUP_DIR"
- if [ ! $? -eq 0 ]; then
- echo "bup: created remote at \"$BACKUP_DIR\""
- bup -d "$(bup_local)" save -r "$BACKUP_DIR" -n "$BACKUP_NAME" "$WORLD_NAME"
+ if [ $status -ne 0 ]; then
+ echo "bup: failed backing up to \"$backup_dir\", reinitializing remote..."
+ bup -d "$(bup_local)" init -r "$backup_dir"
+ if [ $? -ne 0 ]; then
+ echo "bup: created remote at \"$backup_dir\""
+ bup -d "$(bup_local)" save -r "$backup_dir" -n "$BACKUP_NAME" "$WORLD_NAME"
else
- echo "bup: failed to make remote at \"$BACKUP_DIR\", moving on"
+ echo "bup: failed to make remote at \"$backup_dir\", moving on"
fi
else
- if [ "$BACKUP_DIR" = "$(bup_local)" ]; then
- RETCODE=0
+ if [ ! "$backup_dir" = "$(bup_local)" ]; then
+ retcode=0
fi
fi
done
echo "bup: backup finished"
- return $RETCODE
+ return $retcode
}
# server_restore relies on output format of this function
function bup_ls_dir() {
- bup -d "$(bup_local)" ls -r "$BACKUP_DIR" "$BACKUP_NAME"
+ local backup_dir="$1"
+ bup -d "$(bup_local)" ls -r "$backup_dir" "$BACKUP_NAME" | sort -r
}
function bup_ls_all() {
- for BACKUP_DIR in ${BACKUP_DIRS[*]}
+ for backup_dir in ${BACKUP_DIRS[*]}
do
echo "bup: backups in \"$BACKUP_DIR\":"
- bup -d "$(bup_local)" ls -r "$BACKUP_DIR" --human-readable -l "$BACKUP_NAME"
+ bup -d "$(bup_local)" ls -r "$backup_dir" --human-readable -l "$BACKUP_NAME"
done
}
function bup_restore() {
- REMOTE="$1"
- SNAPSHOT="$2"
-
- bup -d "$(bup_local)" restore -r "$REMOTE" "$BACKUP_NAME/$SNAPSHOT/$PWD/."
+ local remote="$1"
+ local snapshot="$2"
+ bup -d "$(bup_local)" restore -r "$remote" "$BACKUP_NAME/$snapshot/$PWD/."
}
diff --git a/backends/tar.sh b/backends/tar.sh
index 1265992..f7ea86e 100644
--- a/backends/tar.sh
+++ b/backends/tar.sh
@@ -7,68 +7,74 @@ function tar_init() {
function tar_create_backup() {
echo "tar: backing up..."
- # save world to a temporary archive
- ARCHNAME="/tmp/${BACKUP_NAME}_`date +%FT%H%M%S%z`.tar.gz"
- tar -czf "$ARCHNAME" "./$WORLD_NAME"
+ local status
- if [ ! $? -eq 0 ]
- then
+ # save world to a temporary archive
+ local archname="/tmp/${BACKUP_NAME}_`date +%FT%H%M%S%z`.tar.gz"
+ tar -czf "$archname" "./$WORLD_NAME"
+ status=$?
+ if [ $status -ne 0 ]; then
echo "tar: failed to save the world"
- rm "$ARCHNAME" #remove (probably faulty) archive
+ rm "$archname" #remove (probably faulty) archive
return 1
- else
- echo "tar: world saved to $ARCHNAME, pushing it to backup directories..."
fi
+ echo "tar: world saved to $archname, pushing it to backup directories..."
- RETCODE=2
- for BACKUP_DIR in ${BACKUP_DIRS[*]}
+ # 0 if could save to at least one backup dir
+ # TODO: make more strict?
+ local retcode=1
+ for backup_dir in ${BACKUP_DIRS[*]}
do
- echo "tar: pushing to \"$BACKUP_DIR\""
+ echo "tar: pushing to \"$backup_dir\""
# scp acts as cp for local destination directories
- scp "$ARCHNAME" "$BACKUP_DIR/"
- if [ ! $? -eq 0 ]; then
- echo "tar: failed pushing to \"$BACKUP_DIR\", moving on"
+ scp "$archname" "$backup_dir/"
+ status=$?
+ if [ $status -ne 0 ]; then
+ echo "tar: failed pushing to \"$backup_dir\", moving on"
else
- RETCODE=0
+ retcode=0
fi
done
- rm "$ARCHNAME"
+ rm "$archname"
echo "tar: backup finished"
- return $RETCODE
+ return $retcode
}
# server_restore relies on output format of this function
function tar_ls_dir() {
- BACKUP_DIR="$1"
- if [[ $BACKUP_DIR == *:* ]]; then
- REMOTE="$(echo "$BACKUP_DIR" | cut -d: -f1)"
- REMOTE_DIR="$(echo "$BACKUP_DIR" | cut -d: -f2)"
- ssh "$REMOTE" "ls -1 $REMOTE_DIR" | grep "tar.gz"
+ 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"
+ ls -1 "$backup_dir" | grep "tar.gz" | sort -r
fi
}
function tar_ls_all() {
- for BACKUP_DIR in ${BACKUP_DIRS[*]}
+ for backup_dir in ${BACKUP_DIRS[*]}
do
- echo "Backups in $BACKUP_DIR:"
- tar_ls_remote "$BACKUP_DIR"
+ echo "tar: backups in ${backup_dir}:"
+ tar_ls_remote "$backup_dir"
done
}
function tar_restore() {
- REMOTE="$1"
- SNAPSHOT="$2"
+ local remote="$1"
+ local snapshot="$2"
+ local status
- scp "$REMOTE/$SNAPSHOT" "/tmp/"
- if [ ! $? -eq 0 ]; then
- echo "Failed to get archive from \"$REMOTE/$SNAPSHOT\""
+ scp "$remote/$snapshot" "/tmp/"
+ status=$?
+ if [ $status -ne 0 ]; then
+ echo "tar: failed to get archive from \"$remote/$snapshot\""
return 1
fi
- tar -xzf "/tmp/$SNAPSHOT"
+ tar -xzf "/tmp/$snapshot"
}
diff --git a/server.sh b/server.sh
index 46156af..ad1a7d8 100755
--- a/server.sh
+++ b/server.sh
@@ -111,14 +111,14 @@ function players_online() {
}
function init_backup() {
- for BACKUP_DIR in ${BACKUP_DIRS[*]}
+ for backup_dir in ${BACKUP_DIRS[*]}
do
- if [[ $BACKUP_DIR == *:* ]]; then
- REMOTE="$(echo "$BACKUP_DIR" | cut -d: -f1)"
- REMOTE_DIR="$(echo "$BACKUP_DIR" | cut -d: -f2)"
- ssh "$REMOTE" "mkdir -p \"$REMOTE_DIR\""
+ if [[ $backup_dir == *:* ]]; then
+ local remote="$(echo "$backup_dir" | cut -d: -f1)"
+ local remote_dir="$(echo "$backup_dir" | cut -d: -f2)"
+ ssh "$remote" "mkdir -p \"$remote_dir\""
else
- mkdir -p "$BACKUP_DIR"
+ mkdir -p "$backup_dir"
fi
done
@@ -144,7 +144,7 @@ function create_backup() {
}
function server_backup_safe() {
- force=$1
+ local force=$1
echo "Detected running server. Checking if players online..."
if [ "$force" != "true" ] && ! players_online; then
echo "Players are not online. Not backing up."
@@ -171,8 +171,7 @@ function server_backup_safe() {
echo "Re-enabling auto-save"
send_cmd "save-on"
- if [ $RET -eq 0 ]
- then
+ if [ $RET -eq 0 ]; then
echo Running backup hook
$BACKUP_HOOK
fi
@@ -182,9 +181,9 @@ function server_backup_unsafe() {
echo "No running server detected. Running Backup"
create_backup
+ local status=$?
- if [ $? -eq 0 ]
- then
+ if [ $status -eq 0 ]; then
echo Running backup hook
$BACKUP_HOOK
fi
@@ -199,7 +198,7 @@ function fbackup_running() {
}
function server_backup() {
- force=$1
+ local force=$1
if [ "$force" = "true" ]; then
if backup_running; then
@@ -218,8 +217,6 @@ function server_backup() {
else
server_backup_unsafe
fi
-
- exit
}
function ls_backups() {
@@ -232,6 +229,7 @@ function ls_backups() {
fi
}
+# creates a selection dialog
function choose_from() {
local items=("$@")
select item in "${items[@]}"; do
@@ -241,60 +239,102 @@ function choose_from() {
echo ""
}
+# checks if an item is in the array
+function is_in() {
+ local item="$1"
+ shift
+ local array=("$@")
+
+ # these :space: things allow checking that *exactly* this item is in array
+ if [[ ${array[*]} =~ (^|[[:space:]])"$item"($|[[:space:]]) ]]; then
+ return
+ fi
+ false
+}
+
function server_restore() {
- echo "Select from where get the snapshot"
- BACKUP_DIR=$(choose_from "${BACKUP_DIRS[@]}")
- if [[ ! ${BACKUP_DIRS[*]} =~ (^|[[:space:]])"$BACKUP_DIR"($|[[:space:]]) ]]; then
+ local backup_dir
+ local snapshot_index
+ local dest
+
+ if [ $# -ge 2 ]; then
+ backup_dir="$1"
+ snapshot_index=$2
+ fi
+
+ if [ $# -eq 3 ]; then
+ dest="$3"
+ fi
+
+ if [ ${#BACKUP_DIRS[@]} -eq 0 ]; then
+ echo "No backup directories found, abort"
+ return 1
+ fi
+ if [ -z $backup_dir ]; then
+ echo "From where get the snapshot?"
+ backup_dir="$(choose_from "${BACKUP_DIRS[@]}")"
+ else
+ backup_dir=${BACKUP_DIRS[backup_dir_index]}
+ fi
+ if ! is_in "$backup_dir" "${BACKUP_DIRS[@]}" ; then
echo "No valid backup directory selected, abort"
return 1
fi
- SNAPSHOTS=$(
+ local snapshots=$(
if [ $BACKUP_BACKEND = "bup" ]; then
- bup_ls_dir "$BACKUP_DIR"
+ bup_ls_dir "$backup_dir"
elif [ $BACKUP_BACKEND = "borg" ]; then
- borg_ls_dir "$BACKUP_DIR"
+ borg_ls_dir "$backup_dir"
else
- tar_ls_dir "$BACKUP_DIR"
+ tar_ls_dir "$backup_dir"
fi
)
- if [ -z "$SNAPSHOTS" ]; then
+ if [ -z "$snapshots" ]; then
echo "No snapshots found, abort"
return 1
fi
# convert multiline string to bash array
- SNAPSHOTS=($(echo "$SNAPSHOTS"))
- echo "Select a snapshot to restore"
- SNAPSHOT=$(choose_from "${SNAPSHOTS[@]}")
- if [[ ! ${SNAPSHOTS[*]} =~ (^|[[:space:]])"$SNAPSHOT"($|[[:space:]]) ]]; then
+ snapshots=($(echo "$snapshots"))
+
+ local snapshot
+ if [ -z $snapshot_index ]; then
+ echo "Select which snapshot to restore"
+ snapshot=$(choose_from "${snapshots[@]}")
+ else
+ snapshot="${snapshots[snapshot_index]}"
+ fi
+ if ! is_in "$snapshot" "${snapshots[@]}" ; then
echo "No valid snapshot selected, abort"
return 1
fi
- echo "Restoring snapshot \"$SNAPSHOT\" from \"$BACKUP_DIR\""
+ echo "Restoring snapshot \"$snapshot\" from \"$backup_dir\""
- OLDWORLD_NAME=""
+ local oldworld_name=""
if [[ -d "$WORLD_NAME" ]]; then
- echo "Saving old world, just in case"
- OLDWORLD_NAME="${WORLD_NAME}.old.$(date +'%F_%H-%M-%S')"
- mv -v "$WORLD_NAME" "$OLDWORLD_NAME"
+ echo -n "Preserving old world: "
+ oldworld_name="${WORLD_NAME}.old.$(date +'%F_%H-%M-%S')"
+ mv -v "$PWD/$WORLD_NAME" "$PWD/$oldworld_name"
fi
if [ $BACKUP_BACKEND = "bup" ]; then
- bup_restore "$BACKUP_DIR" "$SNAPSHOT"
+ bup_restore "$backup_dir" "$snapshot"
elif [ $BACKUP_BACKEND = "borg" ]; then
- borg_restore "$BACKUP_DIR" "$SNAPSHOT"
+ borg_restore "$backup_dir" "$snapshot"
else
- tar_restore "$BACKUP_DIR" "$SNAPSHOT"
+ tar_restore "$backup_dir" "$snapshot"
fi
-
- if [ ! $? -eq 0 ]; then
- echo "Restore failed, reverting old world back"
- rm -r "$WORLD_NAME"
- mv -v "$OLDWORLD_NAME" "$WORLD_NAME"
- else
- echo "Restore finished"
+ local status=$?
+ if [ $status -ne 0 ]; then
+ echo "Failed to restore snapshot, putting old world back where it was:"
+ rm -rv "$PWD/$WORLD_NAME"
+ mv -v "$PWD/$oldworld_name" "$PWD/$WORLD_NAME"
+ return 1
fi
+ echo "Snapshot restored"
+
+ return 0
}
#cd $(dirname $0)