蘋果 發表於 2023-9-9 00:00:00

linux下svn+rsync+inotify实现代码自动同步

<p>1、环境简介</p>
<p>操作系统:CentOS release 5.7 (Final)</p>
<p>Apache版本:Apache/2.2.21 (Unix)</p>
<p>Subversion版本:svn, version 1.7.2</p>
<p>Rsync版本:rsync  version 3.0.6  protocol version 30</p>
<p>Inotify版本:inotifywait 3.14</p>
<p>SVN Server端服务器:以下统称A</p>
<p>同步测试服务器:以下统称B</p>
<p> </p>
<p>2、需求及流程简介</p>
<p>由于程序员协同开发,彼此之间开发习惯各有不同,经常会出现大家误删改他人代码的情况,对线上生产环境的稳定造成了极大的影响。因此特请出SVN来负责代码版本控制,以解决上述问题。</p>
<p>但是简单的代码控制要增加很多不必要的人工成本,如:手动提交、检出、发布、测试等,所以作为运维人员,就自然而然想到有什么办法可以让其将以上操作都自动执行完成。固有了如下需求。</p>
<p>1、代码commit至A服务器后,自动update到代码的working copy</p>
<p>2、update后需直接远程同步至B服务器进行测试</p>
<p>3、定期备份svn服务器代码库文件至备份服务器(此处与B公用一台)</p>
<p>4、待测试完毕后,通过程序控制将working copy文件,自动发布到生产环境(待开发)</p>
<p>以上前3步均是由系统级操作完成,第4步需要程序写出一个交互系统,来完成测试完毕发布的过程。本文档主要实现前3步。</p>
<p> </p>
<p>3、准备</p>
<p>SVN相关下载,详见:</p>
<p>http://www.ttlsa.com/html/723.html</p>
<p> </p>
<p>rsync下载安装</p>
<p></p>
<p>rpm -qa | grep rsync</p>
<p>(如果没有输出的话,执行下面命令安装,如果有,跳过)</p>
<p>yum install -y rsync</p>
<p></p>
<p>inotify下载</p>
<p></p>
<p>wget http://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz</p>
<p></p>
<p>4、安装配置SVN</p>
<p>详见:http://www.ttlsa.com/html/723.html</p>
<p>注:由于在A服务器和B服务器上都要安装Svn client</p>
<p>所以,为了简单起见,建议两台服务器上都完整安装SVN</p>
<p> </p>
<p>5、安装配置rsync+inotify服务端</p>
<p>安装过程主要参考:http://kerry.blog.51cto.com/172631/734087</p>
<p>这里根据自身情况,略加修改,具体内容如下</p>
<p>5.1、B服务器(rsync daemon)</p>
<p>由于是将版本库代码同步至B服务器,所以安装rsync server端的任务就落在了B服务器的身上</p>
<p></p><pre class="brush:bash;toolbar:false"># vi /etc/rsyncd.conf

uid = nobody
gid = nobody
use chroot = no
max connections = 100
timeout = 600
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log file = /var/log/rsyncd.log

path = /data/www/test/
ignore errors
read only = no
list = no
hosts allow = 192.168.1.0/255.255.255.0
auth users = test
secrets file = /etc/rsyncd/test_server.pwd</pre><p></p>
<p></p>
<p># vi /etc/rsyncd/test_server.pwd</p>
<p>test:test</p>
<p># chmod 600 /etc/rsyncd.conf /etc/rsyncd/test_server.pwd</p>
<p># echo "Welcome to use the rsync services\!" &gt;&gt; /var/rsyncd.motd</p>
<p># /usr/bin/rsync --daemon</p>
<p></p>
<p>ok,这样rsync server端就搞定了,接下来就是client端的脚本了</p>
<p>5.2、A服务器版本库</p>
<p>由于A服务器端是源服务器,所以inotify需要安装在源服务器上</p>
<p> </p>
<p></p>
<p># cd /usr/local/src/tarbag</p>
<p># tar xvf inotify-tools-3.14.tar.gz -C ../software</p>
<p># cd ../software/inotify-tools-3.14</p>
<p># ./configure &amp;&amp; make &amp;&amp; make install</p>
<p><span></span></p>
<p> </p>
<p>6、通过svn自带hooks实现自动update(本节内容是为svnsync准备,文件内容可留空即可,如果不使用svnsync功能,可略过此节)</p>
<p>6.1、A服务器,修改post-commit文件</p>
<p></p>
<p># cd  /data/svn/test/hooks/</p>
<p># cp  post-commit.tmpl  post-commit</p>
<p># vi post-commit</p>
<p>清空所有信息,将如下信息替换</p>
<p>#!/bin/sh</p>
<p>export LANG=en_US.UTF-8<br>
REPOS="$1"<br>
REV="$2"</p>
<p>AUTHOR=<code>/usr/local/bin/svnlook author -r $REV $REPOS</code><br>
DATE=<code>date '+%F'</code><br>
TIME=<code>date '+%F %T'</code><br>
DIR=/data/svn/test/hooks<br>
PATH=/usr/local/bin<br>
LOCAL_WORKING_COPY=/data/svn_data/test/<br>
SVN_SRC=/data/svn_data/test/<br>
WEB_SRC=/data/www/test/<br>
PASSWD=/etc/rsyncd/test.pwd<br>
DES=test<br>
USER=test<br>
SVN=$PATH/svn<br>
SVNSYNC=$PATH/svnsync<br>
RSYNC=/usr/bin/rsync<br>
RSYNC_LOGFILE=/var/log/rsyncd/${DATE}-rsync.log<br>
SVN_LOGFILE=/var/log/svn/${DATE}-svn.log<br>
SVN_LOGIN_INFO="--username tonyty163 --password ty1224"</p>
<p>#SVN UPDATE<br>
echo "----------------------------------BEGIN------------------------------------" &gt;&gt; ${SVN_LOGFILE}<br>
echo "The following changes were made to the code:" &gt;&gt; ${SVN_LOGFILE}<br>
echo "[$TIME]--[$AUTHOR] svn commit file:" &gt;&gt; ${SVN_LOGFILE}<br>
echo "REV is $REV,REPOS is $REPOS" &gt;&gt; ${SVN_LOGFILE}<br>
$SVN update $SVN_LOGIN_INFO $LOCAL_WORKING_COPY &gt;&gt; ${SVN_LOGFILE}<br>
if [ "$?" = "0" ];<br>
then<br>
echo "update successed" &gt;&gt; ${SVN_LOGFILE};<br>
else<br>
echo "update failed" &gt;&gt; ${SVN_LOGFILE};<br>
fi<br>
$SVN log $LOCAL_WORKING_COPY -v -r "$REV" $SVN_LOGIN_INFO &gt;&gt; ${SVN_LOGFILE}<br>
$SVN diff $LOCAL_WORKING_COPY -c "$REV" --no-diff-deleted $SVN_LOGIN_INFO &gt;&gt; ${SVN_LOGFILE}<br>
echo "------------------------------------END------------------------------------" &gt;&gt; ${SVN_LOGFILE}</p>
<p>#Rsync TO WEB_SRC<br>
${RSYNC} -aH --delete --progress --exclude=".svn/" ${SVN_SRC} ${WEB_SRC} &amp;&amp;  echo "local rsync succesed" &gt;&gt; ${RSYNC_LOGFILE} 2&gt;&amp;1<br>
echo "------------------------------------END------------------------------------" &gt;&gt; ${RSYNC_LOGFILE} 2&gt;&amp;1;<br>
</span></p>
<p>简单描述下上述脚本的功能</p>
<p>首先post-commit脚本,最主要的作用就是等版本库有人commit提交了以后进行的动作</p>
<p>这个脚本最先生成了一个以日期为文件名的日志在$DIR/logs目录下</p>
<p>然后分别记录了时间,作者,以及svn updata的情况和svn log,svn diff的信息</p>
<p>注:记录日志是为了方便查询排错使用</p>
<p> </p>
<p> </p>
<p>6.2、B服务器,修改start-commit和pre-revprop-change</p>
<p></p>
<p># cd /data/svn/test/hooks/</p>
<p># vi start-commit</p>
<p> </p>
<p>#!/bin/sh</p>
<p> </p>
<p>USER="$2"</p>
<p> </p>
<p>if [ "$USER" = "user" ]; then exit 0; fi</p>
<p> </p>
<p>echo "Only the user user may change revision properties as this is a read-only, mirror repository." &gt;&amp;2</p>
<p># All checks passed, so allow the commit.</p>
<p>exit 1</p>
<p></p>
<p>将文件内容修改为上述内容</p>
<p></p>
<p># vi pre-revprop-change</p>
<p> </p>
<p>#!/bin/sh</p>
<p> </p>
<p>REPOS="$1"</p>
<p>REV="$2"</p>
<p>USER="$3"</p>
<p>PROPNAME="$4"</p>
<p>ACTION="$5"</p>
<p> </p>
<p>if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi</p>
<p> </p>
<p>echo "Changing revision properties other than svn:log is prohibited" &gt;&amp;2</p>
<p>exit 0</p>
<p> </p>
<p>if [ "$USER" = "user" ]; then exit; fi</p>
<p> </p>
<p>echo "Only the user user may change revision properties as this is a read-only, mirror repository." &gt;&amp;2</p>
<p>exit 1</p>
<p></p>
<p>将文件内容修改为上述内容</p>
<p> </p>
<p> </p>
<p>7、通过rsync和inotify实现A服务器与B服务器同步</p>
<p>各组件安装完毕,接下来要自己写一个rsync后台监控脚本,内容如下</p>
<p></p>
<p># vi /usr/local/src/scripts/rsync.sh</p>
<p>#!/bin/bash<br>
HOST=107.6.15.235<br>
SVN_SRC=/data/svn_data/test/<br>
WEB_SRC=/data/www/test/<br>
PASSWD=/etc/rsyncd/test.pwd<br>
DES=test<br>
USER=test<br>
DATE=<code>date '+%F'</code><br>
RSYNC_LOGFILE=/var/log/rsyncd/${DATE}-rsync.log</p>
<p>/usr/local/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format  '%T %w%f' -e modify,delete,create,attrib ${WEB_SRC} | while read  file<br>
do<br>
rsync -aH --delete --progress ${WEB_SRC} ${USER}@${HOST}::${DES} --password-file=${PASSWD} &amp;&amp;  echo "${file} rsync succesed" &gt;&gt; ${RSYNC_LOGFILE} 2&gt;&amp;1<br>
if [ $? -ne 0 ];<br>
then<br>
echo "remote rsync failed" &gt;&gt; ${RSYNC_LOGFILE};<br>
fi<br>
echo "-----------------------------------END-------------------------------------" &gt;&gt; ${RSYNC_LOGFILE} 2&gt;&amp;1;<br>
done</p>
<p></p>
<p>简单说明一下脚本的功能,主要是两个</p>
<p>a、由inotifywait监控${src}目录的变化</p>
<p>b、将变化的文件存入${file},传递给rsync进行同步(即增量同步),并将更新的文件写入日志</p>
<p> </p>
<p>8、通过crontab定时备份SVN</p>
<p></p>
<p># crontab -e</p>
<p>* * * * * /usr/local/src/scripts/svnsync.sh</p>
<p> </p>
<p># vi /usr/local/src/scripts/svnsync.sh</p>
<p>#!/bin/sh</p>
<p>DATE=<code>date '+%F'</code></p>
<p>TIME=<code>date '+%F %T'</code></p>
<p>DIR=/data/svn/test/hooks</p>
<p>PATH=/usr/local/bin</p>
<p>SVN=$PATH/svn</p>
<p>SVNSYNC=$PATH/svnsync</p>
<p>MIRROR_SVN=http://192.168.1.204/svn/test/</p>
<p>SVN_LOGIN_INFO="--username user --password passwd"</p>
<p>$SVNSYNC sync $MIRROR_SVN $SVN_LOGIN_INFO &gt;&gt; $DIR/logs/$DATE-log.txt</p>
<p>if [ "$?" = "0" ];</p>
<p>then</p>
<p>echo "svnsync successed" &gt;&gt; $DIR/logs/$DATE-log.txt;</p>
<p>else</p>
<p>echo "svnsync failed" &gt;&gt; $DIR/logs/$DATE-log.txt;</p>
<p>fi</p>
<p></p>
<p>上述脚本主要功能简介:</p>
<p>首先crontab每分钟执行一次svnsync.sh脚本</p>
<p>脚本中是远程同步本地版本库(注:非working copy,即svn的db文件)</p>
<p>同步完成后将脚本执行结果记录进日志</p>
頁: [1]
查看完整版本: linux下svn+rsync+inotify实现代码自动同步