#!/bin/bash ###################################################################################### # The goal of this script is to permit to do backups, restaurations, to list and # # delete the backups. The script facilitates the use of the repozo.py script given # # with Zope. # # Author: Francois Birot # ###################################################################################### ####################################################################################### # INFORMATION # ####################################################################################### PYTHON_BIN="/zope/bin/python" PYTHON_DIRECTORY="/zope/lib/python" REPOZO_SCRIPT="/zope/bin/repozo.py" ZOPE_DATABASE="/zope/production/server/var/Data.fs" PRODUCTS_DIRECTORY="/zope/production/server/Products" BACKUP_DIRECTORY="/zope/backups" ZOPE_USER="zope" UTC=-4 # The local time is UTC -04:00 ####################################################################################### # DEFAULT OPTIONS # ####################################################################################### VERBOSE="false" # Don't display anything MOVE_CURRENT_DATAFS="false" # Don't backup the current Data.fs before restoring ####################################################################################### # This function checks if the verbose mode is activated and prints the first # # parameter given to the function # ####################################################################################### function print_message() { if [[ $VERBOSE == "yes" ]]; then echo "--> $1" fi } ####################################################################################### # This function maintains a list of parameters to give to the repozo.py script # ####################################################################################### function add_option() { if [[ -z "$OPTIONS" ]]; then OPTIONS="-$1" else OPTIONS=$OPTIONS" -$1" fi } ####################################################################################### # This function permits to delete a backup. It requires the basename of the backup as # # the first parameter # ####################################################################################### function delete_backup() { # If the backup exists, remove it if [[ -f $BACKUP_DIRECTORY/$1 ]]; then print_message "Removing $BACKUP_DIRECTORY/$1" rm $BACKUP_DIRECTORY/$1 # If $1 equals "filename.ext", dat_file will be equals to "filename.dat" dat_file=${1/${1##*.}/dat} # If the dat file corresponding to the backup exists, remove it if [[ -f $BACKUP_DIRECTORY/$dat_file ]]; then print_message "Removing $BACKUP_DIRECTORY/$dat_file" rm $BACKUP_DIRECTORY/$dat_file fi else print_message "The backup $1 doesn't exist" fi } ####################################################################################### # This function permit to display a size of a file in GB, MB, KB or B depending of it # # The function requires one argument: the size to format and display # ####################################################################################### function echo_size() { SCALE=2 # Number of figures after the point if [[ $1 -gt $((1024*1024*1024)) ]]; then # If the size is greater than a GigaByte SIZE_UNIT="GB" SIZE=`echo "scale=$SCALE; $1/$((1024*1024*1024))" | bc -l` elif [[ $1 -gt $((1024*1024)) ]]; then # If the size is greater than a MegaByte SIZE_UNIT="MB" SIZE=`echo "scale=$SCALE; $1/$((1024*1024))" | bc -l` elif [[ $1 -gt $((1024)) ]]; then # If the size is greater than a KiloByte SIZE_UNIT="KB" SIZE=`echo "scale=$SCALE; $1/$((1024))" | bc -l` else # If the size is lower than a KiloByte SIZE_UNIT="B" fi echo -n $SIZE $SIZE_UNIT } ####################################################################################### # This function permits to display the date parsing the name of the backup # ####################################################################################### function echo_date_from_name() { tab[1]="Jan" tab[2]="Feb" tab[3]="Mar" tab[4]="Apr" tab[5]="May" tab[6]="Jun" tab[7]="Jul" tab[8]="Aug" tab[9]="Sep" tab[10]="Oct" tab[11]="Nov" tab[12]="Dec" YEAR=`echo $1 | cut -d '-' -f 1` MONTH=`echo $1 | cut -d '-' -f 2` DAY=`echo $1 | cut -d '-' -f 3` HOUR=`echo $1 | cut -d '-' -f 4` HOUR=$(((24+HOUR+UTC)%24)) MIN=`echo $1 | cut -d '-' -f 5` echo -n ${tab[$MONTH]} $DAY $YEAR $HOUR:$MIN } ####################################################################################### # This functions lists the backups found in $BACKUP_DIRECTORY # ####################################################################################### function list_backups() { i=1 for DATABASE_FILE in `find $BACKUP_DIRECTORY -name "*.fs" -o -name "*.fsz" -o -name "*.deltafs" -o -name "*.deltafsz" | sort -rM`; do SIZE=$(stat -c "%s" $DATABASE_FILE) NAME=`basename $DATABASE_FILE` echo -ne "\t$i) " echo_date_from_name $NAME echo -n " " echo_size $SIZE echo -n " ($NAME : " if [[ ${NAME##*.} == "deltafs" || ${NAME##*.} == "deltafsz" ]]; then echo "INCREMENTAL)" else echo "FULL)" fi ((i++)) done } ####################################################################################### # This function displays some help about how to use the backup script # ####################################################################################### function echo_help() { echo "" echo -e "\t***Zope Backup Script***" echo "" echo -e "\tParameters:" echo -e "\t[-h] \tDisplays this help" echo -e "\t[-F] \tDoes a full backup" echo -e "\t[-I] \tDoes an incremental backup if an old backup is found, else it does a full backup." echo -e "\t[-D ] \tDelete a specific backup file (Don't give the path, only the filename)" echo -e "\t[-R ] \tRestores a specific backup file (Don't give the path, only the filename)" echo -e "\t[-m] \tBackup the current Data.fs before restoring (the parameter -R has to be specified)" echo -e "\t[-l] \tLists the backup files" echo -e "\t[-z] \tCompress with gzip the backup files" echo -e "\t[-v] \tVerbose mode" } ####################################################################################### # BEGINING OF THE SCRIPT # ####################################################################################### # The repozo.py needs the PYTHONPATH environment variable to be set export PYTHONPATH=$PYTHON_DIRECTORY # The action variable can be changed depending of the parameters, to "backup", "suppression" or "restoration" ACTION="nothing" while getopts ":hlvzmFIR:D:" PARAM; do case $PARAM in h) echo_help exit 0 ;; l) list_backups exit 0 ;; F) ACTION="backup" INCREMENTAL_BACKUP="false" ;; I) ACTION="backup" INCREMENTAL_BACKUP="true" ;; R) ACTION="restauration" BACKUP_FILE=$OPTARG ;; D) ACTION="suppression" BACKUP_FILE=$OPTARG ;; m) MOVE_CURRENT_DATAFS="yes" ;; v) VERBOSE="yes" add_option "v" ;; z) add_option "z" ;; *) echo "Try '$0 -h' to get help" exit 1 ;; esac done && shift $(($OPTIND - 1)) if [[ $ACTION == "nothing" ]]; then echo_help exit 1 fi if [[ $ACTION == "backup" ]]; then if [[ -z $INCREMENTAL_BACKUP ]]; then echo "You have to specify the type of backup to do (full or incremental)" exit 1 elif [[ $INCREMENTAL_BACKUP == "false" ]]; then add_option "F" fi # We do the backup using the repozo.py script print_message "Backing up $ZOPE_DATABASE" $PYTHON_BIN $REPOZO_SCRIPT $OPTIONS -B -r $BACKUP_DIRECTORY -f $ZOPE_DATABASE elif [[ $ACTION == "restauration" ]]; then # If there is an actual Data.fs and the "-m" parameter is specified, we backup the current Data.fs if [[ -f $ZOPE_DATABASE && $MOVE_CURRENT_DATAFS == "yes" ]]; then DATE_FORMATED=`date --utc '+%Y-%m-%d-%H-%M-%S'` FS_FILE=$BACKUP_DIRECTORY/$DATE_FORMATED.fs DAT_FILE=$BACKUP_DIRECTORY/$DATE_FORMATED.dat # We move the actual Data.fs to the backup directory print_message "Moving $ZOPE_DATABASE to $FS_FILE" mv $ZOPE_DATABASE $FS_FILE # We now create the .dat file in order that repozo.py can use this Data.fs later, as a real backup print_message "Calculating the MD5 sum of $FS_FILE" echo -n "$FS_FILE 0 `ls -l $FS_FILE | cut -d ' ' -f 5`" > $DAT_FILE echo " `md5sum $FS_FILE | cut -d ' ' -f 1`" >> $DAT_FILE fi # We now retore the backup file print_message "Restoring $BACKUP_DIRECTORY/$BACKUP_FILE" $PYTHON_BIN $REPOZO_SCRIPT $OPTIONS -R -D $BACKUP_FILE -r $BACKUP_DIRECTORY -o $ZOPE_DATABASE # We set $ZOPE_USER as the owner and the group of the Data.fs print_message "Changing the permissions of $ZOPE_DATABASE" chown $ZOPE_USER:$ZOPE_USER $ZOPE_DATABASE elif [[ $ACTION == "suppression" ]]; then delete_backup $BACKUP_FILE fi