2007/01 15
很多人开始使用subversion之后,就想着,要建立一个测试用的服务器,不需要把文件update到本地再进行测试。这个在我以前的一篇文章中写过,但当时理解也不深,也写得很含糊。现在连自己都看不懂了。

原理: 基于subversion的钩子,即hook。在subversion执行一个操作时,那会相应的首先去调用相关的钩子程序(如果存在的话)。那么实现一个同步的测试服务器,我们只需要在一个用户执行完毕一个commit操作之后,让钩子程序去自动更新测试服务器的文件即可。通过这个思路,我们需要作的就是建立一个post-commit的钩子。

钩子文件在你的svn源目录下,即存放subversion版本数据的文件夹。以前面我写的两篇文章中的情况为例,
文一(win)的钩子文件应该在 E:\svn2\hooks
文二(Linux)的钩子文件应该在 /var/svn/hooks
文件夹内已经存在有一些.tmpl文件,这些只是一些模板(TeMPLate)或者说是示例文件。它们不会被执行。


先以linux为例,来讲讲如何构建一个同步的测试服务器127.0.0.2(在Ubuntu 6.10, apache2.0.55,subversion1.3.1下调试通过。2007/1/18)
我们假设你已经建立好了一个apache+subversion的环境。
0.准备工作
为同步服务器建立访问subversion版本的权限,清参考以前的文章

sudo htpasswd2 /etc/apache2/dav_svn.passwd server
 

1. 使用checkout建立一个工作复本

cd /var/www
sudo mkdir /var/www/127.0.0.2 #建立测试服务器站点根目录
sudo chown www-data.www-data 127.0.0.2 #更改用户所有者
sudo su www-data #切换到www-data,需要使用sudo,因为超级权限可以使用任何用户,而不需要密码,执行后会发现命令提示符可能会有变化
svn checkout http://127.0.0.10/lab.rollenc.com/trunk 127.0.0.2  #取出subversion上的文件,可能需要密码
                                                                                  # 请保证执行checkout语句的用户是www-data,否则在以后钩子调用update时会出现无法创建或修改文件的错误
exit #退出www-data用户
 

说明:我们必须把/var/www/127.0.0.2目录的所有者设置成apache的运行者(www-data), 他必须对文件夹具有完全的可读写操作权限。我使用
sudo chown www-data www
sudo su www-data

这样的方式来避免把/var/www/127.0.0.2目录设置成777的权限。
另外可以执行下面的代码实现相同的功能:

cd /var/www
sudo mkdir /var/www/127.0.0.2 #建立测试服务器站点根目录
sudo svn checkout http://127.0.0.10/lab.rollenc.com/trunk 127.0.0.2 #取出subversion上的文件,可能需要密码
sudo chown -R www-data.www-data 127.0.0.2/ #把文件用户修改成apache的执行用户
 

之后使用


ls -Al 127.0.0.2
 


应该可以得到

drwxr-xr-x 7 www-data www-data 4096 2007-01-17 10:21 .svn
...一些其他的文件


2。设置apache,把你需要的域名指向这个文件夹。

sudo gedit /etc/apache2/sites-available/127.0.0.2
 

输入以下文字

<VirtualHost 127.0.0.2>
        ServerAdmin rollenc@localhost.com
        ServerName localhost
        DocumentRoot /var/www/127.0.0.2
        <Directory />
        Options FollowSymLinks
        AllowOverride None
        </Directory>
        <Directory /var/www/127.0.0.2>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
                # Uncomment this directive is you want to see apache2's
                # default start page (in /apache2-default) when you go to /
                #RedirectMatch ^/$ /apache2-default/
        </Directory>

        ErrorLog /var/log/apache2/127.0.0.2_error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /var/log/apache2/127.0.0.2_access.log combined
        ServerSignature On
</VirtualHost>
 

启用他

sudo ln -s /etc/apache2/sites-available/127.0.0.2 /etc/apache2/sites-enabled/127.0.0.2
 

重启apache。

sudo apache2 -k restart
 

在浏览器上使用http://127.0.0.2可以浏览到你subversion上最新版本

3。建立钩子
现在是关键的一步,我们需要使我门的测试服务器127.0.0.2进行同步更新:
在/var/svn/hooks/目录下建立post-commit文件

cd /var/svn/hooks/
sudo gedit post-commit
 

输入以下内容

#!/bin/sh
REPOS="$1"
REV="$2"
svn update /var/www/127.0.0.2 --username server --password serverpassword
#echo `whoami`,$REPOS,$REV >> /home/rollenc/svn_hook_var.txt
#svn update /var/www/127.0.0.2 --username server --password serverpassword 2>/home/rollenc/svn_hook_log.txt
 

说明:REPOS即第一个变量$1是subversion数据库的地址,REV即第二的变量$2是commit之后的版本号。
编辑完毕后设置文件权限为可执行:

sudo chmod 755 post-commit
 

搞定。
下面来试一下,同步有没有成功。
再建立一个工作副本,然后添加或者修改一些东西,最后上传。
以下的操作是在客户端中进行了,不需要在服务器断进行。

cd /var/www
svn checkout http://127.0.0.10/lab.rollenc.com/trunk 127.0.0.6 #取出subversion上的文件作为你的工作副本,你的工作以后就在这个文件夹内展开。
                                        #所以,不需要sudo,但要保证有127.0.0.6文件夹存在,而且可写
echo '<?php phpinfo(); ?>' > phpinfo.php #建立一个phpinfo文件
svn add phpinfo.php   #把phpinfo加入版本库
svn commit  #提交
 

在浏览器中你设定的同步服务器地址http://127.0.0.2/phpinfo.php,愿上帝保佑你的成果一切正常。可以看到phpinfo的信息。

如果不正常你可以稍微修改上面使用#注释掉的命名,使其输出的文件目录符合你的系统。
去掉#,重新运行,并通过查看上面设置的txt来获得一些信息。
第一句[#echo ...]是获取当前的执行用户(如果正常应该与apache的执行用户和测试服务器文件所有者相同),$REPOS,$REV是获得的两个参数
第二句[#svn...]是把update的获取update的结果,一般错误信息在这里可以得到。


在Windows下我使用同样的方法试图建立钩子,但没有成功。感谢水蓝色青蛙(QQ:565259)的帮助,windows下的钩子问题解决。
以下是方法和代码,在windows XP下测试成功。
1,2步很类似,不再重复了
经过1,2步的操作之后,DIR的值E:/htddocs/testserver.lab.rollenc.com 为测试服务器的根目录。如果是win2003,你可能还需要参照ubuntu的方法设置一些权限。
第三步的中的钩子程序名称需要改为:post-commit.bat写成如下:

@echo off
SET REPOS=%1
SET USER=%2
SET SVN="D:/subversion/bin/svn.exe"
SET DIR="E:/htddocs/testserver.lab.rollenc.com"
(call %SVN% update %DIR% --username server --password serverpassword --non-interactive)
 


-------------以下内容已删除-----------

SET REPOS=%1
SET REV=%2
SET svn="D:/subversion/bin/svn.exe"
SET DIR="E:/htdocs/testserver.lab.rollenc.com"
%svn% update %DIR%
 

按理说,和linux的执行是一样的,但就是出错。
如commit一个test文件,则显示错误信息为:

Modified: E:\htdocs\testcopy\test.php
Sending content: E:\htdocs\testcopy\test.php
Error: Commit failed (details follow):
Error: MERGE request failed on '/lab.rollenc.com/trunk'
Error: MERGE of '/lab.rollenc.com/trunk': 200 OK (http://127.0.0.10)

而此时,test.php已经commit成功,在subversion数据库中已经存在有本次记录,但E:\htdocs\testcopy工作复本还是显示为没有commit。需要同步的E:/htdocs/testserver.lab.rollenc.com也没有update。

我个人压根不懂windows下的编程,以上代码是边google边学来的。所以还是希望有达人帮忙,好让我完成这篇blog,我也好给大家一个完整的交待。

最终参考了一些文档,还是没能解决win下的问题,我把测试和输出结果放下面:

@echo off
echo "" >  E:/hookLog.txt
echo "1" >> E:/hookLog.txt
SET REPOS=%1
echo "2" >> E:/hookLog.txt
SET USER=%2
echo "3" >> E:/hookLog.txt
echo %REPOS%, %USER% >> E:/hookLog.txt
SET SVN="D:/subversion/bin/svn.exe"
echo "4" >> E:/hookLog.txt
SET DIR="E:/htdocs/testserver.lab.rollenc.com"
echo "5" >> E:/hookLog.txt
REM call %SVN% update %DIR% >> E:/hookLog.txt
REM SET PATH=D:/subversion/bin/
REM svn update "E:/htdocs/testserver.lab.rollenc.com" >> E:/hookLog.txt
(call %SVN% update "E:/htdocs/testserver.lab.rollenc.com") >> E:/hookLog.txt
echo "6" >> E:/hookLog.txt
 

REM是注释,REM掉了我使用的很多种测试,切换REM可以运行其它的一些测试,但是全部无效。
以下是上面代码的输出:

""
"1"
"2"
"3"
E:/svn2, 54
"4"
"5"
"6"
 

1-6全部正常输出,惟一的是 svn update这一句没有输出任何东西。
完全放弃!等待达人。。。。
------------以上内容已删除-----------------



有问题也欢迎在下面贴出,乐意帮忙:)
Defined tags for this entry: ,

Posted by rollenc

0 Trackbacks

  1. No Trackbacks

22 Comments

Display comments as(Linear | Threaded)
  1. h058 says:

    不错啊!

    Comments ()

  2. Wzhzhang says:

    学习了,不错.

    Comments ()

  3. Anonymous says:

    你好。我想问一下你的这一部
    svn checkout http://127.0.0.10/lab.rollenc.com/trunk 127.0.0.2 #取出subversion上的文件,可能需要密码


    需要的是哪个用户的密码

    Comments ()

  4. Anonymous says:

    subversion 的密码

    Comments ()

  5. Anonymous says:

    你好。我按照你的方法做了一遍。
    系统是freebsd的

    现在就差最后一步。钩子无法触发。
    加入
    #echo `whoami`,$REPOS,$REV >> /home/rollenc/svn_hook_var.txt
    #svn update /var/www/127.0.0.2 --username server --password serverpassword 2>/home/rollenc/svn_hook_log.txt

    只能出现第一个日志
    这是我的post-commit
    #!/bin/sh
    REPOS="$1"
    REV="$2"
    export LANG=en_US.UTF-8
    svn update /usr/local/svn/liandong --username harnek --password shan /usr/local/www/web/harnek
    echo `whoami`,$REPOS,$REV >> /usr/local/svn/svn_hook_var.txt
    svn update /usr/local/svn/liandong --username harnek --password shan /usr/local/www/web/harnek>/usr/local/svn/we/svn_hook_log.

    Comments ()

  6. Anonymous says:

    哦。是我的错误。
    >/usr/local/svn/we/svn_hook_log.回复 ()地址打错了。
    我刚才手动运行了一下可以。
    但用客户端还是无法自动触发post-commit。日志也没记录

    Comments ()

  7. rollenc says:

    1. 检查输出的文件权限,是否可写或可建立;
    2. 检查钩子权限是否可执行;
    3 svn update行错误, 请修正为:
    svn update /var/www/127.0.0.2 --username server --password serverpassword
    说明:
    svn update 你的工作目录 --username svn用户--password svn用户密码
    4. 其他的带有#的语句为测试语句,在测试时请根据需要一句一句测试

    Comments ()

  8. Anonymous says:

    郁闷了。都检查了,权限也没问题。
    但客户端执行时只有一个测试文档svn_hook_var.txt出来。
    -rw-r--r-- 1 vuser vgroup 367 Sep 26 17:56 svn_hook_var.txt

    而手动时却出现-rw-r--r-- 1 root vgroup 16 Sep 26 17:59 svn_hook_log.txt
    -rw-r--r-- 1 vuser vgroup 374 Sep 26 17:59 svn_hook_var.txt

    Comments ()

  9. Anonymous says:

    好象有点头绪。当我su到vuser(apche用户时)harnek@www /usr/local/svn/liandong/hooks # su vuser
    %./post-commit
    At revision 62.
    ./post-commit: cannot create /usr/local/svn/svn_hook_log.txt: Permission denied


    然后跑到测试语句那。-rw-r--r-- 1 root vgroup 16 Sep 26 17:59 svn_hook_log.txt
    -rw-r--r-- 1 vuser vgroup 382 Sep 26 18:01 svn_hook_var.txt
    说明就只出来了第二句

    Comments ()

  10. rollenc says:

    注意这一句: Permission denied
    从这个着手,一步步检查权限吧

    Comments ()

  11. 请教 says:

    您好!
    很高兴看到同道中人!:)

    希望认识更多的linux同仁

    这里请教你个问题,我在linux下装的apache+svn,在客户端用浏览器访问可以了!
    但是用TSVN客户端链接就不行了!

    我iptables里面端口开了,也不行,iptables停了也不行!

    请高手指点一下,相互交流!

    Comments ()

  12. rollenc says:

    请贴出你的错误原因。
    如果是在WINDOWS下,卡巴斯基6.0会使得TSVN不能使用。

    Comments ()

  13. 请教 says:

    卡巴斯基?
    你是指在服务器上还是客户端上?

    我的服务器端是linux内核(centos4)
    我的客户端是XP,客户端装了卡巴斯基!

    这样卡巴斯基会有影响吗?

    Comments ()

  14. rollenc says:

    会的,客户端开着卡巴就用不了TSVN。
    你可以关闭卡巴试一下,应该就可以正确使用。

    Comments ()

  15. 请教 says:

    嗯,我照你说的,把卡巴斯基停了,客户端所有的防火墙都下了。可是还是链接不上,我客户端用的TSVN!

    请兄弟加我msn或者QQ,讨论一下相互学习啊!

    msn:ie_eu@hotmail.com
    qq:11772226

    Comments ()

  16. rollenc says:

    那就不晓得。不能用应该也会有一个错误提示撒,把报错的提示粘贴一下。
    另外,你说的TSVN是TortoiseSVN么?

    Comments ()

  17. 请教 says:

    错误提示:
    Error * Can't connect to host '172.17.7.230': 由于目标机器积极拒绝,无法连接。
    嗯,tsvn就是tortoiseSVN,一个小乌龟的头像

    ps:给你个小建议,你的这个网站是自己写的吧应该。回复的这个编辑框最好能再弄的大点,至少弄的宽点,那样更舒服了!!:)

    Comments ()

  18. rollenc says:

    感谢你的建议:)这个BLOG Powered by Serendipity。

    这个错误和卡巴引起的错误应该是一样的。
    卡巴引起的错误症状:
    不管checkout还是update,出现操作框之后,很长时间(5~15分钟吧)没有相应,最终弹出一个这样的错误报告。

    你可以选择换一台客户端试一下。或者卸载卡巴,重启再试验。

    Comments ()

  19. rollenc says:

    或者,你可以使用其他的客户端,比如Subclipse : http://subclipse.tigris.org/

    Comments ()

  20. 请教 says:

    嗯,我刚才也怀疑到我的客户端了!
    我还有一台svn服务器,是我现在正用的,我用客户端链接到那台服务器是正常的!
    只是那台服务器是winXP环境!

    对了,请教一下,刚才有个朋友更我说,linux下配置澳apache+svn后,就单独启动apache就好了,不用在另外单独启动svn服务器,就可以通过浏览器或者tortoiseSVN等客户端访问了!是这样吗,我不太确定!

    Comments ()

  21. Anonymous says:

    为什么呢。。理了好几遍。现在可以出现日志了。
    #svn update /var/www/127.0.0.2 --username server --password serverpassword 2>/home/rollenc/svn_hook_log.txt
    用的你的这条。可为什么会出现
    /usr/local/svn/liandong/hooks/post-commit: /usr/local/svn: Permission denied
    我已经很小心了。而今操作时都用的apache用户。都没用root。。晕了

    Comments ()

  22. rollenc says:

    可能问题:
    1.最初checkout时使用的用户名和update时使用的用户名不相同,造成update时修改文件的权限失败
    2. /usr/local/svn/liandong/hooks/post-commit: /usr/local/svn: Permission denied 这一句的意思好像是apache用户没有执行svn的权限。你在终端使用


    su - #改变用户为root
    su apache #改变用户为apache
    svn update
     

    试试,检查一下apache用户是否有权限执行。
    Comments ()

Add Comment


You can use [geshi lang=lang_name [,ln={y|n}]][/lang] tags to embed source code snippets
E-Mail addresses will not be displayed and will only be used for E-Mail notifications