New updates and fail safe mechanism
parent
2a3c7341f0
commit
301d5dceda
97
manifest.jps
97
manifest.jps
|
@ -14,6 +14,8 @@ targetNodes:
|
|||
|
||||
globals:
|
||||
envName: "${env.name}"
|
||||
scriptPath: "/home/litespeed/mb-backups"
|
||||
logPath: "/home/litespeed/mb-backups/logs"
|
||||
|
||||
onInstall:
|
||||
- checkAddons
|
||||
|
@ -21,12 +23,46 @@ onInstall:
|
|||
- importScripts
|
||||
|
||||
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:
|
||||
submitUnchanged: true
|
||||
fields:
|
||||
- name: blabel
|
||||
caption: Backup Label
|
||||
type: string
|
||||
|
||||
restoreSettings:
|
||||
submitUnchanged: true
|
||||
fields:
|
||||
|
@ -42,6 +78,26 @@ buttons:
|
|||
successText: The backup process has been finished successfully.
|
||||
|
||||
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
|
||||
confirmText: Do you want to check and repair the backup repository?
|
||||
loadingText: Checking and repairing backup repository...
|
||||
|
@ -104,12 +160,7 @@ menu:
|
|||
- caption: View Database Backups
|
||||
action: viewDatabaseBackups
|
||||
confirmText: Are you sure you want to view database backups?
|
||||
successText: Database backups listed successfully.
|
||||
|
||||
- caption: Auto Backup Sched
|
||||
action: checkBackupSched
|
||||
confirmText: Check the schedules for automated backups?
|
||||
successText: Backup Scheds.
|
||||
successText: Database backups listed successfully.
|
||||
|
||||
onUninstall:
|
||||
- removeScript
|
||||
|
@ -129,6 +180,32 @@ onAfterClone:
|
|||
backupCount: "5"
|
||||
|
||||
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:
|
||||
- cmd[cp]:
|
||||
user: root
|
||||
|
@ -209,13 +286,13 @@ actions:
|
|||
type: info
|
||||
message: "${response.out}"
|
||||
|
||||
checkBackupSched:
|
||||
viewBackupSchedule:
|
||||
- cmd[cp]:
|
||||
user: root
|
||||
commands: bash /home/jelastic/mb-backups/check_sched.sh
|
||||
- return:
|
||||
commands: bash /home/litespeed/mb-backups/check_sched.sh
|
||||
- return:
|
||||
type: info
|
||||
message: "${response.out}"
|
||||
message: "${response.out}"
|
||||
|
||||
checkAddons:
|
||||
- script: |-
|
||||
|
|
|
@ -1,76 +1,174 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Check if Restic password was supplied
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 RESTIC_PASSWORD"
|
||||
exit 1
|
||||
fi
|
||||
# Enable error handling
|
||||
set -e
|
||||
trap 'echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup failed" >> "$LOG_DIR/backup_error.log"' ERR
|
||||
|
||||
# Load the backup logic functions
|
||||
source /home/jelastic/mb-backups/backup-logic.sh
|
||||
|
||||
# Configuration
|
||||
RESTIC_PASSWORD="$1"
|
||||
password_file="/etc/restic-password"
|
||||
APP_PATH='/var/www/webroot/ROOT'
|
||||
WP_CONFIG="${APP_PATH}/wp-config.php"
|
||||
backupPath='/mnt/backups'
|
||||
LOG_DIR="/home/jelastic/mb-backups/logs"
|
||||
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)
|
||||
TEMP_DIR="/tmp/wp_backup_tmp"
|
||||
MAX_BACKUP_SIZE=$((10 * 1024 * 1024 * 1024)) # 10GB
|
||||
|
||||
# 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_PASSWORD='gaQjveXl24Xo66w'
|
||||
|
||||
export RESTIC_REPOSITORY="$backupPath"
|
||||
export RESTIC_PASSWORD
|
||||
|
||||
# Ensure log directory exists
|
||||
# Ensure directories exist
|
||||
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_core_files() {
|
||||
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"
|
||||
|
||||
check_backup_size "$APP_PATH" || return 1
|
||||
|
||||
local excludePaths=("$APP_PATH/wp-content/uploads")
|
||||
|
||||
local excludeOptions=""
|
||||
for path in "${excludePaths[@]}"; do
|
||||
excludeOptions+="--exclude $path "
|
||||
done
|
||||
|
||||
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"
|
||||
else
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Core files backup failed." | tee -a "$log_file"
|
||||
verify_backup "core_files" || return 1
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Core files backup completed successfully" | tee -a "$log_file"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
backup_media_themes() {
|
||||
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"
|
||||
|
||||
local includePaths=("$APP_PATH/wp-content/uploads")
|
||||
|
||||
|
||||
for path in "${includePaths[@]}"; do
|
||||
check_backup_size "$path" || continue
|
||||
|
||||
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
|
||||
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
|
||||
done
|
||||
}
|
||||
|
||||
backup_database() {
|
||||
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"
|
||||
|
||||
# Correctly pass the password to mysqldump
|
||||
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')] Database backup completed successfully." | tee -a "$log_file"
|
||||
|
||||
if ! mysqldump -u "$BACKUP_USER" --password="$BACKUP_PASSWORD" "$DB_NAME" > "$temp_dump" 2>> "$log_file"; then
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Database dump failed" | 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
|
||||
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
|
||||
}
|
||||
|
||||
# Execute backup functions
|
||||
backup_core_files
|
||||
backup_media_themes
|
||||
backup_database
|
||||
cleanup_old_backups() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Starting backup rotation" | tee -a "$LOG_DIR/backup_rotation.log"
|
||||
restic forget \
|
||||
--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
|
||||
|
||||
# Load the backup logic functions
|
||||
source /home/jelastic/mb-backups/backup-logic.sh
|
||||
|
||||
# Check for required arguments
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage: $0 <RESTIC_PASSWORD> <ADDITIONAL_TAG>"
|
||||
|
@ -13,6 +16,7 @@ ADDITIONAL_TAG="$2"
|
|||
# Configuration
|
||||
APP_PATH='/var/www/webroot/ROOT'
|
||||
backupPath='/mnt/backups'
|
||||
password_file="/etc/restic-password"
|
||||
LOG_DIR="/home/jelastic/mb-backups/logs"
|
||||
LOG_FILE="${LOG_DIR}/backup_core_files_$(date +'%Y-%m-%d').log"
|
||||
excludePaths=(
|
||||
|
@ -26,6 +30,26 @@ mkdir -p "$LOG_DIR"
|
|||
export RESTIC_REPOSITORY="$backupPath"
|
||||
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
|
||||
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"
|
||||
else
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Core files backup failed." | tee -a "$LOG_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Logging end
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Backup process finished." | tee -a "$LOG_FILE"
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Load backup logic functions
|
||||
source /home/jelastic/mb-backups/backup-logic.sh
|
||||
|
||||
# Validate input parameters
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: $0 <RESTIC_PASSWORD> <ADDITIONAL_TAG>"
|
||||
|
@ -14,6 +17,7 @@ ADDITIONAL_TAG="$2"
|
|||
APP_PATH='/var/www/webroot/ROOT'
|
||||
WP_CONFIG="${APP_PATH}/wp-config.php"
|
||||
backupPath='/mnt/backups'
|
||||
password_file="/etc/restic-password"
|
||||
LOG_DIR="/home/jelastic/mb-backups/logs"
|
||||
LOG_FILE="${LOG_DIR}/backup_database_$(date +'%Y-%m-%d').log"
|
||||
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
|
||||
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
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Database backup completed successfully with tags: wordpress_db, $ADDITIONAL_TAG." | tee -a "$LOG_FILE"
|
||||
else
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Database backup failed." | tee -a "$LOG_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Logging end
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
#!/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
|
||||
echo "Usage: $0 <RESTIC_PASSWORD> <ADDITIONAL_TAG>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Assign arguments to variables
|
||||
# Assign command line arguments to variables
|
||||
RESTIC_PASSWORD="$1"
|
||||
ADDITIONAL_TAG="$2"
|
||||
|
||||
# Configuration
|
||||
APP_PATH='/var/www/webroot/ROOT'
|
||||
backupPath='/mnt/backups'
|
||||
password_file="/etc/restic-password"
|
||||
LOG_DIR="/home/jelastic/mb-backups/logs/manual/media"
|
||||
LOG_FILE="${LOG_DIR}/backup_media_$(date +'%Y-%m-%d').log"
|
||||
includePaths=("$APP_PATH/wp-content/uploads")
|
||||
|
@ -25,14 +29,35 @@ export RESTIC_REPOSITORY="$backupPath"
|
|||
export RESTIC_PASSWORD
|
||||
|
||||
# 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
|
||||
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"
|
||||
else
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: Backup failed for $path." | tee -a "$LOG_FILE"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
|
@ -4,13 +4,18 @@
|
|||
|
||||
# Define the script path to check in cron jobs
|
||||
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")
|
||||
|
||||
if [ -z "$CRON_JOB" ]; then
|
||||
echo "Automated Backups is not enabled."
|
||||
echo "[$(date)] Automated Backups are NOT enabled." | tee -a "$LOG_FILE"
|
||||
else
|
||||
echo "$CRON_JOB" | awk '{print "Schedule: " $1, $2, $3, $4, $5}'
|
||||
# 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 "[$(date)] Automated Backups are enabled with the following schedule:" | tee -a "$LOG_FILE"
|
||||
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
|
||||
|
|
|
@ -1,62 +1,196 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Enable strict error handling
|
||||
set -euo pipefail
|
||||
trap 'handle_error $? $LINENO' ERR
|
||||
|
||||
# Configuration
|
||||
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_"
|
||||
PASSWORD_FILE="/etc/restic-password"
|
||||
LOCK_FILE="/tmp/backup_schedule.lock"
|
||||
MAX_RETRIES=3
|
||||
RETRY_DELAY=5
|
||||
|
||||
# Ensure the log directory exists
|
||||
mkdir -p "$LOG_DIR"
|
||||
|
||||
log_action() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> "$ACTION_LOG_FILE"
|
||||
# Error handling function
|
||||
handle_error() {
|
||||
local exit_code=$1
|
||||
local line_no=$2
|
||||
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
|
||||
add_update_cron_job() {
|
||||
# Verify Restic password is provided
|
||||
if [ -z "$3" ]; then
|
||||
echo "Restic password is required."
|
||||
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"
|
||||
# Cleanup function
|
||||
cleanup_and_exit() {
|
||||
local exit_code=$1
|
||||
[ -f "$LOCK_FILE" ] && rm -f "$LOCK_FILE"
|
||||
exit "${exit_code}"
|
||||
}
|
||||
|
||||
# Function to remove the cron job
|
||||
remove_cron_job() {
|
||||
crontab -l | grep -v "$BACKUP_SCRIPT" | crontab -
|
||||
local remove_msg="Backup schedule removed."
|
||||
echo "$remove_msg"
|
||||
log_action "$remove_msg"
|
||||
}
|
||||
|
||||
# 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 "$@"
|
||||
# Ensure single instance
|
||||
ensure_single_instance() {
|
||||
if [ -f "$LOCK_FILE" ]; then
|
||||
if kill -0 "$(cat "$LOCK_FILE")" 2>/dev/null; then
|
||||
log_action "ERROR: Another instance is running"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
remove)
|
||||
remove_cron_job
|
||||
;;
|
||||
*)
|
||||
echo "Invalid action: $1. Use add, update, or remove."
|
||||
log_action "Invalid action attempted: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
echo $$ > "$LOCK_FILE"
|
||||
}
|
||||
|
||||
# Enhanced logging function
|
||||
log_action() {
|
||||
local timestamp=$(date +'%Y-%m-%d %H:%M:%S')
|
||||
local log_msg="[$timestamp] $1"
|
||||
echo "$log_msg" | tee -a "$ACTION_LOG_FILE"
|
||||
|
||||
# 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