215 lines
5.5 KiB
Bash
Executable File
215 lines
5.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# PgBackrest backup wrapper script
|
|
|
|
## FUNCTIONS
|
|
|
|
# METHOD: convert_time
|
|
# PARAMS: timestamp in seconds or with milliseconds (nnnn.nnnn)
|
|
# RETURN: formated string with human readable time (d/h/m/s)
|
|
# CALL : var=$(convert_time $timestamp);
|
|
# DESC : converts a timestamp or a timestamp with float milliseconds
|
|
# to a human readable format
|
|
# output is in days/hours/minutes/seconds
|
|
function convert_time
|
|
{
|
|
timestamp=${1};
|
|
# round to four digits for ms
|
|
timestamp=$(printf "%1.4f" "$timestamp");
|
|
# get the ms part and remove any leading 0
|
|
ms=$(echo "${timestamp}" | cut -d "." -f 2 | sed -e 's/^0*//');
|
|
timestamp=$(echo "${timestamp}" | cut -d "." -f 1);
|
|
timegroups=(86400 3600 60 1); # day, hour, min, sec
|
|
timenames=("d" "h" "m" "s"); # day, hour, min, sec
|
|
output=( );
|
|
time_string="";
|
|
for timeslice in "${timegroups[@]}"; do
|
|
# floor for the division, push to output
|
|
output[${#output[*]}]=$(awk "BEGIN {printf \"%d\", ${timestamp}/${timeslice}}");
|
|
timestamp=$(awk "BEGIN {printf \"%d\", ${timestamp}%${timeslice}}");
|
|
done;
|
|
|
|
for ((i=0; i<${#output[@]}; i++)); do
|
|
if [ "${output[$i]}" -gt 0 ] || [ -n "$time_string" ]; then
|
|
if [ -n "${time_string}" ]; then
|
|
time_string=${time_string}" ";
|
|
fi;
|
|
time_string=${time_string}${output[$i]}${timenames[$i]};
|
|
fi;
|
|
done;
|
|
if [ -n "${ms}" ] && [ "${ms}" != "nan" ] && [ "${ms}" -gt 0 ]; then
|
|
time_string=${time_string}" ${ms}ms";
|
|
fi;
|
|
# just in case the time is 0
|
|
if [ -z "${time_string}" ]; then
|
|
time_string="0s";
|
|
fi;
|
|
echo -n "${time_string}";
|
|
}
|
|
|
|
## VARIABLES
|
|
|
|
REGEX_COMMENT="^[\ \t]*#";
|
|
INI_BLOCK="^\[[A-Za-z]*\]";
|
|
BASE_FOLDER=$(dirname "$(readlink -f "$0")")"/";
|
|
CONFIG="${BASE_FOLDER}../config/";
|
|
BACKUP_TYPE="";
|
|
OVERRIDE_STANZA="";
|
|
LIST_STANZA=0;
|
|
TEST=0;
|
|
config_file="${CONFIG}pgbackrest.cfg";
|
|
stanza_file="${CONFIG}stanza.cfg";
|
|
if [ -f "${config_file}" ]; then
|
|
# shellcheck disable=SC1090
|
|
# shellcheck disable=SC2283
|
|
source <(grep = "${config_file}" | sed 's/ *= */=/g')
|
|
else
|
|
echo "Missing config file ${config_file}";
|
|
exit;
|
|
fi;
|
|
if [ -z "${sudo_user}" ]; then
|
|
echo "sudo_user not set in the config file ${config_file}";
|
|
exit;
|
|
fi;
|
|
# stanza list file
|
|
if [ ! -f "${stanza_file}" ]; then
|
|
echo "Missing stanza config file ${stanza_file}";
|
|
exit;
|
|
fi;
|
|
|
|
PRINTF_BLOCK="=== [%-8s: %19s] ==[%s]===============>\n";
|
|
|
|
## OPT PARSEIN
|
|
|
|
while getopts ":b:s:lt" opt; do
|
|
case "${opt}" in
|
|
b)
|
|
# backuptype
|
|
BACKUP_TYPE="${OPTARG}";
|
|
;;
|
|
s)
|
|
# stanza
|
|
OVERRIDE_STANZA="${OPTARG}";
|
|
;;
|
|
l)
|
|
# list
|
|
LIST_STANZA=1;
|
|
;;
|
|
t)
|
|
# test
|
|
TEST=1;
|
|
;;
|
|
:)
|
|
echo "Option -$OPTARG requires an argument."
|
|
;;
|
|
\?)
|
|
echo -e "\n Option does not exist: ${OPTARG}\n";
|
|
echo "-b (backuptype): full/diff";
|
|
echo "-s (stanza): override stanza name, must be in list"
|
|
echo "-l list available stanza"
|
|
echo "-t test run"
|
|
exit 1;
|
|
;;
|
|
esac;
|
|
done;
|
|
|
|
## SCRIPT
|
|
|
|
if [ $TEST -eq 1 ]; then
|
|
echo "[..........] TEST RUN ONLY";
|
|
fi;
|
|
|
|
if [ $LIST_STANZA -eq 1 ]; then
|
|
echo "+ Stanza List:";
|
|
for stanza in ${stanza_list}; do
|
|
echo "${stanza}";
|
|
done;
|
|
while read -r stanza; do
|
|
# skip empty
|
|
[ -z "${stanza}" ] && continue;
|
|
# skip starting with #
|
|
[[ "${stanza}" =~ ${REGEX_COMMENT} ]] && continue;
|
|
# skip the ini header blocks
|
|
[[ "${stanza}" =~ ${INI_BLOCK} ]] && continue;
|
|
# if override stanza matching
|
|
if [ "${stanza}" = "${OVERRIDE_STANZA}" ]; then
|
|
echo "[*] ${stanza}";
|
|
else
|
|
echo "[ ] ${stanza}";
|
|
fi;
|
|
done <<< "$(cat "${stanza_file}")";
|
|
echo "";
|
|
echo "Entry marked with '*' is set as override stanza, and will be the only one backed up";
|
|
echo "";
|
|
exit;
|
|
fi;
|
|
|
|
if [ -z "${BACKUP_TYPE}" ]; then
|
|
echo "[!] Backup type must be set as -b full or -b diff";
|
|
exit;
|
|
fi;
|
|
|
|
if [ "${BACKUP_TYPE}" != "full" ] && [ "${BACKUP_TYPE}" != "diff" ]; then
|
|
echo "[!] Backup type can only be 'full' or 'diff'";
|
|
exit;
|
|
fi;
|
|
|
|
echo "* PgBackrest Backup run type '${BACKUP_TYPE}' on $(date +'%F')";
|
|
SET_OVERRIDE_STANZA=0;
|
|
# if we have override single host
|
|
if [ -n "${OVERRIDE_STANZA}" ]; then
|
|
echo "+ Set override stanza too: ${OVERRIDE_STANZA}";
|
|
while read -r stanza; do
|
|
# skip empty
|
|
[ -z "${stanza}" ] && continue;
|
|
# skip starting with #
|
|
[[ "${stanza}" =~ ${REGEX_COMMENT} ]] && continue;
|
|
# skip the ini header blocks
|
|
[[ "${stanza}" =~ ${INI_BLOCK} ]] && continue;
|
|
# if override stanza matching
|
|
if [ "${stanza}" = "${OVERRIDE_STANZA}" ]; then
|
|
stanza_list="${OVERRIDE_STANZA}";
|
|
SET_OVERRIDE_STANZA=1;
|
|
break;
|
|
fi;
|
|
done <<< "$(cat "${stanza_file}")";
|
|
if [ $SET_OVERRIDE_STANZA = 0 ]; then
|
|
echo "[!!!] Failed to set override stanza: ${OVERRIDE_STANZA}";
|
|
exit;
|
|
fi;
|
|
fi;
|
|
# run backup
|
|
while read -r stanza; do
|
|
# skip empty
|
|
[ -z "${stanza}" ] && continue;
|
|
# skip starting with #
|
|
[[ "${stanza}" =~ ${REGEX_COMMENT} ]] && continue;
|
|
# skip the ini header blocks
|
|
[[ "${stanza}" =~ ${INI_BLOCK} ]] && continue;
|
|
# override stanza check
|
|
if [ -n "${OVERRIDE_STANZA}" ]; then
|
|
if [ "${stanza}" != "${OVERRIDE_STANZA}" ]; then
|
|
continue
|
|
fi;
|
|
fi;
|
|
# main backup start
|
|
START=$(date +'%s');
|
|
# shellcheck disable=SC2059
|
|
printf "${PRINTF_BLOCK}" "START" "$(date +'%F %T')" "${stanza}";
|
|
# --log-level-console=info
|
|
if [ $TEST -eq 1 ]; then
|
|
echo "sudo -u ${sudo_user} pgbackrest --type=${BACKUP_TYPE} --stanza=${stanza} backup;";
|
|
else
|
|
sudo -u "${sudo_user}" pgbackrest --type="${BACKUP_TYPE}" --stanza="${stanza}" backup;
|
|
fi;
|
|
DURATION=$(( $(date +'%s')-START ));
|
|
# shellcheck disable=SC2059
|
|
printf "${PRINTF_BLOCK}" "END" "$(convert_time ${DURATION})" "${stanza}";
|
|
done <<< "$(cat "${stanza_file}")";
|
|
echo "* PgBackrest Backup end";
|
|
if [ $TEST -eq 1 ]; then
|
|
echo "[..........] TEST RUN ONLY";
|
|
fi;
|
|
|
|
## __END__
|