Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
260 lines (194 sloc) 10.2 KB
<?xml version="1.0" encoding="UTF-8"?>
<!--
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
-->
<!-- =================================================================== -->
<sect1 id="psm.preface">
<title>前言</title>
<para>本文来自于笔者<ulink url="http://www.ossxp.com/News/2008-09-02"
>最近完成的一个小项目 pySvnManager</ulink>,源代码已经贡献到开源社区。
项目首页:<ulink url="http://pySvnManager.sf.net"/>。该项目从一开始,
就采用了测试驱动开发(TDD)技术,通过一系列的迭代最终敏捷的实现了预期的需求。</para>
<para>在该项目中采用了 Python 最新流行的 MVC 框架:Pylons。并在 Web 页面中大量使用了
AJAX 技术。本文涉及到的技术术语有:敏捷, TDD, MVC, 单元测试, 代码覆盖测试,
AJAX, 重构, i18n, 开放源代码。</para>
<!-- ================================================================= -->
<sect2 id="psm.preface.background">
<title>项目背景</title>
<para>Subversion使用配置文件进行基于路径的授权,手工配置易于出错。
下面是一个错误百出的配置示例:</para>
<programlisting>
[groups]
admin = &amp;admin, admin1, admin2
group1 = @group2, user1
group2 = user2, @group1
[aliases]
admin = jiangxin
[/]
@admin = rw
[/trunk]
$authenticated = rw
[repos1:/]
* =
user1 =
@group1 = r
@admin = rw
[repos1:/trunk/src]
* =
@group1 = rw
@visiters = r
</programlisting>
<para>其中的错误或可能的错误有:</para>
<orderedlist>
<listitem>
<para><emphasis>组的循环引用:</emphasis>
group1包含了group2,而group2又反过来包含group1,造成循环引用。</para>
</listitem>
<listitem>
<para><emphasis>包含未定义的组或者别名:</emphasis>
例如在 repos1 版本库的 /trunk/src 的策略中用到了 @visiters 组,
而该组没有在[groups]小节中定义;</para>
</listitem>
<listitem>
<para><emphasis>潜在的配置错误:</emphasis>
版本库repos1的根路径,欲限制user1的访问,而实际效果并非如此,
因为uer1属于group1组,而group1组被授权。user1实际获得的权限是策略能够给予
的最大权限;</para>
</listitem>
<listitem>
<para><emphasis>潜在的配置错误:</emphasis>
访问版本库repos1的 /trunk 目录,会参照缺省的[/trunk]小节设置,
这可能跟管理员本意不符。需要对repos1的/trunk重新定义权限以覆盖缺省的
[/trunk]小节的设置。</para>
</listitem>
</orderedlist>
<para>其中1和2的错误会造成Subversion服务中断故障!3和4的问题如果不经过测试很难发现!
在我们为客户实施Subversion技术支持服务过程中,发现了用户迫切需要容错性强的
授权管理工具,于是便有了开发图形化管理界面的打算。选择 Python 是因为 Python
语言的魅力以及 Python 开发过程的高效。</para>
</sect2>
<!-- ================================================================= -->
<sect2 id="psm.preface.implement">
<title>最终的实现</title>
<para>我们先来看看如何部署最终的实现。下面的安装配置过程中的命令是在
Debian Linux 下完成。至于 Windows 或其他平台,应该与之类似。</para>
<!-- =============================================================== -->
<sect3 id="psm.preface.implement.install">
<title>软件安装</title>
<para>理论上最简单的安装模式:</para>
<screen>
$ <emphasis>sudo easy_install pySvnManager</emphasis>
Searching for pySvnManager
Reading http://pypi.python.org/simple/pySvnManager/
Reading https://sourceforge.net/projects/pysvnmanager
</screen>
<para>理论上很简单的东西,却奈何不了复杂的现实:</para>
<para>在项目刚刚开发完成,就出现了相当长一段时间的 <uri>SourceForge.net</uri> 无法访问!
导致 <command>easy_install</command> 为了搜索最新版本,在连接到
<ulink url="http://pysvnmanager.sourceforge.net"/> 时发生了死锁而阻塞。
虽然我打算把项目移到别处,但发现一些依赖的包如: <package>python-ldap</package>
也是要访问 <uri>SourceForge.net</uri> 网站。因此我取消了搬家的打算,耐心且无助的等待解封。
同时将代码镜像在网址:<ulink url="http://svn.worldhello.net/svn/pysvnmanager"/>
上,供不能访问 <ulink url="http://pysvnmanager.sourceforge.net"/> 的用户参考。</para>
<para>如果遇到阻塞,则需要花费更多的时间,手工下载软件包。<command>easy_install</command>
也可以安装已经下载到本地的软件包。</para>
<screen>
$ <emphasis>wget http://pypi.python.org/packages/source/p/pySvnManager/pySvnManager... </emphasis>
$ <emphasis>sudo easy_install pySvnManager-... </emphasis>
</screen>
<note>
<para>PySvnManager 的软件包有两种格式。一种是二进制的格式:<filename>pysvnmanager-xxx.egg</filename>,
另外一种是源码包 <filename>pysvnmanager-xxx.tar.gz</filename>。</para>
<para>二进制包,是针对特定的 Python 版本编译的,如果您当前的 Python 版本和二进制包的版本不符,
就必须从源码包开始安装过程。无论源码包还是二进制的 Egg 包,都可以方便的使用
<command>easy_install</command> 进行安装。</para>
</note>
</sect3>
<!-- =============================================================== -->
<sect3 id="psm.preface.implement.deploy">
<title>网站部署</title>
<para>执行 <command>make-config</command> 和 <command>setup-app</command>
完成部署。部署过程的细节参见后面软件集成的相关内容。</para>
<screen>
$ <emphasis>mkdir deploy</emphasis>
$ <emphasis>cd deploy</emphasis>
$ <emphasis>paster make-config pySvnManager config.ini</emphasis>
Distribution already installed:
pySvnManager 0.1.2dev-r9 from /home/jiangxin/pyenv/lib/python2.5/site-packages/pySvnManager-0.1.2dev_r9-py2.5.egg
Creating config.ini
Now you should edit the config files
config.ini
$ <emphasis>paster setup-app config.ini</emphasis>
Running setup_config() from pysvnmanager.websetup
</screen>
</sect3>
<!-- =============================================================== -->
<sect3 id="psm.preface.implement.config">
<title>配置</title>
<para>部署目录下的四个配置文件:</para>
<itemizedlist>
<listitem>
<para><emphasis><filename>config.ini</filename> :</emphasis>
应用默认运行于5000端口,可以在此文件中定制</para>
</listitem>
<listitem>
<para><emphasis><filename>config/localconfig.py</filename> :</emphasis>
设置应用缺省的认证方式,缺省用 <quote><filename>config/svn.passwd</filename></quote> 口令认证</para>
</listitem>
<listitem>
<para><emphasis><filename>config/svn.passwd</filename> :</emphasis>
缺省该口令文件内所有用户的口令均为 "guess"</para>
</listitem>
<listitem>
<para><emphasis><filename>config/svn.access</filename> :</emphasis>
svn路径授权文件,本应用要处理的文件。注意该文件开头的注释是版本号和版本库管理员帐号设置,
不要随意删除!</para>
</listitem>
</itemizedlist>
</sect3>
<!-- =============================================================== -->
<sect3 id="psm.preface.implement.start">
<title>运行应用</title>
<para>启动应用,自动开启Web服务于5000端口。用Web浏览器访问。推荐使用 Firefox。</para>
<screen>
$ <emphasis>paster serve config.ini</emphasis>
Starting server in PID 28937.
serving on 0.0.0.0:5000 view at http://127.0.0.1:5000
</screen>
</sect3>
<!-- =============================================================== -->
<sect3 id="psm.preface.implement.snapshot">
<title>软件截屏</title>
<para>参见演示网站:<ulink url="http://demo.ossxp.com/svnadmin/security/submit?username=admin&amp;password=admin"
>http://demo.ossxp.com/svnadmin/</ulink></para>
<para>Subversion 的授权机制,可能存在互相冲突的策略,导致用户权限的设置可能并不符合预期。
可以通过“权限检查”的功能对用户权限进行检查。参见:
<xref linkend="psm.preface.implement.snapshot.check"/></para>
<sidebar>
<figure id="psm.preface.implement.snapshot.check">
<title>用户权限测试功能</title>
<graphic fileref="images/snapshot_check.png"/>
</figure>
</sidebar>
<para>管理员可以用图形界面对用户帐号进行角色管理,可以对版本库的授权进行设置。参见:
<xref linkend="psm.preface.implement.snapshot.acl"/></para>
<sidebar>
<figure id="psm.preface.implement.snapshot.acl">
<title>路径授权设置功能</title>
<graphic fileref="images/snapshot_acl.png"/>
</figure>
</sidebar>
<para>PySvnManager 还提供的版本库创建和删除(仅限空版本库),
以及版本库钩子脚本的设置界面。参见:
<xref linkend="psm.preface.implement.snapshot.hooks"/></para>
<sidebar>
<figure id="psm.preface.implement.snapshot.hooks">
<title>版本库创建及钩子脚本扩展</title>
<graphic fileref="images/snapshot_hooks.png"/>
</figure>
</sidebar>
<para>下面将整个开发过程进行概要的介绍,展示如何用 Python 进行敏捷的 Web 开发。</para>
</sect3>
</sect2>
</sect1>