2007年7月27日星期五

Subversion配置安装教程(Apache 版)

引言:一直以来我都认为,MS应该从开源项目中汲取有益的东西,开源项目也要向MS学 习,而不是象网上每次提到.Net和Java就要打嘴仗一样,有些文人相轻的意思。^……^我从工作以来很有幸的能够参与多个Java和.Net项目开 发,时常在这两种技术之间比较思考,现在有机会和大家分享,说的不对的地方,请大家多多指教。首先我准备谈谈SCM,个人认为在现在的大型软件开发中,团 队合作是项目成功最重要的因素之一,尤其是使用.Net和Java这些强大的面向对象的语言开发程序,必然会多次分层,基于组件的共享等等,所以SCM就 更重要了。MS的VSS我想大家应该都用过,也知道VSS的优劣,我就不多说了。(风传VSS不是MS自己开发的,记得有次我去过真正开发VSS的公司的 网站,现在地址也忘记了。并且MS内部也不会使用VSS作为自己的SCM工具,呵呵,不知道是不是真的?)在以后的系列文章里,我会讲解 Subversion,CVS这些主流的开源项目SCM工具,并且会延伸到CI(Continues Integration,即继续集成)和BugTrace领域,毕竟只有版本控制系统对于一个大型软件的开发是远远不够的。在这个旅程中,我还会带大家领 略一下python(我的最爱。。。呵呵,不想试试吗?非常强大!)的旖旎风光,而且这一系列文章也会收录在我准备撰写的《Using Open Source Software to Implement Your .Net Applications》(中英双语版,呵呵。。。考察一下自己的英语)。首先来介绍一下Subversion,以下引自赛迪网-开放系统世界,作者:顾宏军
长久以来,在开源世界中,CVS(Concurrent Versions System)一直都是版本控制的首选。但是现在用户有了另一个选择,就是Subversion。Subversion是下一代版本控制系统,能替代 CVS,项目主页是http://subversion.tigris.org。
Subversion是一个自由、开放源码的版本控制系统。它是一个通用系统,可用来管理任何类型的文件, 其中包括程序源码。
它的初始目标很明确,实现绝大部分CVS的已有功能;充分考虑现有的CVS用户,在使用方式上模仿CVS,同时开发了一系列工具,使得基于CVS的项目能 够顺利迁移到Subversion上。和CVS相比,它有很多优点,例如目录版本控制、不可分割的提交、一致的数据处理方式和更有效率的分支与标记 等。。。


如果你使用过CVS就能体会到上文所说的Subversion好处了,比如目录版本控制,目录的改名等。对于Subversion的原子提交,我 想多说几句,大家可以想象,我们一般做一个修改,可能需要改动多个文件,尤其现在大家多对分层已经趋之若鹜了,除非你还在用着哪种什么东西都写在一起的语 言。(比如PB?呵呵,感觉好像是这样的东西。我现在正在作一个遗留系统的迁移到.Net上的工作,这个系统就是用类似PB的一种脚本语言 Panther,ui,逻辑和数据访问全在一个文件里面,我在代码里面还看到了80年代的注释。呵呵,很强吧?我们公司几个程序员可能是中国为数不多的懂 panther语言的人了。扯远了。。。)如果你的一次提交过程中,由于网路原因或者机器的硬件原因或者根本是你自己落下了一些文件没提交,在逻辑意义上 这次提交是不完整的,Subversion的原子提交能很好的解决这个问题,个人认为这也是对于CVS最大的改进了。怎么样,是不是有些想数据库的事务的 概念呢?动心了吧?ok,废话少说,let's go!(Follow me! Fire in the hole!^……^)

Subversion有两种运行方式,一种是基于Apache Http Server,另外一种是Subversion Standalone Server。下面我讲解的是基于Apache Http Server的Subversion,这样做几个好处:A.能使用WebDAV协议。B.能使用浏览器作为客户端工具浏览源码仓库。C.可以很容易的支持 到SSPI(Windows域认证)和LDAP(AD?),这些都是Apache本身就支持的。D.能得到比较完善的Apache安全认证系统,比如 SSL加密连接。
在正式安装配置Subversion之前我们先来作点准备工 作,由于我们以后会经常在命令行下执行命令,每次打开一个新的命令行窗口默认的当前目录都是C:\Documents and Settings\$UserName,这样在执行命令之前都要切换目录,很麻烦,所以我们先来解决这个问题。在“开始”-“运行”中输入 “regedit”,打开注册表。找到\HKEY_CLASSES_ROOT\Folder\shell,如果没有shell,可以在Folder下新建 一个名为shell的键,在shell下新建一个名为“命令行(Command Windows)”的键,在这个键之下再建一个新的名为“Command”的键,设置默认值为“cmd /K cd /d %L”。

完成后的效果如下:

这样当我们选中一个目录,在右键上下文菜单里面就多了一个“命 令行(Command Windows)”的选项,单击这个选项就可以打开一个命令行窗口并且快速切换到当前选中的目录。说些题外话,很多人提到MS就义愤填膺,可是有多少人真 正掌握MS的技术呢?比如这个小小的CMD命令,建议大家在命令行窗口中输入“cmd /?”,相信收获不少。前段时间在看候捷先生的《Word的排版艺术》,china-pub上很多留的书评都是不屑一顾,我不知道这些人是不是真的能把 WinWord作为自己的“写作平台”?以前我都是用DockBook作为写作的工具,现在才知道Word可以这样用,MS也不是一无是处呀。。。
注意:如果你使用WinXP作为 Subversion服务器,请打上SP1补丁,否则会导致错误的网络数据传输使Subversion的数据库不能正常使用。(我自己的Notebook 是WinXP SP2,工作良好,至于Win2K没有测试,我想应该不会有什么问题吧?)
安装Subversion:
1.到www.apache.org上下载apache http server,注意要下载2.0.X以上的版,否则不能和当前最新的Subversion工作。
2.到http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91上下载Subversion当前1.1.3版本的二进制安装文件,一般tigris.org并不提供二进制包,这些二进制包是有一些志愿者维护的,所以可能不是当前最新的版本。如果你想尝鲜使用Subversion的最新版,请下载源码自己编译。
3.安装apache http server
4.安装Subversion
5.检查$\apache group\apache2\modules下是不是已经有了mod_dav_svn.so和mod_authz_svn.so
6.检查$\apache group\apache2\modules下是不是已经有了libdb42.dll,如图:

7.搜索$\apache group\apache2\conf\httpd.conf配置文件中的#LoadModule dav_fs_module modules/mod_dav_fs.so,把前面的注释#去掉;并检查LoadModule配置节的末尾是不是有了LoadModule dav_svn_module modules/mod_dav_svn.so和LoadModule authz_svn_module modules/mod_authz_svn.so,如图:

注意,请先安装Apache,然后再安装Subversion,这样上述5,6,7步骤都可以免了,在安装Subversion过程中它会自动拷 贝相应文件到相应目录中,并且修改http.conf文件,然后重新启动apache服务使修改生效。但是我发现现在这个版本的Subversion安装 文件可能有个bug,apache的http.conf的配置文件中#LoadModule dav_fs_module modules/mod_dav_fs.so注释没有去掉,所以大家还是小心检查一下。如果你是先安装的Subversion,然后再安装的Apache 的,那么上述的步骤一个也不能漏,都需要自己手动完成。
配置Subversion:
1.在硬盘上建立源码库的根目录,例如E:\SVN
2.在E:\SVN之下建立一个新的目录,例如TestRepository作为我们的测试源码库
3.建立Subversion数据库,当前版本Subversion支持两种格式数据库,一种是FSFS,另外一种是BDB( Berkeley Database)。在命令行下输入svnadmin create --fs-type bdb TestRepository建立BDB格式的数据库(确保当前目录已经切换到E:\SVN\),在命令行下输入svnadmin create --fs-type fsfs TestRepository建立FSFS格式的数据库(确保当前目录已经切换到E:\SVN\)。建好数据库以后,到E:\SVN\ TestRepository下看看是不是多了很多目录和文件,可以研究一下这些文件,对理解Subversion有帮助,但是不要试图直接修改这些文 件!如图:

如果大家经常关注开源技术,就知道BDB是一个轻量级的关系数据库,可以作为一个轻巧的内置数据库,在很多开源项目下有很多应用,比如 CVSTrac。FSFS格式主要的特点是可以支持Subversion的数据库和Subversion服务器可以在不同的物理机器上,可以通过网络共享 (不知道是否支持NFS?),能很好的工作在MS Win98上,并且速度更快,但是由于FSFS是一种新的格式,稳定性可能没有BDB好。推荐大家使用BDB,毕竟BDB有很多年开发历史,比较稳定,而 且我觉得把Subversion的DB和服务器分开放置好像没有什么必要吧?(谁能告诉我这样做的好处?),大家也不会拿一台Win98作server 吧?^……^。不要试图在BDB的格式的数据库上使用网络共享,也不要使用网络磁盘映射,否则会导致无法预料的错误。
4.打开$\apache group\apache2\conf\httpd.conf配置文件,在文件的末尾加入以下语句,

DAV svn
SVNParentPath e:\SVN
AuthType Basic
AuthName "Subversion repositories"
AuthUserFile passwd
#AuthzSVNAccessFile svnaccessfile
Require valid-user

这里建立了一个虚拟目录http://yourServer/svn/,所有的Subversion源码仓库都在这个虚拟目录中,并且使用“passwd”文件中username/password(用户名/密码)列表访问http://yourServer/svn/。关于Subversion的安全配置是一个比较重要的部分,我会留到下次配置SSL加密连接再讲。
5.在命令行下切换到$\apache group\apache2,执行bin\htpasswd -c passwd ,这里是你想要加入的用户名,比如doudou。执行这个命令成功以后就会在bin目 录下建立一个passwd文件,之后如果再加入新的用户和更改已有用户的密码,执行bin\htpasswd passwd 即可。如图:

注意一定要在$\apache group\apache2下执行,这样生成的passwd文件$\apache group\apache2根目录下,而不是在bin目录下,apache默认是在$\apache group\apache2根目录下寻找passwd文件,如果你在bin目录下执行了这个命令请把生成的passwd文件剪切到$\apache group\apache2根目录下。这一点也可以从Apache的log日志中看得出来,如图:

6.重启Apache服务
7.在浏览器地址栏中输入 http://YourServer/svn/TestRepository,输入用户名密码,ok。Subversion现在已经可以正常工作了。
如图:


在写作本文的时候参考了TortoiseSVN的帮助文档,在此感谢TortoiseSVN团队杰出的工作!


今天接着昨天的内容讲Subversion的安全配置。在上一讲中我们在Apachehttpd.conf文件里加入了这样一节:

DAV svn
SVNParentPath e:\SVN
AuthType Basic
AuthName "Subversion repositories"
AuthUserFile passwd
#AuthzSVNAccessFile svnaccessfile
Require valid-user

下面我来解释一下这些配置信息用途:

说明我们所有的代码仓库在/svn这个虚拟目录下

DAV svn

说明Apache会使用svn这个module来解析这个虚拟目录

SVNParentPath e:\SVN

说明所有的代码仓库都在本地硬盘的e:\SVN

AuthType Basic

使用最基本的认证校验,用户名/密码

AuthName "Subversion repositories"

说明在认证对话框弹出的时候,对话框的标题显示,你可以把它修改成你想要的任何提示信息,比如:AuthName "Warning"等等

AuthUserFile passwd

说明我们使用的access list文件的名字,在上一讲中我们建立的文件名字是passwd,所以这里是passwd。如果你建立的文件名字是其他的,这里要作相应的改动

AuthzSVNAccessFile

说明svn自己控制的access list文件,这个文件很重要,可以丰富svn的安全配置,在下面会讲到

Require valid-user

说明只有输入正确的用户名/密码才能访问


上述的配置只能是最简单的安全配置,如果你想拥有更强大的安全配置,就需要加入一些东西了。比如:

  1. 如果你想让所有的匿名用户能访问代码仓库,对某些特定用户才开放可写的权限,则需要把
    Require valid-user
    改成

    Require valid-user
  2. 如果你对于代码仓库里面某些目录还有更细致的访问控制,只用passwd就没办法啦,这个时候我们就需要AuthzSVNAccessFile文件了,去掉#AuthzSVNAccessFile svnaccessfile这一行前面的注释。Apache首先会使用passwd校验用户名和密码,然后会认证信息传给SubversionAuthzSVNAccessFile模块,由这个模块作更进一步的权限控制。首先我们来新建一个文件svnaccessfile,内容如下:
    [groups]
    developers = user1,user2,user3,user4
    docs = user5,user6,user7
    #to allow everyone read access
    [/]
    * = r
    #allow all developers complete access
    @developers = rw
    #give the doc people write access to the docs folder
    [/project/trunk/doc]
    @docs = rw
    首先我们定义了两个group,一个是developer,代表开发组,另外一个是docs,代表文档撰写组,然后
    [/]
    * = r
    意思是对于所有的用户开放可读的权限。注意这里的[/],表示是对根目录下的所有代码仓库赋予权限。接着是
    @developers = rw
    [/project/trunk/doc]
    @docs=rw
    这这里的@应该代表的是group的意思(这个还没有确认,是我自己猜测的,因为如果是直接给单一用户赋予权限,则不需要前面的@,哪位大侠可以证实一下我的猜测?欢迎指教)注意这里对于docs这个组,我们一样指定了目录路径,而不是对于整个代码仓库。

这里再说说SVNParentPath,配置了SVNParentPath,以后每次在根目录下面加入新的repository就不需要再重新配置SubversionApache了,自动获取了根目录的配置信息,很方便。然而这也引发了另外一个问题,当你在浏览器地址栏里输入http://youserver/svn/的时候,服务器会报错,提示你没有权限访问访问这个url,我们想要的效果是浏览到这个url时能够把根目录下的所有的repository列出来。完成这个工作需要写点代码了,使用的工具可以是很多,这里使用php,当然我想用perl或者python一定是没有问题。首先要安装php,使apache支持php. 以下是参考了shg918的文档,在此表示感谢!


  1. 首先去http://www3.skycn.com/soft/9122.html 下载php4.3.1,接下来我们来手动配置一下apache
  2. 将下载的php压缩文件解压,文件夹改名为php复制到你想放置的目录路径下,注意目录名不能有空格,否则apache会找不到相关的module,比如D:/php-4.3.10RC1-Win32
  3. 打开刚才解压的PHP目录,你会发现有一个叫做"php.ini-dist"的文件,这就是PHP的配置文件了,你需要把它改名成"php.ini",然后复制到系统目录windows2K应该是winnt)下。打开这个配置文件,把; cgi.force_redirect = 1改成 cgi.force_redirect = 0,这样做是强迫不运行在cgi模式下,我们希望php工作在Apachemodule模式下。
  4. PHP安装目录下的"php4ts.dll"必须要复制到windows系统的system32目录下。
  5. dllsextensions目录里的所有文件拷到system32里。(我猜测这里是为了支持mysql等才需要作的,可能对我们来说并不需要。)
  6. 打开Apache的配置文件http.conf,在module配置节末尾加上LoadModule php4_module D:/php-4.3.10RC1-Win32/sapi/php4apache2.dllAddType application/x-httpd-php .php .php3 .php4

Ok,配置完毕,现在Apache可以支持php了。现在用文本编辑器编写一个php文件,保存为svn_index.php,内容如下:

<html>

<head>

<title>Subversion Repositoriestitle>

head>

<body>



<h2>Subversion Repositoriesh2>

<p>

php

$svnparentpath = "e:/svn";

$svnparenturl = "/svn";



$dh = opendir( $svnparentpath );

if( $dh ) {

while( $dir = readdir( $dh ) ) {

$svndir = $svnparentpath . "/" . $dir;

$svndbdir = $svndir . "/db";

$svnfstypefile = $svndbdir . "/fs-type";

if( is_dir( $svndir ) && is_dir( $svndbdir ) ) {

echo "
$dir . "\">" . $dir . "
\n";

if( file_exists( $svnfstypefile ) ) {

$handle = fopen ("$svnfstypefile", "r");

$buffer = fgets($handle, 4096);

fclose( $handle );

$buffer = chop( $buffer );

if( strcmp( $buffer, "fsfs" )==0 ) {

echo " (FSFS)
\n";

} else {

echo " (BDB)
\n";

}

} else {

echo " (BDB)
\n";

}

}

}

closedir( $dh );

}

?>

p>

body>

html>


上述php文件中svnparentpath = "e:/svn";需要注意,你的subversion的代码仓库的根目录可能并不在e:/svn,请修改和你自己设置一样的路径。更改Apache的配置文件http.conf文件,把#LoadModule rewrite_module modules/mod_rewrite.so前面的注释去掉。然后在文件末尾加上如下几句:

RewriteEngine on

RewriteRule ^/svn$ /svn_index.php [PT]

RewriteRule ^/svn/$ /svn_index.php [PT]

RewriteRule ^/svn/index.html$ /svn_index.php [PT]

好了,请从新在浏览器地址栏中输入http://youserver/svn ,你会发现Apache会把当前Subversion根目录下的所有代码仓库列出来了。如图:

今天就讲到这里吧,明天继续讲解Subversion的SSL加密连接的设置。



今天来讲讲Subversion的SSL连接。如果没有SSL相关的基础知识,请先自行参阅相关资料。

  1. 首先去http://hunter.campbus.com/ 下载包含openssl模块的apache包,将解压出来的mod_ssl.so 拷贝到Apache的安装路径下的modules目录下,openssl.exe拷贝到bin目录下,conf/ssl.conf拷贝到conf目录下。
  2. 打开拷贝过来ssl.conf,将一下几行加上#注释掉 DocumentRoot "c:/apache/htdocs"
    ServerName www.example.com:443
    ServerAdmin you@example.com
    ErrorLog logs/error_log
    TransferLog logs/access_log
  3. 把SSLCertificateFile conf/ssl.crt/server.crt改成SSLCertificateFile conf/ssl/my-server.cert
  4. 把SSLCertificateKeyFile conf/ssl.key/server.key改成SSLCertificateKeyFile conf/ssl/my-server.key
  5. 把SSLMutex file:logs/ssl_mutex改成SSLMutex default
  6. 删除或者注释这两行
  7. 打开Apache的配置文件http.conf,把其中的#LoadModule ssl_module modules/mod_ssl.so这一行的注释去掉
  8. 下载http://tud.at/programm/openssl.cnf 并保存到bin/openssl.cnf。注意windows会把这个文件显示成一个拨号文件,实际上这是个文本文件,你可以用任何一个文本编辑器打开浏览一下这个文件的内容。实际上这个文件是用来生成证书和公钥的预配置文件。
  9. 在命令行下进入$\program files\apache group\apache2,输入命令:
    bin\openssl req -config bin\openssl.cnf -new -out my-server.csr
    回答相关问题即可生成一个CSR,也就是一个待签名的证书。本质上说,CSR 就是一个在您的服务器上生成的证书,当您向第三方证书颁发机构申请证书时,它用来验证有关您的服务器的计算机特定信息。实际上,CSR 就是一条用公钥/私钥对加密的文本消息。如图:

    然后输入命令:

    bin\openssl rsa -in privkey.pem -out my-server.key
    执行成功会生成私匙,如图:

接着输入bin\openssl x509 -in my-server.csr -out my-server.cert -req -signkey my-server.key -days 4000
这样会生成一个在4000天后过期的用刚刚生成的私匙签名过的x509证书。
最后输入bin\openssl x509 -in my-server.cert -out my-server.der.crt -outform DER
这一步是生成了DER格式的证书,对于那些不能识别PEM格式证书的程序,可以使用这种证书。如图:

最后把在$\Apache Group\Apache2目录下生成的my-server.der.crt, my-server.csr, my-server.key, .rnd, privkey.pem, my-server.cert6个文件复制到conf/ssl下,如果ssl这个目录不存在,请先新建这个目录。Ok,大功告成,请在浏览器地址栏输入
https://youserver/svn/TestRepository/,看到了什么?呵呵,是不是比较有成就感呢?看看我自己生成的证书:

然后是证书的详细信息:

注意:以上3和4步骤可以不更改,改不改完全都是个人喜好,如果不改,那么在第9个步骤里面相关的命令需要做相应的修改。另外,设置了SSL加密连接以后,通过
https://youserver/svn 不会再显示所有的repository列表了,而是显示没有权限访问。而通过http://youserver/svn访问就可以。我怀疑是昨天写的那个php脚本有些问题,没有使用相关的SSL协议访问相关路径,如果有时间我会考虑使用python再次实现。不知道我想的对不对,哪位大侠指教一下?

注意:IIS和Apache的SSL连接会有冲突,具体表现在它们都会尝试使用443作为https协议的端口,我在MS的网站上找到了一篇KB文章,说 是改注册表可以关闭ssl服务,我试了一下,似乎不行,在IIS的控制面板里面更改SSL端口选项是灰色不可选,哪位有好的办法?

没有评论: