From a9d120091ed7a4a2846af36478167e4b8d0f43f6 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 4 Sep 2024 17:49:31 +0000 Subject: [PATCH] Added fixes in backuptool to backup databases that exist in SERVICES but not in app directory --- bin/backuptool | 106 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 83 insertions(+), 23 deletions(-) diff --git a/bin/backuptool b/bin/backuptool index 7b58c57..43ac3f7 100755 --- a/bin/backuptool +++ b/bin/backuptool @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash -x # # Federated Backup / Restore Tool to B2 Backblaze . /federated/lib/functions.sh @@ -67,44 +67,76 @@ backup_service() { # Dump only users and roles for postgresql service if [ "$SERVICE" = "postgresql" ]; then + # When backing up postgresql we need to check if there are any databases that exist in + # postgresql from the SERVICES array, that don't have a /federated/apps/appname directory, + # and back them up. + for db in "${SERVICES[@]}"; do + if [[ ! -d "/federated/apps/$db" ]]; then + if docker exec postgresql psql -U $db -c '\q' 2>/dev/null; then + echo "** Backing up database $db to /federated/apps/postgresql.." + docker exec postgresql /bin/bash -c "pg_dump $db -c -U postgres | gzip -9 > /docker-entrypoint-initdb.d/dump_$db.sql.gz" + [ $? -ne 0 ] && failcheck "* Couldn't pg_dump database files" + fi + fi + done docker exec postgresql /bin/bash -c "pg_dumpall --globals-only -c -U postgres | gzip -9 > /docker-entrypoint-initdb.d/dump_$SERVICE.sql.gz" - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" rm /federated/apps/postgresql/data/docker-entrypoint-initdb.d/dump_* + # Dump mysql databases elif [ "$SERVICE" = "pdnsmysql" ]; then + # When backing up pdnsmysql we need to check if there are any databases that exist in + # mysql from the SERVICES array, that don't have a /federated/apps/appname directory, + # and back them up. + for db in "${SERVICES[@]}"; do + if [[ ! -d "/federated/apps/$db" ]]; then + if docker exec pdnsmysql mysql -uroot -p$MYSQL_PASSWORD $db 2>/dev/null; then + echo "** Backing up database $db to /federated/apps/pdnsmysql.." + docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} $db | gzip -9 > /federated/apps/pdnsmysql/dump_$db.sql.gz + [ $? -ne 0 ] && failcheck "* Couldn't backup files" + fi + fi + done + + # Backup mysql user table docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} mysql user | gzip -9 > /federated/apps/pdnsmysql/dump_$SERVICE.sql.gz - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" - rm /federated/apps/pdnsmysql/dump_$SERVICE.sql.gz + rm /federated/apps/pdnsmysql/dump_* elif [ "$SERVICE" = "pdns" ]; then docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} pdns | gzip -9 > /federated/apps/pdns/dump_$SERVICE.sql.gz - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" rm /federated/apps/pdns/dump_$SERVICE.sql.gz elif [ "$SERVICE" = "pdnsadmin" ]; then docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} pdns | gzip -9 > /federated/apps/pdnsadmin/dump_$SERVICE.sql.gz - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" rm /federated/apps/pdnsadmin/dump_$SERVICE.sql.gz elif [ "$SERVICE" = "castopod" ]; then docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} castopod | gzip -9 > /federated/apps/castopod/dump_$SERVICE.sql.gz - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" rm /federated/apps/castopod/dump_$SERVICE.sql.gz elif [ "$SERVICE" = "wordpress" ]; then docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} wordpress | gzip -9 > /federated/apps/wordpress/dump_$SERVICE.sql.gz - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" rm /federated/apps/wordpress/dump_$SERVICE.sql.gz elif [ "$SERVICE" = "bookstack" ]; then docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} bookstack | gzip -9 > /federated/apps/bookstack/dump_$SERVICE.sql.gz - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" rm /federated/apps/bookstack/dump_$SERVICE.sql.gz elif [ "$SERVICE" = "espocrm" ]; then docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} espocrm | gzip -9 > /federated/apps/espocrm/dump_$SERVICE.sql.gz - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ + [ $? -ne 0 ] && failcheck "* Couldn't backup files" + rm /federated/apps/espocrm/dump_$SERVICE.sql.gz + elif [ "$SERVICE" = "roundcube" ]; then + docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} roundcube | gzip -9 > /federated/apps/roundcube/dump_$SERVICE.sql.gz + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" rm /federated/apps/espocrm/dump_$SERVICE.sql.gz else @@ -115,7 +147,7 @@ backup_service() { [ $? -ne 0 ] && failcheck "* Couldn't pg_dump files" mv /federated/apps/postgresql/data/docker-entrypoint-initdb.d/dump_$SERVICE.sql.gz /federated/apps/$SERVICE/ fi - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/apps/$SERVICE b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$SERVICE/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" [ -f "/federated/apps/$SERVICE/dump_$SERVICE.sql.gz" ] && rm /federated/apps/$SERVICE/dump_$SERVICE.sql.gz fi @@ -126,19 +158,19 @@ backup_system() { echo "* Backing up system files in /federated/{bin,certs,lib,logs}.." echo "* Backing up system files in /federated/bin.." - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/bin b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/bin/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/bin b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/bin/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" echo "* Backing up system files in /federated/certs.." - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/certs b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/certs/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/certs b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/certs/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" echo "* Backing up system files in /federated/lib.." - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/lib b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/lib/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/lib b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/lib/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" echo "* Backing up system files in /federated/logs.." - PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/logs b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/logs/ + PASSPHRASE=$GPG_PASSPHRASE duplicity /federated/logs b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/logs/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" } backup_allservices() { @@ -148,20 +180,46 @@ backup_allservices() { # If app isn't installed then skip [ ! -d "/federated/apps/$i" ] && echo "$i not installed, skipping." && continue - # Backup service + # Backup each service echo "** Backing up /federated/apps/$i.." if [ "$i" = "postgresql" ]; then - # Dump postgresql global objects only, no databases + # When backing up postgresql we need to check if there are any databases that exist in + # postgresql from the SERVICES array, that don't have a /federated/apps/appname directory, + # and back them up. + for db in "${SERVICES[@]}"; do + if [[ ! -d "/federated/apps/$db" ]]; then + if docker exec postgresql psql -U $db -c '\q' 2>/dev/null; then + echo "*** Backing up database $db to /federated/apps/postgresql.." + docker exec postgresql /bin/bash -c "pg_dump $db -c -U postgres | gzip -9 > /docker-entrypoint-initdb.d/dump_$db.sql.gz" + [ $? -ne 0 ] && failcheck "* Couldn't pg_dump database files" + fi + fi + done + + # Dump postgresql global objects only, no databases, then send everything to Backblaze docker exec postgresql /bin/bash -c "pg_dumpall --globals-only -c -U postgres | gzip -9 > /docker-entrypoint-initdb.d/dump_$i.sql.gz" PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$i b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$i/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" rm /federated/apps/postgresql/data/docker-entrypoint-initdb.d/dump_* - # Dump all MySQL databases specified by name below elif [ "$i" = "pdnsmysql" ]; then + # When backing up pdnsmysql we need to check if there are any databases that exist in + # mysql from the SERVICES array, that don't have a /federated/apps/appname directory, + # and back them up. + for db in "${SERVICES[@]}"; do + if [[ ! -d "/federated/apps/$db" ]]; then + if docker exec pdnsmysql mysql -uroot -p$MYSQL_PASSWORD $db 2>/dev/null; then + echo "*** Backing up database $db to /federated/apps/pdnsmysql.." + docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} $db | gzip -9 > /federated/apps/pdnsmysql/dump_$db.sql.gz + [ $? -ne 0 ] && failcheck "* Couldn't backup files" + fi + fi + done + + # Backup pdnsmysql mysql user table and send to backblaze docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} mysql user | gzip -9 > /federated/apps/pdnsmysql/dump_$i.sql.gz PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$i b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$i/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" - rm /federated/apps/pdnsmysql/dump_$i.sql.gz + rm /federated/apps/pdnsmysql/dump_* elif [ "$i" = "pdns" ]; then docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} pdns | gzip -9 > /federated/apps/pdns/dump_$i.sql.gz PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$i b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$i/ @@ -192,10 +250,12 @@ backup_allservices() { PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$i b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$i/ [ $? -ne 0 ] && failcheck "* Couldn't backup files" rm /federated/apps/espocrm/dump_$i.sql.gz + elif [ "$i" = "roundcube" ]; then + docker exec pdnsmysql mysqldump -uroot -p${MYSQL_PASSWORD} roundcube | gzip -9 > /federated/apps/roundcube/dump_$i.sql.gz + PASSPHRASE=$GPG_PASSPHRASE duplicity --full-if-older-than 1M /federated/apps/$i b2://$B2_APPLICATION_KEY_ID:$B2_APPLICATION_KEY@fed-customers/$UUID/federated/apps/$i/ + [ $? -ne 0 ] && failcheck "* Couldn't backup files" + rm /federated/apps/roundcube/dump_$i.sql.gz else - # If the service isn't directly specified above then check if a postgresql database exists for - # that service, if so then move it to it's /federated/apps/appname directory and sync it to backblaze - # This is done for all postgresql services except "postgresql" service above docker exec postgresql psql -U $i -c '\q' &>/dev/null if [ $? -eq 0 ]; then docker exec postgresql /bin/bash -c "pg_dump $i -c -U postgres | gzip -9 > /docker-entrypoint-initdb.d/dump_$i.sql.gz" @@ -235,7 +295,7 @@ listbackup_nfsmounts() { delete_backup() { echo "* Deleting backup files for /federated/apps/$SERVICE.." mkdir -p /federated/tmp/empty - cd /federated/tmp/empty && /federated/bin/b2-linux sync --allowEmptySource --delete . b2://fed-customers/$UUID/federated/apps/$SERVICE/ + cd /federated/tmp/empty && B2_APPLICATION_KEY_ID="$B2_APPLICATION_KEY_ID" B2_APPLICATION_KEY="$B2_APPLICATION_KEY" /federated/bin/b2-linux sync --allowEmptySource --delete . b2://fed-customers/$UUID/federated/apps/$SERVICE/ [ $? -ne 0 ] && failcheck "* Couldn't delete files" cd /federated && rm -rf /federated/tmp/empty }