Update to version 1.6
Added logging, error handline, command line argument names, and command line help. Overall script cleanup.
This commit is contained in:
1 parent
5b15ba3125
commit
e79d26435b
1 file changed
+352
@@ -0,0 +1,352 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Script Name: AppBackup-restic.sh
|
||||
# Description:
|
||||
# Creates a backup of a web application and optionally its MySQL database.
|
||||
# The script archives the application home directory and uploads the backup
|
||||
# either to a remote SFTP server or to a Backblaze B2 repository using Restic,
|
||||
# depending on the host on which it is executed.
|
||||
#
|
||||
# Usage:
|
||||
# AppBackup-restic.sh --appname <name> --appuser <user> [--apppassword <password>]
|
||||
#
|
||||
# Author: Charlie Silverman
|
||||
# Version: 1.6
|
||||
#
|
||||
# Revision History:
|
||||
# 1.0 - Initial version.
|
||||
# 1.1 - Added logging to file.
|
||||
# 1.2 - Added strict error handling, input validation, and FQDN support.
|
||||
# 1.3 - Added trap-based error logging and improved operational visibility.
|
||||
# 1.4 - Added application-specific log files, interrupt handling,
|
||||
# and enhanced logging.
|
||||
# 1.5 - Added command-line help.
|
||||
# 1.6 - Replaced positional parameters with named command-line options
|
||||
# and added support for short/long option formats.
|
||||
#
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Help Function
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
show_help() {
|
||||
|
||||
cat << EOF
|
||||
|
||||
AppBackup-restic.sh v1.6
|
||||
|
||||
DESCRIPTION
|
||||
Creates a backup of a web application's files and optionally its
|
||||
MySQL database. The backup is uploaded either via SFTP or Restic,
|
||||
depending on the host.
|
||||
|
||||
USAGE
|
||||
|
||||
AppBackup-restic.sh --appname <name> --appuser <user> [--apppassword <password>]
|
||||
|
||||
OPTIONS
|
||||
|
||||
-a, --appname <name>
|
||||
Name of the application and MySQL database.
|
||||
Required.
|
||||
|
||||
-u, --appuser <user>
|
||||
Linux account that owns the application files.
|
||||
Required.
|
||||
|
||||
-p, --apppassword <password>
|
||||
MySQL password and SFTP password (if applicable).
|
||||
Optional.
|
||||
|
||||
-h, --help
|
||||
Display this help and exit.
|
||||
|
||||
EXAMPLES
|
||||
|
||||
AppBackup-restic.sh \
|
||||
--appname KISNetManager \
|
||||
--appuser kisuser \
|
||||
--apppassword MySecurePassword
|
||||
|
||||
AppBackup-restic.sh \
|
||||
-a CustomerPortal \
|
||||
-u portaluser
|
||||
|
||||
LOG FILE
|
||||
|
||||
/tmp/AppBackup-<ApplicationName>.log
|
||||
|
||||
AUTHOR
|
||||
|
||||
Charlie Silverman
|
||||
|
||||
VERSION
|
||||
|
||||
1.6
|
||||
|
||||
EOF
|
||||
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Process Command Line Arguments
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
AppName=""
|
||||
AppUser=""
|
||||
AppPassword=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
|
||||
case "$1" in
|
||||
|
||||
-a|--appname)
|
||||
AppName="$2"
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--appname=*)
|
||||
AppName="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
|
||||
-u|--appuser)
|
||||
AppUser="$2"
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--appuser=*)
|
||||
AppUser="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
|
||||
-p|--apppassword)
|
||||
AppPassword="$2"
|
||||
shift 2
|
||||
;;
|
||||
|
||||
--apppassword=*)
|
||||
AppPassword="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "ERROR: Unknown option '$1'"
|
||||
echo
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
done
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Validate Required Parameters
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
if [[ -z "$AppName" || -z "$AppUser" ]]; then
|
||||
echo "ERROR: --appname and --appuser are required."
|
||||
echo
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Runtime Variables
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
DATE=$(date "+%Y%m%d_%H%M%S")
|
||||
HOSTNAME_FQDN="$(hostname -f)"
|
||||
|
||||
SAFE_APPNAME=$(echo "$AppName" | tr -cs '[:alnum:]_-' '_')
|
||||
|
||||
LOGFILE="/tmp/AppBackup-${SAFE_APPNAME}.log"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Logging Function
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
log() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') [$$] $1" | tee -a "$LOGFILE"
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Error Handling
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
error_handler() {
|
||||
|
||||
local exit_code=$?
|
||||
local line_number=$1
|
||||
|
||||
log "ERROR: Backup failed on line ${line_number} with exit code ${exit_code}"
|
||||
|
||||
exit "${exit_code}"
|
||||
}
|
||||
|
||||
interrupt_handler() {
|
||||
|
||||
log "ERROR: Backup interrupted by signal"
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
trap 'error_handler $LINENO' ERR
|
||||
trap interrupt_handler SIGINT SIGTERM
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Startup Logging
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
log "================================================================="
|
||||
log "Starting backup job"
|
||||
log "Application: $AppName"
|
||||
log "Application User: $AppUser"
|
||||
log "Host: $HOSTNAME_FQDN"
|
||||
log "Log File: $LOGFILE"
|
||||
log "================================================================="
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Restic Repository Configuration
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
export RESTIC_REPOSITORY="s3:https://s3.us-west-004.backblazeb2.com/ackitsbucket/docker"
|
||||
export RESTIC_PASSWORD_FILE="/root/.restic-password"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Host Specific Configuration
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
HostPrefix=""
|
||||
|
||||
if [[ "$HOSTNAME_FQDN" == "ackitserver.ackcentuate.com" ]]; then
|
||||
|
||||
if [[ "$AppName" == "KISNetManager" ]]; then
|
||||
HostPrefix="dev-"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
ArchiveFile="${AppName}-${DATE}.tar.bz2"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Prepare Backup Workspace
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
log "Changing to backup directory"
|
||||
|
||||
cd /home/Backups
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Database Backup
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
if [[ -n "$AppPassword" ]]; then
|
||||
|
||||
log "Creating MySQL database backup"
|
||||
|
||||
mkdir -p "/home/${AppUser}/SQLBackup"
|
||||
|
||||
mysqldump \
|
||||
-u "$AppUser" \
|
||||
--password="$AppPassword" \
|
||||
"$AppName" \
|
||||
> "/home/${AppUser}/SQLBackup/${AppName}.sqldump"
|
||||
|
||||
log "MySQL dump completed successfully"
|
||||
|
||||
else
|
||||
|
||||
log "Database password not supplied. Skipping MySQL backup."
|
||||
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Remove Previous Backup Archives
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
log "Removing previous backup archives"
|
||||
|
||||
rm -f /home/Backups/"${AppName}"*.tar.bz*
|
||||
rm -f /home/Backups/"${HostPrefix}${AppName}"*.tar.bz*
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Create Archive
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
log "Creating archive ${HostPrefix}${ArchiveFile}"
|
||||
|
||||
tar cjf \
|
||||
"/home/Backups/${HostPrefix}${ArchiveFile}" \
|
||||
"/home/${AppUser}/"
|
||||
|
||||
log "Archive created successfully"
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Upload Backup
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
if [[ "$HOSTNAME_FQDN" != "ackitserver.ackcentuate.com" ]]; then
|
||||
|
||||
if [[ -z "$AppPassword" ]]; then
|
||||
log "ERROR: SFTP upload requires --apppassword"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "Uploading archive via SFTP"
|
||||
|
||||
lftp "sftp://${AppUser}:${AppPassword}@webbuilder.ackcentuate.com" -e \
|
||||
"cd /home/Backups; put /home/Backups/${HostPrefix}${ArchiveFile}; bye"
|
||||
|
||||
log "SFTP upload completed successfully"
|
||||
|
||||
else
|
||||
|
||||
log "Loading Restic environment"
|
||||
|
||||
source /root/.restic-env
|
||||
|
||||
log "Starting Restic backup"
|
||||
|
||||
restic backup "/home/${AppUser}/" \
|
||||
--tag apache \
|
||||
--tag website \
|
||||
--tag "$AppName" \
|
||||
--tag "$HOSTNAME_FQDN" \
|
||||
>> "$LOGFILE" 2>&1
|
||||
|
||||
log "Restic backup completed successfully"
|
||||
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
if [[ -n "$AppPassword" ]]; then
|
||||
|
||||
log "Removing temporary SQL backup files"
|
||||
|
||||
rm -rf "/home/${AppUser}/SQLBackup"
|
||||
|
||||
fi
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Completion
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
log "Backup completed successfully"
|
||||
log "Application: $AppName"
|
||||
log "Archive: ${HostPrefix}${ArchiveFile}"
|
||||
log "Host: $HOSTNAME_FQDN"
|
||||
log "================================================================="
|
||||
Reference in new issue
Block a user