#!/bin/bash # ver. 20220413_01 source /etc/icewarp/icewarp.conf if testconfigpath="$(head -1 /opt/icewarp/path.dat 2>/dev/null)"; then iwconfigpath="$(echo ${testconfigpath} | tr -d '\r')"; else iwconfigpath="${IWS_INSTALL_DIR}/config"; fi if [[ -z "${iwconfigpath}" ]]; then iwconfigpath="/opt/icewarp/config/"; fi maildirpath="$(${IWS_INSTALL_DIR}/tool.sh get system C_System_Storage_Dir_MailPath | grep -P '(?<=: ).*(?=/mail/)' -o)" backuppath="${maildirpath}/backup" scriptdir="$(cd $(dirname $0) && pwd)" mkdir -p ${maildirpath} mkdir -p ${backuppath} mkdir -p ${scriptdir}/logs #dbport=4008; backupsrvhost="${1}" # if we take backups from another host backupsrvport="${2}" # than the one in IW connection strings cloudplan=$(${IWS_INSTALL_DIR}/tool.sh get system c_license_xml | grep -P '(?<=).*(?=)' -o -m 1) logdate="$(date +%Y%m%d)" logfile="${scriptdir}/logs/bck_${logdate}.log" retention_days=30; retention_log_days=30; extraMysqlOpts="--no-tablespaces --single-transaction"; function log() { echo $(date +%H:%M:%S) $1 >> ${logfile} } function die_error() # ( die with error, log failure to /opt/icewarp/var/iwbackup.mon ) { echo "FAIL" > /opt/icewarp/var/iwbackupstatus.mon exit 1 } function preflight_check() # ( check src/dst paths,src database connection, cloudplan, util test ) { # check src storage fstabtest=$(/usr/bin/cat /etc/fstab | grep -o "${maildirpath}") mounttest=$(/usr/bin/mount | grep -o "${maildirpath}" | tail -1) if [[ "$maildirpath" == "$fstabtest" ]] then log "Storage is a mountpoint - checking." if [[ "$maildirpath" != "$mounttest" ]] then log "Storage not mounted. Aborting." die_error; else log "Storage mountcheck ok." fi else log "Storage is not a mountpoint - continuing." fi # check dst storage sizeK=$(df -k "${backuppath}" | tail -1 | awk '{print $4}'); sizeM=$(( $sizeK / 1024 )); if [[ $sizeM -le 2048 ]]; then log "Insufficient space on the backup target path: ${sizeM} MB left on ${backuppath}"; die_error; else log "Backup destination OK"; fi # check cloud plan #if [ -z "$cloudplan" ] || [ "$cloudplan" != "cloud" ] #then # log "Aborting - not Cloud licence." # die_error; #fi # util test utiltest="$(/usr/bin/find /usr/lib64 -type f -name "Entities.pm")" if [[ -z "${utiltest}" ]] then log "Installing Entities.pm" /usr/bin/yum -y install epel-release /usr/bin/yum -y install perl-HTML-Encoding.noarch fi } function discover_dbnames() # ( 1: dbtype -> dbname ) { case ${1} in acc) local accdbname="$(${IWS_INSTALL_DIR}/tool.sh get system c_system_storage_accounts_odbcconnstring | perl -pe 's|^c_system_storage_accounts_odbcconnstring: (.*);(.*);.*;.*;.*;.*$|\1|')"; echo "${accdbname}" ;; asp) local aspdbname="$(${IWS_INSTALL_DIR}/tool.sh get system c_as_challenge_connectionstring | egrep -v '^mysql:' | perl -pe 's|^c_as_challenge_connectionstring: (.*);.*;.*;.*;.*;.*$|\1|')"; echo "${aspdbname}" ;; grw) local grwdbname="$(${IWS_INSTALL_DIR}/tool.sh get system c_gw_connectionstring | perl -pe 's|^c_gw_connectionstring: (.*);(.*);.*;.*;.*;.*$|\1|')"; echo "${grwdbname}" ;; dc) local dcdbname="$(${IWS_INSTALL_DIR}/tool.sh get system c_accounts_global_accounts_directorycacheconnectionstring | perl -pe 's|^c_accounts_global_accounts_directorycacheconnectionstring: (.*);(.*);.*;.*;.*;.*$|\1|')"; echo "${dcdbname}" ;; eas) local easdbname="$(${IWS_INSTALL_DIR}/tool.sh get system c_activesync_dbconnection | ${IWS_INSTALL_DIR}/tool.sh get system c_activesync_dbconnection | egrep -o "mysql:host=.*;dbname=.*" | perl -pe 's|^mysql:host=.*;port=.*;dbname=(.*)$|\1|')"; echo "${easdbname}" ;; wc) local wcdbname="$(cat ${iwconfigpath}/_webmail/server.xml | egrep -o "mysql:host=.*;port=.*;dbname=.*" | perl -pe 's|^\mysql:host=(.*);port=(.*);dbname=(.*)\$|\3|')"; echo "${wcdbname}" esac } function discover_creds() # ( -> username password ) { local dbuser="$(/usr/bin/cat ${iwconfigpath}/_webmail/server.xml | egrep -o ".*" | perl -pe 's|^\(.*)\$|\1|')"; local dbpass="$(/usr/bin/cat ${iwconfigpath}/_webmail/server.xml | cat ${iwconfigpath}/_webmail/server.xml | egrep -o ".*" | perl -pe 's|^\(.*)\$|\1|' | perl -MHTML::Entities -pe 'decode_entities($_);')"; echo "${dbuser} ${dbpass}" } function discover_dbhost() # ( -> db connection IP/hostname ) { local dbhost="$(/usr/bin/cat ${iwconfigpath}/_webmail/server.xml | egrep -o "mysql:host=.*;port=.*;dbname=.*" | perl -pe 's|^\mysql:host=(.*);port=(.*);dbname=(.*)\$|\1|')"; echo "${dbhost}" } function discover_dbport() # ( -> db connection port ) { local dbport="$(/usr/bin/cat ${iwconfigpath}/_webmail/server.xml | egrep -o "mysql:host=.*;port=.*;dbname=.*" | perl -pe 's|^\mysql:host=(.*);port=(.*);dbname=(.*)\$|\2|')"; echo "${dbport}" } # MAIN trap 'echo "FAIL" > /opt/icewarp/var/iwbackupstatus.mon' SIGINT SIGTERM log "Starting backup." preflight_check; log "Reading DB access data." read -r dbuser dbpass <<< "$(discover_creds)"; dbhost="$(discover_dbhost)"; dbport="$(discover_dbport)"; accdbname="$(discover_dbnames "acc")"; aspdbname="$(discover_dbnames "asp")"; grwdbname="$(discover_dbnames "grw")"; dcdbname="$(discover_dbnames "dc")"; easdbname="$(discover_dbnames "eas")"; wcdbname="$(discover_dbnames "wc")"; if [ ! -z "${backupsrvhost}" ]; then dbhost="${backupsrvhost}"; fi # if we take backups from another host if [ ! -z "${backupsrvport}" ]; then dbport="${backupsrvport}"; fi # than the one we connect to # generate backup file names ( databases: accounts, antispam, groupware, directory cache, activesync, webclient cache; server config and calendar folder; domains and accounts csv export ) accdbbckfile="${backuppath}/bck_db_acc_${accdbname}`date +%Y%m%d-%H%M`.sql.gz"; aspdbbckfile="${backuppath}/bck_db_asp_${aspdbname}`date +%Y%m%d-%H%M`.sql.gz"; grwdbbckfile="${backuppath}/bck_db_grw_${grwdbname}`date +%Y%m%d-%H%M`.sql.gz"; dcdbbckfile="${backuppath}/bck_db_dc_${dcdbname}`date +%Y%m%d-%H%M`.sql.gz"; easdbbckfile="${backuppath}/bck_db_eas_${easdbname}`date +%Y%m%d-%H%M`.sql.gz"; wcdbbckfile="${backuppath}/bck_db_wc_${wcdbname}`date +%Y%m%d-%H%M`.sql.gz"; cnfbckfile="${backuppath}/bck_cnf`date +%Y%m%d-%H%M`.tgz"; calbckfile="${backuppath}/bck_cal`date +%Y%m%d-%H%M`.tgz"; logbckfile="${backuppath}/bck_log`date +%Y%m%d-%H%M`.tgz"; accbckfile="${backuppath}/bck_acc_backup`date +%Y%m%d-%H%M`.csv"; dombckfile="${backuppath}/bck_dom_backup`date +%Y%m%d-%H%M`.csv"; log "Starting DB backup." /usr/bin/mysqldump ${extraMysqlOpts} -u ${dbuser} -p${dbpass} -h${dbhost} -P ${dbport} ${accdbname} | gzip -c | cat > ${accdbbckfile} /usr/bin/mysqldump ${extraMysqlOpts} -u ${dbuser} -p${dbpass} -h${dbhost} -P ${dbport} ${aspdbname} | gzip -c | cat > ${aspdbbckfile} /usr/bin/mysqldump ${extraMysqlOpts} -u ${dbuser} -p${dbpass} -h${dbhost} -P ${dbport} ${grwdbname} | gzip -c | cat > ${grwdbbckfile} /usr/bin/mysqldump ${extraMysqlOpts} -u ${dbuser} -p${dbpass} -h${dbhost} -P ${dbport} ${dcdbname} | gzip -c | cat > ${dcdbbckfile} /usr/bin/mysqldump ${extraMysqlOpts} -u ${dbuser} -p${dbpass} -h${dbhost} -P ${dbport} ${easdbname} | gzip -c | cat > ${easdbbckfile} /usr/bin/mysqldump ${extraMysqlOpts} -u ${dbuser} -p${dbpass} -h${dbhost} -P ${dbport} ${wcdbname} | gzip -c | cat > ${wcdbbckfile} log "Finished DB backup." log "Starting IW config backup." /usr/bin/tar -czf ${cnfbckfile} ${IWS_INSTALL_DIR}/config > /dev/null 2>&1 /usr/bin/tar -czf ${calbckfile} ${IWS_INSTALL_DIR}/calendar > /dev/null 2>&1 /usr/bin/find ${IWS_INSTALL_DIR}/logs -type f -mtime -1 -print0 | /usr/bin/tar -czvf ${logbckfile} --null -T - > /dev/null 2>&1 ${IWS_INSTALL_DIR}/tool.sh export account "*@*" u_backup > ${accbckfile} ${IWS_INSTALL_DIR}/tool.sh export domain "*" d_backup > ${dombckfile} log "Finished IW config backup." log "Checking all backupfiles are created." sleep 10; for I in accdbbckfile aspdbbckfile grwdbbckfile dcdbbckfile easdbbckfile wcdbbckfile cnfbckfile calbckfile logbckfile accbckfile dombckfile; do eval ref=\$${I}; if [ "${I}" = "accbckfile" ] || [ "${I}" = "dombckfile" ]; then lines=$(wc -l ${ref} | awk '{print $1}') if [[ ${lines} -lt 2 ]] then log "Backup file ${I} shorter than 2 lines ( ${lines} lines ), fail."; die_error; else log "Backup file ${I} lenght ${lines} lines, OK" fi else sizeK=$(du -k ${ref} | awk '{print $1}'); if [[ ${sizeK} -lt 3 ]] then log "Backup file ${I} size lower than 3K ( ${sizeK}KB ), fail."; die_error; else log "Backup file ${I} size ${sizeK}KB, OK" fi fi done log "Cleaning old backups and logs." /usr/bin/find ${backuppath}/ -type f -name "bck_*" -mtime +${retention_days} -delete > /dev/null 2>&1 /usr/bin/find ${scriptdir}/logs/ -type f -name "bck_*.log" -mtime +${retention_log_days} -delete > /dev/null 2>&1 log "All done." echo "OK" > /opt/icewarp/var/iwbackupstatus.mon exit 0