diff --git a/changelogs.md b/changelogs.md index bda1c33..b07ca1a 100644 --- a/changelogs.md +++ b/changelogs.md @@ -1,5 +1,33 @@ # Changelog +## Version 1.6 + +### Added +- **`check_repo_stats.sh`**: + - Introduced a new script to automate the retrieval of repository statistics and perform maintenance tasks. + - Logs repository stats, retention policy application, and integrity checks to dynamically named log files (`repo_stats_YYYY-MM-DD.log`). + - Automatically applies a retention policy (`--keep-last 7 --prune`) to manage repository size. + - Includes an integrity check (`restic check --read-data-subset=5%`) to validate repository consistency and data reliability. + - Detects and removes stale locks before performing operations. + - Ensures dependencies (`restic`) and repository access are validated before execution. + - Handles errors gracefully with detailed logging for each step. + +- **Enhanced `backup_repo_check` Functionality**: + - Created a standalone script `check_backup_repo.sh` to validate repository integrity and initialize repositories if empty. + - Logs actions and errors to `/home/litespeed/logs/backup_repo_check.log` for better traceability. + - Improved stale lock handling by detecting and removing locks when necessary. + - Validates or creates a password file (`/etc/restic-password`) to ensure smooth operation without prompts. + - Automatically initializes a new repository if no files are present in the backup path. + +### Fixed +- Addressed permission issues in `check_backup_repo.sh` by ensuring the log directory and repository paths are writable by the correct user. +- Corrected potential errors in handling stale locks by adding proper validation before removing them. + +### Improved +- Enhanced logging across `check_repo_stats.sh` and `check_backup_repo.sh` for better monitoring and traceability. +- Optimized script robustness with dependency validation, error handling, and reduced redundancy. +- Streamlined repository maintenance by combining retention policy application, stale lock removal, and integrity checks into `check_repo_stats.sh`. + ## Version 1.5 ### Added diff --git a/manifest.jps b/manifest.jps index e5d5608..2e2f830 100644 --- a/manifest.jps +++ b/manifest.jps @@ -1,5 +1,5 @@ type: update -jpsVersion: 1.5 +jpsVersion: 1.6 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. @@ -127,6 +127,12 @@ menu: confirmText: Are you sure you want to view database backups? successText: Database backups listed successfully. + - caption: Check Repository Stats + confirmText: Check repository stats? + loadingText: Checking repository stats... + action: checkRepoStats + successText: Repository stats checked successfully. + onUninstall: - removeScript @@ -165,7 +171,7 @@ actions: checkBackupRepo: - cmd[cp]: user: root - commands: bash /home/jelastic/mb-backups/backup-logic.sh check_backup_repo + commands: bash /home/jelastic/mb-backups/check_backup_repo.sh - return: type: info message: "${response.out}" @@ -250,6 +256,14 @@ actions: type: info message: "${response.out}" + checkRepoStats: + - cmd[cp]: + user: root + commands: bash /home/jelastic/mb-backups/check_repo_stats.sh + - return: + type: info + message: "${response.out}" + checkAddons: - script: |- var onAfterReturn = { setGlobals: {} }, @@ -320,7 +334,6 @@ actions: - mkdir -p /home/litespeed/mb-backups/logs/restore - chown -R litespeed:litespeed /home/litespeed/mb-backups - cd /home/jelastic/mb-backups - - curl -O https://deploy-proxy.mightybox.io/addons/mb-backup-manager/raw/branch/main/scripts/backup-logic.sh - 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 - curl -O https://deploy-proxy.mightybox.io/addons/mb-backup-manager/raw/branch/main/scripts/imports/backup_database.sh @@ -329,5 +342,7 @@ actions: - curl -O https://deploy-proxy.mightybox.io/addons/mb-backup-manager/raw/branch/main/scripts/imports/manage_backup_schedule.sh - curl -O https://deploy-proxy.mightybox.io/addons/mb-backup-manager/raw/branch/main/scripts/imports/restore_backup_direct.sh - curl -O https://deploy-proxy.mightybox.io/addons/mb-backup-manager/raw/branch/main/scripts/imports/view_snapshots.sh + - curl -O https://deploy-proxy.mightybox.io/addons/mb-backup-manager/raw/branch/main/scripts/imports/check_backup_repo.sh + - curl -O https://deploy-proxy.mightybox.io/addons/mb-backup-manager/raw/branch/main/scripts/imports/check_repo_stats.sh - chmod +x /home/litespeed/mb-backups/*.sh - sudo chown -R litespeed:litespeed /home/litespeed/mb-backups \ No newline at end of file diff --git a/scripts/imports/check_backup_repo.sh b/scripts/imports/check_backup_repo.sh new file mode 100644 index 0000000..2d08e29 --- /dev/null +++ b/scripts/imports/check_backup_repo.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +# Exit on errors +set -e + +# Configuration +BACKUP_REPO_PATH="/mnt/backups" +PASSWORD_FILE="/etc/restic-password" +LOG_FILE="/var/log/backup_repo_check.log" + +# Ensure the log file exists +mkdir -p "$(dirname "$LOG_FILE")" + +# Logging function +log_message() { + echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" +} + +# Main function to check the backup repository +check_backup_repo() { + # Ensure the backup repository path exists + mkdir -p "$BACKUP_REPO_PATH" + + # Validate or create the password file + if [ ! -f "$PASSWORD_FILE" ]; then + log_message "Password file not found. Creating a new one with a default password." + echo "default-password" > "$PASSWORD_FILE" + fi + + # Export the password and repository path for Restic + export RESTIC_PASSWORD=$(cat "$PASSWORD_FILE") + export RESTIC_REPOSITORY="$BACKUP_REPO_PATH" + + # Check if the repository contains files + if [ "$(find "$BACKUP_REPO_PATH" -mindepth 1 | wc -l)" -gt 0 ]; then + log_message "Checking the backup repository integrity and consistency." + + # Remove stale locks if they exist + if [ -d "$BACKUP_REPO_PATH/locks" ] && [ "$(ls -A "$BACKUP_REPO_PATH/locks")" ]; then + log_message "Stale lock detected in the repository. Removing lock." + if ! restic -r "$BACKUP_REPO_PATH" unlock; then + log_message "Failed to remove stale lock. Exiting." + exit 1 + fi + fi + + # Perform repository integrity check + if ! restic -q -r "$BACKUP_REPO_PATH" check --read-data-subset=5%; then + log_message "Repository integrity check failed. Please investigate." + exit 1 + fi + log_message "Backup repository integrity check passed." + else + # Initialize a new Restic repository if empty + log_message "No files found in the backup repository. Initializing a new repository." + if ! restic init -r "$BACKUP_REPO_PATH"; then + log_message "Failed to initialize the backup repository. Exiting." + exit 1 + fi + log_message "Backup repository initialized successfully." + fi +} + +# Execute the function +check_backup_repo diff --git a/scripts/imports/check_repo_stats.sh b/scripts/imports/check_repo_stats.sh new file mode 100644 index 0000000..31c4ca6 --- /dev/null +++ b/scripts/imports/check_repo_stats.sh @@ -0,0 +1,109 @@ +#!/bin/bash + +# Exit on error +set -e + +# Configuration +BACKUP_REPO_PATH="/mnt/backups" +PASSWORD_FILE="/etc/restic-password" +LOG_DIR="/home/litespeed/logs" +LOG_FILE="${LOG_DIR}/repo_stats_$(date +'%Y-%m-%d').log" +RETENTION_POLICY="--keep-last 7 --prune" # Modify retention policy as needed + +# Ensure the log directory exists +mkdir -p "$LOG_DIR" + +# Logging function +log_message() { + echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" +} + +# Function: Validate dependencies +validate_dependencies() { + for cmd in restic; do + if ! command -v "$cmd" &>/dev/null; then + log_message "ERROR: Required command '$cmd' not found." + exit 1 + fi + done +} + +# Function: Validate repository access +validate_repository() { + if [ ! -f "$PASSWORD_FILE" ]; then + log_message "ERROR: Password file not found at $PASSWORD_FILE." + exit 1 + fi + export RESTIC_PASSWORD=$(cat "$PASSWORD_FILE") + export RESTIC_REPOSITORY="$BACKUP_REPO_PATH" + + if ! restic snapshots &>/dev/null; then + log_message "ERROR: Unable to access the Restic repository. Check password and repository path." + exit 1 + fi + log_message "Repository access validated." +} + +# Function: Check repository stats +check_repository_stats() { + log_message "Fetching repository stats..." + if restic stats --mode restore-size >> "$LOG_FILE" 2>&1; then + log_message "Repository stats fetched successfully." + else + log_message "ERROR: Failed to fetch repository stats." + exit 1 + fi +} + +# Function: Apply retention policy +apply_retention_policy() { + log_message "Applying retention policy: $RETENTION_POLICY" + if restic forget $RETENTION_POLICY >> "$LOG_FILE" 2>&1; then + log_message "Retention policy applied successfully. Unnecessary snapshots pruned." + else + log_message "ERROR: Failed to apply retention policy." + exit 1 + fi +} + +# Function: Check for stale locks +check_and_remove_stale_locks() { + log_message "Checking for stale locks in the repository..." + if [ -d "${BACKUP_REPO_PATH}/locks" ] && [ "$(ls -A "${BACKUP_REPO_PATH}/locks" 2>/dev/null)" ]; then + log_message "Stale locks detected. Removing locks..." + if restic unlock; then + log_message "Stale locks removed successfully." + else + log_message "ERROR: Failed to remove stale locks." + exit 1 + fi + else + log_message "No stale locks found." + fi +} + +# Function: Perform integrity check +perform_integrity_check() { + log_message "Performing repository integrity check..." + if restic check --read-data-subset=5% >> "$LOG_FILE" 2>&1; then + log_message "Repository integrity check passed." + else + log_message "ERROR: Repository integrity check failed." + exit 1 + fi +} + +# Main execution +main() { + log_message "Starting repository stats check and maintenance..." + validate_dependencies + validate_repository + check_and_remove_stale_locks + check_repository_stats + apply_retention_policy + perform_integrity_check + log_message "Repository stats check and maintenance completed successfully." +} + +# Execute main function +main