Ver 1.7 Improved restoration script, Automatic Backup Tagging, Resolved issues with incorrect handling of database restoration paths
parent
a2f0cf6634
commit
a36be25ae9
|
@ -1,5 +1,50 @@
|
|||
# Changelog
|
||||
|
||||
## Version 1.7
|
||||
|
||||
### Added
|
||||
- **`restore_backup_direct.sh` Enhancements**:
|
||||
- Improved restoration script to handle specific backup types (core files, media files, database backups) based on tags.
|
||||
- Integrated functionality to restore databases directly by piping `.sql` files from Restic to MySQL.
|
||||
- Added automatic detection of database credentials from `wp-config.php` with fallback to default values for `DB_HOST`.
|
||||
- Ensured proper environment setup with `RESTIC_PASSWORD` retrieved securely from `/etc/restic-password`.
|
||||
|
||||
- **Automatic Backup Tagging**:
|
||||
- Modified `backup_all.sh` to differentiate between manual (`manual-backup-YYYY-MM-DD_HH-MM-SS`) and automated (`auto-backup-YYYY-MM-DD_HH-MM-SS`) backups.
|
||||
- Ensured backups triggered by cron jobs are tagged appropriately for easy identification.
|
||||
|
||||
- **`manage_backup_schedule.sh` Enhancements**:
|
||||
- Ensured `backup_all.sh` runs in `auto` mode when added to cron, guaranteeing automated backups have the correct tags.
|
||||
- Validated cron job syntax and dependencies to avoid misconfigurations.
|
||||
- Added explicit logging of cron actions, including schedule additions, updates, removals, and listing.
|
||||
|
||||
- **Improved Error Messaging**:
|
||||
- Enhanced restoration script to provide detailed error messages when database restoration fails, including incorrect credentials or insufficient privileges.
|
||||
|
||||
### Fixed
|
||||
- Resolved issues with incorrect handling of database restoration paths, ensuring `.sql` files are restored directly into MySQL when detected.
|
||||
- Addressed potential confusion in tagging by clearly segregating manual and automated backups in logs and tags.
|
||||
- Corrected empty `DB_HOST` values in the restoration script by setting a default to `localhost` when no value is provided in `wp-config.php`.
|
||||
|
||||
### Updated
|
||||
- **Logging and Traceability**:
|
||||
- Enhanced all relevant scripts (`restore_backup_direct.sh`, `backup_all.sh`, `manage_backup_schedule.sh`) to log detailed timestamps and descriptive messages.
|
||||
- Improved consistency in log formatting across scripts for better traceability.
|
||||
- Added detailed logs for all cron operations in `manage_backup_schedule.sh` to track automated backups effectively.
|
||||
|
||||
### Improved
|
||||
- **Backup and Restore Modularity**:
|
||||
- Streamlined the orchestration of backups and restores to ensure modularity and easier debugging.
|
||||
- Improved robustness of `restore_backup_direct.sh` by handling different backup types dynamically using snapshot tags.
|
||||
- Simplified management of cron schedules with better error handling and validation in `manage_backup_schedule.sh`.
|
||||
|
||||
- **Error Handling**:
|
||||
- Ensured all scripts exit gracefully on errors with detailed logs to pinpoint issues.
|
||||
- Enhanced dependency validation to check for all required tools (`restic`, `mysql`, `jq`, `crontab`, etc.) before execution.
|
||||
|
||||
- **Code Maintenance**:
|
||||
- Centralized key operations such as password retrieval, lock handling, and backup tagging across scripts for easier maintenance and fewer redundancies.
|
||||
|
||||
## Version 1.6
|
||||
|
||||
### Added
|
||||
|
|
21
manifest.jps
21
manifest.jps
|
@ -1,5 +1,5 @@
|
|||
type: update
|
||||
jpsVersion: 1.6
|
||||
jpsVersion: 1.7
|
||||
name: MightyBox WordPress Backup/Restore Addon
|
||||
id: mb-backup-manager
|
||||
description: Custom Backup and Restore Addon for WordPress using Restic. Supports backing up databases, core files, media files, and full backups with scheduling and retention policies.
|
||||
|
@ -52,6 +52,12 @@ menu:
|
|||
title: Configure Automated Backup Schedule
|
||||
submitButtonText: Save Schedule
|
||||
|
||||
- caption: List Scheduled Backups
|
||||
action: listScheduledBackups
|
||||
confirmText: List scheduled backups?
|
||||
loadingText: Listing scheduled backups...
|
||||
successText: Scheduled backups listed successfully
|
||||
|
||||
- caption: Remove Auto Backup
|
||||
action: removeAutoBackup
|
||||
confirmText: Remove automated backup schedule?
|
||||
|
@ -160,6 +166,14 @@ actions:
|
|||
type: info
|
||||
message: "Daily backup schedule configured successfully"
|
||||
|
||||
listScheduledBackups:
|
||||
- cmd[cp]:
|
||||
user: root
|
||||
commands: bash /home/litespeed/mb-backups/manage_backup_schedule.sh list
|
||||
- return:
|
||||
type: info
|
||||
message: "${response.out}"
|
||||
|
||||
removeAutoBackup:
|
||||
- cmd[cp]:
|
||||
user: root
|
||||
|
@ -179,7 +193,7 @@ actions:
|
|||
backupnow:
|
||||
- cmd[cp]:
|
||||
user: root
|
||||
commands: bash /home/jelastic/mb-backups/backup_all.sh backup_now
|
||||
commands: bash /home/jelastic/mb-backups/backup_all.sh manual
|
||||
- return:
|
||||
type: info
|
||||
message: "${response.out}"
|
||||
|
@ -332,7 +346,8 @@ actions:
|
|||
- mkdir -p /home/litespeed/mb-backups/logs/auto
|
||||
- mkdir -p /home/litespeed/mb-backups/logs/manual
|
||||
- mkdir -p /home/litespeed/mb-backups/logs/restore
|
||||
- chown -R litespeed:litespeed /home/litespeed/mb-backups
|
||||
- sudo chown -R litespeed:litespeed /home/litespeed/mb-backups/logs
|
||||
- sudo chmod -R u+rw /home/litespeed/mb-backups/logs
|
||||
- cd /home/jelastic/mb-backups
|
||||
- curl -O https://deploy-proxy.mightybox.io/addons/mb-backup-manager/raw/branch/main/scripts/imports/backup_all.sh
|
||||
- curl -O https://deploy-proxy.mightybox.io/addons/mb-backup-manager/raw/branch/main/scripts/imports/backup_core_files.sh
|
||||
|
|
|
@ -9,7 +9,7 @@ LOG_DIR="/home/jelastic/mb-backups/logs"
|
|||
CORE_BACKUP_SCRIPT="/home/jelastic/mb-backups/backup_core_files.sh"
|
||||
DATABASE_BACKUP_SCRIPT="/home/jelastic/mb-backups/backup_database.sh"
|
||||
MEDIA_BACKUP_SCRIPT="/home/jelastic/mb-backups/backup_media.sh"
|
||||
MANUAL_BACKUP_TAG="manual-backup-$(date +'%Y-%m-%d_%H-%M-%S')"
|
||||
TIMESTAMP=$(date +'%Y-%m-%d_%H-%M-%S')
|
||||
|
||||
# Ensure log directory exists
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
@ -22,24 +22,37 @@ log_message() {
|
|||
|
||||
# Main execution
|
||||
main() {
|
||||
log_message "Starting full backup process with tag: $MANUAL_BACKUP_TAG"
|
||||
local backup_type="$1"
|
||||
local backup_tag=""
|
||||
|
||||
# Determine the backup tag based on the type
|
||||
if [ "$backup_type" == "manual" ]; then
|
||||
backup_tag="manual-backup-$TIMESTAMP"
|
||||
log_message "Starting manual backup process with tag: $backup_tag"
|
||||
elif [ "$backup_type" == "auto" ]; then
|
||||
backup_tag="automated-backup-$TIMESTAMP"
|
||||
log_message "Starting automated backup process with tag: $backup_tag"
|
||||
else
|
||||
log_message "ERROR: Invalid backup type. Use 'manual' or 'auto'."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run individual backup scripts
|
||||
if bash "$CORE_BACKUP_SCRIPT" "$(cat /etc/restic-password)" "$MANUAL_BACKUP_TAG"; then
|
||||
if bash "$CORE_BACKUP_SCRIPT" "$(cat /etc/restic-password)" "$backup_tag"; then
|
||||
log_message "Core files backup completed successfully."
|
||||
else
|
||||
log_message "ERROR: Core files backup failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if bash "$DATABASE_BACKUP_SCRIPT" "$(cat /etc/restic-password)" "$MANUAL_BACKUP_TAG"; then
|
||||
if bash "$DATABASE_BACKUP_SCRIPT" "$(cat /etc/restic-password)" "$backup_tag"; then
|
||||
log_message "Database backup completed successfully."
|
||||
else
|
||||
log_message "ERROR: Database backup failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if bash "$MEDIA_BACKUP_SCRIPT" "$(cat /etc/restic-password)" "$MANUAL_BACKUP_TAG"; then
|
||||
if bash "$MEDIA_BACKUP_SCRIPT" "$(cat /etc/restic-password)" "$backup_tag"; then
|
||||
log_message "Media files backup completed successfully."
|
||||
else
|
||||
log_message "ERROR: Media files backup failed."
|
||||
|
@ -50,9 +63,20 @@ main() {
|
|||
}
|
||||
|
||||
# Argument handling
|
||||
if [ "$1" == "backup_now" ]; then
|
||||
main
|
||||
else
|
||||
echo "Usage: $0 backup_now"
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 {manual|auto}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
manual)
|
||||
main "manual"
|
||||
;;
|
||||
auto)
|
||||
main "auto"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {manual|auto}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -5,44 +5,53 @@ BACKUP_SCRIPT="/home/litespeed/mb-backups/backup_all.sh"
|
|||
LOG_DIR="/home/litespeed/mb-backups/logs/auto"
|
||||
ACTION_LOG_FILE="${LOG_DIR}/schedule_actions.log"
|
||||
BACKUP_LOG_PREFIX="${LOG_DIR}/backup_"
|
||||
CRON_FILE="/var/spool/cron/crontabs/$(whoami)"
|
||||
CRON_PATH="/usr/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
# Ensure the log directory exists
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
# Logging function
|
||||
log_action() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "$ACTION_LOG_FILE"
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$ACTION_LOG_FILE"
|
||||
}
|
||||
|
||||
# Function: Validate dependencies
|
||||
validate_dependencies() {
|
||||
for cmd in dnf crontab systemctl restic; do
|
||||
if ! command -v "$cmd" &>/dev/null; then
|
||||
log_action "ERROR: Required command '$cmd' not found."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Function: Install and start cron service if needed
|
||||
check_and_install_cron() {
|
||||
if ! command -v crontab &> /dev/null; then
|
||||
echo "Cron is not installed. Installing..."
|
||||
sudo dnf install -y cronie || { echo "Failed to install cron."; exit 1; }
|
||||
if ! command -v crontab &>/dev/null; then
|
||||
log_action "Cron is not installed. Installing..."
|
||||
sudo dnf install -y cronie || { log_action "Failed to install cron."; exit 1; }
|
||||
fi
|
||||
|
||||
if ! systemctl is-active --quiet crond; then
|
||||
echo "Starting cron service..."
|
||||
log_action "Starting cron service..."
|
||||
sudo systemctl start crond
|
||||
sudo systemctl enable crond
|
||||
sudo systemctl enable crond || { log_action "Failed to enable cron service."; exit 1; }
|
||||
fi
|
||||
|
||||
if systemctl is-active --quiet crond; then
|
||||
echo "Cron service is running."
|
||||
else
|
||||
echo "Failed to start cron service."
|
||||
log_action "Failed to start cron service."
|
||||
exit 1
|
||||
fi
|
||||
log_action "Cron service is running and ready."
|
||||
}
|
||||
|
||||
# Function: Validate cron schedule format
|
||||
validate_cron_syntax() {
|
||||
local schedule="$1"
|
||||
if ! echo "$schedule" | grep -Eq '^(\*|[0-9]|[0-5][0-9]) (\*|[0-9]|1[0-9]|2[0-3]) (\*|[0-9]|3[0-1]) (\*|[1-9]|1[0-2]) (\*|[0-6])$'; then
|
||||
echo "Invalid cron schedule format: $schedule"
|
||||
log_action "Invalid cron schedule format: $schedule"
|
||||
log_action "ERROR: Invalid cron schedule format: $schedule"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function: Add or update a cron job
|
||||
add_update_cron_job() {
|
||||
local action="$1"
|
||||
local schedule="$2"
|
||||
|
@ -51,46 +60,44 @@ add_update_cron_job() {
|
|||
validate_cron_syntax "$schedule"
|
||||
|
||||
if [ -z "$restic_password" ]; then
|
||||
echo "Restic password is required."
|
||||
log_action "Attempted to $action a schedule without providing a Restic password."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local restic_path="/usr/local/bin/restic"
|
||||
if [ ! -x "$restic_path" ]; then
|
||||
echo "Error: restic not found at $restic_path. Please verify installation."
|
||||
log_action "restic not found at $restic_path"
|
||||
log_action "ERROR: Restic password is required."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Prepare the cron job command
|
||||
local cmd="SHELL=/bin/bash"
|
||||
cmd+=" PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
cmd+=" RESTIC_PASSWORD=\"$restic_password\""
|
||||
cmd+=" $BACKUP_SCRIPT"
|
||||
local cmd="SHELL=/bin/bash PATH=$CRON_PATH RESTIC_PASSWORD=\"$restic_password\""
|
||||
cmd+=" $BACKUP_SCRIPT auto"
|
||||
cmd+=" > \"${BACKUP_LOG_PREFIX}\$(date +\\%Y-\\%m-\\%d_\\%H-\\%M-\\%S).log\" 2>&1"
|
||||
|
||||
# Debug: Output the command to verify
|
||||
echo "Adding the following cron job:"
|
||||
echo "$schedule $cmd"
|
||||
|
||||
# Remove any existing lines containing $BACKUP_SCRIPT, then add the new one
|
||||
# Remove existing job and add a new one
|
||||
(crontab -l 2>/dev/null | grep -v "$BACKUP_SCRIPT"; echo "$schedule $cmd") | crontab -
|
||||
|
||||
if crontab -l | grep -q "$BACKUP_SCRIPT"; then
|
||||
echo "Cron job $action successfully."
|
||||
if crontab -l | grep -q "$BACKUP_SCRIPT auto"; then
|
||||
log_action "Cron job $action successfully: $schedule"
|
||||
else
|
||||
echo "Failed to $action cron job. Please check logs for details."
|
||||
log_action "Failed to $action cron job: $schedule"
|
||||
log_action "ERROR: Failed to $action cron job. Please check logs."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
check_and_install_cron
|
||||
# Function: Remove cron jobs
|
||||
remove_cron_jobs() {
|
||||
crontab -l 2>/dev/null | grep -v "$BACKUP_SCRIPT auto" | crontab -
|
||||
log_action "All backup schedules removed."
|
||||
}
|
||||
|
||||
case $1 in
|
||||
# Function: List cron jobs
|
||||
list_cron_jobs() {
|
||||
log_action "Listing all current cron jobs:"
|
||||
crontab -l 2>/dev/null | tee -a "$ACTION_LOG_FILE"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
validate_dependencies
|
||||
check_and_install_cron
|
||||
|
||||
case "$1" in
|
||||
add|update)
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo "Usage for add/update: $0 {add|update} 'schedule' 'restic_password'"
|
||||
|
@ -101,16 +108,18 @@ case $1 in
|
|||
fi
|
||||
;;
|
||||
remove)
|
||||
tmp_cron=$(mktemp)
|
||||
crontab -l 2>/dev/null | grep -v "$BACKUP_SCRIPT" > "$tmp_cron"
|
||||
crontab "$tmp_cron"
|
||||
rm -f "$tmp_cron"
|
||||
echo "All backup schedules removed."
|
||||
log_action "All backup schedules removed."
|
||||
remove_cron_jobs
|
||||
;;
|
||||
list)
|
||||
list_cron_jobs
|
||||
;;
|
||||
*)
|
||||
echo "Invalid action: $1. Use add, update, or remove."
|
||||
echo "Usage: $0 {add|update|remove|list} [schedule] [restic_password]"
|
||||
log_action "Invalid action attempted: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
}
|
||||
|
||||
# Execute main function
|
||||
main "$@"
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Exit immediately on errors
|
||||
# Exit on errors and enable error tracing
|
||||
set -e
|
||||
trap 'log "ERROR: An error occurred during the restoration process."' ERR
|
||||
|
||||
# Validate input parameters
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: $0 <snapshot_id> <restic_password>"
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <snapshot_id>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Assign input to variables
|
||||
SNAPSHOT_ID=$1
|
||||
RESTIC_PASSWORD=$2
|
||||
RESTIC_PASSWORD_FILE="/etc/restic-password"
|
||||
RESTIC_REPOSITORY="/mnt/backups"
|
||||
LOG_DIR="/home/litespeed/mb-backups/logs/restore"
|
||||
WP_CONFIG="/var/www/webroot/ROOT/wp-config.php"
|
||||
|
||||
# Set up the environment
|
||||
export RESTIC_PASSWORD
|
||||
# Ensure the log directory exists
|
||||
mkdir -p "$LOG_DIR"
|
||||
LOG_FILE="${LOG_DIR}/restore_$(date +'%Y-%m-%d_%H-%M-%S').log"
|
||||
|
||||
|
@ -26,95 +26,137 @@ log() {
|
|||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Check for required dependencies
|
||||
for cmd in restic jq mysql; do
|
||||
# Validate required dependencies
|
||||
validate_dependencies() {
|
||||
for cmd in restic jq mysql; do
|
||||
if ! command -v $cmd >/dev/null 2>&1; then
|
||||
log "Error: '$cmd' command not found. Please install $cmd."
|
||||
log "ERROR: '$cmd' command not found. Please install $cmd."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
# Ensure there are no stale locks in the repository
|
||||
log "Checking for stale locks in the repository..."
|
||||
if restic -r "$RESTIC_REPOSITORY" list locks | grep -q "lock"; then
|
||||
# Set up Restic environment
|
||||
setup_restic_environment() {
|
||||
if [ ! -f "$RESTIC_PASSWORD_FILE" ]; then
|
||||
log "ERROR: Restic password file not found at $RESTIC_PASSWORD_FILE."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export RESTIC_PASSWORD=$(cat "$RESTIC_PASSWORD_FILE")
|
||||
export RESTIC_REPOSITORY="$RESTIC_REPOSITORY"
|
||||
log "Restic environment set up successfully."
|
||||
}
|
||||
|
||||
# Ensure no stale locks exist in the repository
|
||||
remove_stale_locks() {
|
||||
log "Checking for stale locks in the repository..."
|
||||
if restic list locks | grep -q "lock"; then
|
||||
log "Stale lock detected. Unlocking repository..."
|
||||
restic -r "$RESTIC_REPOSITORY" unlock
|
||||
restic unlock || {
|
||||
log "ERROR: Failed to remove stale locks."
|
||||
exit 1
|
||||
}
|
||||
log "Repository unlocked successfully."
|
||||
else
|
||||
else
|
||||
log "No stale locks found. Proceeding with restoration."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Extract database credentials from wp-config.php
|
||||
if [ ! -f "$WP_CONFIG" ]; then
|
||||
log "Error: wp-config.php not found at $WP_CONFIG. Ensure WordPress is installed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DB_NAME=$(awk -F"'" '/define\( *'"'"'DB_NAME'"'"'/{print $4}' "$WP_CONFIG")
|
||||
DB_USER=$(awk -F"'" '/define\( *'"'"'DB_USER'"'"'/{print $4}' "$WP_CONFIG")
|
||||
DB_PASSWORD=$(awk -F"'" '/define\( *'"'"'DB_PASSWORD'"'"'/{print $4}' "$WP_CONFIG")
|
||||
|
||||
if [ -z "$DB_NAME" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ]; then
|
||||
log "Error: Could not extract database credentials from wp-config.php."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Starting restoration for snapshot ID: $SNAPSHOT_ID..."
|
||||
|
||||
# Retrieve snapshot data
|
||||
SNAPSHOT_DATA=$(restic -r "$RESTIC_REPOSITORY" snapshots --json | jq -r ".[] | select(.short_id == \"$SNAPSHOT_ID\")")
|
||||
if [ -z "$SNAPSHOT_DATA" ]; then
|
||||
log "Error: Snapshot ID $SNAPSHOT_ID not found in repository."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SNAPSHOT_PATH=$(echo "$SNAPSHOT_DATA" | jq -r ".paths[] // empty")
|
||||
SNAPSHOT_TAGS=$(echo "$SNAPSHOT_DATA" | jq -r ".tags[] // empty")
|
||||
|
||||
if [ -z "$SNAPSHOT_PATH" ]; then
|
||||
log "Error: Snapshot $SNAPSHOT_ID does not contain valid paths."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Snapshot Data Retrieved: Path=$SNAPSHOT_PATH, Tags=$SNAPSHOT_TAGS"
|
||||
|
||||
# Determine the restoration type based on the tags
|
||||
if [[ "$SNAPSHOT_TAGS" == *"wordpress_db"* ]] && [[ "$SNAPSHOT_PATH" == "/stdin" ]]; then
|
||||
log "Detected database backup. Restoring database $DB_NAME..."
|
||||
if restic -r "$RESTIC_REPOSITORY" dump "$SNAPSHOT_ID" stdin | mysql -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME"; then
|
||||
log "Database restoration completed successfully for $DB_NAME from Snapshot ID: $SNAPSHOT_ID."
|
||||
else
|
||||
log "Error: Database restoration failed for Snapshot ID: $SNAPSHOT_ID."
|
||||
extract_db_credentials() {
|
||||
if [ ! -f "$WP_CONFIG" ]; then
|
||||
log "ERROR: wp-config.php not found at $WP_CONFIG. Ensure WordPress is installed."
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$SNAPSHOT_TAGS" == *"core_files"* ]]; then
|
||||
|
||||
DB_NAME=$(awk -F"'" '/define\( *'"'"'DB_NAME'"'"'/{print $4}' "$WP_CONFIG")
|
||||
DB_USER=$(awk -F"'" '/define\( *'"'"'DB_USER'"'"'/{print $4}' "$WP_CONFIG")
|
||||
DB_PASSWORD=$(awk -F"'" '/define\( *'"'"'DB_PASSWORD'"'"'/{print $4}' "$WP_CONFIG")
|
||||
DB_HOST=$(awk -F"'" '/define\( *'"'"'DB_HOST'"'"'/{print $4}' "$WP_CONFIG")
|
||||
|
||||
# Set default DB_HOST if empty
|
||||
if [ -z "$DB_HOST" ]; then
|
||||
DB_HOST="localhost"
|
||||
fi
|
||||
|
||||
if [ -z "$DB_NAME" ] || [ -z "$DB_USER" ] || [ -z "$DB_PASSWORD" ]; then
|
||||
log "ERROR: Could not extract database credentials from wp-config.php."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Retrieve snapshot metadata
|
||||
retrieve_snapshot_metadata() {
|
||||
log "Retrieving metadata for snapshot ID: $SNAPSHOT_ID..."
|
||||
SNAPSHOT_DATA=$(restic snapshots --json | jq -r ".[] | select(.short_id == \"$SNAPSHOT_ID\")")
|
||||
|
||||
if [ -z "$SNAPSHOT_DATA" ]; then
|
||||
log "ERROR: Snapshot ID $SNAPSHOT_ID not found in the repository."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SNAPSHOT_PATH=$(echo "$SNAPSHOT_DATA" | jq -r ".paths[] // empty")
|
||||
SNAPSHOT_TAGS=$(echo "$SNAPSHOT_DATA" | jq -r ".tags[] // empty")
|
||||
|
||||
if [ -z "$SNAPSHOT_PATH" ]; then
|
||||
log "ERROR: Snapshot $SNAPSHOT_ID does not contain valid paths."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Snapshot metadata retrieved: Path=$SNAPSHOT_PATH, Tags=$SNAPSHOT_TAGS"
|
||||
}
|
||||
|
||||
# Perform the restoration based on snapshot tags
|
||||
restore_snapshot() {
|
||||
if [[ "$SNAPSHOT_TAGS" == *"wordpress_db"* ]] && [[ "$SNAPSHOT_PATH" == *".sql"* ]]; then
|
||||
log "Detected database backup. Restoring database $DB_NAME..."
|
||||
log "Using DB credentials: User=$DB_USER, Host=$DB_HOST, DB=$DB_NAME"
|
||||
|
||||
if restic dump "$SNAPSHOT_ID" "$SNAPSHOT_PATH" | mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME"; then
|
||||
log "Database restoration completed successfully for $DB_NAME."
|
||||
else
|
||||
log "ERROR: Database restoration failed. Verify MySQL credentials or permissions."
|
||||
log "Check that 'DB_USER=$DB_USER' has necessary privileges on 'DB_NAME=$DB_NAME'."
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$SNAPSHOT_TAGS" == *"core_files"* ]]; then
|
||||
RESTORE_DIR="/var/www/webroot/ROOT"
|
||||
log "Detected core files backup. Restoring to $RESTORE_DIR..."
|
||||
if restic -r "$RESTIC_REPOSITORY" restore "$SNAPSHOT_ID" --target "$RESTORE_DIR"; then
|
||||
log "Core files restoration completed successfully for Snapshot ID: $SNAPSHOT_ID."
|
||||
if restic restore "$SNAPSHOT_ID" --target "$RESTORE_DIR"; then
|
||||
log "Core files restoration completed successfully."
|
||||
else
|
||||
log "Error: Core files restoration failed for Snapshot ID: $SNAPSHOT_ID."
|
||||
log "ERROR: Core files restoration failed."
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$SNAPSHOT_TAGS" == *"media_themes"* ]]; then
|
||||
elif [[ "$SNAPSHOT_TAGS" == *"media_themes"* ]]; then
|
||||
RESTORE_DIR="/var/www/webroot/ROOT/wp-content/uploads"
|
||||
log "Detected media files backup. Restoring to $RESTORE_DIR..."
|
||||
if restic -r "$RESTIC_REPOSITORY" restore "$SNAPSHOT_ID" --target "$RESTORE_DIR"; then
|
||||
log "Media files restoration completed successfully for Snapshot ID: $SNAPSHOT_ID."
|
||||
if restic restore "$SNAPSHOT_ID" --target "$RESTORE_DIR"; then
|
||||
log "Media files restoration completed successfully."
|
||||
else
|
||||
log "Error: Media files restoration failed for Snapshot ID: $SNAPSHOT_ID."
|
||||
log "ERROR: Media files restoration failed."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log "Unknown snapshot type. Attempting general restoration to /..."
|
||||
else
|
||||
log "Unknown snapshot type. Attempting general restoration to a temporary directory..."
|
||||
TEMP_RESTORE_DIR="/tmp/restoration_$SNAPSHOT_ID"
|
||||
mkdir -p "$TEMP_RESTORE_DIR"
|
||||
if restic -r "$RESTIC_REPOSITORY" restore "$SNAPSHOT_ID" --target "$TEMP_RESTORE_DIR"; then
|
||||
log "General file restoration completed successfully to temporary directory: $TEMP_RESTORE_DIR."
|
||||
if restic restore "$SNAPSHOT_ID" --target "$TEMP_RESTORE_DIR"; then
|
||||
log "General restoration completed successfully to $TEMP_RESTORE_DIR."
|
||||
else
|
||||
log "Error: File restoration failed for Snapshot ID: $SNAPSHOT_ID."
|
||||
log "ERROR: General restoration failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution flow
|
||||
validate_dependencies
|
||||
setup_restic_environment
|
||||
remove_stale_locks
|
||||
extract_db_credentials
|
||||
retrieve_snapshot_metadata
|
||||
restore_snapshot
|
||||
|
||||
log "Restoration process completed successfully."
|
||||
|
|
Loading…
Reference in New Issue