Архивы по Категориям: Администрирование

VLC Mass IP cams transcoding

В общем есть такой тип проектов, в которых используют большое количество ip камер. Как правило это проекты связанные с городской безопасностью. Например http://www.podryad.tv/live_cam/ один из таких проектов..

В данной статье я расскажу как просто и эффективно реализовать подобный сервис. Соответственно будем считать, что камеры по городу или объекту расставлены, работают и доступны по сети. В данном конкретном случае будут использоваться камеры AXIS различных моделей. Благо интерфейс доступа к потоку у них стандартизирован.

Еще один не маловажный момент это однородность состава камер, я имею ввиду, что важно иметь камеры одного вендора и даже модели это позволит избежать мучений с настройкой и обслуживанием.

Кратко опишу техническую задачу.

Есть некоторое количество камер потоки с которых нужно транслировать на сайт предварительно перекодировав поток с заворачиванием в FLV контейнер. Как дальше оно будет разруливаться не особо важно.

Для решения задачи я взял всем известный проект VideoLan , который является не только прекрасным проигрывателем мультимедиа, но и не менее прекрасным медиа-сервером.

Небольшая ремарка по поводу производительности..

Рабочий проект содержащий > 60 камер, обслуживался одним сервером Dell R710 с двумя процессорами Intel Xeon SixCore X5650 @ 2.67GHz c 6Gb RAM при этом потоки принимались на один гигабитный сетевой интерфейс и через такой же отдавались.. Интенсивность потока в среднем 400Mb/s при разрешении картинки в 840х480.. Средняя загрузка системы за 5ть минут составляла примерно 30 единиц.

Работать все будет под управлением OS GNU/Debian 6.0. В принципе под другими дистрибутивами наверно будет работать не хуже.

И так начнем. Для начала нужно поставить необходимые пакеты, в частности сам vlc (а точнее vlc-noc) со всеми зависимостями. так же советую подключить репозитории проекта debian-multimedia если вам понадобится кодировать потоки например в h264.

Когда установка будет закончена, надо создать не привилегированного пользователя от имени которого и будет работать vlc.

Теперь собственно о том как настроить и как всем этим управлять..

В VLC есть такая приятная фишка как  VLM, по сути простой стрим лист. возможности которого по настоящему безграничны.

Вот пример такого листа:

new cam26 broadcast enabled
setup cam26 input http://user:*****@XXX.XXX.XXX.XXX/axis-cgi/mjpg/video.cgi
setup cam26 output #transcode{vcodec=FLV1,vb=5000,fps=25,ab=192,samplerate=48000}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8080/stream26.flv}
control cam26 play

new cam25 broadcast enabled
setup cam25 input http://user:*****@XXX.XXX.XXX.XXX/axis-cgi/mjpg/video.cgi
setup cam25 output #transcode{vcodec=FLV1,vb=5000,fps=25,ab=192,samplerate=48000}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8080/stream25.flv}
control cam25 play

По сути нету ничего сложного, важно, что лист может содержать огромное количество подобных записей.

Немного об опциях транскодинга и вывода.

#transcode{vcodec=FLV1,vb=5000,fps=25,ab=192,samplerate=48000}

  • vcodec — собственно видео кодек в нашем случае это флеш кодек.
  • vb — видео буфер — значение подбирается экспериментально, если изображение мигает или сыпется, данный параметр нужно увеличить. Помните, что увеличивая его вы увеличиваете количество пожираемой ОЗУ.
  • fps — количество кадров в секунду, советую устанавливать значение равное значению выставленному на камере.. Если сервер транскодинга слабоват, значение можно уменьшить, но и качество соответственно будет хуже.
  • ab — аудио буфер — если планируется трансляция звука.
  • samplerate — входная частота дискретизации.

{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8080/stream25.flv}

  • access — указывает на тип доступа к потоку, в нашем случае http
  • mime — mime тип для транспорта
  • mux — мультиплексор, в нашем случае ffmpeg, который будет заворачивать поток в контейнер flv
  • dst — собственно url по которому наш поток будет доступен для клиентов.

Теперь немного об аргументах с которыми стартует сервер. Вся строка выглядит так :

cvlc -d -q —pidfile=/var/run/vlc.pid —ttl 8 -I telnet —telnet-host=0.0.0.0 —telnet-password=********* —sout-transcode-high-priority —http-reconnect —http-caching=10000 —logmode=syslog —rt-priority —vlm-conf /home/vlc/vlc-stream-list.cfg

Разберем ее по порядку:

  • -d — опция которая говорит vlc запускаться как демон
  • -q — опция подавляющая вывод в stdout/stderr сообщений.
  • —pidfile — опция указывающая где будет создан файл идентификатора процесса, так как наш сервер будет запущен с опцией -d то это будет актуально, особенно если вы захотите в дальнейшем написать скрипт для /etc/init.d
  • —ttl — параметр не особо важный, но все же. Его назначение это указание маршрутизаторам время жизни транспортного пакета.. по истечению которого оный будет уничтожен.. Если трансляция осуществляется в рамках одного сегмента, можно установить параметр в единицу, меньше мусора будет.
  • -I тип интерфейса управления, в нашем случае telnet, есть еще http и что-то еще я уже не помню..
  • —telnet-host — с какого адреса ждать подключения к telnet консоли.
  • —telnet-password — тут все понятно..
  • —sout-transcode-high-priority — опция говорит что процессы транскодинга должны выполнятся с наивысшем приоритетом (аналог системной утилиты nice).
  • —http-reconnect — опция заставляющая vlc пытаться восстановить соединение с http транспортом камер. (При условии что таковой используется, если забор потока идет через rtp сия опция бесполезна)
  • —http-caching — кеш http трафика полезная опция при высокой нагрузке на сеть
  • —logmode логи работы vlc будут обрабатываться системными средствами, в частности syslog
  • —rt-priority очень важная опция заставляющая работать процессы vlc  с приоритетом реального времени. ВНИМАНИЕ! Если на сервере транскодинга запущены другие программы фонового характера работы.. Данная опция может серьезно снизить их производительность.
  • —vlm-conf путь до стрим листа.

Вот собственно и все..

Дальше все, что вам нужно сделать это забить стрим лист данными о потоках и запустить сервер.

Вот так после запуска это выглядит у меня :

Работа vlc транскодера на 60 потоках.

Теперь надо подумать о том как этим управлять..

Для управления я сделал следующее:

  1. Создал таблицу в бд где храню информацию о потоках, их номера параметры кодирования и вывода, IP адреса логины и пароли для доступа к камерам и многое другое, что сильно упрощает жизнь.
  2. На сервер я поместил скрипт который по крону или в ручную регенерирует стрим лист и перезагружает сервер.
  3. Написал небольшую программку для управления записями в БД.

Собственно все.. Кому будет интересно могу предоставить структуру таблицы и сходный код программки..

За сим откланюсь, надеюсь изложенная информация будет вам интересна и полезна.

Успехов.

Iptables and Ipset in Debian

Включаем поддержку ipset в iptables.

Актуально для ядер > 2.6.30

# apt-get install module-assistant xtables-addons-source
# module-assistant prepare
# module-assistant auto-install xtables-addons-source

# # modprobe ipt_set

VsFTPD and Virtual users on Debian

На заметку..

Пакеты:

apt-get install libpam-pwdfile vsftpd

Предположим, что сайтики лежат в /srv/www/{sitename — вида www.mysite.ru}/htdocs , соответственно ограничиваем пользователя доступом в корень, т.е. не выше директории www.mysite.ru.

И так чистим дефолтный конфиг vsftpd

echo "" > /etc/vsftpad.conf

И записываем туды следующие..

listen=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
# пользователя vsftpd нужно создать системным без шела, например useradd -M -r vsftpd
nopriv_user=vsftpd
virtual_use_local_privs=YES
guest_enable=YES
user_sub_token=$USER
# Токен $USER предполагает что к пути /srv/www/ будет добавлено имя пользователя, он и будет являться корнем для него.
local_root=/srv/www/$USER
chroot_local_user=YES
hide_ids=YES
guest_username=vsftpd
chown_uploads=YES
# От имени и группы www-data пашет Apache.
chown_username=www-data
guest_enable=YES
guest_username=www-data
chown_upload_mode=0775

use_localtime=YES
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=YES

dirmessage_enable=YES
ascii_upload_enable=YES
ascii_download_enable=YES
ftpd_banner=Welcome developer to WWW server!
ls_recurse_enable=YES
secure_chroot_dir=/var/run/vsftpd/empty

pasv_enable=YES
pasv_min_port=62000
pasv_max_port=64000

Далее надо настроит pam аутентификацию, для сего лезим в /etc/pam.d/vsftpd и комментим все попутно добавив туда две строчки

auth required pam_pwdfile.so pwdfile /etc/ftpd.passwd
account required pam_permit.so

Собственно создаем файлик /etc/ftpd.passwd командой

htpasswd -c /etc/ftpd.passwd

Добавление пользователя осуществляется аналогично, только без опции -с и с названием корневой директории сайта в качестве пользователя

htpasswd /etc/ftpd.passwd www.mysite.ru

Ребутим vsftpd и радуемся..

Grub2 и framebuffer в Debian

Ахтунг!!! Не надо ничего менять в /boot/grub/grub.conf , это не наш метод.

Разрешение ЖК моего ноутбука 1280×800, не забываем его сменить на свое!

Для начала открываем  /etc/default/grub и ищем строку:

GRUB_GFXMODE=800x600

Правим ее немного, что бы получилось:

GRUB_GFXMODE=1280x800@32
# ниже добавляем строку
GRUB_GFXPAYLOAD=1280x800x32

Теперь лезем в /etc/grub.d/00_header ищем там строку:

if [ "x${GRUB_GFXMODE}" = "x" ] ; then GRUB_GFXMODE=800x600x32 ; fi
#меняем разрешение на свое и ниже добавляем еще одну
if [ "x${GRUB_GFXPAYLOAD}" = "x" ] ; then GRUB_GFXPAYLOAD=1280X800x32 ; fi

В самом конце файла ищем строку

set gfxmode=${GRUB_GFXMODE}

и ниже добавляем

set gfxpayload=${GRUB_GFXPAYLOAD}

Сохраняем и запускаем update-grub2.

Удачи.



Xen 3.2-1 and HVM Windows config

Очередной пост для себя любимого.. Но и Вы гости дорогие жуйте если что не стесняйтесь..

Сие есть просто файл конфигурации HVM домена с Win2k3..

Пост не претендует на новизну и оригинальность.

 

kernel="hvmloader"
device_model = 'qemu-dm'
builder='hvm'
memory = 5120
name = "win2k3
vcpus= 4
pae=1
acpi= 1
apic= 1
#usb= 1 разкомментировать если нужна поддержка USB в гостевой ОС. #usbdevice= [ 'host:0529:0514' ]  DID, USB устройства которое нужно пробросить.
cpus = "
2-5"
vif=[ 'mac=00:16:3e:01:01:01,bridge=eth0,type=ioemu' ]
disk = [
'file:/C.img,hda,w',
'file:/D.img,hdb,w'
]
'file:/win2003/win2003.iso,hdc:cdrom,r',
'file:/win2003-2.iso,hdd:cdrom,r'
#]
on_poweroff = 'destroy'
on_shutdown = 'shutdown'
on_reboot   = 'restart'
on_crash    = 'restart'
boot='c'
sdl=0
vnc=1
vnclisten="
0.0.0.0"
vncconsole=0
stdvga=0
serial='pty'

Note:

Для тех кто не в курсе.. Для работы HVM домена необходима поддержка Intel®Virtualization Technology (VT) или Pacifica (AMD)  процессором (ами) сервера. Проверить можно следующими способами:

# xm info | grep caps
hw_caps                : 178bfbff:ebd3fbff:00000000:00000010:00002001:00000000:0000001f
xen_caps               : xen-3.0-x86_32p hvm-3.0-x86_32 hvm-3.0-x86_32p

# xm dmesg | grep VMX
(XEN) VMXON is done
(XEN) VMXON is done

# xm dmesg | grep -i svm
(XEN) AMD SVM Extension is enabled for cpu 0.
(XEN) AMD SVM Extension is enabled for cpu 1.

Траблы:

  • Через опу работает AMD VT-d в силу зачаточности реализации..
  • Через туда же работает USB .
  • При установки паравиртуальных драйверов для Windows (В частности Win2k3) отваливаются CDROM`ы.. (на версии драйвера gplpv_2003x64_0.11.0.188 от 3 января  2010 г.)

Ну на этом с траблами вроде все, по крайней мере я более не обнаружил..

Кстати вопреки слухам о запущенности и унынии свободной реализации паравиртуальных драйверов для виндовсов.. Отнюдь.. Драйвера активно разрабатываются и они довольно таки стабильны. Кому надо, ссылка в конце поста.

Хозяйке на заметку:

  1. В качестве виртуального HDD для гостевой ОС предпочтительнее использовать блочное устройство, нежели файловое.  Синтаксис опции : phy:UNAME,DEV,MODE
  2. Для ОС семейства MSWindows (особенно серверных) установки паравиртуальных драйверов крайне предпочтительна, ибо в качестве профита появится многоканальный SATA контроллер, 1G сетевой адаптер и.т.д в зависимости от типа ОС (сие особенно полезно если в гостевом сервере крутится БД ).

Полезные ссылки:

Сборка расширейний для Iptables в Debian

Данная заметка (именно заметка !) сделана в основном для себя , дабы не забыть.  Ну и для масс, авось кому понадобится.

И так кратко (для масс!), что есть Iptables extensions, это набор патчей для Iptables существенно расширяющий его функционал. В Debian Lenny эти патчи собраны в пакете netfilter-extensions-source , подробнее о составе пакета  можно почитать здесь, там же можно найти примеры по использованию.

И так качаем и ставим пакет netfilter-extensions-source:

apt-get install netfilter-extensions-source linux-headers-`uname -r`

Внимание! Тянет много зависимостей.

Ну и собственно сборка:

m-a build netfilter-extensions
m-a update && m-a a-i netfilter-extensions

Ну вот и все :)

Резервное копирование Zimbra CS OSE

zimbra_logo

Самый большой недостаток Zimbra CS OSE, это отсутствия нативных инструментов для создания резервных копий. В связи с этим пытливыми умами было написано немало всевозможных скриптов призванных выполнять данную функцию. Со всем многообразием этих самых скриптов можно ознакомится в соответствующем разделе Zimbra Wiki.

На всякий случай выложу один из вариантов (на мой взгляд один из самых удачных) скрипта для резервного копирования.

Сайт разработчиков

Ну и собственно сам скрипт.

#!/bin/bash
## *** Info ***
# USAGE:    -h or --help for help & usage.
#           -f or --full for Full backup.
#           -d or --diff for Diff backup.
#           -V or --version for version info.
#           --INSTALL    for script install and setup.
#
# This is a backup script for the FOSS version of Zimbra mail server.
# The script is free and open source and for use by anyone who can find a use for it.
#
# THIS SCRIPT IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
# HOLDERS AND/OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS DOCUMENT, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# What this script does:
# 1. Makes daily off-line backups, at a service downtime of ~ < 2 min.
# 2. Weekly backup cycle - 1 full backup & 6 diffs.
# 3. Predefined archive sizes, for writing backups to CD or DVD media...
# 4. Backup archive compression.
# 5. Backup archive encryption.
# 6. Backup archive integrity checks and md5 checksums creation.
# 7. Automated DR - Off-site copy of backup archives via ssh.
# 8. Install and setup function for needed sofrware (Ubuntu Systems only)
# 9. Weekly eMail report & eMail on error - including CC address.
#
# This script makes use of following tools:
# apt-get, cron, dar, dpkg, mailx, md5sum, rsync, ssh, uuencode, wget, zimbra mta.
#
# We have opted to use a pre-sync directory to save on "down time", but this
# causes one to have huge additional space usage.
# But hard drives are cheep today!
#
# What is still to come or needs work on:
# 1. Recover option
# 2. Better documentation
#
#------- CONFIG -------#
# Edit this part of the script to fit your needs.
#

#--- Directories ---#
# Please add the trailing "/" to directories!
ZM_HOME=/opt/zimbra/
SYNC_DIR=/tmp/fakebackup/
ARCHIVEDIR=/home/archive/bkp/
TOO_MEDIA_DIR=/home/media/bkp/old/

#
#--- PROGRAM OPTIONS ---#
RSYNC_OPTS="-aHK --delete --exclude=*.pid"

#
#--- ARCHIVE NAMES ---#
BACKUPNAME="Zimbra_Backup"
BACKUPTYPE_F="FULL" # name prefix to sort between full and diff backups
BACKUPTYPE_D="DIFF"
BACKUPDATE=`date +%d-%B-%Y`

#
#--- ARCHIVE SIZE ---#
# storage media size
ARCHIVESIZE="1000M"
COMPRESS="9"        # valid answers are 1 - 9 ( 9 = best )

CRYPT="yes"     # valid answers are "yes" or "no"
PASSDIR=/etc/zmbac/
PASSFILE="bac.cf"

#
#--- EMAIL ADDRESS ---#
EMAIL=""
EMAILCC=""
LOG=""

#--- SSH REMOTE DR COPY ---#
# This option will secure copy you archives to a remote server via 'scp'
DRCP="no"       # valid answers are "yes" or "no"
SSHUSER="heinzg"
SSHKEY="rsa"     # recommended answers are "rsa" or "dsa" but "rsa1" is also valid.
REMOTEHOST="172.16.184.1"
REMOTEDIR="/tmp/"

#--- USE HACKS !?! ---#
# Built in hacks to fix common problems
#Hack to start Stats, even run zmlogprocess if needed
STATHACK="yes"      # valid answers are "yes" or "no"

## ~~~~~!!!! SCRIPT RUNTIME !!!!!~~~~~ ##
# Best you don't change anything from here on,
# ONLY EDIT IF YOU KNOW WHAT YOU ARE DOING
#
#

# Check if Zimbra install dir is there
if [ ! -d $ZM_HOME ]
then
echo "$ZM_HOME not found!"
exit 1
fi

if [ ! -d $SYNC_DIR ]
then
mkdir $SYNC_DIR
fi

# Check the script is being run by root, or die.
ROOT_UID=0
if [ "$UID" -ne "$ROOT_UID" ]
then
echo "Run script as "root"."
echo
exit 1
fi

# Create Log file
touch $LOG

# Script Timer
STARTTIME=(`date +%s`)

# Week prefix used for backup weekly rotation and naming
BACKUPWEEK=`date +%W`

# Finding out who is the zimbra proc user
ZM_USER=`ps -ef | grep "$ZM_HOME" | grep "java" | grep -v "zmmailboxdmgr" | awk '{print $1}' | head -n 1`
if [ -z $ZM_USER ]
then
echo "Unable to determan the zimbra user"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
elif [ $ZM_USER = "root" ]
then
echo "Zimbra user should never be root! I'll die now..."
# send email....
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

# Location of Zimbra's PID files
STATPIDBASE="$ZM_HOME""zmstat/pid/"

case $1 in
-V | --version)
echo
echo "Version 1.02"
echo "first published Feb 08"
echo
echo "Change Log March 08:"
echo "- Use the su command insted if sudo to stop and start services"
echo "- Using shutdown insted of stop with zmcontrol"
echo "- DATE_VERSION.txt now contains date and version and is created with full backups"
echo "- Built in some more checks"
echo "- eMail notification on error"
echo "- Documentation - Added more comments"
echo "- Dar archive is now built from current dir"
echo "- Stats hack to make sure stats is starting again"
echo "- 260 more lines of code... and who knows how many bugs"
echo
;;

-h | --help)
echo
echo "Configure the "CONFIG" part of the script to suit your needs."
echo
echo "USAGE:    -h or --help for help & usage."
echo "          -f or --full for Full backup."
echo "          -d or --diff for Diff backup."
echo "          --INSTALL    for script install and setup."
echo
echo "Usage with cron, e.g."
echo "0 3 * * 1     /bin/bash     /root/zmbac.sh -f > $LOG 2>&1"
echo "0 3 * * 2-7   /bin/bash     /root/zmbac.sh -d >> $LOG 2>&1"
echo
;;

--INSTALL)

# Check for configured Directories or Create them

if [ ! -d $SYNC_DIR ]
then
echo
echo "$SYNC_DIR not found!"
echo -n "Create $SYNC_DIR "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
mkdir -vp -m 600 $SYNC_DIR
else
echo "Please check script Config, and try again"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi

if [ ! -d $ARCHIVEDIR ]
then
echo
echo "$ARCHIVEDIR not found!"
echo -n "Create $ARCHIVEDIR "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
mkdir -vp -m 600 $ARCHIVEDIR
else
echo "Please check script Config, and try again"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi

if [ ! -d $TOO_MEDIA_DIR ]
then
echo
echo "directory $TOO_MEDIA_DIR not found!"
echo -n "Create $TOO_MEDIA_DIR "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
mkdir -vp -m 600 $TOO_MEDIA_DIR
else
echo "Please check script Config, and try again"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi

# Check for needed software or try install it

MAILX=`whereis mailx | awk '{print $2}'`
if [ ! -e "$MAILX" ]
then
echo
echo "'mailx' is not installed!"
echo
echo "For a "Howto" install mailx without postfix please visit the link below"
echo "http://www.zimbra.com/forums/administrators/13528-sending-email-comand-line-logwatch-ubuntu-6-06-a.html#post70636"
echo
echo "Should I "try" install this for you?"
echo
echo "!! Only say yes if you are running Ubuntu!!"
echo
echo -n "install "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
echo
echo "Downloading "mta-dummy" package to "/tmp""
cd /tmp
wget -v -S -c -t 40 --random-wait -T 60 http://ubuntu.lnix.net/misc/mta-dummy/mta-dummy_1.0_all.deb
if [ "$?" -ne "0" ]
then
echo "Had some form of problem getting the mta-dummy package... ask for help in the forums"
echo
exit 1
fi
echo
dpkg -i mta-dummy_1.0_all.deb
if [ "$?" -ne "0" ]
then
echo "Had some form of problem getting installing the mta-dummy package... ask for help in the forums"
echo
exit 1
fi

echo
echo
apt-get -y install mailx
if [ "$?" -ne "0" ]
then
echo "Had some form of problem installing 'mailx'... ask for help in the forums"
echo
exit 1
fi
echo
echo "Writing config file "/etc/mail.rc""
echo "set sendmail=$ZM_HOME"postfix/sbin/sendmail"" >> /etc/mail.rc
else
echo "This script would like to send you a mail or two... so please install a dummy mta for your Distro"
echo
exit 1
fi
fi

UUENCODE=`whereis uuencode | awk '{print $2}'`
if [ ! -e "$UUENCODE" ]
then
echo
echo "'uuencode' is not installed!"
echo
echo "Should I "try" install 'uuencode' for you?"
echo
echo "!! Only say yes if you are running Ubuntu!!"
echo -n "install "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
apt-get -y install sharutils
if [ "$?" -ne "0" ]
then
echo "Had some form of problem installing "sharutils"... ask for help in the forums"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi
fi

DAR_BIN=`whereis dar | awk '{print $2}'`
if [ ! -e "$DAR_BIN" ]
then
echo
echo "'dar' is not installed!"
echo
echo "Should I "try" install 'dar' for you?"
echo
echo "!! Only say yes if you are running Ubuntu!!"
echo -n "install "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
apt-get -y install dar
if [ "$?" -ne "0" ]
then
echo "Had some form of problem installing "dar"... ask for help in the forums"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi
fi

SSH_BIN=`whereis ssh | awk '{print $2}'`
if [ ! -e "$SSH_BIN" ]
then
echo
echo "Please install "ssh"!"
echo
echo "Should I "try" install a 'ssh client & server' for you?"
echo
echo "!! Only say yes if you are running Ubuntu!!"
echo -n "install "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
apt-get -y install openssh-server
if [ "$?" -ne "0" ]
then
echo "Had some form of problem installing "openssh-server"... ask for help in the forums"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
echo
exit 1
fi
fi
fi

if [ $CRYPT = "yes" ]
then
if [ ! -d "$PASSDIR" ]
then
echo "Create $PASSDIR"
echo -n "install "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
mkdir -vp -m 600 $PASSDIR
echo "done"
echo
else
echo "Please check script Config, and try again"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi
fi

if [ ! -e "$PASSDIR""$PASSFILE" ]
then
echo "Create $PASSFILE"
echo -n "install "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
touch "$PASSDIR""$PASSFILE"
chmod 600 "$PASSDIR""$PASSFILE"
echo "'G'enerate or 'E'nter a secure passphrase"
echo -n "please enter G or E: "
read ANSWER
if [ "$ANSWER" = "G" ]
then
openssl rand -base64 48 -out "$PASSDIR""$PASSFILE" 2>/dev/null
else
echo -n "Enter a secure passphrase: "
read PASSPHRASE
echo $PASSPHRASE > "$PASSDIR""$PASSFILE"
echo "done"
echo
fi
else
echo "Please check script Config, and try again"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi

echo
if [ $DRCP = "yes" ]
then
echo
echo "For 'scp' to work, you have to have setup PKI authentication (passwork less login)"
echo "Should I try setup this for you?"
echo "If you have a key an PKI authentication works answer 'n'"
echo -n "install "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
ssh-copy-id "$SSHUSER"@"$REMOTEHOST"
if [ "$?" -ne "0" ]
then
echo "$?"
echo -n "Create ssh ID? "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
echo "Please except the 'defaults'and DO NOT ENTER A 'passphrase' !!"
ssh-keygen -t "$SSHKEY"
echo
echo "copying your ID to $REMOTEHOST"
echo "please enter your '$SSHUSER' user password on '$REMOTEHOST' at the prompt"
if [ "$SSHKEY" = "rsa" ]
then
ssh-copy-id -i /root/.ssh/id_rsa "$SSHUSER"@"$REMOTEHOST"
elif [ "$SSHKEY" = "dsa" ]
then
ssh-copy-id -i /root/.ssh/id_dsa "$SSHUSER"@"$REMOTEHOST"
elif [ "$SSHKEY" = "rsa1" ]
then
ssh-copy-id -i /root/.ssh/identity "$SSHUSER"@"$REMOTEHOST"
fi
fi
fi
fi
fi

echo
echo "Install cronjob to automate the nightly backups"
echo -n "install "y" or "n": "
read ANSWER
if [ $ANSWER = "y" ]
then
crontab -l > $HOME/.crontab.save
echo "Setting the time when to start the backup cycle"
echo -n "At what hour? 0-23: "
read HOUR
echo
echo -n "and what minute do you want the backup to start? 0-59: "
read MINUTE
echo
echo "path to script e.g. /root/scripts"
read SPATH
echo "" >> $HOME/.crontab.save
echo "$MINUTE $HOUR * * 1     /bin/bash     $SPATH/zmbac.sh -f > $LOG 2>&1" >> $HOME/.crontab.save
echo "$MINUTE $HOUR * * 2-7   /bin/bash     $SPATH/zmbac.sh -d >> $LOG 2>&1" >> $HOME/.crontab.save
echo "" >> $HOME/.crontab.save
crontab $HOME/.crontab.save
rm $HOME/.crontab.save
echo
crontab -l
echo
echo "Done setting up crontab"
echo
fi

;;

-f | --full)
echo
echo "      Full Backup started at: `date +%H:%M`"
echo
DAR_BIN=`whereis dar | awk '{print $2}'`
if [ ! -e "$DAR_BIN" ]
then
echo "Please install "dar"!"
echo "Try running the script with --INSTALL"
exit 1
fi

MAILX=`whereis mailx | awk '{print $2}'`
if [ ! -e "$MAILX" ]
then
echo "mailx is not installed!"
echo "Try running the script with --INSTALL"
exit 1
fi

RSYNC_BIN=`whereis rsync | awk '{print $2}'`
if [ ! -f "$RSYNC_BIN" ]
then
echo $SYNC_BIN
echo "Please install "rsync"!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

SSH_BIN=`whereis ssh | awk '{print $2}'`
if [ ! -e "$SSH_BIN" ]
then
echo "Please install "ssh"!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

MD5SUM_BIN=`whereis md5sum | awk '{print $2}'`
if [ ! -e "$MD5SUM_BIN" ]
then
echo "Please install "md5sum"!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

if [ ! -d $ZM_HOME ]
then
echo "$ZM_HOME not found!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

if [ ! -d $SYNC_DIR ]
then
echo "$SYNC_DIR not found!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

if [ ! -d $ARCHIVEDIR ]
then
echo "$ARCHIVEDIR not found!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

if [ ! -d $TOO_MEDIA_DIR ]
then
echo "directory $TOO_MEDIA_DIR not found!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
echo
exit 1
fi

# Look for old backups and put then in directory from where you write them to some form of
# storage media
LAST_FULL_DAR=`ls -A -1 $ARCHIVEDIR | grep $BACKUPNAME | cut -d _ -f1 | head -n1`

if [ -z "$LAST_FULL_DAR" ]
then
echo "No old backups found"

elif [ "$LAST_FULL_DAR" -lt "$BACKUPWEEK" ]
then
echo "Old backups found...old week= $LAST_FULL_DAR current week= $BACKUPWEEK"
echo
for i in `ls -A -1 "$ARCHIVEDIR""$LAST_FULL_DAR"_"$BACKUPNAME"*`
#for i in `ls -A -1 "$ARCHIVEDIR""$LAST_FULL_DAR"_"$BACKUPNAME"*dar`
do
mv $i $TOO_MEDIA_DIR
if [ "$?" -ne "0" ]
then
echo "error during move!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "$i moved to $TOO_MEDIA_DIR"
fi
done
fi

# Checking for a backup file collisions. Creating Date and Marker file.
CURRENTNAME1=`ls -A -1 "$ARCHIVEDIR""$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_F"*dar 2> /dev/null | head -qn1`
if [ -f "$CURRENTNAME1" ]
then
echo
echo "Full Zimbra Backup failed!"
echo "FOUND A BACKUP WITH SAME NAME IN $ARCHIVEDIR >> Please check why ????"
echo "!! You should only run this script once a day with the current backup date settings !!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
su - "$ZM_USER" -c $ZM_HOME"bin/zmcontrol -v" > /dev/null
if [ -z "$?" ]
then
echo
echo "zmcontrol has some problems! check config or call for help..."
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo
echo "Setting date & version Marker into "$ZM_HOME"DATE_VERSION.txt"
echo
echo "$BACKUPDATE" > "$ZM_HOME"DATE_VERSION.txt
su - "$ZM_USER" -c $ZM_HOME"bin/zmcontrol -v" | grep ^R >> "$ZM_HOME"DATE_VERSION.txt
fi

# HotSync to backup directory
echo "Doing a hotsync of $ZM_HOME to $SYNC_DIR"

nice -19 $RSYNC_BIN $RSYNC_OPTS $ZM_HOME $SYNC_DIR
if [ "$?" -ne "0" ]
then
echo
echo "rsync had threw an hotsync error this is not that wild... continuing"
#cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
else
echo "sync went ok"
echo
fi

# Stopping Zimbra
echo "Stopping the Zimbra server"
echo

#Disable zimbra user's crontab, we don't want it starting any jobs while we backup
crontab -u $ZM_USER -l > "$ZM_HOME"crontab.org
if [ "$?" -ne "0" ]
then
echo "could not backup "$ZM_USER"'s crontab..."
echo "continuing with out changing users crontab!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
touch "$ZM_HOME"crontab.blank
crontab -u $ZM_USER "$ZM_HOME"crontab.blank
rm "$ZM_HOME"crontab.blank
echo "Deactivated "$ZM_USER"'s cronjobs"
echo
fi

#Starting 'service downtime' counter
DOWNTIMEA=(`date +%s`)

su - $ZM_USER -c $ZM_HOME"bin/zmcontrol stop"
if [ "$?" -eq "1" ]
then
echo "zmcontrol shutdown had an error!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo
echo "Zimbra server has stopped "
fi
echo
# Some times I still have zimbra procs running, so I murder them! :-O
sleep 5
echo "kill any left over $ZM_USER procs"
PROX=(`ps -u $ZM_USER | awk '{print $1}' | grep -v PID`)
if [ "$PROX" ]
then
ps -u $ZM_USER | awk '{print $1}' | grep -v PID | xargs kill -s 15
echo "Did a Mr. Bush on some left over procs..."
echo
else
echo "Nothing to kill"
echo
fi
# ColdSyncing the zimbra server
echo "Doing a fast cold sync..."

$RSYNC_BIN $RSYNC_OPTS $ZM_HOME $SYNC_DIR
if [ "$?" -ne "0" ]
then
echo "rsync had threw an error!"
echo "This should not happen at this stage... exiting!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "sync went ok"
fi
echo

# Starting the Zimbra server again

#Reinstate zimbra user's crontab
crontab -u $ZM_USER "$ZM_HOME"crontab.org
if [ "$?" -ne "0" ]
then
echo "!!Could not reinstate "$ZM_USER"'s crontab!!"
echo "Please do this manually!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "Reinstated "$ZM_USER"'s cronjobs"
echo
fi

su - "$ZM_USER" -c $ZM_HOME"bin/zmcontrol start"
if [ "$?" -ne "0" ]
then
echo "There was an error starting Zimbra!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo
echo "Zimbra has started"
fi
# Service Timerc
DOWNTIMEB=(`date +%s`)
RUNTIME=$(expr $DOWNTIMEB \- $DOWNTIMEA)
hours=$(($RUNTIME / 3600))
seconds=$(($RUNTIME  % 3600))
minutes=$(($RUNTIME  / 60))
seconds=$(($RUNTIME  % 60))
echo
echo "Service down time was - Hr:$hours Min:$minutes Sec:$seconds"
echo

# Hack to start the stats component
if [ $STATHACK = "yes" ]
then
echo "Running A hack... This one to check and start Stats subsystem"
#Checking if Stats is running
sleep 5
STAT_CK=(`su - "$ZM_USER" -c $ZM_HOME"bin/zmcontrol status" |grep -i stats | awk '{print $2}'`)
if [ "$STAT_CK" = "Stopped" ]
then
echo "Stats is not running, thus booting Stats subsystem!"
echo
# Stopping Stats
su - $ZM_USER -c $ZM_HOME"bin/zmstatctl stop"
if [ "$?" -ne "0" ]
then
echo "Stopping stats failed!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "Stats have been stopped"
echo
fi

# Running Stats cronjob zmlogprocess manually
su - $ZM_USER -c $ZM_HOME"libexec/zmlogprocess" > /tmp/logprocess.out 2>&1
if [ "$?" -ne "0" ]
then
echo "Error running 'logprocess'"
echo
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "Logprocess done..."
echo
fi

# Running Stats cronjob zmqueuelog manually
su - $ZM_USER -c $ZM_HOME"libexec/zmqueuelog"
if [ "$?" -ne "0" ]
then
echo "Error running 'libexec/zmqueuelog'"
echo
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "zmqueuelog done..."
echo
fi

# Starting Stats
sleep 2
su - "$ZM_USER" -c $ZM_HOME"bin/zmstatctl start"
if [ "$?" -ne "0" ]
then
echo "Starting stats failed!"
echo
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "Stats started..."
fi
else
echo "Hack not needed Stats seems to be running fine..."
fi
fi

# Status Check to see that is running
STATUS=(`su - "$ZM_USER" -c "/opt/zimbra/bin/zmcontrol status" | grep -i Stopped`)
if [ "$STATUS" ]
then
echo
echo "Services that are not running"
echo $STATUS
cat $LOG | mail -c $EMAILCC -s "Zimbra Services Stopped on `hostname --fqdn`" $EMAIL
else
echo
echo "All services are running"
echo
fi
echo
echo "Writing a full backup called:"
echo "      $BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_F"
echo "in: $ARCHIVEDIR with file sizes of max: $ARCHIVESIZE"
cd $SYNC_DIR
if [ $CRYPT = "yes" ]
then
KEY=`cat "$PASSDIR""$PASSFILE"`
echo "Archive is Encrypted"
nice -19 $DAR_BIN -K bf:$KEY -s $ARCHIVESIZE -z$COMPRESS -Z "*.gz" -Z "*.zip"\
-Z "*.bz2" -Z "*.tgz" -Z "*.zgz" -Z "*.jar" -Z "*.tiff" \
-Z "*.jpg" -Z "*.png" -Z "*.gif" -Z "*.jpeg" -R `pwd` \
-c "$ARCHIVEDIR""$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_F" -Q
else
echo "Archive is NOT Encrypted!!!"
nice -19 $DAR_BIN -s $ARCHIVESIZE -z$COMPRESS -Z "*.gz" -Z "*.zip"\
-Z "*.bz2" -Z "*.tgz" -Z "*.zgz" -Z "*.jar" -Z "*.tiff" \
-Z "*.jpg" -Z "*.png" -Z "*.gif" -Z "*.jpeg" -R `pwd` \
-c "$ARCHIVEDIR""$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_F" -Q
fi
if [ "$?" -ne "0" ]
then
echo
echo "Dar had a problem!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "Archive Created successfully"
echo
# Create MD5 Checksums to verify archives after writing to media or network transfers
cd $ARCHIVEDIR
FILENAME=`ls -A "$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_F"*`
if [ -e $FILENAME ]
then
echo "Create MD5 Checksum for $FILENAME"
$MD5SUM_BIN -b $FILENAME > "$FILENAME".md5
if [ "$?" -ne "0" ]
then
echo
echo "MD5 Checksum failed!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo
echo "MD5 Checksum Created successfully"
echo
fi
else
echo "$FILENAME not found!"
echo "This should not happen"
echo
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi
# DRCP Section. To scp newly created archives to a remote system
if [ $DRCP = "yes" ]
then
CPNAME=`ls -A "$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_F"*`
echo "copy archive to $REMOTEHOST" remote directory $REMOTEDIR
scp -i /root/.ssh/id_rsa $CPNAME "$SSHUSER"@"$REMOTEHOST":"$REMOTEDIR"
if [ "$?" -ne "0" ]
then
echo
echo "Error copying archive and checksum to $REMOTEHOST"
echo
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi
fi

# over view of all the files which where backed up
echo
echo "Create file listing from archive"
if [ $CRYPT = "yes" ]
then
KEY=`cat "$PASSDIR""$PASSFILE"`
nice -19 $DAR_BIN -K bf:$KEY -l "$ARCHIVEDIR""$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_F" -Q\
> "$ARCHIVEDIR"Backuplist-"$BACKUPDATE".txt && gzip -9 "$ARCHIVEDIR"Backuplist-"$BACKUPDATE".txt
else
nice -19 $DAR_BIN -l "$ARCHIVEDIR""$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_F" -Q\
> "$ARCHIVEDIR"Backuplist-"$BACKUPDATE".txt && gzip -9 "$ARCHIVEDIR"Backuplist-"$BACKUPDATE".txt
fi
# Script Timer
STOPTIME=(`date +%s`)
RUNTIME=$(expr $STOPTIME \- $STARTTIME)
hours=$(($RUNTIME / 3600))
seconds=$(($RUNTIME  % 3600))
minutes=$(($RUNTIME  / 60))
seconds=$(($RUNTIME  % 60))
echo
echo "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
echo "Full Zimbra Backup ended at: `date +%H:%M`"
echo "Backup took Hr:$hours Min:$minutes Sec:$seconds to complete"
echo ":::::::::::::::::Cheers Osoffice for the script:::::::::::::::::::::::"
(cat $LOG; $UUENCODE "$ARCHIVEDIR"Backuplist-"$BACKUPDATE".txt.gz "$ARCHIVEDIR"Backuplist-"$BACKUPDATE".txt.gz) | mail -c $EMAILCC \
-s "Zimbra Full Backup Log on `hostname --fqdn`" $EMAIL
echo
;;

-d | --diff)
echo
echo "      Diff Backup started at: `date +%H:%M`"

DAR_BIN=`whereis dar | awk '{print $2}'`
if [ ! -e "$DAR_BIN" ]
then
echo "Please install "dar"!"
echo "Try running the script with --INSTALL"
exit 1
fi

MAILX=`whereis mailx | awk '{print $2}'`
if [ ! -e "$MAILX" ]
then
echo "mailx is not installed!"
echo "Try running the script with --INSTALL"
exit 1
fi

RSYNC_BIN=`whereis rsync | awk '{print $2}'`
if [ ! -f "$RSYNC_BIN" ]
then
echo $SYNC_BIN
echo "Please install "rsync"!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

SSH_BIN=`whereis ssh | awk '{print $2}'`
if [ ! -e "$SSH_BIN" ]
then
echo "Please install "ssh"!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

MD5SUM_BIN=`whereis md5sum | awk '{print $2}'`
if [ ! -e "$MD5SUM_BIN" ]
then
echo "Please install "md5sum"!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

if [ ! -d $ZM_HOME ]
then
echo "$ZM_HOME not found!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

if [ ! -d $SYNC_DIR ]
then
echo "$SYNC_DIR not found!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

if [ ! -d $ARCHIVEDIR ]
then
echo "$ARCHIVEDIR not found!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi

if [ ! -d $TOO_MEDIA_DIR ]
then
echo "directory $TOO_MEDIA_DIR not found!"
echo "Try running the script with --INSTALL"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
echo
exit 1
fi

CURRENTNAME2=`ls -A -1 "$ARCHIVEDIR""$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_D"*dar 2> /dev/null | head -qn1`
CURRENTFULL=`ls -A -1 "$ARCHIVEDIR""$BACKUPWEEK"*FULL*dar 2>/dev/null | cut -d . -f1 `

if [ -f "$CURRENTNAME2" ]
then
echo "Full Zimbra Backup failed! FOUND A BACKUP WITH SAME NAME"
echo "Please check why! You should only run this script once a day with the current backup date settings!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
elif [ $CURRENTFULL ]
then
echo
# HotSync to backup directory
echo "Doing a hotsync of $ZM_HOME to $SYNC_DIR"
nice -19 $RSYNC_BIN $RSYNC_OPTS $ZM_HOME $SYNC_DIR
if [ "$?" -ne "0" ]
then
echo
echo "rsync had threw an hotsync error this is not that wild... continuing"
#cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
else
echo
echo "sync went ok"
fi

echo

# Stopping Zimbra
echo "Stopping the Zimbra server"
echo

#Disable zimbra user's crontab, we don't want it starting any jobs while we backup
crontab -u $ZM_USER -l > "$ZM_HOME"crontab.org
if [ "$?" -ne "0" ]
then
echo "could not backup "$ZM_USER"'s crontab..."
echo "continuing with out changing users crontab!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
touch "$ZM_HOME"crontab.blank
crontab -u $ZM_USER "$ZM_HOME"crontab.blank
rm "$ZM_HOME"crontab.blank
echo "Deactivated "$ZM_USER"'s cronjobs"
echo
fi

#Starting 'service downtime' counter
DOWNTIMEA=(`date +%s`)

su - $ZM_USER -c $ZM_HOME"bin/zmcontrol stop"
if [ "$?" -eq "1" ]
then
echo "zmcontrol shutdown had an error!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo
echo "Zimbra server has stopped "
fi
echo
# Some times I still have zimbra procs running, so I murder them! :-O
sleep 5
echo "kill any left over $ZM_USER procs"
PROX=(`ps -u $ZM_USER | awk '{print $1}' | grep -v PID`)
if [ "$PROX" ]
then
ps -u $ZM_USER | awk '{print $1}' | grep -v PID | xargs kill -s 15
echo "Did a Mr. Bush on some left over procs..."
echo
else
echo "Nothing to kill"
echo
fi
# ColdSyncing the zimbra server
echo "Doing a fast cold sync..."

$RSYNC_BIN $RSYNC_OPTS $ZM_HOME $SYNC_DIR
if [ "$?" -ne "0" ]
then
echo "rsync had threw an error!"
echo "This should not happen at this stage... exiting!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "sync went ok"
fi
echo

# Starting the Zimbra server again

#Reinstate zimbra user's crontab
crontab -u $ZM_USER "$ZM_HOME"crontab.org
if [ "$?" -ne "0" ]
then
echo "!!Could not reinstate "$ZM_USER"'s crontab!!"
echo "Please do this manually!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "Reinstated "$ZM_USER"'s cronjobs"
echo
fi

su - "$ZM_USER" -c $ZM_HOME"bin/zmcontrol start"
if [ "$?" -ne "0" ]
then
echo "There was an error starting Zimbra!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo
echo "Zimbra has started"
fi
# Service Timerc
DOWNTIMEB=(`date +%s`)
RUNTIME=$(expr $DOWNTIMEB \- $DOWNTIMEA)
hours=$(($RUNTIME / 3600))
seconds=$(($RUNTIME  % 3600))
minutes=$(($RUNTIME  / 60))
seconds=$(($RUNTIME  % 60))
echo
echo "Service down time was - Hr:$hours Min:$minutes Sec:$seconds"
echo

# Hack to start the stats component
if [ $STATHACK = "yes" ]
then
echo "Running A hack... This one to check and start Stats subsystem"
#Checking if Stats is running
sleep 5
STAT_CK=(`su - "$ZM_USER" -c $ZM_HOME"bin/zmcontrol status" |grep -i stats | awk '{print $2}'`)
if [ "$STAT_CK" = "Stopped" ]
then
echo "Stats is not running, thus booting Stats subsystem!"
echo
# Stopping Stats
su - $ZM_USER -c $ZM_HOME"bin/zmstatctl stop"
if [ "$?" -ne "0" ]
then
echo "Stopping stats failed!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "Stats have been stopped"
echo
fi

# Running Stats cronjob zmlogprocess manually
su - $ZM_USER -c $ZM_HOME"libexec/zmlogprocess" > /tmp/logprocess.out 2>&1
if [ "$?" -ne "0" ]
then
echo "Error running 'logprocess'"
echo
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "Logprocess done..."
echo
fi

# Running Stats cronjob zmqueuelog manually
su - $ZM_USER -c $ZM_HOME"libexec/zmqueuelog"
if [ "$?" -ne "0" ]
then
echo "Error running 'libexec/zmqueuelog'"
echo
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "zmqueuelog done..."
echo
fi

# Starting Stats
sleep 2
su - "$ZM_USER" -c $ZM_HOME"bin/zmstatctl start"
if [ "$?" -ne "0" ]
then
echo "Starting stats failed!"
echo
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "Stats started..."
fi
else
echo "Hack not needed Stats seems to be running fine..."
fi
fi

# Status Check to see that is running
STATUS=(`su - "$ZM_USER" -c "/opt/zimbra/bin/zmcontrol status" | grep -i Stopped`)
if [ "$STATUS" ]
then
echo
echo "Services that are not running"
echo $STATUS
cat $LOG | mail -c $EMAILCC -s "Zimbra Services Stopped on `hostname --fqdn`" $EMAIL
else
echo
echo "All services are running"
echo
fi
echo

echo "Writing a diff backup called:"
echo "      $BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_D"
echo "in: $ARCHIVEDIR with file sizes of max: $ARCHIVESIZE"
cd $SYNC_DIR
if [ $CRYPT = "yes" ]
then
KEY=`cat "$PASSDIR""$PASSFILE"`
echo "Archive is Encrypted"
nice -19 $DAR_BIN -J bf:$KEY -s $ARCHIVESIZE -z$COMPRESS -Z "*.gz" -Z "*.zip"\
-Z "*.bz2" -Z "*.tgz" -Z "*.zgz" -Z "*.jar" -Z "*.tiff" \
-Z "*.jpg" -Z "*.png" -Z "*.gif" -Z "*.jpeg" -R `pwd` \
-c "$ARCHIVEDIR""$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_D" -Q\
-A "$CURRENTFULL" -Q
else
echo "Archive is NOT Encrypted!!!"
nice -19 $DAR_BIN -s $ARCHIVESIZE -z$COMPRESS -Z "*.gz" -Z "*.zip"\
-Z "*.bz2" -Z "*.tgz" -Z "*.zgz" -Z "*.jar" -Z "*.tiff" \
-Z "*.jpg" -Z "*.png" -Z "*.gif" -Z "*.jpeg" -R `pwd` \
-c "$ARCHIVEDIR""$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_D" -Q\
-A "$CURRENTFULL" -Q
fi
if [ "$?" -ne "0" ]
then
echo
echo "Dar had a problem!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo "Archive Created successfully"
echo
# Create MD5 Checksums to verify archives after writing to media or network transfers
cd $ARCHIVEDIR
FILENAME=`ls -A "$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_D"*`
if [ -e $FILENAME ]
then
echo "Create MD5 Checksum for $FILENAME"
$MD5SUM_BIN -b $FILENAME > "$FILENAME".md5
if [ "$?" -ne "0" ]
then
echo
echo "MD5 Checksum failed!"
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
else
echo
echo "MD5 Checksum Created successfully"
echo
fi
else
echo "$FILENAME not found!"
echo "This should not happen"
echo
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi
# DRCP Section. To scp newly created archives to a remote system
if [ $DRCP = "yes" ]
then
CPNAME=`ls -A "$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_D"*`
echo "copy archive to $REMOTEHOST" remote directory $REMOTEDIR
scp -i /root/.ssh/id_rsa $CPNAME "$SSHUSER"@"$REMOTEHOST":"$REMOTEDIR"
if [ "$?" -ne "0" ]
then
echo
echo "Error copying archive and checksum to $REMOTEHOST"
echo
cat $LOG | mail -c $EMAILCC -s "Zimbra backup error on `hostname --fqdn`" $EMAIL
exit 1
fi
fi
fi

# over view of all the files which where backed up
echo
echo "Create file listing from archive"
if [ $CRYPT = "yes" ]
then
KEY=`cat "$PASSDIR""$PASSFILE"`
nice -19 $DAR_BIN -K bf:$KEY -l "$ARCHIVEDIR""$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_D" -Q\
> "$ARCHIVEDIR"Backuplist-"$BACKUPDATE".txt && gzip -9 "$ARCHIVEDIR"Backuplist-"$BACKUPDATE".txt
else
nice -19 $DAR_BIN -l "$ARCHIVEDIR""$BACKUPWEEK"_"$BACKUPNAME"_"$BACKUPDATE"_"$BACKUPTYPE_D" -Q\
> "$ARCHIVEDIR"Backuplist-"$BACKUPDATE".txt && gzip -9 "$ARCHIVEDIR"Backuplist-"$BACKUPDATE".txt
fi
# Script Timer
STOPTIME=(`date +%s`)
RUNTIME=$(expr $STOPTIME \- $STARTTIME)
hours=$(($RUNTIME / 3600))
seconds=$(($RUNTIME  % 3600))
minutes=$(($RUNTIME  / 60))
seconds=$(($RUNTIME  % 60))
echo
echo "::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
echo "Diff Zimbra Backup ended at: `date +%H:%M`"
echo "Backup took Hr:$hours Min:$minutes Sec:$seconds to complete"
echo ":::::::::::::::Cheers Osoffice for the script:::::::::::::::::::::::::"
echo
;;

*)
echo
echo "use -h or --help for assistance"
echo
;;

esac
exit 0

Установка и настройка Zimbra CS OSE в Debian

zimbra_logo

Примерно 2 года назад мне как системному администратору поставили задачу найти и внедрить почтовую систему обладающую определенными свойствами, среди которых были:

  • Бесплатность (свабода).
  • Приемлемый уровень локализации.
  • Функциональный вэб интерфейс.
  • Хотя бы зачатки CRM.
  • Безопасность.
  • Производительность.
  • Высокая скорость работы с почтовыми ящиками очень большого размера.

Учитывая все эти требования я принялся бороздить просторы интернета в поисках чего-то похожего. Перебрав несколько более или менее подходящих экземпляров я честно говоря впал в отчаянье. Не один из них не подпадал даже под половину требований.. Среди них были и OpenExchange, Phpgroupware и некоторые другие, в каждом из них как на зло находились весьма досадные недостатки которые напрочь исключали возможность их использования. Но тем не менее задача требовала решения и поиск продолжался пока я случайно не наткнулся на сайт zimbra.com. Представленный там продукт при детальном рассмотрении соответствовал 90% требований (в OSE варианте по сей день нету вменяемых инструментов для резервного копирования). Не смотря на некоторые недостатки, список достоинств был весьма внушителен, что не могло не радовать. И так вооружившись wget`ом и xen я приступил к первичному осмотру. Результатом которого является успешная эксплуатация сей системы в течении 2 лет.
В данной статье я постараюсь провести краткий ликбез по Zimbra CS OSE о процессе ее установки и настройки. Читать далее »

Zimbra CS OSE. Баг 41301 (Блок статистики «Нет доступных данных»)

zimbra_logoСей нелицеприятный баг был замечен при переходе с версии 5.0.18 на 6.0 и был обещан фикс в версии 6.0.1, Но к сожелению Баг небыл пофикшен и в 6.0.1..

На официальном форме по этому поводу был инициирован довольно жирный тред , где один из экспертов Zimbra некий »pfnguyen» сообщил, что это очередной баг, теперь уже под номером 41301(дубликат).

Решения проблемы пока нет, так что следим за баг-трекером и ждем заплатку..

Zimbra Collaboration Suite OSE

zimbra_logoВот решил начать серию статей о почтовой системе с открытым исходным кодом Zimbra Collaboration Suite Open Source Edition. Да да … именно Open Source Edition… ибо коммерческие дистрибуции меня в полной мере не интересуют, хотя краткий обзор по всем вариантам распространения этой системы я все таки сделаю, так на всякий случай… Постараюсь осветить все тонкости работы с этой системой, начиная от установки на популярные (и не очень… в том числе на те, что официально не поддерживаются) дистрибутивы Linux, заканчивая прикручиванием дополнительного функционала… Все это конечно можно найти в официальной документации, wiki или на страницах форума… Но к сожалению далеко не каждый может себе позволить чтение доков на английском, а Русское сообщество крайне малочисленное.. Потому я решил частично исправить положение… опубликовав цикл стаей основанных на личном опыте работы с этой системой…

Продолжение следует…