#!/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}" mkdir -p "${backup_repo_path}" echo $$ > "/var/run/${ENV_NAME}_backup.pid" echo "$(date) ${ENV_NAME} Creating the ${BACKUP_TYPE} backup" | tee -a "${BACKUP_LOG_FILE}" # Ensure Restic repository is initialized restic -r "${backup_repo_path}" snapshots &>/dev/null || restic -r "${backup_repo_path}" init # Extract database credentials DB_NAME=$(grep DB_NAME /var/www/webroot/ROOT/wp-config.php | cut -d "'" -f 4) DB_USER=$(grep DB_USER /var/www/webroot/ROOT/wp-config.php | cut -d "'" -f 4) DB_PASSWORD=$(grep DB_PASSWORD /var/www/webroot/ROOT/wp-config.php | cut -d "'" -f 4) DB_HOST=$(grep DB_HOST /var/www/webroot/ROOT/wp-config.php | cut -d "'" -f 4 | awk -F':' '{print $1}') DB_PORT=$(grep DB_HOST /var/www/webroot/ROOT/wp-config.php | cut -d "'" -f 4 | awk -F':' '{print $2}') DB_PORT=${DB_PORT:-3306} echo "$(date) ${ENV_NAME} Creating the DB dump" | tee -a "${BACKUP_LOG_FILE}" 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" if [ $? -ne 0 ]; then echo "$(date) ${ENV_NAME} DB backup process failed." | tee -a "${BACKUP_LOG_FILE}" exit 1 fi # Backup process restic -r "${backup_repo_path}" backup "${backup_repo_path}/wp_db_backup.sql" "${APP_PATH}" --tag "${BACKUP_TYPE}" --host "${ENV_NAME}" if [ $? -ne 0 ]; 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 $?