#!/bin/bash #Date:2018-01-08 #Author:xxxxxx #Function:xxxxxx #Change:2018-01-17 # #设置忽略CTRL+C信号 trap 'my_exit;exit' SIGINT SIGTERM SIGQUIT #开启DEBUG模式 #set -x #如果有命令执行返回值为非0,那么脚本将结束,不再继续执行 # set -e #导入rsync使用的密码 export RSYNC_PASSWORD='xxxxxx' #设置脚本涉及的目录变量 pathdir=$(cd $(dirname $0);pwd) #源主机同步到本机的临时目录 tmpdir='/data/migrate_tmp' # tmpdir='/data/migrate_tmp/tmp' #测试用 #管理机 domain_m=("cms.domain.com" "pic.domain.com") youxi_m=("/data1/www/abc.test.com" "/data1/www/pic.domain.com") # youxi_m=("/data/migrate_tmp/abc.test.com" "/data/migrate_tmp/pic.domain.com") #测试用 #模板机 domain_t='cms.domain.com' youxi_t='/data2/www/abc.test.com' #web机 domain_web='' youxi_web='/data/webapps' #youxi_web='/data/migrate_tmp/webapps' #测试用 #图片机 domain_pic='pic.domain.com' youxi_pic='/data/webapps/pic.domain.com' #判断临时目录是否存在,若不存在则创建 [ -d ${tmpdir} ] && rm -rf ${tmpdir}/* || mkdir -p ${tmpdir} #备份目录 # [ -d /data/fabuqi_bak ] && mkdir /data/fabuqi_bak #进入到脚本所在的目录 cd ${pathdir} #定义grep查找需要替换的文件列表正则 grep_re="img.dwstatic.com|img[1-5].dwstatic.com|pic[1-5].domain.com|pic[0-5]1.domain.com|public.domain.com|pic.domain.(com|cn)" #trap的执行函数 function my_exit(){ echo trap_handle_time: $(date "+%Y-%m-%d %H:%M:%S") echo "exit" } #脚本使用说明函数 function usage(){ echo "Usage: $0 [OPTIONS]" echo " - Here to display help info ." echo " - The args is only two ." echo " - OPTIONS: [ all | zhuanqu_ID | 专区ID ] ." echo " example: /bin/bash migrate.sh zxyzxy " exit 1 } #logger function function log_info(){ DATA_N=$(date "+%Y-%m-%d %H:%M:%S") USER_N=$(whoami) echo "${DATA_N} ${USER_N} execute $0 [INFO] $@" | tee -a ${pathdir}/migrate.log } #配置变量函数,sync_dir是同步的源主机子目录,destdir是新发布器目标目录。 function config_and_rsync_single(){ #从源主机的哪个机器同步数据 rsync_from=${2} #目标同步的目录 if [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then #拉取单个专区文件资源,保留文件时间属性 for i in `seq 0 $(expr ${#domain_m[*]} - 1)` do log_info "set the sync_dir and destdir value ..." sync_dir=${domain_m[$i]} destdir=${youxi_m[$i]} #备份目录 log_info "backup the destdir ..." cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,如果临时目录已经存在,就直接拷贝文件,如果不存在就创建临时目录在拷贝目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。 log_info "create tmpdir ..." [ -d ${tmpdir}/${sync_dir} ] && cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} 2>>${pathdir}/migrate.log || mkdir -p ${tmpdir}/${sync_dir} && cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} 2>>${pathdir}/migrate.log log_info "Start to get ${1} files ......" rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/${1} ${tmpdir}/${sync_dir} | tee -a ${pathdir}/migrate.log log_info "Start to execute update_single_id function ......" update_single_id ${tmpdir}/${sync_dir} ${1} ${destdir} done log_info "建立专区对应的软连接 ..." ln -nfs /data1/www/abc.test.com/${id} /data1/webapps/${id}.domain.com 2>>${pathdir}/migrate.log chown -R www-data:www-data /data1/webapps/${id}.domain.com elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then log_info "set the sync_dir and destdir value ..." sync_dir=${domain_t} destdir=${youxi_t} #备份目录 log_info "backup the destdir ..." cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。 log_info "create tmpdir ..." cp -rpvu ${destdir}/* ${tmpdir} 2>>${pathdir}/migrate.log log_info "Start to get ${1} files ......" rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/${1} ${tmpdir}/ | tee -a ${pathdir}/migrate.log log_info "Start to execute update_single_id function ......" update_single_id ${tmpdir} ${1} ${destdir} log_info "建立专区对应的软连接 ..." ln -snf ${destdir}/${id} /data/data1/www/abc.test.com/${id}.domain.com 2>>${pathdir}/migrate.log chown -R www-data:www-data /data/data1/www/abc.test.com/${id}.domain.com elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then log_info "set the sync_dir and destdir value ..." sync_dir=${domain_web} destdir=${youxi_web} #备份目录 log_info "backup the destdir ..." cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。 log_info "create tmpdir ..." cp -rpvu ${destdir}/* ${tmpdir} 2>>${pathdir}/migrate.log log_info "Start to get ${1} files ......" rsync -avuzt game_test@${rsync_from}::game_test/${1}.domain.com ${tmpdir}/ | tee -a ${pathdir}/migrate.log log_info "Start to execute update_single_id function ......" update_single_id ${tmpdir} ${1}.domain.com ${destdir} log_info "Start to backup ${1} nginx configure file......" [ -d /data/services/nginx_vhost_bak ] || mkdir -p /data/services/nginx_vhost_bak cp -pvu /data/services/nginx_vhost/${1}.*.conf /data/services/nginx_vhost_bak/ 2>>${pathdir}/migrate.log log_info "Start to rsync ${1} nginx configure file ......" rsync -avuzt game_test@${rsync_from}::nginx_test/${1}.*.conf /data/services/nginx_vhost/ log_info "update the ${1} nginx conf,please to reload nginx service by manual ..." # service nginx reload else log_info "set the sync_dir and destdir value ..." sync_dir=${domain_pic} destdir=${youxi_pic} #备份目录 log_info "backup the destdir ..." cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。 log_info "create tmpdir ..." cp -rpvu ${destdir}/* ${tmpdir} 2>>${pathdir}/migrate.log log_info "Start to get ${1} files ......" rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/${1} ${tmpdir}/ | tee -a ${pathdir}/migrate.log log_info "Start to execute update_single_id function ......" update_single_id ${tmpdir} ${1} ${destdir} fi } #迁移单个专区函数 function update_single_id(){ _tmpdir=${1} id=${2} _destdir=${3} cd ${_tmpdir} log_info "replace contexts in the files that in the ${id} directory ..." #判断目录是否为空 if [ "`ls -A ${_tmpdir}/${id}`" = "" ]; then log_info "the ${id} is indeed empty." #判断目录及其子目录是否为空 elif [ "`find ${_tmpdir}/${id}/* -type f`" = "" ]; then log_info "the ${id} and subdir are empty." #判断是否有文件需要做内容替换 elif [ "`grep -rEl ${grep_re} ${_tmpdir}/${id}/*`" = "" ]; then log_info "the ${id} not files need to replace." #不为空时执行修改文件内容操作 else log_info "Start to sed ......" sed -i -e 's/img.dwstatic.com/img.game.dwstatic.com/g' -e 's/img(.).dwstatic.com/img1.game.dwstatic.com/g' -e 's/pic(.).domain.com/img1.game.dwstatic.com/g' -e 's/pic01.domain.com/img.game.dwstatic.com/g' -e 's/pic(.)(.).domain.com/img1.game.dwstatic.com/g' -e 's/public.domain.com/publicgame.domain.com/g' -e 's/pic.domain.(com|cn)/img.game.dwstatic.com/g' $(grep -rEl ${grep_re} ${_tmpdir}/${id}/*) fi if [ -d ${_destdir}/${id} ];then log_info "the ${id} is a exist id,backup old ${id} dirs ..." [ -d /data/fabuqi_bak/${id}_bak ] && log_info "the ${id}_bak is exist,not need to backup ..." || cp -rfp ${_destdir}/${id} /data/fabuqi_bak/${id}_bak log_info "replace old ${id} dirs by new ${id} dirs ..." #同步专区目录到新发布器目标目录中,只会在源文件的更改时间较目标文件更新时或是目标文件并不存在时,才复制文件,保留文件时间属性 cp -rpvu ${_tmpdir}/${id}/* ${_destdir}/${id}/ | tee -a ${pathdir}/migrate.log chown -R www-data:www-data ${_destdir}/${id} else log_info "the ${id} is a new id,not to backup." #同步专区目录到新发布器目标目录中 cp -rpvu ${_tmpdir}/${id} ${_destdir}/${id} | tee -a ${pathdir}/migrate.log chown -R www-data:www-data ${_destdir}/${id} fi log_info "update_single_id task done." } #配置变量函数,sync_dir是同步的源主机子目录,destdir是新发布器目标目录。 function config_and_rsync_all(){ #从源主机的哪个机器同步数据 rsync_from=${1} #目标同步的目录 if [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then #拉取所有专区文件资源,保留文件时间属性 for i in `seq 0 $(expr ${#domain_m[*]} - 1)` do log_info "set the sync_dir and destdir value ..." sync_dir=${domain_m[$i]} destdir=${youxi_m[$i]} #备份目录 log_info "backup the destdir ..." cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,如果临时目录已经存在,就直接拷贝文件,如果不存在就创建临时目录在拷贝目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。 log_info "create tmpdir ..." [ -d ${tmpdir}/${sync_dir} ] && cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} || mkdir -p ${tmpdir}/${sync_dir} && cp -rpvu ${destdir}/* ${tmpdir}/${sync_dir} log_info "Start to get ${sync_dir} all files ......" rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/* ${tmpdir}/${sync_dir} | tee -a ${pathdir}/migrate.log log_info "Start to execute update_all_id ${sync_dir} function ......" update_all_id ${tmpdir}/${sync_dir} ${destdir} done for id in $(ls ${tmpdir}/${domain_m[0]}) do log_info "建立专区对应的软连接 ..." ln -nfs /data1/www/abc.test.com/${id} /data1/webapps/${id}.domain.com chown -R www-data:www-data /data1/webapps/${id}.domain.com done elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then log_info "set the sync_dir and destdir value ..." sync_dir=${domain_t} destdir=${youxi_t} #备份目录 log_info "backup the destdir ..." cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。 log_info "create tmpdir ..." cp -rpvu ${destdir}/* ${tmpdir}/ log_info "Start to get all files ......" rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/* ${tmpdir}/ | tee -a ${pathdir}/migrate.log log_info "Start to execute update_all_id function ......" update_all_id ${sync_dir} ${destdir} for id in $(ls ${tmpdir}/${sync_dir}) do log_info "建立专区对应的软连接 ..." ln -snf ${destdir}/${id} /data/data1/www/abc.test.com/${id}.domain.com chown -R www-data:www-data /data/data1/www/abc.test.com/${id}.domain.com done elif [[ "${rsync_from}" == "xxx.xxx.xxx.xxx" ]]; then log_info "set the sync_dir and destdir value ..." sync_dir=${domain_web} destdir=${youxi_web} #备份目录 log_info "backup the destdir ..." cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。 log_info "create tmpdir ..." cp -rpvu ${destdir}/* ${tmpdir}/ log_info "Start to get all files ......" rsync -avuzt game_test@${rsync_from}::game_test/* ${tmpdir}/ | tee -a ${pathdir}/migrate.log log_info "Start to execute update_all_id function ......" update_all_id ${sync_dir} ${destdir} log_info "Start to backup all nginx configure file......" cp -r /data/services/nginx_vhost /data/services/nginx_vhost_bak log_info "Start to rsync all nginx configure file ......" rsync -avuzt game_test@${rsync_from}::nginx_test/* /data/services/nginx_vhost/ log_info "update the nginx conf,please to reload nginx service by manual ..." # service nginx reload else log_info "set the sync_dir and destdir value ..." sync_dir=${domain_pic} destdir=${youxi_pic} #备份目录 log_info "backup the destdir ..." cp -rp ${destdir} ${destdir}_`date "+%Y%m%d%H%M%S"` #将目标目录拷贝到临时目录,为了保证sed处理之后文件时间改变不影响覆盖目标目录,所以将目标目录拷贝到临时目录处理之后再覆盖到目标目录中。 log_info "create tmpdir ..." cp -rpvu ${destdir}/* ${tmpdir}/ log_info "Start to get all files ......" rsync -avuzt game_test@${rsync_from}::game_test/${sync_dir}/* ${tmpdir}/ | tee -a ${pathdir}/migrate.log log_info "Start to execute update_all_id function ......" update_all_id ${sync_dir} ${destdir} fi } #批量迁移所有专区的函数 function update_all_id(){ _tmpdir=${1} _destdir=${2} cd ${_tmpdir} for id in $(ls ${_tmpdir}/) do if [[ ${id} == "ssss" || ${id} == "testsslj" ]]; then log_info "skip the ${id}." elif [[ -f ${_tmpdir}/${id} ]]; then log_info "the ${_tmpdir}/${id} is a file,not dir,please check it and sync by manual." else log_info "migrate ${id} start..." cd ${_tmpdir}/${id} log_info "replace contexts in the files that in the ${id} directory ..." #判断目录是否为空 if [ "`ls -A ${_tmpdir}/${id}`" = "" ]; then log_info "the ${id} is indeed empty." #判断目录及其子目录是否为空 elif [ "`find ${_tmpdir}/${id}/* -type f`" = "" ]; then log_info "the ${id} and subdir are empty." #判断是否有文件需要做内容替换 elif [ "`grep -rEl ${grep_re} ${_tmpdir}/${id}/*`" = "" ]; then log_info "the ${id} not files need to replace." #不为空时执行修改文件内容操作 else log_info "Start to sed ......" sed -i -e 's/img.dwstatic.com/img.game.dwstatic.com/g' -e 's/img(.).dwstatic.com/img1.game.dwstatic.com/g' -e 's/pic(.).domain.com/img1.game.dwstatic.com/g' -e 's/pic01.domain.com/img.game.dwstatic.com/g' -e 's/pic(.)(.).domain.com/img1.game.dwstatic.com/g' -e 's/public.domain.com/publicgame.domain.com/g' -e 's/pic.domain.(com|cn)/img.game.dwstatic.com/g' $(grep -rEl ${grep_re} ${_tmpdir}/${id}/*) fi if [ -d ${_destdir}/${id} ]; then log_info "the ${id} is a exist id,backup old ${id} dirs ..." [ -d /data/fabuqi_bak/${id}_bak ] && log_info "the ${id}_bak is exist,not need to backup ..." || cp -rfp ${_destdir}/${id} /data/fabuqi_bak/${id}_bak log_info "replace old ${id} dirs by new ${id} dirs ..." #同步专区目录到新发布器目标目录中,只会在源文件的更改时间较目标文件更新时或是目标文件并不存在时,才复制文件,保留文件时间属性 cp -rpvu ${tmpdir}/${1}/${id}/* ${_destdir}/${id}/ | tee -a ${pathdir}/migrate.log chown -R www-data:www-data ${_destdir}/${id} else log_info "the ${id} is a new id,not to backup." #同步专区目录到新发布器目标目录中 cp -rpvu ${tmpdir}/${1}/${id} ${_destdir}/${id} | tee -a ${pathdir}/migrate.log chown -R www-data:www-data ${_destdir}/${id} fi log_info "migrate ${id} end..." fi done log_info "update_all_id task done." } #主函数 function main(){ domain_ip=("xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx") youxi_ip=("xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx" "xxx.xxx.xxx.xxx") #限制执行脚本的ip,并且制定对应的新管理机从源主机管理机拉取文件,其他类型的机器一样,否则,不执行脚本。 for index in `seq 0 $(expr ${#domain_ip[*]} - 1)` do if [ $(ifconfig | grep ${youxi_ip[$index]} | wc -l) -eq 1 ]; then ip=${domain_ip[$index]} break else ip="error_x" continue fi done if [ $# -ne 1 ]; then usage # elif [[ ${1} == "all" ]]; then # config_and_rsync_all ${2} elif [[ ${1} == "ssss" || ${1} == "testsslj" ]]; then log_info "skip the ${1}." else if [[ ${ip} == "error_x" ]]; then log_info "this host $(ifconfig | grep 'inet addr'|awk '{print $2}'| awk -F: '{print $2}'| grep -vE '^$' | head -1) no exist youxi_ip list,please add this ip to youxi_ip on this scripts." else config_and_rsync_single ${1} ${ip} fi fi } #执行主函数 main $@