#!/bin/zsh # # backup.zsh # # Create a backup of all important things. # # Features: # - MySQL dump # - Create archives of: # - FTP root # - HTTP root # # Links: # - https://linuxize.com/post/how-to-back-up-and-restore-mysql-databases-with-mysqldump/ # - https://www.shkodenko.com/mysql-and-mysqldump-defaults-file-without-a-password/ # SCRIPT_NAME="$(basename $0)" SCRIPT_VERSION="0.20121214.2" SCRIPT_START=$(date +%s.%3N) BACKUP_FS="/mnt/backup" BACKUP_DEST="$BACKUP_FS/$(date +%Y-%m-%d)_${SCRIPT_NAME}" VERBOSE=0 RUN_CONTEXT="${RUN_CONTEXT:-shell}" # Script utility lib # Part of Git repo https://github.com/malte70/scripts source /home/malte70/bin/_base.inc.sh # Italic output for informative messages message_info() { _print_term $_ANSI_COLOR_GREEN _print "[${SCRIPT_NAME}] " _print_term $_ANSI_RESET _print_term $_ANSI_ATTR_ITALIC _println $@ _print_term $_ANSI_RESET } # Custom messages for crontab execution context if [[ $RUN_CONTEXT == "crontab" ]] then message() { _print "[${SCRIPT_NAME}] " _print "[$(date --rfc-3339=seconds)] " _print " " _println $@ } message_info() { _print "[${SCRIPT_NAME}] " _print "[$(date --rfc-3339=seconds)] " _print " " _println $@ } message_error() { _print "[${SCRIPT_NAME}] " _print "[$(date --rfc-3339=seconds)] " _print " " _println $@ } fi # Be verbose if running in crontab context, or the command line # switch was given #if [[ $1 == "--verbose" || $1 == "-V" || $RUN_CONTEXT == "crontab" ]] if [[ $1 == "--verbose" || $1 == "-V" ]] then VERBOSE=1 fi # Config file if [[ -f "$HOME/.backuprc" ]] then source "$HOME/.backuprc" fi # # Mount backup drive # if ! grep --silent ${BACKUP_FS} /proc/mounts then message "Mounting backup FS..." if [[ $UID -eq 0 ]]; then mount ${BACKUP_FS} else sudo mount ${BACKUP_FS} fi else message_info "Note: Backup FS already mounted." fi # # Create backup destination folder # message "Creating destination folder..." mkdir -p ${BACKUP_DEST} cd ${BACKUP_DEST} # # MySQL Backup # message "Dumping MySQL databases..." if [[ -z $MYSQL_USER || -z $MYSQL_PASSWORD ]]; then echo -n "MySQL User? " read MYSQL_USER echo -n "MySQL Password? " read -rs MYSQL_PASSWORD echo fi echo "[client] user=$MYSQL_USER password=$MYSQL_PASSWORD" >mysqldump.cnf mkdir -p MySQL for DB in $(mysql --defaults-file=mysqldump.cnf -e 'show databases' -s --skip-column-names); do case $DB in "information_schema"|"performance_schema") #"information_schema"|"performance_schema"|"mysql") continue ;; esac mysqldump --defaults-file=mysqldump.cnf $DB > "MySQL/$DB.sql"; done rm -f mysqldump.cnf # # Backup /srv/ftp # message "Archiving /srv/ftp..." _archive="${BACKUP_DEST}/srv-ftp.tar.bz2" pushd /srv >/dev/null if [[ $VERBOSE -eq 0 ]]; then sudo tar cjf "$_archive" ftp/ else sudo tar cjvf "$_archive" ftp/ fi if ! file -i "$_archive" | grep --silent "application/x-bzip2"; then message_error "Fail!" exit 1 fi popd >/dev/null # # Backup /srv/http # message "Archiving /srv/http..." _archive="${BACKUP_DEST}/srv-http.tar.bz2" pushd /srv >/dev/null if [[ $VERBOSE -eq 0 ]]; then sudo tar cjf "$_archive" http/ else sudo tar cjvf "$_archive" http/ fi if ! file -i "$_archive" | grep --silent "application/x-bzip2"; then message_error "Fail!" exit 1 fi popd >/dev/null # # Finished. # SCRIPT_END=$(date +%s.%3N) SCRIPT_RUNTIME=$(echo "scale=3;$SCRIPT_END-$SCRIPT_START" | bc) message "Done after ${SCRIPT_RUNTIME} seconds." message "Everything was stored in ${BACKUP_DEST}" # # Notify admin via Pushover # _backup_size=$(du -sh ${BACKUP_DEST} | awk '{print $1}') echo "${SCRIPT_NAME} finished after $(echo $SCRIPT_RUNTIME | cut -d. -f1) seconds. Backup location: $BACKUP_DEST Size: $_backup_size" | pushover-notify "${SCRIPT_NAME} successfull"