martes, 27 de diciembre de 2011

Backup buzones zimbra en intervalos de fechas

Esta ves escribo para comentar como hice para hacer backups a zimbra de forma tal que solamente haga backups a un determinado rango de fechas concretamente la ultima semana teniendo en cuenta que el scritp se ejecuta en el cron.weekly.

para este caso solamente tenemos un script llamado bweek.sh el cual ubicaremos en un directorio el cual pueda ser leido y ejecutado por zimbra.

antes de todo vamos a crear en /var/tmp una carpeta para mantener los archivos de control, logs y demás archivos que genera el script, entonces seria algo como lo siguiente:
mkdir /var/tmp/zimbra ; chown -R zimbra /var/tmp/zimbra
tambien necesitamos crear y dar permisos al directorio en conde vamos a enviar las carpetas del backup para este caso lo vamos a dejar en /mnt, entonces quedaría de la siguiente forma:
mkdir /mnt/backup ; chown -R zimbra /mnt/backup


pues bien ahora tenemos el script:

##################bweek.sh############

#!/bin/bash
PLOG=/var/tmp/zimbra/copia.log

DIRC=/var/tmp/zimbra
DIRB=/mnt/backup

# rutina para la verificar si ya existe un proceso de backup.
if [ -e $DIRC/copia.lock ] ; then
  echo "$(date) ya hay un proceso de copia ejecutandose" >> $PLOG
    exit 1
        fi
        # -----------------------------------

        echo "$(date) Se inicia el proceso de copia de seguridad" >> $PLOG
        touch $DIRC/copia.lock

        if [ -e $DIRC/fecha.ctrl ] ; then
        FECHA=`cat $DIRC/fecha.ctrl`
        MESI=`cat $DIRC/datesback.ctrl | awk -F: '{print $1}'`
        DIAI=`cat $DIRC/datesback.ctrl | awk -F: '{print $2}'`
        MESF=`cat $DIRC/datesback.ctrl | awk -F: '{print $3}'`
        DIAF=`cat $DIRC/datesback.ctrl | awk -F: '{print $4}'`
        YEAR=`cat $DIRC/datesback.ctrl | awk -F: '{print $5}'`
        else
        FECHA="`date +%d%m%Y  -d '1 week ago 1 day ago'`to`date +%d%m%Y  -d 'now'`"
        DIAI=`date +%d -d '1 week ago 1 day ago' | bc`
        DIAF=`date +%d -d 'now' | bc`
        MESI=`date +%m -d '1 week ago' | bc`
        MESF=`date +%m -d 'now' | bc`
        YEAR=`date +%Y -d 'now'`
        fi

        # rutina para verificar si la carpeta ya existe si no existe la crea.
        if [ ! -e $DIRB/$FECHA ] ; then
            mkdir $DIRB/$FECHA
                /opt/zimbra/bin/zmprov -l gaa > $DIRC/users.txt
                sed -i '/spam.*\|ham.*\|virus-*\|quarantine.*\|admin/d' $DIRC/users.txt
                sed -i 's/@midominio.com.co//g' $DIRC/users.txt
        fi

cat $DIRC/users.txt | while read usuario
do
  echo "$(date) backup to $usuario" >> $PLOG #falta el filtro para tomar desde fechas el backup

  /opt/zimbra/bin/zmmailbox -z -m $usuario@midominio.com.co getRestURL -o $DIRB/$FECHA/$usuario.tgz "//?fmt=tgz&query=before:$MESF/$DIAF/$YEAR and after:$MESI/$DIAI/$YEAR" 2> $DIRC/dumperr.log

  ERR=$?
  if [ "`cat $DIRC/dumperr.log | grep 'No data found'`" == "" ] ; then
      if [ $ERR -eq 0 ] ; then
              sed -i  "/$usuario/d" $DIRC/users.txt
          echo "$(date) Finalizó correctamente" >> $PLOG
      else
          echo "$(date) error en el backup del usuario $usuario" >> $PLOG
      fi
  else
      sed -i  "/$usuario/d" $DIRC/users.txt
      echo "$(date) Finalizó, no se encontraron datos" >> $PLOG
  fi
                                                                                                                 
done
# crear rutina en caso que no haya terminado agregue una linea al cron para que automatice

if [ "`cat $DIRC/users.txt`" == "" ] ; then
    echo "$(date) El proceso de copia de seguridad termino exitosamente para todos los usuarios" >> $PLOG
        if [ -e $DIRC/fecha.ctrl ] ; then
            rm -f $DIRC/fecha.ctrl
                rm -f $DIRC/datesback.ctrl
            crontab -l > /tmp/crontabzim.tmp
            sed -i "/backup-semanal/d" /tmp/crontabzim.tmp
            crontab /tmp/crontabzim.tmp
            rm -f /tmp/crontabzim.tmp
        fi
else
        #   echo "$(date) El proceso de copia de seguridad no termino para todos los usuarios.. agregando registro a crontab y capturando la fecha de copia" >> $PLOG
        if [ ! -e $DIRC/fecha.ctrl ] ; then
                echo "$(date) El proceso de copia de seguridad no termino para todos los usuarios.. agregando registro a crontab y capturando la fecha de copia" >> $PLOG
        crontab -l > /tmp/crontabzim.tmp
        echo "*/20 * * * * $DIRC/backup-semanal.sh" >> /tmp/crontabzim.tmp
        crontab /tmp/crontabzim.tmp
        rm -f /tmp/crontabzim.tmp
        echo $FECHA >>
$DIRC/fecha.ctrl
        echo "$MESI:$DIAI:$MESF:$DIAF:$YEAR" >> $DIRC/datesback.ctrl
        else
        echo "$(date) El proceso de copia de seguridad no termino para todos los usuarios.. pero ya hay un archivo de control para continuar con el backup" >> $PLOG
        fi 
fi

rm -f $DIRC/copia.lock


############fin del script###############

Pues bien ya tenemos el script ahora vamos a comentar las partes mas importantes del script.

1) Las variables de las fechas, los días y los meses:

        FECHA="`date +%d%m%Y  -d '1 week ago 1 day ago'`to`date +%d%m%Y  -d 'now'`"
        DIAI=`date +%d -d '1 week ago 1 day ago' | bc`
        DIAF=`date +%d -d 'now' | bc`
        MESI=`date +%m -d '1 week ago' | bc`
        MESF=`date +%m -d 'now' | bc`
        YEAR=`date +%Y -d 'now'`


Estas variables lo que nos permite es capturar una fecha inmediata (la fecha final de la copia) y las fechas iniciales de copia es decir una semana antes de lanzarse el script.

2) la orden de copia del buzón en especifico:
/opt/zimbra/bin/zmmailbox -z -m $usuario@midominio.com.co getRestURL -o $DIRB/$FECHA/$usuario.tgz "//?fmt=tgz&query=before:$MESF/$DIAF/$YEAR and after:$MESI/$DIAI/$YEAR" 2> $DIRC/dumperr.log

aquí lo que se tiene es basicamente la cadena construida para el backup, en donde se enmarca el usuario al cual se le hará la copia $usuario@midominio.com.co, la ruta a donde se enviará la copia $DIRB/$FECHA/$usuario.tgz, el formato de compresión y la cadena de filtro o query //?fmt=tgz&query=before:$MESF/$DIAF/$YEAR and after:$MESI/$DIAI/$YEAR, En este segmento debemos tener muy en cuenta que el formato de fecha es MM/DD/YYYY ademas de esto en caso que un mes este compuesto por un solo dígito no se aceptará el anteponer 0, y por ultimo el capturar el resultado de la operación  2> $DIRC/dumperr.log, esto basicamente lo hacemos es para poder establecer si un buzón esta vacío, en caso de estar vacío lo tomamos como una backup exitoso.

3) la sección en donde se manipula el crontab de zimbra, esto lo hacemos para poder retomar un backup en caso tal que se hayan tenido errores durante el primer intento.

Muy bien esto a sido todo por el momento, estoy seguro que a alguien le va a ser util ;) por lo menos a mi me fue muy util..

PD: recomendaciones, insultos, quejas y otras son bienvenidas ;)