New updates and fail safe mechanism
parent
2a3c7341f0
commit
301d5dceda
97
manifest.jps
97
manifest.jps
|
@ -14,6 +14,8 @@ targetNodes:
|
||||||
|
|
||||||
globals:
|
globals:
|
||||||
envName: "${env.name}"
|
envName: "${env.name}"
|
||||||
|
scriptPath: "/home/litespeed/mb-backups"
|
||||||
|
logPath: "/home/litespeed/mb-backups/logs"
|
||||||
|
|
||||||
onInstall:
|
onInstall:
|
||||||
- checkAddons
|
- checkAddons
|
||||||
|
@ -21,12 +23,46 @@ onInstall:
|
||||||
- importScripts
|
- importScripts
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
|
scheduleSettings:
|
||||||
|
submitUnchanged: true
|
||||||
|
fields:
|
||||||
|
- name: frequency
|
||||||
|
caption: Backup Frequency
|
||||||
|
type: list
|
||||||
|
values:
|
||||||
|
daily: Daily Backup
|
||||||
|
weekly: Weekly Backup
|
||||||
|
default: daily
|
||||||
|
|
||||||
|
- name: hour
|
||||||
|
caption: Backup Hour (0-23)
|
||||||
|
type: string
|
||||||
|
regex: "^([0-9]|1[0-9]|2[0-3])$"
|
||||||
|
regexText: Enter a valid hour (0-23)
|
||||||
|
default: "0"
|
||||||
|
|
||||||
|
- name: dayOfWeek
|
||||||
|
caption: Day of Week (0=Sunday)
|
||||||
|
type: list
|
||||||
|
values:
|
||||||
|
0: Sunday
|
||||||
|
1: Monday
|
||||||
|
2: Tuesday
|
||||||
|
3: Wednesday
|
||||||
|
4: Thursday
|
||||||
|
5: Friday
|
||||||
|
6: Saturday
|
||||||
|
default: "0"
|
||||||
|
showIf:
|
||||||
|
frequency: weekly
|
||||||
|
|
||||||
backupSettings:
|
backupSettings:
|
||||||
submitUnchanged: true
|
submitUnchanged: true
|
||||||
fields:
|
fields:
|
||||||
- name: blabel
|
- name: blabel
|
||||||
caption: Backup Label
|
caption: Backup Label
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
restoreSettings:
|
restoreSettings:
|
||||||
submitUnchanged: true
|
submitUnchanged: true
|
||||||
fields:
|
fields:
|
||||||
|
@ -42,6 +78,26 @@ buttons:
|
||||||
successText: The backup process has been finished successfully.
|
successText: The backup process has been finished successfully.
|
||||||
|
|
||||||
menu:
|
menu:
|
||||||
|
- caption: Configure Auto Backup
|
||||||
|
action: configureAutoBackup
|
||||||
|
confirmText: Configure automated backup schedule?
|
||||||
|
loadingText: Setting up backup schedule...
|
||||||
|
successText: Backup schedule configured successfully
|
||||||
|
settings: scheduleSettings
|
||||||
|
title: Configure Automated Backup Schedule
|
||||||
|
submitButtonText: Save Schedule
|
||||||
|
|
||||||
|
- caption: Remove Auto Backup
|
||||||
|
action: removeAutoBackup
|
||||||
|
confirmText: Remove automated backup schedule?
|
||||||
|
loadingText: Removing backup schedule...
|
||||||
|
successText: Backup schedule removed successfully
|
||||||
|
|
||||||
|
- caption: View Schedule
|
||||||
|
action: viewBackupSchedule
|
||||||
|
confirmText: View current backup schedule?
|
||||||
|
successText: Current schedule retrieved successfully
|
||||||
|
|
||||||
- caption: Check Backup Repository
|
- caption: Check Backup Repository
|
||||||
confirmText: Do you want to check and repair the backup repository?
|
confirmText: Do you want to check and repair the backup repository?
|
||||||
loadingText: Checking and repairing backup repository...
|
loadingText: Checking and repairing backup repository...
|
||||||
|
@ -104,12 +160,7 @@ menu:
|
||||||
- caption: View Database Backups
|
- caption: View Database Backups
|
||||||
action: viewDatabaseBackups
|
action: viewDatabaseBackups
|
||||||
confirmText: Are you sure you want to view database backups?
|
confirmText: Are you sure you want to view database backups?
|
||||||
successText: Database backups listed successfully.
|
successText: Database backups listed successfully.
|
||||||
|
|
||||||
- caption: Auto Backup Sched
|
|
||||||
action: checkBackupSched
|
|
||||||
confirmText: Check the schedules for automated backups?
|
|
||||||
successText: Backup Scheds.
|
|
||||||
|
|
||||||
onUninstall:
|
onUninstall:
|
||||||
- removeScript
|
- removeScript
|
||||||
|
@ -129,6 +180,32 @@ onAfterClone:
|
||||||
backupCount: "5"
|
backupCount: "5"
|
||||||
|
|
||||||
actions:
|
actions:
|
||||||
|
configureAutoBackup:
|
||||||
|
- cmd[cp]:
|
||||||
|
user: root
|
||||||
|
commands: |
|
||||||
|
if [ ! -f /etc/restic-password ]; then
|
||||||
|
echo "Error: Restic password file not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
RESTIC_PWD=$(cat /etc/restic-password)
|
||||||
|
if [ "${settings.frequency}" = "daily" ]; then
|
||||||
|
bash ${globals.scriptPath}/manage_backup_schedule.sh add "0 ${settings.hour} * * *" "$RESTIC_PWD"
|
||||||
|
else
|
||||||
|
bash ${globals.scriptPath}/manage_backup_schedule.sh add "0 ${settings.hour} * * ${settings.dayOfWeek}" "$RESTIC_PWD"
|
||||||
|
fi
|
||||||
|
- return:
|
||||||
|
type: info
|
||||||
|
message: "${response.out}"
|
||||||
|
|
||||||
|
removeAutoBackup:
|
||||||
|
- cmd[cp]:
|
||||||
|
user: root
|
||||||
|
commands: bash /home/litespeed/mb-backups/manage_backup_schedule.sh remove
|
||||||
|
- return:
|
||||||
|
type: info
|
||||||
|
message: "${response.out}"
|
||||||
|
|
||||||
checkBackupRepo:
|
checkBackupRepo:
|
||||||
- cmd[cp]:
|
- cmd[cp]:
|
||||||
user: root
|
user: root
|
||||||
|
@ -209,13 +286,13 @@ actions:
|
||||||
type: info
|
type: info
|
||||||
message: "${response.out}"
|
message: "${response.out}"
|
||||||
|
|
||||||
checkBackupSched:
|
viewBackupSchedule:
|
||||||
- cmd[cp]:
|
- cmd[cp]:
|
||||||
user: root
|
user: root
|
||||||
commands: bash /home/jelastic/mb-backups/check_sched.sh
|
commands: bash /home/litespeed/mb-backups/check_sched.sh
|
||||||
- return:
|
- return:
|
||||||
type: info
|
type: info
|
||||||
message: "${response.out}"
|
message: "${response.out}"
|
||||||
|
|
||||||
checkAddons:
|
checkAddons:
|
||||||
- script: |-
|
- script: |-
|
||||||
|
|
|
@ -1,76 +1,174 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Check if Restic password was supplied
|
# Enable error handling
|
||||||
if [ "$#" -ne 1 ]; then
|
set -e
|
||||||
echo "Usage: $0 RESTIC_PASSWORD"
|
trap 'echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup failed" >> "$LOG_DIR/backup_error.log"' ERR
|
||||||
exit 1
|
|
||||||
fi
|
# Load the backup logic functions
|
||||||
|
source /home/jelastic/mb-backups/backup-logic.sh
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
RESTIC_PASSWORD="$1"
|
password_file="/etc/restic-password"
|
||||||
APP_PATH='/var/www/webroot/ROOT'
|
APP_PATH='/var/www/webroot/ROOT'
|
||||||
WP_CONFIG="${APP_PATH}/wp-config.php"
|
WP_CONFIG="${APP_PATH}/wp-config.php"
|
||||||
backupPath='/mnt/backups'
|
backupPath='/mnt/backups'
|
||||||
LOG_DIR="/home/jelastic/mb-backups/logs"
|
LOG_DIR="/home/jelastic/mb-backups/logs"
|
||||||
DB_NAME=$(grep "define( 'DB_NAME'" $WP_CONFIG | cut -d "'" -f 4)
|
TEMP_DIR="/tmp/wp_backup_tmp"
|
||||||
DB_USER=$(grep "define( 'DB_USER'" $WP_CONFIG | cut -d "'" -f 4)
|
MAX_BACKUP_SIZE=$((10 * 1024 * 1024 * 1024)) # 10GB
|
||||||
DB_PASSWORD=$(grep "define( 'DB_PASSWORD'" $WP_CONFIG | cut -d "'" -f 4)
|
|
||||||
|
# Database configuration
|
||||||
|
DB_NAME=$(grep "define( 'DB_NAME'" "$WP_CONFIG" | cut -d "'" -f 4)
|
||||||
|
DB_USER=$(grep "define( 'DB_USER'" "$WP_CONFIG" | cut -d "'" -f 4)
|
||||||
|
DB_PASSWORD=$(grep "define( 'DB_PASSWORD'" "$WP_CONFIG" | cut -d "'" -f 4)
|
||||||
BACKUP_USER='wp_backup'
|
BACKUP_USER='wp_backup'
|
||||||
BACKUP_PASSWORD='gaQjveXl24Xo66w'
|
BACKUP_PASSWORD='gaQjveXl24Xo66w'
|
||||||
|
|
||||||
export RESTIC_REPOSITORY="$backupPath"
|
# Ensure directories exist
|
||||||
export RESTIC_PASSWORD
|
|
||||||
|
|
||||||
# Ensure log directory exists
|
|
||||||
mkdir -p "$LOG_DIR"
|
mkdir -p "$LOG_DIR"
|
||||||
|
mkdir -p "$TEMP_DIR"
|
||||||
|
|
||||||
|
# Cleanup function
|
||||||
|
cleanup() {
|
||||||
|
local exit_code=$?
|
||||||
|
rm -rf "${TEMP_DIR}"/*
|
||||||
|
if [ $exit_code -ne 0 ]; then
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup failed with exit code $exit_code" | tee -a "$LOG_DIR/backup_error.log"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
# Check backup size
|
||||||
|
check_backup_size() {
|
||||||
|
local path="$1"
|
||||||
|
local size=$(du -sb "$path" | cut -f1)
|
||||||
|
|
||||||
|
if [ "$size" -gt "$MAX_BACKUP_SIZE" ]; then
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Warning: Backup size exceeds 10GB for $path" | tee -a "$LOG_DIR/backup_warning.log"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify backup
|
||||||
|
verify_backup() {
|
||||||
|
local tag="$1"
|
||||||
|
local latest_snapshot=$(restic snapshots --latest 1 --tag "$tag" --json | jq -r '.[0].id')
|
||||||
|
if [ -n "$latest_snapshot" ]; then
|
||||||
|
restic check --read-data "$latest_snapshot"
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Initialize backup
|
||||||
|
if [ ! -f "$password_file" ]; then
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Password file not found at $password_file" | tee -a "$LOG_DIR/backup_error.log"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
export RESTIC_PASSWORD=$(cat "$password_file")
|
||||||
|
export RESTIC_REPOSITORY="$backupPath"
|
||||||
|
|
||||||
|
# Check repository
|
||||||
|
check_backup_repo
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup repository check failed" | tee -a "$LOG_DIR/backup_error.log"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Backup functions
|
# Backup functions
|
||||||
backup_core_files() {
|
backup_core_files() {
|
||||||
local log_file="${LOG_DIR}/backup_core_files_$(date +'%Y-%m-%d').log"
|
local log_file="${LOG_DIR}/backup_core_files_$(date +'%Y-%m-%d').log"
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Core Files Backup" | tee -a "$log_file"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Core Files Backup" | tee -a "$log_file"
|
||||||
|
|
||||||
|
check_backup_size "$APP_PATH" || return 1
|
||||||
|
|
||||||
local excludePaths=("$APP_PATH/wp-content/uploads")
|
local excludePaths=("$APP_PATH/wp-content/uploads")
|
||||||
|
|
||||||
local excludeOptions=""
|
local excludeOptions=""
|
||||||
for path in "${excludePaths[@]}"; do
|
for path in "${excludePaths[@]}"; do
|
||||||
excludeOptions+="--exclude $path "
|
excludeOptions+="--exclude $path "
|
||||||
done
|
done
|
||||||
|
|
||||||
if restic backup $excludeOptions "$APP_PATH" --tag core_files --tag full_backup; then
|
if restic backup $excludeOptions "$APP_PATH" --tag core_files --tag full_backup; then
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Core files backup completed successfully." | tee -a "$log_file"
|
verify_backup "core_files" || return 1
|
||||||
else
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Core files backup completed successfully" | tee -a "$log_file"
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Core files backup failed." | tee -a "$log_file"
|
return 0
|
||||||
fi
|
fi
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
backup_media_themes() {
|
backup_media_themes() {
|
||||||
local log_file="${LOG_DIR}/backup_media_themes_$(date +'%Y-%m-%d').log"
|
local log_file="${LOG_DIR}/backup_media_themes_$(date +'%Y-%m-%d').log"
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Media and Themes Backup" | tee -a "$log_file"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Media and Themes Backup" | tee -a "$log_file"
|
||||||
|
|
||||||
local includePaths=("$APP_PATH/wp-content/uploads")
|
local includePaths=("$APP_PATH/wp-content/uploads")
|
||||||
|
|
||||||
for path in "${includePaths[@]}"; do
|
for path in "${includePaths[@]}"; do
|
||||||
|
check_backup_size "$path" || continue
|
||||||
|
|
||||||
if restic backup "$path" --tag media_themes --tag full_backup; then
|
if restic backup "$path" --tag media_themes --tag full_backup; then
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup completed successfully for $path." | tee -a "$log_file"
|
verify_backup "media_themes" || return 1
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup completed successfully for $path" | tee -a "$log_file"
|
||||||
else
|
else
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup failed for $path." | tee -a "$log_file"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup failed for $path" | tee -a "$log_file"
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
backup_database() {
|
backup_database() {
|
||||||
local log_file="${LOG_DIR}/backup_database_$(date +'%Y-%m-%d').log"
|
local log_file="${LOG_DIR}/backup_database_$(date +'%Y-%m-%d').log"
|
||||||
|
local temp_dump="${TEMP_DIR}/wp_backup_${DB_NAME}_$(date +'%Y%m%d').sql"
|
||||||
|
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Database Backup" | tee -a "$log_file"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Database Backup" | tee -a "$log_file"
|
||||||
|
|
||||||
# Correctly pass the password to mysqldump
|
if ! mysqldump -u "$BACKUP_USER" --password="$BACKUP_PASSWORD" "$DB_NAME" > "$temp_dump" 2>> "$log_file"; then
|
||||||
if mysqldump -u "$BACKUP_USER" --password="$BACKUP_PASSWORD" "$DB_NAME" | restic backup --stdin --tag wordpress_db --tag full_backup; then
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Database dump failed" | tee -a "$log_file"
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Database backup completed successfully." | tee -a "$log_file"
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
check_backup_size "$temp_dump" || return 1
|
||||||
|
|
||||||
|
if restic backup "$temp_dump" --tag wordpress_db --tag full_backup; then
|
||||||
|
verify_backup "wordpress_db" || return 1
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Database backup completed successfully" | tee -a "$log_file"
|
||||||
|
return 0
|
||||||
else
|
else
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Database backup failed." | tee -a "$log_file"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Database backup failed" | tee -a "$log_file"
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute backup functions
|
cleanup_old_backups() {
|
||||||
backup_core_files
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting backup rotation" | tee -a "$LOG_DIR/backup_rotation.log"
|
||||||
backup_media_themes
|
restic forget \
|
||||||
backup_database
|
--keep-daily 7 \
|
||||||
|
--keep-weekly 4 \
|
||||||
|
--keep-monthly 3 \
|
||||||
|
--prune \
|
||||||
|
--tag full_backup \
|
||||||
|
2>> "$LOG_DIR/backup_rotation.log"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
main() {
|
||||||
|
local start_time=$(date +%s)
|
||||||
|
local backup_date=$(date +'%Y-%m-%d_%H-%M-%S')
|
||||||
|
local main_log="${LOG_DIR}/full_backup_${backup_date}.log"
|
||||||
|
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting full backup process" | tee -a "$main_log"
|
||||||
|
|
||||||
|
backup_core_files || exit 1
|
||||||
|
backup_media_themes || exit 1
|
||||||
|
backup_database || exit 1
|
||||||
|
|
||||||
|
cleanup_old_backups
|
||||||
|
|
||||||
|
local end_time=$(date +%s)
|
||||||
|
local duration=$((end_time - start_time))
|
||||||
|
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Full backup completed in $duration seconds" | tee -a "$main_log"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute main function
|
||||||
|
main
|
|
@ -1,5 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Load the backup logic functions
|
||||||
|
source /home/jelastic/mb-backups/backup-logic.sh
|
||||||
|
|
||||||
# Check for required arguments
|
# Check for required arguments
|
||||||
if [ $# -ne 2 ]; then
|
if [ $# -ne 2 ]; then
|
||||||
echo "Usage: $0 <RESTIC_PASSWORD> <ADDITIONAL_TAG>"
|
echo "Usage: $0 <RESTIC_PASSWORD> <ADDITIONAL_TAG>"
|
||||||
|
@ -13,6 +16,7 @@ ADDITIONAL_TAG="$2"
|
||||||
# Configuration
|
# Configuration
|
||||||
APP_PATH='/var/www/webroot/ROOT'
|
APP_PATH='/var/www/webroot/ROOT'
|
||||||
backupPath='/mnt/backups'
|
backupPath='/mnt/backups'
|
||||||
|
password_file="/etc/restic-password"
|
||||||
LOG_DIR="/home/jelastic/mb-backups/logs"
|
LOG_DIR="/home/jelastic/mb-backups/logs"
|
||||||
LOG_FILE="${LOG_DIR}/backup_core_files_$(date +'%Y-%m-%d').log"
|
LOG_FILE="${LOG_DIR}/backup_core_files_$(date +'%Y-%m-%d').log"
|
||||||
excludePaths=(
|
excludePaths=(
|
||||||
|
@ -26,6 +30,26 @@ mkdir -p "$LOG_DIR"
|
||||||
export RESTIC_REPOSITORY="$backupPath"
|
export RESTIC_REPOSITORY="$backupPath"
|
||||||
export RESTIC_PASSWORD
|
export RESTIC_PASSWORD
|
||||||
|
|
||||||
|
# Verify that the password file exists and matches the supplied password
|
||||||
|
if [ ! -f "$password_file" ]; then
|
||||||
|
echo "ERROR: Password file not found at $password_file" | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Load and verify password from the file
|
||||||
|
stored_password=$(cat "$password_file")
|
||||||
|
if [ "$stored_password" != "$RESTIC_PASSWORD" ]; then
|
||||||
|
echo "ERROR: Password mismatch. Aborting backup." | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check repository accessibility and integrity
|
||||||
|
check_backup_repo
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup repository check failed. Aborting backup." | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Logging start
|
# Logging start
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Core Files Backup with tags: core_files, $ADDITIONAL_TAG" | tee -a "$LOG_FILE"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Core Files Backup with tags: core_files, $ADDITIONAL_TAG" | tee -a "$LOG_FILE"
|
||||||
|
|
||||||
|
@ -40,8 +64,8 @@ if restic backup $excludeOptions "$APP_PATH" --tag core_files --tag "$ADDITIONAL
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Core files backup completed successfully." | tee -a "$LOG_FILE"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Core files backup completed successfully." | tee -a "$LOG_FILE"
|
||||||
else
|
else
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Core files backup failed." | tee -a "$LOG_FILE"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Core files backup failed." | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Logging end
|
# Logging end
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup process finished." | tee -a "$LOG_FILE"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup process finished." | tee -a "$LOG_FILE"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Load backup logic functions
|
||||||
|
source /home/jelastic/mb-backups/backup-logic.sh
|
||||||
|
|
||||||
# Validate input parameters
|
# Validate input parameters
|
||||||
if [ "$#" -ne 2 ]; then
|
if [ "$#" -ne 2 ]; then
|
||||||
echo "Usage: $0 <RESTIC_PASSWORD> <ADDITIONAL_TAG>"
|
echo "Usage: $0 <RESTIC_PASSWORD> <ADDITIONAL_TAG>"
|
||||||
|
@ -14,6 +17,7 @@ ADDITIONAL_TAG="$2"
|
||||||
APP_PATH='/var/www/webroot/ROOT'
|
APP_PATH='/var/www/webroot/ROOT'
|
||||||
WP_CONFIG="${APP_PATH}/wp-config.php"
|
WP_CONFIG="${APP_PATH}/wp-config.php"
|
||||||
backupPath='/mnt/backups'
|
backupPath='/mnt/backups'
|
||||||
|
password_file="/etc/restic-password"
|
||||||
LOG_DIR="/home/jelastic/mb-backups/logs"
|
LOG_DIR="/home/jelastic/mb-backups/logs"
|
||||||
LOG_FILE="${LOG_DIR}/backup_database_$(date +'%Y-%m-%d').log"
|
LOG_FILE="${LOG_DIR}/backup_database_$(date +'%Y-%m-%d').log"
|
||||||
DB_NAME=$(grep "define( 'DB_NAME'" $WP_CONFIG | cut -d "'" -f 4)
|
DB_NAME=$(grep "define( 'DB_NAME'" $WP_CONFIG | cut -d "'" -f 4)
|
||||||
|
@ -35,11 +39,32 @@ export MYSQL_PWD=$BACKUP_PASSWORD # Use the backup user's password for mysqldum
|
||||||
# Logging start
|
# Logging start
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Database Backup with additional tag: $ADDITIONAL_TAG" | tee -a "$LOG_FILE"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Database Backup with additional tag: $ADDITIONAL_TAG" | tee -a "$LOG_FILE"
|
||||||
|
|
||||||
# Perform backup with additional tag
|
# Verify that the password file exists and matches the supplied password
|
||||||
|
if [ ! -f "$password_file" ]; then
|
||||||
|
echo "ERROR: Password file not found at $password_file" | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Load and verify password from the file
|
||||||
|
stored_password=$(cat "$password_file")
|
||||||
|
if [ "$stored_password" != "$RESTIC_PASSWORD" ]; then
|
||||||
|
echo "ERROR: Password mismatch. Aborting backup." | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check repository accessibility and integrity
|
||||||
|
check_backup_repo
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup repository check failed. Aborting backup." | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Perform database backup with additional tag
|
||||||
if mysqldump -u "$BACKUP_USER" "$DB_NAME" | restic backup --stdin --tag wordpress_db --tag "$ADDITIONAL_TAG"; then
|
if mysqldump -u "$BACKUP_USER" "$DB_NAME" | restic backup --stdin --tag wordpress_db --tag "$ADDITIONAL_TAG"; then
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Database backup completed successfully with tags: wordpress_db, $ADDITIONAL_TAG." | tee -a "$LOG_FILE"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Database backup completed successfully with tags: wordpress_db, $ADDITIONAL_TAG." | tee -a "$LOG_FILE"
|
||||||
else
|
else
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Database backup failed." | tee -a "$LOG_FILE"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Database backup failed." | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Logging end
|
# Logging end
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Check for required arguments
|
# Load backup logic functions
|
||||||
|
source /home/jelastic/mb-backups/backup-logic.sh
|
||||||
|
|
||||||
|
# Validate input parameters
|
||||||
if [ "$#" -ne 2 ]; then
|
if [ "$#" -ne 2 ]; then
|
||||||
echo "Usage: $0 <RESTIC_PASSWORD> <ADDITIONAL_TAG>"
|
echo "Usage: $0 <RESTIC_PASSWORD> <ADDITIONAL_TAG>"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Assign arguments to variables
|
# Assign command line arguments to variables
|
||||||
RESTIC_PASSWORD="$1"
|
RESTIC_PASSWORD="$1"
|
||||||
ADDITIONAL_TAG="$2"
|
ADDITIONAL_TAG="$2"
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
APP_PATH='/var/www/webroot/ROOT'
|
APP_PATH='/var/www/webroot/ROOT'
|
||||||
backupPath='/mnt/backups'
|
backupPath='/mnt/backups'
|
||||||
|
password_file="/etc/restic-password"
|
||||||
LOG_DIR="/home/jelastic/mb-backups/logs/manual/media"
|
LOG_DIR="/home/jelastic/mb-backups/logs/manual/media"
|
||||||
LOG_FILE="${LOG_DIR}/backup_media_$(date +'%Y-%m-%d').log"
|
LOG_FILE="${LOG_DIR}/backup_media_$(date +'%Y-%m-%d').log"
|
||||||
includePaths=("$APP_PATH/wp-content/uploads")
|
includePaths=("$APP_PATH/wp-content/uploads")
|
||||||
|
@ -25,14 +29,35 @@ export RESTIC_REPOSITORY="$backupPath"
|
||||||
export RESTIC_PASSWORD
|
export RESTIC_PASSWORD
|
||||||
|
|
||||||
# Logging start
|
# Logging start
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Media Backup" | tee -a "$LOG_FILE"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting Media and Themes Backup" | tee -a "$LOG_FILE"
|
||||||
|
|
||||||
# Perform backup with additional tag
|
# Verify that the password file exists and matches the supplied password
|
||||||
|
if [ ! -f "$password_file" ]; then
|
||||||
|
echo "ERROR: Password file not found at $password_file" | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Load and verify password from the file
|
||||||
|
stored_password=$(cat "$password_file")
|
||||||
|
if [ "$stored_password" != "$RESTIC_PASSWORD" ]; then
|
||||||
|
echo "ERROR: Password mismatch. Aborting backup." | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check repository accessibility and integrity
|
||||||
|
check_backup_repo
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup repository check failed. Aborting backup." | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Perform media backup with additional tag
|
||||||
for path in "${includePaths[@]}"; do
|
for path in "${includePaths[@]}"; do
|
||||||
if restic backup "$path" --tag media_themes --tag "$ADDITIONAL_TAG"; then
|
if restic backup "$path" --tag media_themes --tag "$ADDITIONAL_TAG"; then
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup completed successfully for $path with tags: media_themes, $ADDITIONAL_TAG." | tee -a "$LOG_FILE"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup completed successfully for $path with tags: media_themes, $ADDITIONAL_TAG." | tee -a "$LOG_FILE"
|
||||||
else
|
else
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup failed for $path." | tee -a "$LOG_FILE"
|
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup failed for $path." | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,18 @@
|
||||||
|
|
||||||
# Define the script path to check in cron jobs
|
# Define the script path to check in cron jobs
|
||||||
SCRIPT_PATH="/home/litespeed/mb-backups/backup_all.sh"
|
SCRIPT_PATH="/home/litespeed/mb-backups/backup_all.sh"
|
||||||
|
LOG_FILE="/home/litespeed/mb-backups/logs/cron_check.log"
|
||||||
|
|
||||||
# Use crontab -l to list all cron jobs, then grep to check for the specific script path
|
# Log the start of the script check
|
||||||
|
echo "[$(date)] Checking for automated backup cron job..." | tee -a "$LOG_FILE"
|
||||||
|
|
||||||
|
# Check if the cron job is found in the crontab
|
||||||
CRON_JOB=$(crontab -l | grep -F "$SCRIPT_PATH")
|
CRON_JOB=$(crontab -l | grep -F "$SCRIPT_PATH")
|
||||||
|
|
||||||
if [ -z "$CRON_JOB" ]; then
|
if [ -z "$CRON_JOB" ]; then
|
||||||
echo "Automated Backups is not enabled."
|
echo "[$(date)] Automated Backups are NOT enabled." | tee -a "$LOG_FILE"
|
||||||
else
|
else
|
||||||
echo "$CRON_JOB" | awk '{print "Schedule: " $1, $2, $3, $4, $5}'
|
echo "[$(date)] Automated Backups are enabled with the following schedule:" | tee -a "$LOG_FILE"
|
||||||
# Note: This script stops here, providing the schedule. Computing the next run time in a human-readable format is not straightforward in bash without external tools.
|
echo "$CRON_JOB" | awk '{print "Schedule: " $1, $2, $3, $4, $5}' | tee -a "$LOG_FILE"
|
||||||
|
echo "[$(date)] Note: Computing the next human-readable run time requires external tools." | tee -a "$LOG_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,62 +1,196 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Enable strict error handling
|
||||||
|
set -euo pipefail
|
||||||
|
trap 'handle_error $? $LINENO' ERR
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
BACKUP_SCRIPT="/home/litespeed/mb-backups/backup_all.sh"
|
BACKUP_SCRIPT="/home/litespeed/mb-backups/backup_all.sh"
|
||||||
LOG_DIR="/home/litespeed/mb-backups/logs/auto"
|
LOG_DIR="/home/litespeed/mb-backups/logs/auto"
|
||||||
ACTION_LOG_FILE="${LOG_DIR}/schedule_actions.log"
|
ACTION_LOG_FILE="${LOG_DIR}/schedule_actions.log"
|
||||||
BACKUP_LOG_PREFIX="${LOG_DIR}/backup_"
|
BACKUP_LOG_PREFIX="${LOG_DIR}/backup_"
|
||||||
|
PASSWORD_FILE="/etc/restic-password"
|
||||||
|
LOCK_FILE="/tmp/backup_schedule.lock"
|
||||||
|
MAX_RETRIES=3
|
||||||
|
RETRY_DELAY=5
|
||||||
|
|
||||||
# Ensure the log directory exists
|
# Error handling function
|
||||||
mkdir -p "$LOG_DIR"
|
handle_error() {
|
||||||
|
local exit_code=$1
|
||||||
log_action() {
|
local line_no=$2
|
||||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "$ACTION_LOG_FILE"
|
log_action "ERROR: Command failed at line ${line_no} with exit code ${exit_code}"
|
||||||
|
cleanup_and_exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to add or update the cron job with dynamic logging
|
# Cleanup function
|
||||||
add_update_cron_job() {
|
cleanup_and_exit() {
|
||||||
# Verify Restic password is provided
|
local exit_code=$1
|
||||||
if [ -z "$3" ]; then
|
[ -f "$LOCK_FILE" ] && rm -f "$LOCK_FILE"
|
||||||
echo "Restic password is required."
|
exit "${exit_code}"
|
||||||
log_action "Attempted to add/update a schedule without providing a Restic password."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Prepare the cron command to include dynamic date in the backup log filename
|
|
||||||
CMD="RESTIC_PASSWORD=\"$3\" $BACKUP_SCRIPT > \"${BACKUP_LOG_PREFIX}\$(date +\\%Y-\\%m-\\%d_\\%H-\\%M-\\%S).log\" 2>&1"
|
|
||||||
|
|
||||||
# Add or update the cron job
|
|
||||||
(crontab -l | grep -v "$BACKUP_SCRIPT" 2>/dev/null; echo "$2 $CMD") | crontab -
|
|
||||||
local update_msg="Backup schedule updated to: $2"
|
|
||||||
echo "$update_msg"
|
|
||||||
log_action "$update_msg"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to remove the cron job
|
# Ensure single instance
|
||||||
remove_cron_job() {
|
ensure_single_instance() {
|
||||||
crontab -l | grep -v "$BACKUP_SCRIPT" | crontab -
|
if [ -f "$LOCK_FILE" ]; then
|
||||||
local remove_msg="Backup schedule removed."
|
if kill -0 "$(cat "$LOCK_FILE")" 2>/dev/null; then
|
||||||
echo "$remove_msg"
|
log_action "ERROR: Another instance is running"
|
||||||
log_action "$remove_msg"
|
exit 1
|
||||||
}
|
|
||||||
|
|
||||||
# Main logic to add, update, or remove the cron job based on user input
|
|
||||||
case $1 in
|
|
||||||
add|update)
|
|
||||||
if [ "$#" -ne 3 ]; then
|
|
||||||
echo "Usage for add/update: $0 {add|update} 'schedule' 'restic_password'"
|
|
||||||
echo "Example: $0 add '0 1 * * *' 'secret_password'"
|
|
||||||
log_action "Incorrect usage for add/update. Correct format not followed."
|
|
||||||
else
|
|
||||||
add_update_cron_job "$@"
|
|
||||||
fi
|
fi
|
||||||
;;
|
fi
|
||||||
remove)
|
echo $$ > "$LOCK_FILE"
|
||||||
remove_cron_job
|
}
|
||||||
;;
|
|
||||||
*)
|
# Enhanced logging function
|
||||||
echo "Invalid action: $1. Use add, update, or remove."
|
log_action() {
|
||||||
log_action "Invalid action attempted: $1"
|
local timestamp=$(date +'%Y-%m-%d %H:%M:%S')
|
||||||
exit 1
|
local log_msg="[$timestamp] $1"
|
||||||
;;
|
echo "$log_msg" | tee -a "$ACTION_LOG_FILE"
|
||||||
esac
|
|
||||||
|
# Log critical errors to system log
|
||||||
|
if [[ "$1" == *"ERROR"* ]]; then
|
||||||
|
logger -t "backup-schedule" "$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Validate system requirements
|
||||||
|
check_system_requirements() {
|
||||||
|
local required_space=1048576 # 1GB in KB
|
||||||
|
local available_space=$(df -k "$LOG_DIR" | awk 'NR==2 {print $4}')
|
||||||
|
|
||||||
|
if [ ! -x "$BACKUP_SCRIPT" ]; then
|
||||||
|
log_action "ERROR: Backup script not executable or not found"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$available_space" -lt "$required_space" ]; then
|
||||||
|
log_action "ERROR: Insufficient disk space"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Validate cron schedule
|
||||||
|
validate_schedule() {
|
||||||
|
local schedule="$1"
|
||||||
|
if ! [[ $schedule =~ ^[0-9,\*/-]+ [0-9,\*/-]+ [0-9,\*/-]+ [0-9,\*/-]+ [0-9,\*/-]+$ ]]; then
|
||||||
|
log_action "ERROR: Invalid cron schedule format: $schedule"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get Restic password with retry mechanism
|
||||||
|
get_restic_password() {
|
||||||
|
local retry_count=0
|
||||||
|
while [ $retry_count -lt $MAX_RETRIES ]; do
|
||||||
|
if [ -f "$PASSWORD_FILE" ] && [ -s "$PASSWORD_FILE" ]; then
|
||||||
|
cat "$PASSWORD_FILE"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
retry_count=$((retry_count + 1))
|
||||||
|
sleep $RETRY_DELAY
|
||||||
|
done
|
||||||
|
log_action "ERROR: Failed to retrieve Restic password after $MAX_RETRIES attempts"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enhanced cron job management
|
||||||
|
add_update_cron_job() {
|
||||||
|
local action="$1"
|
||||||
|
local schedule="$2"
|
||||||
|
local restic_password="$3"
|
||||||
|
local temp_crontab="/tmp/temp_crontab.$$"
|
||||||
|
|
||||||
|
# Validate inputs
|
||||||
|
if ! validate_schedule "$schedule"; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prepare cron command with environment variables and error handling
|
||||||
|
local CMD="RESTIC_PASSWORD=\"$restic_password\" \
|
||||||
|
LOG_FILE=\"${BACKUP_LOG_PREFIX}\$(date +\\%Y-\\%m-\\%d_\\%H-\\%M-\\%S).log\" \
|
||||||
|
$BACKUP_SCRIPT > \"\$LOG_FILE\" 2>&1 || echo \"\$(date) Backup failed\" >> \"$ACTION_LOG_FILE\""
|
||||||
|
|
||||||
|
# Safely update crontab
|
||||||
|
crontab -l 2>/dev/null | grep -v "$BACKUP_SCRIPT" > "$temp_crontab" || true
|
||||||
|
echo "$schedule $CMD" >> "$temp_crontab"
|
||||||
|
|
||||||
|
if crontab "$temp_crontab"; then
|
||||||
|
log_action "Successfully ${action}d backup schedule: $schedule"
|
||||||
|
rm -f "$temp_crontab"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_action "ERROR: Failed to ${action} backup schedule"
|
||||||
|
rm -f "$temp_crontab"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Enhanced cron job removal
|
||||||
|
remove_cron_job() {
|
||||||
|
local temp_crontab="/tmp/temp_crontab.$$"
|
||||||
|
|
||||||
|
if crontab -l 2>/dev/null | grep -q "$BACKUP_SCRIPT"; then
|
||||||
|
crontab -l | grep -v "$BACKUP_SCRIPT" > "$temp_crontab"
|
||||||
|
if crontab "$temp_crontab"; then
|
||||||
|
log_action "Backup schedule successfully removed"
|
||||||
|
rm -f "$temp_crontab"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_action "ERROR: Failed to remove backup schedule"
|
||||||
|
rm -f "$temp_crontab"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_action "No backup schedule found to remove"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main execution
|
||||||
|
main() {
|
||||||
|
# Create log directory with proper permissions
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
chmod 750 "$LOG_DIR"
|
||||||
|
|
||||||
|
# Ensure single instance
|
||||||
|
ensure_single_instance
|
||||||
|
|
||||||
|
# Check system requirements
|
||||||
|
if ! check_system_requirements; then
|
||||||
|
cleanup_and_exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
add|update)
|
||||||
|
if [ "$#" -ne 3 ]; then
|
||||||
|
log_action "Usage: $0 {add|update} 'schedule' 'restic_password'"
|
||||||
|
log_action "Example: $0 add '0 1 * * *' 'secret_password'"
|
||||||
|
cleanup_and_exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local restic_password="${3:-$(get_restic_password)}"
|
||||||
|
if [ -z "$restic_password" ]; then
|
||||||
|
cleanup_and_exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
add_update_cron_job "$1" "$2" "$restic_password"
|
||||||
|
;;
|
||||||
|
remove)
|
||||||
|
remove_cron_job
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
crontab -l | grep "$BACKUP_SCRIPT" || echo "No backup schedule found"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_action "Invalid action: $1. Use add, update, remove, or status"
|
||||||
|
cleanup_and_exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cleanup_and_exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Execute main function with all arguments
|
||||||
|
main "$@"
|
Loading…
Reference in New Issue