mb-backup-manager/scripts/backup-logic.sh

218 lines
9.3 KiB
Bash

#!/bin/bash
BASE_URL=$2
BACKUP_TYPE=$3
BACKUP_LOG_FILE=$4
ENV_NAME=$5
BACKUP_COUNT=$6
APP_PATH=$7
USER_SESSION=$8
USER_EMAIL=$9
BACKUP_PATH=${10}
# Ensure restic is installed
if ! which restic &>/dev/null; then
if which dnf &>/dev/null; then
dnf install -y epel-release
dnf install -y restic
elif which yum &>/dev/null; then
yum-config-manager --add-repo https://copr.fedorainfracloud.org/coprs/copart/restic/repo/epel-7/copart-restic-epel-7.repo
yum-config-manager --enable copart-restic
yum -y install restic
yum-config-manager --disable copart-restic
fi
fi
# Function definitions remain the same, but adjustments are made to use $BACKUP_PATH
function update_restic(){
restic self-update 2>&1;
}
function check_backup_repo(){
local backup_repo_path="/mnt/backups/${ENV_NAME}"
[ -d "${backup_repo_path}" ] || mkdir -p "${backup_repo_path}"
export FILES_COUNT=$(find "${backup_repo_path}" -mindepth 1 | wc -l)
if [ "${FILES_COUNT}" -gt 0 ]; then
echo "$(date) ${ENV_NAME} Checking the backup repository integrity and consistency" | tee -a "${BACKUP_LOG_FILE}"
if [[ $(ls -A "${backup_repo_path}/locks") ]]; then
echo "$(date) ${ENV_NAME} Backup repository has a stale lock, removing" | tee -a "${BACKUP_LOG_FILE}"
GOGC=20 RESTIC_PASSWORD="${ENV_NAME}" restic -r "${backup_repo_path}" unlock
sendEmailNotification
fi
if ! GOGC=20 RESTIC_PASSWORD="${ENV_NAME}" restic -q -r "${backup_repo_path}" check --read-data-subset=5%; then
echo "Backup repository integrity check failed." | tee -a "${BACKUP_LOG_FILE}"
exit 1
fi
else
echo "$(date) ${ENV_NAME} Initializing new backup repository" | tee -a "${BACKUP_LOG_FILE}"
GOGC=20 RESTIC_PASSWORD="${ENV_NAME}" restic init -r "${backup_repo_path}"
fi
}
function sendEmailNotification() {
if [ -e "/usr/lib/jelastic/modules/api.module" ]; then
[ -e "/var/run/jem.pid" ] && return 0;
CURRENT_PLATFORM_MAJOR_VERSION=$(jem api apicall -s --connect-timeout 3 --max-time 15 [API_DOMAIN]/1.0/statistic/system/rest/getversion 2>/dev/null | jq .version | grep -o [0-9.]* | awk -F . '{print $1}')
if [ "${CURRENT_PLATFORM_MAJOR_VERSION}" -ge "7" ]; then
echo "$(date) ${ENV_NAME} Sending e-mail notification about removing the stale lock" | tee -a "$BACKUP_LOG_FILE"
SUBJECT="Stale lock is removed on ${BACKUP_PATH}/${ENV_NAME} backup repo"
BODY="Please pay attention to ${BACKUP_PATH}/${ENV_NAME} backup repo because the stale lock left from previous operation is removed during the integrity check and backup rotation. Manual check of backup repo integrity and consistency is highly desired."
jem api apicall -s --connect-timeout 3 --max-time 15 [API_DOMAIN]/1.0/message/email/rest/send --data-urlencode "session=$USER_SESSION" --data-urlencode "to=$USER_EMAIL" --data-urlencode "subject=$SUBJECT" --data-urlencode "body=$BODY"
if [[ $? != 0 ]]; then
echo "$(date) ${ENV_NAME} Sending of e-mail notification failed" | tee -a "$BACKUP_LOG_FILE"
else
echo "$(date) ${ENV_NAME} E-mail notification is sent successfully" | tee -a "$BACKUP_LOG_FILE"
fi
elif [ -z "${CURRENT_PLATFORM_MAJOR_VERSION}" ]; then
echo "$(date) ${ENV_NAME} Error when checking the platform version" | tee -a "$BACKUP_LOG_FILE"
else
echo "$(date) ${ENV_NAME} Email notification is not sent because this functionality is unavailable for current platform version." | tee -a "$BACKUP_LOG_FILE"
fi
else
echo "$(date) ${ENV_NAME} Email notification is not sent because this functionality is unavailable for current platform version." | tee -a "$BACKUP_LOG_FILE"
fi
}
function rotate_snapshots(){
local backup_repo_path="/mnt/backups/${ENV_NAME}"
echo "$(date) ${ENV_NAME} Rotating snapshots by keeping the last ${BACKUP_COUNT}" | tee -a "${BACKUP_LOG_FILE}"
if [[ $(ls -A "${backup_repo_path}/locks") ]]; then
echo "$(date) ${ENV_NAME} Backup repository has a stale lock, removing" | tee -a "${BACKUP_LOG_FILE}"
GOGC=20 RESTIC_PASSWORD="${ENV_NAME}" restic -r "${backup_repo_path}" unlock
sendEmailNotification
fi
if ! GOGC=20 RESTIC_COMPRESSION=off RESTIC_PACK_SIZE=8 RESTIC_PASSWORD="${ENV_NAME}" restic forget -q -r "${backup_repo_path}" --keep-last "${BACKUP_COUNT}" --prune | tee -a "${BACKUP_LOG_FILE}"; then
echo "Backup rotation failed." | tee -a "${BACKUP_LOG_FILE}"
exit 1
fi
}
function create_snapshot(){
local backup_repo_path="/mnt/backups/${ENV_NAME}"
DUMP_NAME=$(date "+%F_%H%M%S_%Z")
echo "$(date) ${ENV_NAME} Begin uploading the ${DUMP_NAME} snapshot to backup storage" | tee -a "${BACKUP_LOG_FILE}"
if ! GOGC=20 RESTIC_COMPRESSION=off RESTIC_PACK_SIZE=8 RESTIC_READ_CONCURRENCY=8 RESTIC_PASSWORD="${ENV_NAME}" restic backup -q -r "${backup_repo_path}" --tag "${DUMP_NAME} ${BACKUP_ADDON_COMMIT_ID} ${BACKUP_TYPE}" "${APP_PATH}" ~/wp_db_backup.sql | tee -a "${BACKUP_LOG_FILE}"; then
echo "Backup snapshot creation failed." | tee -a "${BACKUP_LOG_FILE}"
exit 1
fi
echo "$(date) ${ENV_NAME} End uploading the ${DUMP_NAME} snapshot to backup storage" | tee -a "${BACKUP_LOG_FILE}"
}
function backup(){
local backup_repo_path="/mnt/backups/${ENV_NAME}"
echo $$ > "/var/run/${ENV_NAME}_backup.pid"
BACKUP_ADDON_REPO=$(echo "${BASE_URL}" | sed 's|https://raw.githubusercontent.com/||' | awk -F '/' '{print $1"/"$2}')
BACKUP_ADDON_BRANCH=$(echo "${BASE_URL}" | sed 's|https://raw.githubusercontent.com/||' | awk -F '/' '{print $3}')
BACKUP_ADDON_COMMIT_ID=$(git ls-remote "https://github.com/${BACKUP_ADDON_REPO}.git" | grep "/${BACKUP_ADDON_BRANCH}$" | awk '{print $1}')
echo "$(date) ${ENV_NAME} Creating the ${BACKUP_TYPE} backup (using the backup addon with commit id ${BACKUP_ADDON_COMMIT_ID})" | tee -a "${BACKUP_LOG_FILE}"
# Database credentials and dump
source /var/www/webroot/ROOT/wp-config.php
DB_HOST=$(echo "${DB_HOST}" | awk -F ':' '{print $1}')
DB_PORT=$(echo "${DB_HOST}" | awk -F ':' '{print $2:-3306}')
echo "$(date) ${ENV_NAME} Creating the DB dump" | tee -a "${BACKUP_LOG_FILE}"
if ! mysqldump -h "${DB_HOST}" -P "${DB_PORT}" -u "${DB_USER}" -p"${DB_PASSWORD}" "${DB_NAME}" --force --single-transaction --quote-names --opt --databases > "${backup_repo_path}/wp_db_backup.sql"; then
echo "$(date) ${ENV_NAME} DB backup process failed." | tee -a "${BACKUP_LOG_FILE}"
exit 1
fi
# Backup process
if ! restic -r "${backup_repo_path}" backup "${backup_repo_path}/wp_db_backup.sql" "${APP_PATH}" --tag "${BACKUP_TYPE}" --host "${ENV_NAME}"; then
echo "$(date) ${ENV_NAME} Backup process failed." | tee -a "${BACKUP_LOG_FILE}"
exit 1
fi
echo "$(date) ${ENV_NAME} Backup process completed successfully." | tee -a "${BACKUP_LOG_FILE}"
rm -f "/var/run/${ENV_NAME}_backup.pid"
}
function backup_wp_core() {
echo "Starting backup of WordPress core files excluding uploads directory..."
# Define the path to the WordPress installation and the backup tag
local wp_path="$APP_PATH"
local backup_tag="wp-core-$(date "+%F_%H%M%S_%Z")"
# Exclude the uploads directory using the --exclude option
GOGC=20 RESTIC_PASSWORD="$RESTIC_PASSWORD" restic -r "$backupPath" backup \
--tag "$backup_tag" \
--exclude="$wp_path/wp-content/uploads" \
"$wp_path"
echo "WordPress core files backup completed."
}
function backup_uploads() {
echo "Starting backup of WordPress uploads directory..."
# Define the path to the uploads directory and the backup tag
local uploads_path="$APP_PATH/wp-content/uploads"
local backup_tag="wp-uploads-$(date "+%F_%H%M%S_%Z")"
# Perform the backup
GOGC=20 RESTIC_PASSWORD="$RESTIC_PASSWORD" restic -r "$backupPath" backup \
--tag "$backup_tag" \
"$uploads_path"
echo "WordPress uploads directory backup completed."
}
function backup_database() {
echo "Starting backup of WordPress database..."
# Define the backup tag and the path for the temporary SQL dump
local backup_tag="wp-db-$(date "+%F_%H%M%S_%Z")"
local sql_dump_path="/tmp/wp_db_backup.sql"
# Create a database dump
mysqldump -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" > "$sql_dump_path"
# Perform the backup
GOGC=20 RESTIC_PASSWORD="$RESTIC_PASSWORD" restic -r "$backupPath" backup \
--tag "$backup_tag" \
"$sql_dump_path"
# Remove the temporary SQL dump file
rm -f "$sql_dump_path"
echo "WordPress database backup completed."
}
case "$1" in
backup)
backup_wp_core
backup_uploads
backup_database
;;
backup_wp_core)
backup_wp_core
;;
backup_uploads)
backup_uploads
;;
backup_database)
backup_database
;;
check_backup_repo)
check_backup_repo
;;
rotate_snapshots)
rotate_snapshots
;;
create_snapshot)
create_snapshot
;;
update_restic)
update_restic
;;
*)
echo "Usage: $0 {backup|backup_wp_core|backup_uploads|backup_database|check_backup_repo|rotate_snapshots|create_snapshot|update_restic}"
exit 2
esac
exit $?