#!/usr/bin/env bash NO_NEW_BACKUP=${NO_NEW_BACKUP:=false} manual=${manual:=false} #if [[ $MANUAL != false && $MANUAL != true ]]; then # echo -e "\n[ Error ]: Usage: `basename $0` [true|false]\n" # exit 2 #fi ## - if you plan to run the backup scripts as a cronjob, ## - you have to set this variable manually ## - USER=$LOGNAME DEFAULT_SSH_KEY="/root/.ssh/id_ed25519-backup" ## - global configuration for the remote backup-script ## - rcopy_base_dir="$(realpath $(dirname $0))" rcopy_conf_file="$rcopy_base_dir/conf/rcopy.conf" rcopy_functions_file=$rcopy_base_dir/conf/rcopy_functions.conf ## - location of the logfile ## - logFile="/var/log/rcopy.log" disk_label_log_file="/var/log/backup_disk-label.log" ## - Note: the file "/var/lib/logrotate/status" must have ## - write permissions for the script-user ## - if [[ -f "$rcopy_base_dir/conf/logrotate.conf" ]]; then logrotate_conf_file="$rcopy_base_dir/conf/logrotate.conf" elif [[ -f "$rcopy_base_dir/conf/logrotate.conf.sample" ]]; then logrotate_conf_file="$rcopy_base_dir/conf/logrotate.conf.sample" else logrotate_conf_file="" fi [ -f $rcopy_functions_file ] || exit 1 . $rcopy_functions_file ## - load configuration ## - [ -f $rcopy_conf_file ] || exit 1 . $rcopy_conf_file NO_NEW_BACKUP=false ONLY_BACKUP=false MANUAL=false while getopts Bhk:Nm opt ; do case $opt in B) ONLY_BACKUP=true ;; k) SSH_KEY=$OPTARG ;; m) MANUAL=true ;; N) NO_NEW_BACKUP=true ;; h) usage ;; \?) usage ;; esac done if [[ -z "${SSH_KEY}" ]] ; then SSH_KEY="${DEFAULT_SSH_KEY}" fi if $ONLY_BACKUP && $NO_NEW_BACKUP ; then fatal "Parameter '-B' AND '-N' is not possible." fi # - Be compartible with older configuration files # - if [ "X$remote_disk" = "X" ] ; then remote_disk=false fi if [ "X$check_mountpoint" = "X" ] ; then check_mountpoint=false fi # ---------- # - Read commandline parameter # ---------- if $MANUAL ; then ## - this is for manual start, we don't want inform anyone and ## - also don't restart any service ## - send_reminder=false restart_samba_service=false manual_hosts_file="${rcopy_base_dir}/conf/manual_hosts.conf" fi if $NO_NEW_BACKUP ; then ## - Note: the file "/var/lib/logrotate/status" must have ## - write permissions for the script-user ## - if [[ -f "$rcopy_base_dir/conf/logrotate_handle-backups.conf" ]]; then logrotate_conf_file="$rcopy_base_dir/conf/logrotate_handle-backups.conf" elif [[ -f "$rcopy_base_dir/conf/logrotate_handle-backups.conf.sample" ]]; then logrotate_conf_file="$rcopy_base_dir/conf/logrotate_handle-backups.conf.sample" else logrotate_conf_file="" fi logFile="/var/log/rcopy-handle_backups.log" fi export logFile disk_label_log_file ONLY_BACKUP NO_NEW_BACKUP rcopy_base_dir rcopy_conf_file rcopy_functions_file ## - if backup job already runs, stop execution.. ## - if mkdir "$LOCK_DIR" 2> /dev/null ; then ## - Remove lockdir when the script finishes, or when it receives a signal trap 'rm -rf "$LOCK_DIR"' 0 2 15 else msg="[ Error ]: A previos instance of the backup script seems already be running.\n\tExiting now.." if $MANUAL ; then echo -e "\n$msg\n" else datum="$(date +"%d.%m.%Y")" subject="Backup Errors $company -- $datum" subject_utf8="$(echo "$subject" | iconv -t UTF8)" subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" echo -e "To:${admin_email}\n${content_type}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors BACKUP $company" -f $from_address $admin_email fi echo "" echo "[ Error ]: A previos instance of the backup script seems already be running." echo "" echo -e "\tExiting now.." echo "" exit 1 fi if $check_mountpoint ; then if [[ ! -d $backup_mountpoint ]];then msg00="[ Error ]: Mountpoint \"$backup_mountpoint\" for Backup Partion \"$backup_partition\" not found.\n" msg01=" exiting now.." msg="${msg00}\n${msg01}" if $MANUAL ; then echo -e "\n$msg\n" else datum="$(date +"%d.%m.%Y")" subject="Backup Errors $company -- $datum" subject_utf8="$(echo "$subject" | iconv -t UTF8)" subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" echo -e "To:${admin_email}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors BACKUP $company" -f $from_address $admin_email fi exit 1 fi fi if $extern_usb_disk || $extern_sata_disk || $intern_disk ; then ## - Backup Device mounted ? ## - if ! df | grep "$backup_partition" > /dev/null 2>&1 ;then if $crypto_backup_device ;then $cryptsetup --key-file $crypto_key_file luksOpen $backup_raw_partition $backup_partition_name > /dev/null 2>&1 fi mount $mount_flags $backup_partition $backup_mountpoint > /dev/null 2>&1 sleep 5 elif ! $(df -h | grep $backup_partition | grep -q $backup_mountpoint 2> /dev/null) ; then msg="[ Warning ]: Backup Partition '${backup_partition}' is mounted, but mount point differs from script defined one ($backup_mountpoint)." msg="$msg\n Try to unmount partitionn and mount it again.." if $MANUAL ; then echo -e "\n$msg\n" fi echolog "\n[ Warning ]: Backup Partition \033[1m${backup_partition}\033[mis mounted, but mount point differs from script defined one which is '$backup_mountpoint'.\n\n Try to unmount partition and mount it again.." $umount $backup_partition > /dev/null 2>&1 sleep 5 mount $mount_flags $backup_partition $backup_mountpoint > /dev/null 2>&1 sleep 5 fi elif $remote_disk ; then if ! df | grep "$backup_mountpoint" > /dev/null 2>&1 ;then mount "$backup_mountpoint" > /dev/null 2>&1 sleep 5 fi fi # Check if Backup device is correctly mounted # if $extern_usb_disk || $extern_sata_disk || $intern_disk ; then if ! df | grep "$backup_partition" > /dev/null 2>&1 ;then msg="[ Error ]: Cannot mount Backup Partion \"$backup_partition\". exiting now.." if $MANUAL ; then echo -e "\n$msg\n" else datum="$(date +"%d.%m.%Y")" subject="Backup Errors $company -- $datum" subject_utf8="$(echo "$subject" | iconv -t UTF8)" subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" echo -e "To:${admin_email}\n${content_type}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors BACKUP $company" -f $from_address $admin_email fi exit 1 elif ! $(df -h | grep $backup_partition | grep -q $backup_mountpoint 2> /dev/null) ; then msg="[ Error ]: Backup Partition '${backup_partition}' is mounted, but mount point differs from script defined one ($backup_mountpoint)." if $MANUAL ; then echo -e "\n$msg\n" else datum="$(date +"%d.%m.%Y")" subject="Backup Errors $company -- $datum" subject_utf8="$(echo "$subject" | iconv -t UTF8)" subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" echo -e "To:${admin_email}\n${content_type}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors BACKUP $company" -f $from_address $admin_email fi exit 1 fi elif $remote_disk ; then if ! df | grep "$backup_mountpoint" > /dev/null 2>&1 ;then msg="[ Error ]: Mounting remote disk to '$backup_mountpoint' failed. exiting now.." if $MANUAL ; then echo -e "\n$msg\n" else datum="$(date +"%d.%m.%Y")" subject="Backup Errors $company -- $datum" subject_utf8="$(echo "$subject" | iconv -t UTF8)" subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" echo -e "To:${admin_email}\n${content_type}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors BACKUP $company" -f $from_address $admin_email fi exit 1 fi fi # --- # SSH agent stuff ## -- # Kill remaining ssh-agent processes if exists # if $(ps -U ${USER} -u ${USER} | ${grep} -q ssh-agent 2> /dev/null) ; then killall ssh-agent > /dev/null 2> /dev/null unset SSH_AGENT_PID fi # Run SSH-Agent as background process.. # eval $(ssh-agent 2> /dev/null | tee ${AGENT}) > /dev/null # Load the SSH private key into ssh agent # ssh-add -q ${SSH_KEY} 2> /dev/null # Check if ssh key was loaded # if ! $(ps -U ${USER} -u ${USER} | $grep "$SSH_AGENT_PID" | $grep -q ssh-agent 2> /dev/null) ; then msg_00="\n[ Error ]: No Prozess for ssh-agent with Process ID \"$SSH_AGENT_PID\" found !!" msg_01="\t =======================" msg_02="\t !! BACKUP INTERUPTED !!" msg_03="As user \"$USER\" do:\n\tssh-agent > $AGENT; . $AGENT; ssh-add" msg="${msg_00}\n\n${msg_01}\n${msg_02}\n${msg_01}\n\n${msg_03}" if $MANUAL ; then echo -e "$msg\n" else datum="$(date +"%d.%m.%Y")" subject="Backup Errors $company -- $datum" subject_utf8="$(echo "$subject" | iconv -t UTF8)" subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" echo -e "To:${admin_email}\n${content_type}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors BACKUP $company" -f $from_address $admin_email fi exit 1 fi /usr/bin/ssh-add -l > /dev/null 2>&1 if [ ! $? -eq 0 ]; then msg_00="\n[ Error ]: No Keys associated with ssh-agent !!" msg_01="\t =======================" msg_02="\t !! BACKUP INTERUPTED !!" msg_03="As user \"$USER\" do:\n\tssh-agent > $AGENT; . $AGENT; ssh-add" msg="${msg_00}\n\n${msg_01}\n${msg_02}\n${msg_01}\n\n${msg_03}" if $MANUAL ; then echo -e "\n$msg\n" else datum="$(date +"%d.%m.%Y")" subject="Backup Errors $company -- $datum" subject_utf8="$(echo "$subject" | iconv -t UTF8)" subject_utf8_encoded="=?utf-8?B?$(echo $subject_utf8 | base64 --wrap=0)?=" echo -e "To:${admin_email}\n${content_type}\nSubject:${subject_utf8_encoded}\n${msg}\n" | /usr/sbin/sendmail -F "Errors BACKUP $company" -f $from_address $admin_email fi exit 1 fi ## - searching hosts for backup ## - host_scripts="" if $MANUAL ; then if [[ -f "$manual_hosts_file" ]] ; then source "$manual_hosts_file" for script in $hosts ; do host_scripts="$host_scripts ${hosts_base_dir}/${script}.sh" done else host_scripts="${hosts_base_dir}/localhost.sh" fi else host_scripts=`$find $hosts_base_dir -maxdepth 1 -type f -perm -700 | $sort` fi found=true if [ "X$host_scripts" == "X" ]; then found=false echo "[Warning]: no hosts for backup found" echolog "\n[Warning]: no hosts for backup found\n" fi if $found ; then root_begin_h=`date +%H` root_begin_m=`date +%M` root_backup_date=`date +"%d.%m.%Y"` root_begin_timestamp=`date +"%s"` echolog "\nbegin backup \"$company\" : $root_backup_date ( ${root_begin_h}:${root_begin_m} h )\n" ## - only for output into logfile ## - echolog "\nfound host scripts:\n" for host_script in $host_scripts ; do host_script=`$basename $host_script` echolog "\t$host_script" done; ## - for each host exec a script.. ## - for script in $host_scripts ; do #host=`$basename $script | $cut -d. -f1` host=`$basename $script | sed -e "s/\.sh$//g"` $script done root_end_h=`$date +%H` root_end_m=`$date +%M` root_backup_date=`$date +"%d.%m.%Y"` root_end_timestamp=`date +"%s"` root_time=`expr $root_end_timestamp - $root_begin_timestamp` root_h=`expr $root_time / 60 / 60` rest_h=`expr $root_time - $root_h \\* 60 \\* 60` root_m=`expr $rest_h / 60` root_s=`expr $rest_h - $root_m \\* 60` if [ $root_m -lt 10 ] ;then root_m="0$root_m" fi if [ $root_s -lt 10 ] ;then root_s="0$root_s" fi ## - write backup info to ## - if $extern_usb_disk || $extern_sata_disk ; then label="$(tune2fs -l $backup_partition | grep -e "Filesystem volume name:" | awk '{print$4}')" elif $remote_disk ; then label="$backup_resource" elif $intern_disk ; then label="$backup_partition" else label="$backup_base_dir" fi echo >> $info_file echo -e "\tBackup Host...............: $BACKUP_HOST" >> $info_file echo -e "\tBackup Date...............: `/bin/date +'%d.%m.%Y'`" >> $info_file echo -e "\tBackup Time...............: `/bin/date +'%H:%M'` h" >> $info_file echo >> $info_file echo -e "\tBackup resource / Label...: $label" >> $info_file echo >> $info_file #echo -e "\tBackup Size.........: `du -sm $backup_base_dir | awk '{print$1}' ` MB" >> $info_file echo >> $info_file ## - save current backup_disk_label ## - echo "$label" > $disk_label_log_file if cp $info_file $backup_base_dir > /dev/null ; then echolog "write backup info to $backup_base_dir/`basename $info_file` .. [ ok ] \n" else echolog "[Error]: write backup info to $backup_base_dir/`basename $info_file` ..[ failed ]\n" fi rm -f $info_file echolog "\nend backup \"$company\" : $root_backup_date ( ${root_end_h}:${root_end_m} h ) - duration: ${root_h} h : ${root_m} min : ${root_s} sec\n\n" if $restart_samba_service ; then echolog "\n\n[`date`] stoping samba service ..." $samba_init_script stop > /dev/null sleep 5 PIDS="" PIDS=`ps aux | grep "$samba_exe" | grep -v grep | awk '{print$2}'` while [ "X${PIDS}X" != "XX" ]; do for pid in $PIDS ; do kill -9 $pid > /dev/null 2>&1 done done echolog "[`date`] starting samba service ..." $samba_init_script start > /dev/null sleep 2 NEW_PIDS=`ps aux | grep "$samba_exe" | grep -v grep | awk '{print$2}'` if [ "X${NEW_PIDS}X" == "XX" ]; then echolog "" echolog "\t[Error]: Restarting samba services failed !!" echo -e "\n\t[Error]: Restarting samba services failed !!\n" echolog "" else PIDS="" for pid in $NEW_PIDS ; do PIDS="$PIDS $pid" done echolog echolog "\tI have restarted teh samba services. The new PIDs are $PIDS" echolog fi fi [ -x $logrotate ] || exit 2 [ -f $logrotate_conf_file ] || exit 3 #export backup_partition logDuration logFile admin_email from_address company export label $logrotate $logrotate_conf_file rm -f $logDuration fi retval=2 if $extern_usb_disk || $extern_sata_disk ; then #$sync #sleep 10 $umount $backup_partition 2> /dev/null retval=$? sleep 2 if [ "$retval" != "0" ] ;then echo -e "\n[ERROR] something went wrong with unmounting $backup_partition..\n" else if ! df | grep "$backup_partition" > /dev/null 2>&1 ;then declare -i mount_count=`$tune2fs -l $backup_partition | $grep "Mount count" | $cut -d ":" -f 2` declare -i max_mount_count=`$tune2fs -l $backup_partition | $grep "Maximum mount count" | $cut -d ":" -f 2` if [ $mount_count -ge $max_mount_count ]; then echo -e "Check partition '${backup_partition}' - Run: $e2fsck -p $backup_partition .." $e2fsck -p $backup_partition if [ $? -gt 0 ]; then echo -e "\n[ERROR] filecheck on $backup_partition failed.." else echo "" echo -e "Check agaim in order to optimize - Run: $e2fsck -fy $backup_partition .." $e2fsck -fy $backup_partition fi $tune2fs -C 0 $backup_partition fi fi fi elif $remote_disk || $intern_disk ; then $umount $backup_mountpoint 2> /dev/null fi if $send_reminder ; then if [ "$retval" = "0" -a "`date +%A`" = "$reminder_day" ] ; then datum=`date +"%d.%m.%Y"` label=`tune2fs -l $backup_partition | grep -e "Filesystem volume name:" | awk '{print$4}'` msg_00="Don't reply on this mail - its autogenerated !!" msg_01="\t ==========================" msg_02="\t Please change backup disk " msg_03="Current Disk Label: $label " msg="${msg_00}\n\n${msg_01}\n${msg_02}\n${msg_01}\n\n${msg_03}\n" echo -e "To:${reminder_email}\nSubject:Reminder - please change backup-disk\n${msg}\n" | /usr/sbin/sendmail -F "BACKUP $company" -f $from_address $reminder_email echo -e "To:${admin_email}\nSubject:Reminder - please change backup-disk\n${msg}\n" | /usr/sbin/sendmail -F "BACKUP $company" -f $from_address $admin_email if [ "X$reminder_email_2" != "X" ]; then echo -e "To:${reminder_email}\nSubject:Reminder - please change backup-disk\n${msg}\n" | /usr/sbin/sendmail -F "BACKUP $company" -f $from_address $reminder_email_2 fi fi fi if $crypto_backup_device ;then $cryptsetup luksClose $backup_partition_name fi