Better error handling
This commit is contained in:
parent
d4d75a63e5
commit
f7829e5500
2 changed files with 53 additions and 41 deletions
80
backup.sh
80
backup.sh
|
@ -177,7 +177,10 @@ rcon-command () {
|
||||||
|
|
||||||
# Open a TCP socket
|
# Open a TCP socket
|
||||||
# Source: https://www.xmodulo.com/tcp-udp-socket-bash-shell.html
|
# Source: https://www.xmodulo.com/tcp-udp-socket-bash-shell.html
|
||||||
exec 3<>/dev/tcp/"$HOST"/"$PORT"
|
if ! exec 3<>/dev/tcp/"$HOST"/"$PORT"; then
|
||||||
|
log-warning "RCON connection failed: Could not connect to $HOST:$PORT"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
login "$PASSWORD" || return 1
|
login "$PASSWORD" || return 1
|
||||||
debug-log "$(run-command "$COMMAND")"
|
debug-log "$(run-command "$COMMAND")"
|
||||||
|
@ -371,6 +374,44 @@ delete-thinning () {
|
||||||
delete-sequentially
|
delete-sequentially
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Delete old backups
|
||||||
|
delete-old-backups () {
|
||||||
|
case $DELETE_METHOD in
|
||||||
|
"sequential") delete-sequentially
|
||||||
|
;;
|
||||||
|
"thin") delete-thinning
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
clean-up () {
|
||||||
|
# Re-enable world autosaving
|
||||||
|
execute-command "save-on"
|
||||||
|
|
||||||
|
# Save the world
|
||||||
|
execute-command "save-all"
|
||||||
|
|
||||||
|
# Notify players of completion
|
||||||
|
WORLD_SIZE_BYTES=$(du -b --max-depth=0 "$SERVER_WORLD" | awk '{print $1}')
|
||||||
|
ARCHIVE_SIZE_BYTES=$(du -b "$ARCHIVE_PATH" | awk '{print $1}')
|
||||||
|
ARCHIVE_SIZE=$(du -h "$ARCHIVE_PATH" | awk '{print $1}')
|
||||||
|
BACKUP_DIRECTORY_SIZE=$(du -h --max-depth=0 "$BACKUP_DIRECTORY" | awk '{print $1}')
|
||||||
|
TIME_DELTA=$((END_TIME - START_TIME))
|
||||||
|
|
||||||
|
# Check that archive size is not null and at least 200 Bytes
|
||||||
|
if [[ "$ARCHIVE_EXIT_CODE" == "0" && "$WORLD_SIZE_BYTES" -gt 0 && "$ARCHIVE_SIZE" != "" && "$ARCHIVE_SIZE_BYTES" -gt 200 ]]; then
|
||||||
|
COMPRESSION_PERCENT=$((ARCHIVE_SIZE_BYTES * 100 / WORLD_SIZE_BYTES))
|
||||||
|
message-players-success "Backup complete!" "$TIME_DELTA s, $ARCHIVE_SIZE/$BACKUP_DIRECTORY_SIZE, $COMPRESSION_PERCENT%"
|
||||||
|
delete-old-backups
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
message-players-error "Backup was not saved!" "Please notify an administrator"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
trap "clean-up" 2
|
||||||
|
|
||||||
# Ensure backup directory exists
|
# Ensure backup directory exists
|
||||||
mkdir -p "$(dirname "$ARCHIVE_PATH")"
|
mkdir -p "$(dirname "$ARCHIVE_PATH")"
|
||||||
|
|
||||||
|
@ -394,39 +435,4 @@ fi
|
||||||
sync
|
sync
|
||||||
END_TIME=$(date +"%s")
|
END_TIME=$(date +"%s")
|
||||||
|
|
||||||
# Enable world autosaving
|
clean-up
|
||||||
execute-command "save-on"
|
|
||||||
|
|
||||||
# Save the world
|
|
||||||
execute-command "save-all"
|
|
||||||
|
|
||||||
# Delete old backups
|
|
||||||
delete-old-backups () {
|
|
||||||
case $DELETE_METHOD in
|
|
||||||
"sequential") delete-sequentially
|
|
||||||
;;
|
|
||||||
"thin") delete-thinning
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Notify players of completion
|
|
||||||
WORLD_SIZE_BYTES=$(du -b --max-depth=0 "$SERVER_WORLD" | awk '{print $1}')
|
|
||||||
ARCHIVE_SIZE_BYTES=$(du -b "$ARCHIVE_PATH" | awk '{print $1}')
|
|
||||||
ARCHIVE_SIZE=$(du -h "$ARCHIVE_PATH" | awk '{print $1}')
|
|
||||||
BACKUP_DIRECTORY_SIZE=$(du -h --max-depth=0 "$BACKUP_DIRECTORY" | awk '{print $1}')
|
|
||||||
TIME_DELTA=$((END_TIME - START_TIME))
|
|
||||||
|
|
||||||
# Check that archive size is not null and at least 200 Bytes
|
|
||||||
if [[ "$ARCHIVE_EXIT_CODE" -eq 0 && "$WORLD_SIZE_BYTES" -gt 0 && "$ARCHIVE_SIZE" != "" && "$ARCHIVE_SIZE_BYTES" -gt 200 ]]; then
|
|
||||||
COMPRESSION_PERCENT=$((ARCHIVE_SIZE_BYTES * 100 / WORLD_SIZE_BYTES))
|
|
||||||
message-players-success "Backup complete!" "$TIME_DELTA s, $ARCHIVE_SIZE/$BACKUP_DIRECTORY_SIZE, $COMPRESSION_PERCENT%"
|
|
||||||
delete-old-backups
|
|
||||||
else
|
|
||||||
message-players-error "Backup was not saved!" "Please notify an administrator"
|
|
||||||
if [ "$ARCHIVE_EXIT_CODE" -ne 0 ]; then
|
|
||||||
exit "$ARCHIVE_EXIT_CODE"
|
|
||||||
else
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
14
test/test.sh
14
test/test.sh
|
@ -23,7 +23,7 @@ setUp () {
|
||||||
echo "$!" > "$TEST_TMP/rcon-pid"
|
echo "$!" > "$TEST_TMP/rcon-pid"
|
||||||
|
|
||||||
while ! [[ (-f "$TEST_TMP/screen-output") && (-f "$TEST_TMP/tmux-output") && (-f "$TEST_TMP/rcon-output") ]]; do
|
while ! [[ (-f "$TEST_TMP/screen-output") && (-f "$TEST_TMP/tmux-output") && (-f "$TEST_TMP/rcon-output") ]]; do
|
||||||
sleep 0.2
|
sleep 0.3
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ test-screen-interface () {
|
||||||
./backup.sh -i "$TEST_TMP/server/world" -o "$TEST_TMP/backups" -s "$SCREEN_TMP" -f "$TIMESTAMP"
|
./backup.sh -i "$TEST_TMP/server/world" -o "$TEST_TMP/backups" -s "$SCREEN_TMP" -f "$TIMESTAMP"
|
||||||
EXPECTED_CONTENTS=$(echo -e "save-off\nsave-on\nsave-all")
|
EXPECTED_CONTENTS=$(echo -e "save-off\nsave-on\nsave-all")
|
||||||
SCREEN_CONTENTS="$(cat "$TEST_TMP/screen-output")"
|
SCREEN_CONTENTS="$(cat "$TEST_TMP/screen-output")"
|
||||||
assertEquals "$SCREEN_CONTENTS" "$EXPECTED_CONTENTS"
|
assertEquals "$EXPECTED_CONTENTS" "$SCREEN_CONTENTS"
|
||||||
}
|
}
|
||||||
|
|
||||||
test-tmux-interface () {
|
test-tmux-interface () {
|
||||||
|
@ -167,7 +167,7 @@ test-tmux-interface () {
|
||||||
./backup.sh -w tmux -i "$TEST_TMP/server/world" -o "$TEST_TMP/backups" -s "$SCREEN_TMP" -f "$TIMESTAMP"
|
./backup.sh -w tmux -i "$TEST_TMP/server/world" -o "$TEST_TMP/backups" -s "$SCREEN_TMP" -f "$TIMESTAMP"
|
||||||
EXPECTED_CONTENTS=$(echo -e "save-off\nsave-on\nsave-all")
|
EXPECTED_CONTENTS=$(echo -e "save-off\nsave-on\nsave-all")
|
||||||
SCREEN_CONTENTS="$(cat "$TEST_TMP/tmux-output")"
|
SCREEN_CONTENTS="$(cat "$TEST_TMP/tmux-output")"
|
||||||
assertEquals "$SCREEN_CONTENTS" "$EXPECTED_CONTENTS"
|
assertEquals "$EXPECTED_CONTENTS" "$SCREEN_CONTENTS"
|
||||||
}
|
}
|
||||||
|
|
||||||
test-rcon-interface () {
|
test-rcon-interface () {
|
||||||
|
@ -175,7 +175,7 @@ test-rcon-interface () {
|
||||||
./backup.sh -w rcon -i "$TEST_TMP/server/world" -o "$TEST_TMP/backups" -s "localhost:$RCON_PORT:$RCON_PASSWORD" -f "$TIMESTAMP"
|
./backup.sh -w rcon -i "$TEST_TMP/server/world" -o "$TEST_TMP/backups" -s "localhost:$RCON_PORT:$RCON_PASSWORD" -f "$TIMESTAMP"
|
||||||
EXPECTED_CONTENTS=$(echo -e "save-off\nsave-on\nsave-all")
|
EXPECTED_CONTENTS=$(echo -e "save-off\nsave-on\nsave-all")
|
||||||
SCREEN_CONTENTS="$(head -n3 "$TEST_TMP/rcon-output")"
|
SCREEN_CONTENTS="$(head -n3 "$TEST_TMP/rcon-output")"
|
||||||
assertEquals "$SCREEN_CONTENTS" "$EXPECTED_CONTENTS"
|
assertEquals "$EXPECTED_CONTENTS" "$SCREEN_CONTENTS"
|
||||||
}
|
}
|
||||||
|
|
||||||
test-rcon-interface-wrong-password () {
|
test-rcon-interface-wrong-password () {
|
||||||
|
@ -184,6 +184,12 @@ test-rcon-interface-wrong-password () {
|
||||||
assertContains "$OUTPUT" "Wrong RCON password"
|
assertContains "$OUTPUT" "Wrong RCON password"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test-rcon-interface-not-running () {
|
||||||
|
TIMESTAMP="$(date +%F_%H-%M-%S --date="2021-01-01")"
|
||||||
|
OUTPUT="$(./backup.sh -w RCON -i "$TEST_TMP/server/world" -o "$TEST_TMP/backups" -s "@!@#:$RCON_PORT:$RCON_PASSWORD" -f "$TIMESTAMP" 2>&1)"
|
||||||
|
assertContains "$OUTPUT" "Could not connect"
|
||||||
|
}
|
||||||
|
|
||||||
test-sequential-delete () {
|
test-sequential-delete () {
|
||||||
for i in $(seq 0 99); do
|
for i in $(seq 0 99); do
|
||||||
TIMESTAMP="$(date +%F_%H-%M-%S --date="2021-01-01 +$i hour")"
|
TIMESTAMP="$(date +%F_%H-%M-%S --date="2021-01-01 +$i hour")"
|
||||||
|
|
Loading…
Add table
Reference in a new issue