玄箱HG(debian lenny) のデータをLinkstationを起動、マウントして、rsyncするバックアップ処理を作った
大まかな仕様は以下
- 通常電源OFF状態の、同一ネットワーク内にあるLinkstationを 定時刻に wakeonlan にて起動
- 起動した Linkstation をネットワーク経由にてマウント
- サーバデータを全てrsyncしてバックアップ
- 処理の開始、終了時、特定のメールアドレスへメール送信する
必要パッケージのインストール
sudo apt-get update
sudp apt-get upgrade
sudo apt-get install wakeonlan
sudo apt-get install rsync
# mysql はインストール済みとする
# python はインストール済みとする
メール送信処理
特定アドレスにGメール送信する処理
Gmail 送信処理本体 GmailApi.py
と、それを使用する sendMail.py
で構成
まずは、Gmail送信処理から
新規作成 vim GmailApi.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import smtplib
from email.MIMEText import MIMEText
from email.Header import Header
from email.Utils import formatdate
class sendGmail:
def __init__(self, encoding, subject, body, from_addr, to_addr, login_addr, passwd):
self.date = formatdate()
self.encoding = encoding
self.subject = subject
self.body = body.encode('utf-8')
self.from_addr = from_addr
self.to_addr = to_addr
self.login_addr = login_addr
self.passwd = passwd
def sendMail(self):
msg = MIMEText(self.body, 'html', self.encoding)
msg['Subject'] = Header(self.subject, self.encoding)
msg['From'] = self.from_addr
msg['To'] = self.to_addr
msg['Date'] = self.date
s = smtplib.SMTP('smtp.gmail.com', 587)
s.ehlo()
s.starttls()
s.ehlo()
s.login(self.login_addr, self.passwd)
s.sendmail(self.from_addr, self.to_addr, msg.as_string())
s.close()
上記を使用し、Gmail送信する処理 引数は以下で
- 送信先アドレス
- タイトル
- メール本文
新規作成 vim sendMail.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from GmailApi import *
argvs = sys.argv
argc = len(argvs)
if (argc != 4):
print 'start arg count is not 4.'
sys.exit(1)
encoding = 'utf-8'
to_addr = argvs[1]
subject = argvs[2]
body = argvs[3]
from_addr = 'XXXXXXXX@gmail.com' # 送信元Gmailのアドレスを指定
login_addr = 'XXXXXXXX@gmail.com' # 送信元Gmailのアドレスを指定
passwd = '********' # 送信元Gmailのパスワードを指定
sg = sendGmail(encoding, subject, body, from_addr, to_addr, login_addr, passwd)
sg.sendMail()
マジックパケットによる、wakeonlan 起動処理
Macaddress, IPアドレス(ブロードキャスト)、送信間隔を指定して、Magicpacket を送信し続ける処理
終了はKillで
新規作成 vim magic.packet.sh
#!/bin/bash
BROADCAST=$1 # ブロードキャストIPアドレス
MAC_ADDR=$2 # Linkstaionの Macaddress
INTERVAL=$3 # 送信間隔
fncMagicPacket()
{
/usr/bin/wakeonlan -i $1 $2 >/dev/null 2>&1
}
while true
do
fncMagicPacket $BROADCAST $MAC_ADDR
sleep $INTERVAL
done
バックアップ処理本体
以下仕様
- 処理開始・終了時指定アドレスへGmail送信
- 同一ネットワーク内 Linkstation を wakeonlan 起動
- 起動した Linkstaion をネットワークマウント
- mysql dump し dump ファイルをHDD保存
- サーバデータ全てを対象に Linkstaion へ rsync バックアップ
- 完全同期型(サーバから消去されたデータは バックアップ先からも削除)
新規作成 vim backupserver.sh
#!/bin/bash
################################################################################
# SETTINGS
################################################################################
#=========================================
# BASE SETTINGS
#=========================================
SHELL_FLNM=`basename $0`
DIR_BIN=/tmp/bin # このファイル含め全てのプログラムが配置されているディレクトリを指定
DIR_LOG=/tmp/log # ディレクトリ作成済みのこと
DATE_STR="`date '+%Y%m%d.%H%M%S'`"
FIL_LOG=${DIR_LOG}/${SHELL_FLNM}.${DATE_STR}.log
#=========================================
# ERROR MAIL PACKET SETTINGS
#=========================================
SEND_MAIL=${DIR_BIN}/sendMail.py
SEND_MAIL_TO=xxxxxxx@xxxx.xxx # バックアップ処理結果送信先を指定
SEND_MAIL_SUBJECT="好きなメールタイトルを"
SEND_MAIL_BODY=""
#=========================================
# MAGIC PACKET SETTINGS
#=========================================
MAGIC_PACCKET=$DIR_BIN/magic.packet.sh
IP_BROADCAST=192.168.24.255 # ブロードキャストアドレスを指定
MACADDR_BACKUP_SRV=XX:XX:XX:XX:XX:XX # 対象の Linkstaion Macaddress を指定
MPACKET_INTERVAL=60 # マジックパケット送信間隔
MAGIC_PACCKET_PID=""
#=========================================
# MOUNT SETTINGS
#=========================================
MOUNT_POINT_BKUP_SRV=/media/ls-xhle74 # Linkstaion マウント先
MOUNT_AT_BKUP_SRV=//ls-xhle74/share # Linkstaion 共有ディレクトリ
MOUNT_USR_NAME=XXXXX # Linkstaion マウントユーザを指定
MOUNT_USR_PWD=******** # Linkstaion マウントユーザパスワードを指定
MOUNT_UID=1000 # マウントオプション UID
MOUNT_GID=1000 # マウントオプション GID
MOUNT_INTERVAL_INIT=70 # マジックパケット初回wait
MOUNT_INTERVAL=10 # wakeonlan 起動待ち時、sleep時間
MOUNT_RETRY_LIMIT=6 # マウントリトライ最大回数
#=========================================
# MYSQL SETTINGS
#=========================================
MYSQLDUMP_USR=XXXX # mysql ログインユーザ
MYSQLDUMP_PWD=******* # mysql ログインユーザパスワード
MYSQLDUMP_HST=localhost # mysql ホスト名
MYSQLDUMP_DATABASE=XXXXXXXXX # バックアップ対象データベース名
DIR_MYSQLDUMP=/tmp/mysqldump # データダンプバックアップ先
MYSQLDUMP_BASENAME=${MYSQLDUMP_DATABASE}.dump
#=========================================
# RSYNC SETTINGS
#=========================================
RSYNC_FROM=/tmp # バックアップ対象 ROOT ディレクトリ
RSYNC_TO=${MOUNT_POINT_BKUP_SRV}/bkup # バックアップ先(Linkstaion)ディレクトリ
################################################################################
fncHandleError()
{
if [ $1 -ne 0 ]
then
fncEndProc $1
fi
}
fncLog()
{
echo "$*" >> $FIL_LOG
}
fncEchoLog()
{
MSG=$*
DSTR=`date '+%Y%m%d:%H:%M:%S'`
OUTMSG="[$SHELL_FLNM] $DSTR $MSG"
fncLog "$OUTMSG"
echo "$OUTMSG"
}
fncIsDirectoryCheck() {
if [ ! -d $1 ] ; then
fncEchoLog "[$1] is not directory."
fncEndProc 1
fi
}
fncWaitEnter()
{
fncEchoLog "when you quit this program, input 'n' and enter."
read Wait
if [ "$Wait" = "n" ]
then
fncEchoLog "######################################"
fncEchoLog " Quited program "
fncEchoLog "######################################"
read Wait
exit
fi
}
fncStartProc()
{
fncEchoLog "######################################"
fncEchoLog " Start program "
fncEchoLog "######################################"
$SEND_MAIL $SEND_MAIL_TO "(PROCESS STARTED) $SEND_MAIL_SUBJECT" "server backup process is started."
}
fncEndProc()
{
if [ $1 -ne 0 ]
then
fncEchoLog "######################################"
fncEchoLog " !! Exception !! "
fncEchoLog "######################################"
$SEND_MAIL $SEND_MAIL_TO "( !!! EXCEPTION OCCURED !!! ) $SEND_MAIL_SUBJECT" "---< EXCEPTION OCCURED >--- $SEND_MAIL_BODY"
else
fncEchoLog "######################################"
fncEchoLog " mission completed. "
fncEchoLog "######################################"
$SEND_MAIL $SEND_MAIL_TO "(MISSION COMPLETED) $SEND_MAIL_SUBJECT" "server backup process is completed."
fi
exit
}
fncExecInternal()
{
CMD=$*
fncEchoLog "###########################################"
fncEchoLog " exec command. [$CMD]"
fncEchoLog "###########################################"
$CMD >>$FIL_LOG 2>&1
RC=$?
}
fncExec()
{
fncExecInternal $*
if [ $RC -ne 0 ] ; then
fncEndProc $RC
fi
}
fncExecAllowError()
{
fncExecInternal $*
}
fncStartMagicPacket()
{
SEND_MAIL_BODY="error at magic packet process."
fncEchoLog "Start magic packet process."
fncEchoLog "###########################################"
fncEchoLog " exec command. [$MAGIC_PACCKET $IP_BROADCAST $MACADDR_BACKUP_SRV $MPACKET_INTERVAL & >>$FIL_LOG 2>&1]"
fncEchoLog "###########################################"
$MAGIC_PACCKET $IP_BROADCAST $MACADDR_BACKUP_SRV $MPACKET_INTERVAL & >>$FIL_LOG 2>&1
MAGIC_PACCKET_PID=$!
fncEchoLog "magic packet process started. pid=$MAGIC_PACCKET_PID"
}
fncStopMagicPacket()
{
SEND_MAIL_BODY="error at stop magic packet process."
fncEchoLog "Stop magic packet process."
fncExec kill -9 $MAGIC_PACCKET_PID
}
fncWaitMountBkSrv()
{
SEND_MAIL_BODY="error at mount linkstation process."
fncEchoLog "Mounting. LinkStation."
FLG_MOUNTED=0
TRYCOUNT=1
while [ $TRYCOUNT -le $MOUNT_RETRY_LIMIT ]
do
fncEchoLog "###########################################"
fncEchoLog " exec command. [mount -vt cifs $MOUNT_AT_BKUP_SRV $MOUNT_POINT_BKUP_SRV -o username=$MOUNT_USR_NAME,password=*****,iocharset=utf8,uid=$MOUNT_UID,gid=$MOUNT_GID]"
fncEchoLog "###########################################"
mount -vt cifs $MOUNT_AT_BKUP_SRV $MOUNT_POINT_BKUP_SRV -o username=$MOUNT_USR_NAME,password=$MOUNT_USR_PWD,iocharset=utf8,uid=$MOUNT_UID,gid=$MOUNT_GID >>$FIL_LOG 2>&1
MOUNTRC=$?
if [ $MOUNTRC -ne 0 ] ; then
fncEchoLog "(RC=$MOUNTRC) mount error. try count $TRYCOUNT."
else
fncEchoLog "mount ok. try count $TRYCOUNT."
FLG_MOUNTED=1
break
fi
if [ $TRYCOUNT -eq 1 ] ; then
fncEchoLog "Waiting for boot to complete the LinkStation. sleep ${MOUNT_INTERVAL_INIT} s"
fncExec sleep $MOUNT_INTERVAL_INIT
else
fncExec sleep $MOUNT_INTERVAL
fi
TRYCOUNT=$(($TRYCOUNT+1))
done
if [ $FLG_MOUNTED -eq 0 ] ; then
fncEchoLog "we could not mounted $MOUNT_AT_BKUP_SRV. we retry $MOUNT_RETRY_LIMIT count. last return cord is $MOUNTRC. we give up."
fncEndProc $MOUNTRC
fi
}
fncUnMountBkSrv()
{
SEND_MAIL_BODY="error at umount linkstation process."
fncExec umount $MOUNT_POINT_BKUP_SRV
}
fncBackupArchiveDatabase()
{
SEND_MAIL_BODY="error at backup and archice database process."
cd $DIR_MYSQLDUMP
MYSQLDUMP_DUMPSQL=${MYSQLDUMP_BASENAME}.${DATE_STR}.sql
MYSQLDUMP_DUMPTARGZ=${MYSQLDUMP_DUMPSQL}.tar.gz
fncEchoLog "###########################################"
fncEchoLog " exec command. [mysqldump -u $MYSQLDUMP_USR -h $MYSQLDUMP_HST $MYSQLDUMP_DATABASE -p***** > $MYSQLDUMP_DUMPSQL]"
fncEchoLog "###########################################"
mysqldump -u $MYSQLDUMP_USR -h $MYSQLDUMP_HST $MYSQLDUMP_DATABASE -p$MYSQLDUMP_PWD > $MYSQLDUMP_DUMPSQL
RC=$?
if [ $RC -ne 0 ] ; then
fncEndProc $RC
fi
fncExec tar cvfpz $MYSQLDUMP_DUMPTARGZ $MYSQLDUMP_DUMPSQL
fncExec rm -fv $MYSQLDUMP_DUMPSQL
# todo old data remove?
}
fncBackupAllData()
{
SEND_MAIL_BODY="error at rsync process."
fncEchoLog "Start sync to backup data. from=[$RSYNC_FROM] to=[$RSYNC_TO]"
fncExec rsync -vrual --delete $RSYNC_FROM $RSYNC_TO
}
fncMain()
{
fncStartProc
# start magic packet.
fncStartMagicPacket
# wait and mount linkstation
fncWaitMountBkSrv
# buckup and archive database
fncBackupArchiveDatabase
# backup all data
fncBackupAllData
# unmount linkstation
fncUnMountBkSrv
# stop magic packet.
fncStopMagicPacket
fncEndProc $RC
}
fncMain