1
0
Fork 0

Add dobapor script from helios

DOBAPOR - DumpOrBackupAndPruneOrRestore
This commit is contained in:
Tobias Strobel 2021-08-12 17:55:42 +02:00
parent 041861f7b4
commit 8a9f082424
1 changed files with 457 additions and 0 deletions

457
aech/dobapor.sh Normal file
View File

@ -0,0 +1,457 @@
#!/bin/bash
# DOBAPOR - DumpOrBackupAndPruneOrRestore
# (c) 2019 Tobias Strobel <git@strobeltobias.de>
DATEFORMAT='%Y-%m-%d-%H-%M-%S'
BKPPATH='/root/backup'
LOGPATH="${BKPPATH}/log"
TMPDIR=$(mktemp -d)
HOST=$(hostname)
DOMAIN=$(hostname -d)
ROOT_DIR='/opt'
CONFIG_DIR="${ROOT_DIR}/config"
DATA_DIR="${ROOT_DIR}/data"
RUNTIME_DIR="${ROOT_DIR}/runtime"
ACTIONS=( dump backup restore prune status )
MCSERVICE='vmail|crypt|redis|rspamd|postfix|mysql'
SERVICE='rootfs|etc'
#DUMPSERVICE='nextcloud|wallabag|mailcow|ttrss|ejabberd'
DUMPSERVICE='wallabag|mailcow|ejabberd'
CHOOSESERVICE="${SERVICE}|${DUMPSERVICE}|all"
CHOOSEMCSERVICE="${MCSERVICE}|all"
DB_KEEPLATEST=4 # n+1
LOGS_KEEPLATEST=11 # n+1
#BORG_KEEPWITHIN=2d
#BORG_KEEPDAILY=7
#BORG_KEEPWEEKLY=4
#BORG_KEEPMONTHLY=3
BORG_KEEPWITHIN=1H
BORG_KEEPDAILY=0
BORG_KEEPWEEKLY=0
BORG_KEEPMONTHLY=0
declare -a BORG_REPOS
declare -a BORG_PASSPHRASES
BORG_REPOS[1]='/localbackup'
BORG_PASSPHRASES[1]='truth plug charcoal spoils thank ladder chaperone scale playmate retiree'
BORG_REPOS[2]='rsync.net:borg-aech'
BORG_PASSPHRASES[2]='debtor snowcap protrude swinger doozy catchy frenzy shininess denote ferris'
# only for Rsync.net users
export BORG_REMOTE_PATH=/usr/local/bin/borg1/borg1
if [[ ! ${1} =~ (dump|backup|restore|prune|status) ]]; then
echo "First parameter needs to be 'dump|backup|restore|prune|status'"
exit 1
elif [[ ${1} =~ (backup|prune) && ! ${2} =~ (${CHOOSESERVICE}) ]]; then
echo "Second parameter needs to be '${CHOOSESERVICE}'"
exit 1
elif [[ ${1} =~ (dump) && ! ${2} =~ (${DUMPSERVICE}) ]]; then
echo "Second parameter needs to be '${DUMPSERVICE}'"
exit 1
fi
ACTION=${1}
if [ ! -d "${BKPPATH}" ]; then
mkdir -p ${BKPPATH}
fi
if [ ! -d "${LOGPATH}" ]; then
mkdir -p ${LOGPATH}
fi
LOGFILE="${LOGPATH}/${ACTION}-$(date +${DATEFORMAT}).log"
## FUNCTIONS ###################################################
function dumpDBfromDocker() {
if [[ ! ${1} =~ (mysql|postgres) ]]; then
echo 'First parameter needs to be mysql or postgres.'
exit 1
fi
if [[ ${1} =~ (postgres) ]] && [[ ! ${2} =~ (nextcloud|wallabag|ttrss|ejabberd) ]]; then
echo 'Second parameter needs to be nextcloud, wallabag, ttrss or ejabberd.'
exit 1
fi
mkdir -p "${DATA_DIR}/${2}/dumps"
chmod 700 -R "${DATA_DIR}/${2}/dumps"
echo "Dump ${1} database of ${2}..."
case "${1}" in
mysql)
if [[ ! -f ${CONFIG_DIR}/${2}/${2}.env ]]; then
echo "No env file for ${2} found!"
exit 1
fi
source ${CONFIG_DIR}/${2}/${2}.env
SQLIMAGE=$(grep -iEo '(mysql|mariadb)\:.+' ${CONFIG_DIR}/${2}/docker-compose.yml|head -n1)
docker run --rm \
--network $(docker network ls -qf name=${2}_internal) \
-v ${RUNTIME_DIR}/${2}/db:/var/lib/mysql/ \
--entrypoint= \
-v ${DATA_DIR}/${2}/dumps:/dump \
${SQLIMAGE} /bin/sh -c "mysqldump -h${MYSQL_HOST:-db} -u${MYSQL_USER:-${2}} -p${MYSQL_PASSWORD} --all-databases --single-transaction --quick|gzip -c >/dump/mysql-$(date +${DATEFORMAT}).gz; \
ls -tp /dump/mysql*| grep -v '/$' | tail -n +${DB_KEEPLATEST:-4} | xargs -d '\n' -r rm --"
check $?
;;&
postgres)
if [[ ! -f ${CONFIG_DIR}/${2}/${2}.env ]]; then
echo "No env file for ${2} found!"
exit 1
fi
source ${CONFIG_DIR}/${2}/${2}.env
SQLIMAGE=$(grep -iEo 'postgres\:.+' ${CONFIG_DIR}/${2}/docker-compose.yml|head -n1)
docker run --rm \
--network $(docker network ls -qf name=${2}_internal) \
-v ${RUNTIME_DIR}/${2}/postgres:/var/lib/postgresql/data \
--entrypoint= \
-v ${DATA_DIR}/${2}/dumps:/dump \
${SQLIMAGE} /bin/sh -c "pg_dump -Fc postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD}@${POSTGRES_HOST:-postgres}:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-${2}} -f /dump/postgres-$(date +${DATEFORMAT}).dump; \
ls -tp /dump/postgres*| grep -v '/$' | tail -n +${DB_KEEPLATEST:-4} | xargs -d '\n' -r rm --"
check $?
;;
esac
}
function runBorgBackup() {
if [[ ! ${1} =~ (${SERVICE}|${DUMPSERVICE}) ]]; then
echo "First parameter needs specify the service: '${SERVICE}'"
exit 1
fi
if [[ ! -f ${TMPDIR}/fileList.borg ]]; then
echo 'No file list for borg is present in tmpdir!'
exit 1
fi
if [[ ! -f ${TMPDIR}/excludeList.borg ]]; then
touch ${TMPDIR}/excludeList.borg
fi
for ((i=1;i<=${#BORG_REPOS[@]};i++))
do
BORG_REPO=${BORG_REPOS[$i]}
export BORG_PASSPHRASE=${BORG_PASSPHRASES[$i]}
echo "Push backup of ${1} to $BORG_REPO..."
borg create -v --stats --compression lz4 --exclude-from ${TMPDIR}/excludeList.borg \
${BORG_REPO}::${1}'-{now:%Y-%m-%d_%H:%M:%S}' $(<${TMPDIR}/fileList.borg)
check $?
echo
done
>${TMPDIR}/excludeList.borg
>${TMPDIR}/fileList.borg
}
function runBorgPrune() {
if [[ ! ${1} =~ (${SERVICE}|${DUMPSERVICE}) ]]; then
echo "First parameter needs specify the service: '${SERVICE}'"
exit 1
fi
echo "###### Pruning backup for ${1} on $(date) ######"
for ((i=1;i<=${#BORG_REPOS[@]};i++))
do
BORG_REPO=${BORG_REPOS[$i]}
export BORG_PASSPHRASE=${BORG_PASSPHRASES[$i]}
borg prune -v --list --prefix ${1} ${BORG_REPO} \
--keep-within=${BORG_KEEPWITHIN:-2d} \
--keep-daily=${BORG_KEEPDAILY:-7} \
--keep-weekly=${BORG_KEEPWEEKLY:-4} \
--keep-monthly=${BORG_KEEPMONTHLY:-6}
check $?
echo
done
}
function pruneLogs() {
cd ${LOGPATH}
for ACT in ${ACTIONS[@]}
do
find . -maxdepth 1 -name "${ACT}*.log" | tail -n +${LOGS_KEEPLATEST:-6} | xargs -i rm -- {}
done
}
function showBorgStats() {
for ((i=1;i<=${#BORG_REPOS[@]};i++))
do
BORG_REPO=${BORG_REPOS[$i]}
export BORG_PASSPHRASE=${BORG_PASSPHRASES[$i]}
#borg info ${1} ${BORG_REPO}
echo
done
}
function mailcowBaR () {
if [[ ! ${1} =~ (${MCSERVICE}|all) ]]; then
echo "First parameter needs to be ${MCSERVICE}|all"
exit 1
fi
echo "Execute mailcow backup script for ${1}..."
MAILCOW_BACKUP_LOCATION=${ROOT_DIR}/data/mailcow/dumps /opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup ${1} >/dev/null
check $?
cd ${ROOT_DIR}/data/mailcow/dumps/; ls -1 -d "$PWD/"* -t | tail -n +${DB_KEEPLATEST:-4} | xargs -i rm -r -- {}
}
function nextcloudMaintenanceMode() {
/usr/bin/docker exec $(docker ps -qf name=nextcloud_cron) php /var/www/html/occ maintenance:mode --${1:-off}
}
function notifyAdmin() {
if [ -f ${TMPDIR}/errorsOccured ]; then
/usr/bin/mailx -a "From: ${HOST}.${DOMAIN} <root@${HOST}.${DOMAIN}>" -s "[${HOST}] ${ACTION} - errors occured" hostmaster@${DOMAIN} < ${LOGFILE}
rm ${TMPDIR}/errorsOccured
fi
}
function check() {
if [ $1 -eq 1 ]; then
echo '==> FAILED!'
if [ ! -f ${TMPDIR}/errorsOccured ]; then
touch ${TMPDIR}/errorsOccured
fi
return 1
fi
}
function dump() {
while (( "$#" )); do
case "${1}" in
# nextcloud|all)
# nextcloudMaintenanceMode on
# dumpDBfromDocker postgres nextcloud
# nextcloudMaintenanceMode off
# ;;&
wallabag|all)
dumpDBfromDocker postgres wallabag
;;&
# ttrss|all)
# dumpDBfromDocker postgres ttrss
# ;;&
ejabberd|all)
dumpDBfromDocker postgres ejabberd
;;&
mailcow|all)
while (( "$#" )); do
case "${2}" in
all)
mailcowBaR all
;;&
vmail)
mailcowBaR vmail
;;&
crypt)
mailcowBaR crypt
;;&
redis)
mailcowBaR redis
;;&
rspamd)
mailcowBaR rspamd
;;&
postfix)
mailcowBaR postfix
;;&
mysql)
mailcowBaR mysql
;;
esac
shift
done
;;
esac
shift
done
}
function backup() {
echo "###### Start backup of $HOST on $(date) ######"
while (( "$#" )); do
case "${2}" in
rootfs|all)
echo 'Get current locally installed software...'
dpkg --get-selections > ${BKPPATH}/software.list
check $?
cat <<EOT >>${TMPDIR}/fileList.borg
/root
/home
/opt
EOT
cat <<EOT >>${TMPDIR}/excludeList.borg
/root/.ssh/rsyncnet*
${LOGPATH}/*.log
${RUNTIME_DIR}
/opt/mailcow-dockerized
${DATA_DIR}/nextcloud*
${DATA_DIR}/wallabag*
${DATA_DIR}/ttrss*
${DATA_DIR}/mailcow*
${DATA_DIR}/ejabberd*
${DATA_DIR}/filer*
EOT
runBorgBackup rootfs
;;&
etc|rootfs)
cat <<EOT >>${TMPDIR}/fileList.borg
/etc
EOT
cat <<EOT >>${TMPDIR}/excludeList.borg
/etc/shadow*
EOT
runBorgBackup etc
;;&
# nextcloud|all)
# dump nextcloud
# nextcloudMaintenanceMode on
# cat <<EOT >>${TMPDIR}/fileList.borg
# ${CONFIG_DIR}/nextcloud
# ${DATA_DIR}/nextcloud
#EOT
# runBorgBackup nextcloud
# nextcloudMaintenanceMode off
# ;;&
wallabag|all)
dump wallabag
cat <<EOT >>${TMPDIR}/fileList.borg
${CONFIG_DIR}/wallabag
${DATA_DIR}/wallabag
EOT
runBorgBackup wallabag
;;&
# ttrss|all)
# dump ttrss
# cat <<EOT >>${TMPDIR}/fileList.borg
# ${CONFIG_DIR}/ttrss
# ${DATA_DIR}/ttrss
#EOT
# runBorgBackup ttrss
# ;;&
ejabberd|all)
dump ejabberd
cat <<EOT >>${TMPDIR}/fileList.borg
${CONFIG_DIR}/ejabberd
${DATA_DIR}/ejabberd
${CONFIG_DIR}/filer
${DATA_DIR}/filer
EOT
runBorgBackup ejabberd
;;&
mailcow|all)
# if [ "${2}" -eq 'all' ] ; then
# 3='all'
# fi
# while (( "$#" )); do
# case "${3}" in
# all)
dump mailcow all
cat <<EOT >>${TMPDIR}/fileList.borg
${ROOT_DIR}/mailcow-dockerized
${DATA_DIR}/mailcow
EOT
runBorgBackup mailcow
# ;;
# vmail)
# dump mailcow vmail
# # IMPLEMENT BACKUP VIA MC-VMAIL and so on!!
# ;;
# crypt)
# dump mailcow crypt
# ;;
# redis)
# dump mailcow redis
# ;;
# rspamd)
# dump mailcow rspamd
# ;;
# postfix)
# dump mailcow postfix
# ;;
# mysql)
# dump mailcow mysql
# ;;
# esac
# shift
# done
;;
esac
shift
done
echo
}
function prune() {
while (( "$#" )); do
case "${2}" in
rootfs|all)
runBorgPrune rootfs
;;&
etc|all)
runBorgPrune rootfs
;;&
# nextcloud|all)
# runBorgPrune nextcloud
# ;;&
wallabag|all)
runBorgPrune wallabag
;;&
# ttrss|all)
# runBorgPrune ttrss
# ;;&
ejabberd|all)
runBorgPrune ejabberd
;;&
mailcow|all)
# if [ "${2}" = 'all' ] ; then
# mailcowOpt='all'
# fi
# while (( "$#" )); do
# case "${mailcowOpt}" in
# all)
runBorgPrune mailcow
# ;;
# vmail)
# runBorgPrune mailcow
# ;;
# crypt)
# runBorgPrune mailcow
# ;;
# redis)
# runBorgPrune mailcow
# ;;
# rspamd)
# runBorgPrune mailcow
# ;;
# postfix)
# runBorgPrune mailcow
# ;;
# mysql)
# runBorgPrune mailcow
# ;;
# esac
# shift
# done
# ;;&
# all)
# pruneLogs
;;
esac
shift
done
}
# Write output to logfile
exec > >(tee -i ${LOGFILE})
exec 2>&1
if [[ ${ACTION} == 'dump' ]]; then
dump ${@,,}
elif [[ ${ACTION} == 'backup' ]]; then
backup ${@,,}
elif [[ ${ACTION} == 'restore' ]]; then
echo 'Restore not yet implemented!'
elif [[ ${ACTION} == 'prune' ]]; then
prune ${@,,}
elif [[ ${ACTION} == 'status' ]]; then
showBorgStats ${2}
fi
echo "Finished!"
notifyAdmin
rm -r $TMPDIR