SVN 简介和工作原理

Subversion(svn)是近几年崛起的版本管理软件,是cvs的接班人,目前绝大多数开源软件都使用svn作为代码版本管理软件。

Subversion支持linux和windows,但较多安装在linux下搭建,

Subversion 结合 apache httpd 进行web访问,不支持nginx直接访问,但可以做反向代理 nginx + apache

本文的安装方案:CentOS 7.5 + Apache-2.4.34 自定义编译安装 + subversion-1.7.14 命令安装(因为编译安装 svnadmin create xxx一直报错"addressing logical")

先前的安装方案:CentOS 6.5 + Apache-2.2.27 命令安装 + subversion-1.6.11 命令安装

 

Subversion 官网: https://subversion.apache.org

svn 下载最新版subversion-1.10.2.tar.gz (2018-07-20)

 

SVN 服务器有两种运行方式

独立服务器和借助于apache,服务器端访问svn:// 或 http(s)://svn,客户端工具 tortoisesvn

版本url:

file:// 直接版本库访问(本地磁盘)

http:// 通过配置Subversion的Apache服务器的web协议访问

https:// 与http://相似,但是包括SSL加密

svn:// 通过svnserve服务自定义的协议访问

SVN Server配置语言,默认为 export LANG=en_US.UTF-8

en_US.UTF-8:你说英语,你在美国,字符集是utf-8 
zh_CN.UTF-8:你说中文,你在中国,字符集是utf-8 

如果你的LANG环境变量是en_US.UTF-8,那么系统的菜单、程序的工具栏语言、输入法默认语言就都是英文的。 

如果你的LANG环境变量是zh_CN.UTF-8,那么系统的菜单、程序的工具栏语言、输入法默认语言就都是中文的。

 

SVN 基本工作原理

在一台服务器上建立一个源代码库,库里可以存放许多不同项目的源程序,由源代码库管理员统一管理这些源程序。

centeros-build-svn-server-02

每个用户在使用源代码库之前,首先要把源代码库里的项目文件下载到本地,然后开发人员可以在本地编辑修改,然后用svn命令进行提交,由源代码库统一管理修改。

 

SVN 版本控制解决的问题

1) 代码管理混乱

2) 解决代码冲突困难

3) 在代码整合期间引发bug

4) 无法对代码的拥有者进行权限控制

5) 项目不同版本的发布困难。

 

Subversion目录说明

svnadmin 创建一个svn仓库命令:

svnadmin create /home/data/SVN/repository

[root@mimvp SVN]# svnadmin create /home/data/SVN/repository
[root@mimvp SVN]# ll repository/
total 24
drwxr-xr-x 2 root root 4096 Jul 29 12:33 conf
drwxr-sr-x 6 root root 4096 Jul 29 12:26 db
-r--r--r-- 1 root root    2 Jul 29 11:21 format
drwxr-xr-x 2 root root 4096 Jul 29 11:21 hooks
drwxr-xr-x 2 root root 4096 Jul 29 11:21 locks
-rw-r--r-- 1 root root  246 Jul 29 11:21 README.txt

说明:

dav目录:是提供apache与mod_dav_svn使用的目录,让他们存储内部数据

db目录:是所有版本控制的数据存放文件

hooks目录:放置hook脚本文件的目录

locks目录:用来放置subversion锁定数据的目录,用来追踪存取文件库的客户端

format文件:是一个文本文件,里面只放了一个整数。表示当前文件库配置的版本号

conf目录:是这个仓库的配置文件(仓库的用户访问账号、权限等)

 

SVN Server 详细配置手册

系统环境

CentOS 6.5 安装 + subversion + yum,需关闭 iptables 和 selinux (yum 命令安装,subversion-1.6.11,2014-05-06)

CentOS 7.5安装 + apache httpd 源码 + subversion 源码,需关闭 iptables 和 selinux (源码编译安装,subversion-1.10.2,2018-07-28)

 

一、安装必须的软件包

方式1、yum 命令安装(推荐方案

sudo yum -y install mod_dav_svn subversion

sudo yum -y install mod_dav_svn subversion mysql-server httpd mod_perl sendmail wget gcc-c++ make unzip perl* ntsysv vim-enhanced

说明:

subversion (SVN服务器安装包,源码 subversion-1.10.2.tar.gz)

mysql-server (用于code striker 代码检查)

httpd mod_dav_svn mod_perl (apache 服务器,用于支持WEB方式管理SVN服务器)

sendmail (用于配置用户提交代码后发邮件提醒)

wget gcc-c++ make unzip perl* (必备软件包)

ntsysv vim-enhanced (可选)

 

方式2、源码编译安装(可参考,跳过

apache httpd 官网:http://httpd.apache.org

subversion 官网:http://subversion.apache.org

sqlite 官网:https://www.sqlite.org

neon 官网:http://www.webdav.org.neno

serf 官网:http://serf.apache.org

openssl 官网:https://www.openssl.org

 

1)下载源码

httpd-2.4.34.tar.gz  (2018-07-16)

subversion-1.10.2.tar.gz  (2018-07-20)

sqlite-snapshot-201807272333.tar.gz (2018-06-04)

sqlite-amalgamation-3240000.zip (2018-06-04)

neon-0.29.6.tar.gz

serf-1.3.9.zip

openssl-1.0.2o.tar.gz  (默认会安装,没安装则自己安装

 

2)编译安装可参考,跳过

apr 和 apr-util一般会在 httpd 的安装包内,subversion安装会使用到apr和par-util,如果当前系统没有则需要自定义安装

安装 apr、apr-util、pcre ,请参见米扑博客:Ubuntu配置Apache

2.1)安装 apache httpd

tar zxvf httpd-2.4.34.tar.gz 
cd httpd-2.4.34
./configure --prefix=/usr/local/httpd --enable-module=all --enable-module=so
--enable-dav --enable-maintainer-mode --enable-rewrite --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-pcre=/usr/local/pcre
make && make install

 

2.2)安装 sqlite3

tar zxvf sqlite-snapshot-201807272333.tar.gz 
cd sqlite-snapshot-201807272333
./configure --prefix=/usr/local/sqlite3
make && make install

 

2.3)安装 neon (subversion-1.8.x 以前使用 neon,之后使用 serf

首先,介绍neon有什么用呢?若没有 neon 或 serf ,则svn无法使用 http 或 https 下载svn代码

这里查了很多资料,折腾了很久,最后发现 subversion-1.8.x 以前使用 neon,之后使用 serf

为了具体解释,先看米扑博客折腾的几个版本

a)CentOS 6.5 + svn-1.6.11,含有 ra_neon,支持 http、https 

# svn --version
svn, version 1.6.11 (r934486)
   compiled Mar  6 2014, 10:49:10

The following repository access (RA) modules are available:

* ra_neon : Module for accessing a repository via WebDAV protocol using Neon.
  - handles 'http' scheme
  - handles 'https' scheme
* ra_svn : Module for accessing a repository using the svn network protocol.
  - with Cyrus SASL authentication
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme

 

b)CentOS 7.4 + svn-1.7.14,含有 ra_neon,支持 http、https 

# svn --version
svn, version 1.7.14 (r1542130)
   compiled Aug 23 2017, 20:43:38

The following repository access (RA) modules are available:

* ra_neon : Module for accessing a repository via WebDAV protocol using Neon.
  - handles 'http' scheme
  - handles 'https' scheme
* ra_svn : Module for accessing a repository using the svn network protocol.
  - with Cyrus SASL authentication
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme

 

c)MacOS 10.13.4 + svn-1.9.4,含有 ra_serf,支持 http、https 

$ svn --version
svn, version 1.9.4 (r1740329)
   compiled Nov  6 2017, 18:06:35 on x86_64-apple-darwin16.1.0

The following repository access (RA) modules are available:

* ra_svn : Module for accessing a repository using the svn network protocol.
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme
* ra_serf : Module for accessing a repository via WebDAV protocol using serf.
  - using serf 1.3.8 (compiled with 1.3.8)
  - handles 'http' scheme
  - handles 'https' scheme

 

d)CentOS 7.5 + svn-1.10.2,不含有ra_neon 和 ra_serf,不支持 http、https 

# svn --version
svn, version 1.10.2 (r1835932)
   compiled Jul 29 2018, 14:17:06 on x86_64-unknown-linux-gnu

The following repository access (RA) modules are available:

* ra_svn : Module for accessing a repository using the svn network protocol.
  - with Cyrus SASL authentication
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme

总结,一般通过 yum -y install svn 会自动安装 ra_neon 或 ra_serf,但自编译安装 subversion则没有安装 ra_neon 和 ra_serf

因此,这里需要自定义安装 neon(subversion-1.8.x以前) 和 serf(subversion-1.8.x以后)

tar -zxvf neon-0.29.6.tar.gz
cd neon-0.29.6/
./configure --prefix=/usr/local/neon --with-ssl --with-openssl --enable-shared
make && make install

 

2.4)安装 serf

SVN 1.8版本的安装与之前最大的不同是使用serf代替了neon,而安装serf 需要使用scons编译工具,

这个工具在编译serf时,又需要使用openssl的库,所以Openssl成了必须安装的软件.

yum -y install scons
unzip serf-1.3.9.zip
cd serf-1.3.9
scons PREFIX=/usr/local/serf APR=/usr/local/apr APU=/usr/local/apr-util
scons install

配置环境变量,否则会提示找不到(非常重要

svn: error while loading shared libraries: libserf-1.so.1: cannot open shared object file: No such file or directory

vim /etc/profile 

添加两行:

export SERF_ROOT=/usr/local/serf
export LD_LIBRARY_PATH=${SERF_ROOT}/lib:${LD_LIBRARY_PATH} 

使其生效:

source /etc/profile

 

2.5)安装 subversion

tar zxvf subversion-1.10.2.tar.gz 
cd subversion-1.10.2
./configure --prefix=/usr/local/subversion
--with-apxs=/usr/local/httpd/bin/apxs --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-ssl--with-openssl --with-zlib --enable-maintainer-mode --with-lz4=internal --with-utf8proc=internal --with-sqlite=/usr/local/sqlite3 --with-neon=/usr/local/neon --with-serf=/usr/local/serf
make && make install

说明:

subversion-1.8.x 以上版本编译时,会提示警告,说明 ssl 已经被 openssl 替代, neon 已经被 serf 替代

configure: WARNING: unrecognized options: --with-ssl, --with-neon

然后查看 svn 是否支持 serf 以及 http、https

svn --version

# svn --version      
svn, version 1.10.2 (r1835932)
   compiled Jul 29 2018, 15:14:51 on x86_64-unknown-linux-gnu

The following repository access (RA) modules are available:

* ra_svn : Module for accessing a repository using the svn network protocol.
  - with Cyrus SASL authentication
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme
* ra_serf : Module for accessing a repository via WebDAV protocol using serf.
  - using serf 1.3.9 (compiled with 1.3.9)
  - handles 'http' scheme
  - handles 'https' scheme

好事多磨,大功告成!

 

3、配置环境变量

vim /etc/profile

添加红色字体配置

export HTTPD_ROOT=/usr/local/httpd
export PATH=$HTTPD_ROOT/bin:$PATH

export SUBVERSION_ROOT=/usr/local/subversion
export LD_LIBRARY_PATH=${SUBVERSION_ROOT}/lib:${LD_LIBRARY_PATH} 
export PATH=$SUBVERSION_ROOT/bin:$PATH

使其生效

source /etc/profile   

 

问题与解决

问题1:fatal error: sqlite3ext.h: No such file or directory

解决:subversion 安装需要提前安装 sqlite,因此需要先下载安装编译 sqlite,如步骤2.2)

然后,创建目录 mkdir /home/data/tool-server/subversion-1.10.2/sqlite-amalgamation

拷贝源码 sqlite3.c 到 subversion-1.10.2/sqlite-amalgamation

cp /home/data/tool-server/sqlite-snapshot-201807272333/sqlite3.c /home/data/tool-server/subversion-1.10.2/sqlite-amalgamation

或直接在步骤2.3)编译命令中,添加 --with-lz4=internal --with-utf8proc=internal --with-sqlite=/usr/local/sqlite3

或解压 sqlite-amalgamation-3240000.zip ,然后拷贝到 subversion-1.10.2/sqlite-amalgamation

错误1:configure: error: Subversion requires LZ4 >= r129, or use --with-lz4=internal
解决:./configure命令添加 --with-lz4=internal 

错误2:configure: error: Subversion requires UTF8PROC
解决:./configure命令添加  --with-utf8proc=internal

 

问题2:Unknown DAV provider: svn

解决:apache httpd 配置 DAV svn 后,找不到 dav_svn

因此,先需要安装步骤 2.3),然后拷贝 cp /usr/local/subversion/libexec/* /usr/local/httpd/modules/ ,最后添加配置

vim /usr/local/httpd/conf/httpd.conf

添加两行红色字体配置,并取消红色字体注释,如下

LoadModule unixd_module modules/mod_unixd.so
LoadModule dav_module modules/mod_dav.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
#LoadModule info_module modules/mod_info.so
#LoadModule cgid_module modules/mod_cgid.so

LoadModule dav_fs_module modules/mod_dav_fs.so
#LoadModule vhost_alias_module modules/mod_vhost_alias.so
#LoadModule negotiation_module modules/mod_negotiation.so
LoadModule dir_module modules/mod_dir.so
#LoadModule actions_module modules/mod_actions.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule userdir_module modules/mod_userdir.so
LoadModule alias_module modules/mod_alias.so
#LoadModule rewrite_module modules/mod_rewrite.so
LoadModule php7_module        modules/libphp7.so

LoadModule dav_svn_module modules/mod_dav_svn.so 
LoadModule authz_svn_module modules/mod_authz_svn.so

 

 

二、基本的SVN服务器配置

1,新建一个目录用于存储SVN所有文件

# mkdir /home/data/SVN

 

2,新建一个版本仓库

# svnadmin create /home/data/SVN/repository

这里,查看下文件

# cat repository/db/format    
4
layout sharded 1000

若不是上面的文字,例如多了一行 "addressing logical",则表示 svnadmin create 创建版本不对,需要重新安装 subversion (yum或源码安装)

8
layout sharded 1000
addressing logical

 

3,初始化版本仓库中的目录

cd /home/data/SVN/

# mkdir myproject myproject/trunk myproject/branches myproject/tags     (建立临时目录,初始化 trunk、branches、tags,后面可删除)

# svn import myproject/ file:///home/data/SVN/repository -m "it is comment init SVN dir"

# rm -rf myproject           (删除临时建立的目录)

若有多个项目,则将 myproject 创建为多个,如 myproject2、myproject3,或者把多个项目全部放在 trunk/myproject2,trunk/myproject3 下

 

4,添加用户

添加SVN用户非常简单,只需在/home/data/SVN/project/conf/passwd文件添加一个形如“key=value”的条目。为了测试,添加了如下内容:

vim /home/data/SVN/repository/conf/passwd

[users]
# harry = harryssecret
# sally = sallyssecret
user1 = password1
user2 = password2
group_trunk = password_trunk
group_branches = password_branches
group_tags = password_tags
group_guest = password_guest

 

5,修改用户访问策略

vim /home/data/SVN/repository/conf/authz

[aliases]
# joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average

#[groups]
# harry_and_sally = harry,sally
# harry_sally_and_joe = harry,sally,&joe

# [/foo/bar]
# harry = rw
# &joe = r
# * =

# [repository:/baz/fuz]
# @harry_and_sally = rw
# * = r

[groups]
project_p = user1, user2
project_trunk = group_trunk, user1, user2
project_branches = group_branches, user1, user2
project_tags = group_tags, user1, user2
project_guest = group_guest


[repository:/]
@project_p = rw
@project_guest = r
* = 

[repository:/trunk]
@project_p = rw
@project_guest = r
@project_trunk = r
* = r

[repository:/branches]
@project_p = rw
@project_guest = r
@project_branches = rw
* = r

[repository:/tags]
@project_p = rw
@project_guest = r
@project_tags = rw
* = r

说明:

上面配置文件里,一定要先注释掉 #[groups],只保留一个 [groups],否则会显示配置报错 svn: E220003: Invalid authz configuration

以上信息表示,只有project_p用户组有根目录的读写权。r表示对该目录有读权限,w表示对该目录有写权限,rw表示对该目录有读写权限。

最后一行的 * = 表示,除了上面设置了权限的用户组之外,其他任何人都被禁止访问本目录。

这个很重要,一定要加上!

 

6,修改svnserve.conf文件

让用户和策略配置升效 svnserve.conf 内容如下:

vim /home/data/SVN/repository/conf/svnserve.conf

去掉如下内容的注释,记得每行定格写,行头不要留空格

[general]
anon-access = none     # none 禁止匿名访问,必须输入密码验证; 默认 read 允许匿名访问
auth-access = write
password-db = passwd
authz-db = authz
realm = My First Repository    # 项目介绍

 

7,启动服务器

# svnserve -d -r /home/data/SVN/ --listen-port=3690

查看 svnserve 是否启动

# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      1120/php-fpm: maste 
tcp        0      0 0.0.0.0:808             0.0.0.0:*               LISTEN      909/nginx: master p 
tcp        0      0 0.0.0.0:3690            0.0.0.0:*               LISTEN      1938/svnserve       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1796/httpd          
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1430/sshd           
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1502/sendmail: acce 
tcp6       0      0 :::33406                :::*                    LISTEN      1099/mysqld    

注意:如果修改了svn 配置,需要重启svn服务,步骤如下:

# ps -aux | grep -v grep | grep svnserve | awk '{print $2}' | xargs kill -9

# ps -aux | grep svnserve

# kill -9 process-ID号

# svnserve -d -r /home/data/SVN/              // 重启svn服务,默认端口号 3690

 

8,测试服务器

# svn co svn://115.29.237.28/repository

Authentication realm: <svn://115.29.237.28:3690> 92731041-2dae-4c23-97fd-9e1ed7f0d18d Password for ‘root’:                                   # 直接Enter跳过

Authentication realm: <svn://115.29.237.28:3690> 92731041-2dae-4c23-97fd-9e1ed7f0d18d

Username: user1

Password for ‘user1’: password1

svn: Authorization failed ( server_group没用根目录的访问权 )

# svn co svn://115.29.237.28/repository

Authentication realm: <svn://192.168.60.10:3690> 92731041-2dae-4c23-97fd-9e1ed7f0d18d

Password for ‘root’:

Authentication realm: <svn://115.29.237.28:3690> 92731041-2dae-4c23-97fd-9e1ed7f0d18d

Username: pm

Password for ‘pm’: xxxxxx

A project/test

A project/server

A project/client

Checked out revision 1.                                # ( 测试提取成功 )

# cd repository/trunk

# vim main.c

# svn add main.c

# svn commit main.c -m "add server/main.c file"

Adding main.c

Transmitting file data .

Committed revision 2.                                  # ( 测试提交成功 )

 

查看 repository 目录

svn list svn://115.29.237.28/repository

# svn list svn://115.29.237.28/repository
branches/
tags/
trunk/

 

 

三、配置SVN服务器的HTTP支持

1,转换SVN服务器的密码

由于SVN服务器的密码是明文的,HTTP服务器不支持,所以需要转换成HTTP支持的格式。

我写了一个Perl脚本完成这个工作.

脚本内容如下:

# cd /home/data/SVN/project/conf/

# vim P2WP.pl

#!/usr/bin/perl
# write by ithomer.net, 2014-12-12
# change passwd to webpasswd by htpasswd

use warnings;
use strict;

# open the svn passwd file
open (FILE, "passwd") or die ("Cannot open the passwd file!!!n");


# clear the apache passwd file
open (OUT_FILE, ">webpasswd") or die ("Cannot open the webpasswd file!!!n");
close (OUT_FILE);

# begin
foreach (<FILE>){
    if($_ =~ m/^[^#].*=/) {
        $_ =~ s/=//;
        `htpasswd -b webpasswd $_`;
    }
}

# chmod +x P2WP.pl

# ./P2WP.pl

# perl P2WP.pl 
Adding password for user user1
Adding password for user user2
Adding password for user group_trunk
Adding password for user group_branches
Adding password for user group_tags
Adding password for user group_guest

现在目录下会多一个 webpasswd 文件。

# ll /home/data/SVN/repository/conf
total 20
-rw-r--r-- 1 root root 1600 Jul 28 21:21 authz
-rwxr-xr-x 1 root root  462 Dec 14  2014 P2WP.pl
-rw-r--r-- 1 root root  447 Jul 28 21:20 passwd
-rw-r--r-- 1 root root 3230 Jul 28 21:24 svnserve.conf
-rw-r--r-- 1 root root  295 Jul 28 21:30
webpasswd

 

2,修改httpd.conf

添加关于SVN服务器的内容

vim /etc/httpd/conf/httpd.conf

在最后添加如下信息:

<Location /repository>
    DAV svn
    SVNPath /home/data/SVN/repository/
    AuthType Basic
    AuthName "svn for repository"
    AuthUserFile /home/data/SVN/repository/conf/webpasswd
    AuthzSVNAccessFile /home/data/SVN/repository/conf/authz
    Satisfy all
    Require valid-user
</Location>

3,修改svn目录的所有者属主为apache帐号:

chown -R apache:apache /home/data/SVN/repository/

4,重启Web服务器:

# /etc/init.d/httpd restart

Stopping httpd: [FAILED]

Starting httpd: [ OK ]

5,测试,用浏览器访问: http://115.29.237.28/repository/

 

四,配置邮件提醒支持

安装perl编译组件​(跳过

yum -y install perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker

解决出现如下的问题:

[root@ithomer Perl-OSType-1.007]# perl Makefile.PL 
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at Makefile.PL line 8.
BEGIN failed--compilation aborted at Makefile.PL line 8.

 

perl 模块安装跳过

perl 模块安装可以用perl第三方库工具cpan

cpan安装见博客: CentOS 安装 perl

cpan安装命令: yum install cpan

cpan安装模块示例:

cpan Authen::SASL

cpan Net::SMTP_auth

cpan SVN::Notify

 

0,安装Perl模块Perl::OSType(跳过

# wget http://search.cpan.org/CPAN/authors/id/D/DA/DAGOLDEN/Perl-OSType-1.007.tar.gz
# tar xvf Perl-OSType-1.007.tar.gz
# cd Perl-OSType-1.007
# perl Makefile.PL
# make
# make install
# cd ..

安装Perl模块Module::Meta

wget http://search.cpan.org/CPAN/authors/id/D/DA/DAGOLDEN/CPAN-Meta-2.143240.tar.gz

安装Perl模块Module::Metadata

# wget http://search.cpan.org/CPAN/authors/id/E/ET/ETHER/Module-Metadata-1.000024.tar.gz
# tar xvf Module-Metadata-1.000024.tar.gz
# cd Module-Metadata-1.000024
# perl Makefile.PL
# make
# make install
# cd ..

 

1,安装Perl模块Module::Build跳过

# wget http://www.cpan.org/authors/id/D/DA/DAGOLDEN/Module-Build-0.39_01.tar.gz
# tar xvf Module-Build-0.39_01.tar.gz
# cd Module-Build-0.39_01
# perl Build.PL
# ./Build
# ./Build test
# ./Build install
# cd ..

 

2,安装Perl模块Authen::SASL跳过

# wget http://search.cpan.org/CPAN/authors/id/G/GB/GBARR/Authen-SASL-2.15.tar.gz
# tar xvf Authen-SASL-2.15.tar.gz
# cd Authen-SASL-2.15
# perl Makefile.PL
# make test
# make install
# cd ..

 

3,安装Perl模块Net::SMTP_auth

# wget http://search.cpan.org/CPAN/authors/id/A/AP/APLEINER/Net-SMTP_auth-0.08.tar.gz
# tar xvf Net-SMTP_auth-0.08.tar.gz
# cd Net-SMTP_auth-0.08
# perl Makefile.PL
# make test
# make install
# cd ..

 

4,安装Perl模块SVN::Notify

# wget http://search.cpan.org/CPAN/authors/id/D/DW/DWHEELER/SVN-Notify-2.80.tar.gz
# tar xvf SVN-Notify-2.80.tar.gz
# cd SVN-Notify-2.80
# perl Build.PL
# ./Build
# ./Build test
# ./Build install
# cd ..

 

5,启动邮件服务器

# service sendmail restart

# systemctl start sendmail.service

 

6,配置自动发邮件脚本重要

修改post-commit脚本,以支持邮件通知功能.

# cd /home/data/SVN/repository/hooks/
# cp post-commit.tmpl post-commit
# chmod +x post-commit
# vim post-commit

采用默认的 sendmail 发送邮件, vim post-commit 内容如下(推荐):

REPOS="$1"
REV="$2"

# mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf

mailer='/usr/share/doc/subversion-1.6.11/tools/hook-scripts/mailer/mailer.py'
mailer_conf='/usr/share/doc/subversion-1.6.11/tools/hook-scripts/mailer/mailer.conf'

$mailer commit "$REPOS" "$REV" $mailer_conf

if [ $? -ne 0 ]; then
    echo "failure to mailer.py commit $REPOS $REV" >> /var/log/svn_mail.log
fi

说明:脚本里代码有 /var/log/svn_mail.log 是用来记录发送时的日志 

或者,若是自定义安装的 subversion,则 mailer 路径是自定义的解压目录

REPOS="$1"
REV="$2"
TXN_NAME="$3"

#mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf

mailer='/home/data/tool-server/subversion-1.10.2/tools/hook-scripts/mailer/mailer.py'
mailer_conf='/home/data/tool-server/subversion-1.10.2/tools/hook-scripts/mailer/mailer.conf'

$mailer commit "$REPOS" "$REV" $mailer_conf

或者,采用svnnotify发送邮件,vim post-commit 内容如下:

#!/bin/sh
REPOS="$1"
REV="$2"

/usr/bin/svnnotify -repos-path "$1" -revision "$2" -to yanggang@163.com -from robot@ithomer.net.com -handler "HTML::ColorDiff" -with-diff -smtp localhost -smtp-user root -smtp-pass 5201314318 -c "UTF-8" -g zh_CN -o raw -svnlook /usr/bin/svnlook -subject-prefix '[SVN Update]'

这里,mailer.conf 文件还需要配置一些文件和参数:

1)拷贝 mailer.conf.example 为 mailer.conf

cp /home/data/tool-server/subversion-1.10.2/tools/hook-scripts/mailer/mailer.conf.example /home/data/tool-server/subversion-1.10.2/tools/hook-scripts/mailer/mailer.conf

2)配置 mailer.conf

vim /home/data/tool-server/subversion-1.10.2/tools/hook-scripts/mailer/mailer.conf

需要修改的配置项如下

[general]
mail_command = /usr/sbin/sendmail
   REPOS/
     trunk_group/
     branches_group/
     tags_group/

[defaults]
commit_subject_prefix = [mimvp_svn]
from_addr = xxx@mimvp.com
to_addr = xxx@163.com xxx@qq.com

说明:上面的默认配置,采用本机25端口号以及sendmail通过管道发送通知邮件

mailer.py 脚本共有三种发送邮件的方式,简单介绍如下:

vim /home/data/tool-server/subversion-1.10.2/tools/hook-scripts/mailer/mailer.py

class Messenger:
  def __init__(self, pool, cfg, repos, prefix_param):
    self.pool = pool 
    self.cfg = cfg
    self.repos = repos

    if cfg.is_set('general.mail_command'):
      cls = PipeOutput
    elif cfg.is_set('general.smtp_hostname'):
      cls = SMTPOutput
    else:
      cls = StandardOutput

    self.output = cls(cfg, repos, prefix_param)

从脚本代码可以看出,三种发送邮件的方式分别为:

1)PipeOutput 管道方式,使用默认的 sendmail 发送邮件,默认采用25端口号,容易被阿里云、腾讯云屏蔽25端口号

2)SMTPOutput 设置本机或第三方发送邮件,支持默认25端口号,以及465端口号(需要自己修改脚本代码,下文介绍)

3)StandardOutput 标准控制台输出发送邮件,就是把邮件内容打印在控制台,一般用于调试,没法发送到邮箱,不考虑

通过分析源代码,已经很清晰了,要在阿里云、腾讯云屏蔽25端口号云服务器上使用发送邮件,必须自己改动 mailer.py 源码,使其支持 465 端口号

 

修改 mailer.py 源码步骤如下:

1)修改 mailer.conf 配置 smtp (推荐

vim /home/data/tool-server/subversion-1.10.2/tools/hook-scripts/mailer/mailer.conf

完整配置如下:

[general]
#mail_command = /usr/sbin/sendmail

smtp_hostname = smtp.exmail.qq.com
smtp_username = robot@mimvp.com
smtp_password = mimvp-password

[defaults]
commit_subject_prefix = [mimvp_svn]
from_addr = robot@mimvp.com  		# 邮箱地址应该与smtp_username相同,并且from_addr是[defaults]标签下的,已舍弃的[general]中也有一个from_addr,不做修改
to_addr = abc@qq.com 123@mimvp.com  # 多个收件人邮箱地址,用空格分开  

 

2)修改 mailer.py 支持 smtp ssl 465 端口号(推荐

  def finish(self):
#    server = smtplib.SMTP(self.cfg.general.smtp_hostname)
   
server = smtplib.SMTP_SSL(self.cfg.general.smtp_hostname, 465) 

注释掉 server = smtplib.SMTP(self.cfg.general.smtp_hostname)添加支持 ssl 的 server = smtplib.SMTP_SSL(self.cfg.general.smtp_hostname, 465)

或者

  def finish(self):
    if self.cfg.is_set('general.smtp_ssl') and self.cfg.general.smtp_ssl == 'yes':
     
server = smtplib.SMTP_SSL(self.cfg.general.smtp_hostname)
    else:
      server = smtplib.SMTP(self.cfg.general.smtp_hostname)

 

post-commit 文件内容说明:

to 参数代表接收邮件的地址,可以有多个邮箱地址,其参数来自位于 mailer.conf 文件 to_addr 配置项

from 参数是虚拟的,代表你的发送地址,其参数来自位于 mailer.conf 文件 from_addr 配置项,一般情况下这个参数不重要,但如果接收者的邮件服务器有反垃圾邮件的功能,需要判定源地址的话,这个参数是否合法就显得很重要了

再给该脚本添加可执行权限

# chmod +x post-commit

 

测试发送邮件,有多种方式:

方式1)修改文件,svn ci -m "xxx" 正常提交文件,检测自动发送邮件

方式2) 直接命令模拟发送邮件

/usr/share/doc/subversion-1.6.11/tools/hook-scripts/mailer/mailer.py /home/data/SVN/repository/ 1000 /usr/share/doc/subversion-1.6.11/tools/hook-scripts/mailer/mailer.conf

其中 1000 是svn提交时的版本号,这个版本号一定是svn上存在的,否则会报错svn.core.SubversionException: ('No such revision 1000', 160006) 

如何知道svn提交的版本号:我在配置过程中,是在eclipse的svn插件提交测试的,可惜的是第一次邮件发送没有成功,然后我查看了一下mail.log, 里面记录的失败提交的版本号,这样我就搞到了一个svn存在版本号了,然后用以上代码直接命令行测试就好

 

7,再次提交时,就会给指定邮件地址发信了。

 

问题与解决:

问题1:

Warning: post-commit hook failed (exit code 1) with output:
You need version 1.5.0 or better of the Subversion Python bindings.

解决:stackoverflow上的大佬给的两种解释是1) svn.core cannot be imported, or 2) the version number in svn.core is too low.

安装最新版的 

yum -y install subversion-python

 

问题2:

# svn co http://svbversion.mimvp.com/repository repository

通过 http 下载代码出错信息如下:

svn: E170000: Unrecognized URL scheme for 'http://svbversion.mimvp.com/repository'

解决:

通过http或者https协议访问版本库,那就必须安装neno、或 serf 软件包,详见上文的 neon、serf 安装

SVN有ra_dav(http,https)、ra_svn(svn原生协议)、ra_local(本地路径)三种存取模块,系统为默认安装了ra_svn和ra_local,我们自己需要安装neon库,从而让svn支持ra_dav存储模块。

下面是不安装neon的情况下,svn的输出

# svn --version      
svn, version 1.10.2 (r1835932)
   compiled Jul 29 2018, 13:48:46 on x86_64-unknown-linux-gnu

The following repository access (RA) modules are available:

* ra_svn : Module for accessing a repository using the svn network protocol.
  - with Cyrus SASL authentication
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme

当我们正确安装neon,svn已经支持ra_dav之后,执行上述命令应该是如下输出:

# svn --version
svn, version 1.6.11 (r934486)
   compiled Mar  6 2014, 10:49:10

The following repository access (RA) modules are available:

* ra_neon : Module for accessing a repository via WebDAV protocol using Neon.
  - handles 'http' scheme
  - handles 'https' scheme
* ra_svn : Module for accessing a repository using the svn network protocol.
  - with Cyrus SASL authentication
  - handles 'svn' scheme
* ra_local : Module for accessing a repository on local disk.
  - handles 'file' scheme

 

 

五,其它常用配置

1,强制写log脚本

配置pre-commit文件,要求用户每次更新文件都必须写log

# cd /home/data/SVN/project/hooks/
# cp pre-commit.tmpl pre-commit
# chmod +x pre-commit
# vim pre-commit

配置后,完整的文件内容如下:

#!/bin/sh

REPOS="$1"
TXN="$2"

# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
#$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" > /dev/null || exit 1
log_msg_len=`$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" | wc -c`
log_msg_feature=`$SVNLOOK log -t "$TXN" "$REPOS" | grep "feature" `
log_msg_reviewer=`$SVNLOOK log -t "$TXN" "$REPOS" | grep "reviewer" `
if [ "$log_msg_len" -lt 5 ]; then
    echo -e "error_msg: no comment" 1>&2
    echo -e "write some comments more than 5 characters..." 1>&2
    exit 1
fi

if [ -z "$log_msg_reviewer" ]; then
    echo -e "error_msg: need reviewer, example: " 1>&2
    echo -e "feature: add main.c\nreviewer: yanggang\n" 1>&2
    exit 1
fi

if [ -z "$log_msg_feature" ]; then
    echo -e "error_msg: need feature, example: " 1>&2
    echo -e "feature: add main.c\nreviewer: yanggang\n" 1>&2
    exit 1
fi
# Check that the author of this commit has the rights to perform
# the commit on the files and directories being modified.
#commit-access-control.pl "$REPOS" "$TXN" commit-access-control.cfg || exit 1
commit_access_control='/usr/share/doc/subversion-1.6.11/tools/hook-scripts/commit-access-control.pl'
commit_access_control_cfg='/usr/share/doc/subversion-1.6.11/tools/hook-scripts/commit-access-control.cfg'
#$commit_access_control "$REPOS" "$TXN" $commit_access_control_cfg || exit 1

# All checks passed, so allow the commit.
exit 0

配置完成后,给本件加上可执行权限,再提交代码时,就必须按要求写注释了

记得拷贝配置文件:

cp /usr/share/doc/subversion-1.6.11/tools/hook-scripts/commit-access-control.cfg.example /usr/share/doc/subversion-1.6.11/tools/hook-scripts/commit-access-control.cfg

要求注释字符数不少于5个字符,注释中需要注明审核人(reviewer) 和功能说明(feature)

成功发送邮件内容如下:

 

2,可修改log脚本

配置pre-revprop-change文件,此文件在show log中修改log时会运行,得到修改的权限,否则会报错:

DAV request failed; it’s possible that the repository’s pre-revprop-change hook either failed or is non-existent. At least one property change failed; repository is unchanged

# cd /home/data/SVN/project/hooks/
# cp pre-revprop-change.tmpl pre-revprop-change
# chmod +x pre-revprop-change
# vim pre-revprop-change

文件内容如下:

REPOS="$1"
REV="$2"
USER="$3"
PROPNAME="$4"
if ["$PROPNAME" = "svn:log"];then exit 0;fi
exit 1

或者

REPOS="$1"
REV="$2"
USER="$3"
PROPNAME="$4"
ACTION="$5"

if [ "$ACTION" = "M" -a "$PROPNAME" = "svn:log" ]; then exit 0; fi

echo "Changing revision properties other than svn:log is prohibited" >&2
exit 1

配置完后加可执行权限升效。

 

六,svn服务器的备份管理 

备份管理 svn服务器的定期备份是很重要的,最简单的方式是定时备份仓库目录。

1,新建备份目录

# mkdir /opt/repository_backup

2,编写备份脚本

# cd /root/script/

# vim repository_backup.sh

内容如下:

#!/bin/bash
#
# mimvp.com
# 2015.10.01

cd /home/data/SVN/
now=`/bin/date +%Y%m%d`
/bin/tar czvf "repository_backup_$now.tar.gz" repository/ 
rm -rf /opt/repository_backup/* 
/bin/mv repository_backup_*.tar.gz /opt/repository_backup/
if [ $? == 0 ]; then
	result="backup success"
else
	result="backup failed"
fi

# send mail to admin
/bin/mail xxx@mimvp.com -s "repository_backup_$now" << MESSAGE
Result: `/bin/echo $result`
MESSAGE

给该脚本添加可执行权限:

chmod +x repository_backup.sh

3,设定每天定时执行该脚本.

# crontab -e

输入如下内容:

30 3 * * * /root/script/repository_backup.sh

表示每天清晨3:30分夜深人静时运行此脚本。

经过以上三步操作,就可以自动备份SVN资料了,且不论备份是否成功,都会给用户发送邮件信息。

 

七,svnstat 分析SVN数据

示例演示: http://svnstat.sourceforge.net

1、安装 Java

svnstat 是Java应用程序,需要先安装Java环境。

Java EE 官网:http://www.oracle.com/technetwork/java/javaee/downloads/index.html (最新版 jdk-10.0.2_linux-x64_bin.tar.gz  , 2018-07-17)

下载jre: jre-6u20-linux-i586-rpm.bin

安装:

# chmod +x jre-6u20-linux-i586-rpm.bin

# ./jre-6u20-linux-i586-rpm.bin

 

2、下载 svnstat

下载网址: https://sourceforge.net/projects/svnstat/files/latest/download

# wget http://downloads.sourceforge.net/project/svnstat/svnstat/Release-1.0/SvnStat-1.0.zip

# wget http://jaist.dl.sourceforge.net/project/svnstat/svnstat/Release-1.1-beta/SvnStat-1.1-beta.zip 推荐

unzip SvnStat-1.1-beta.zip
cd SvnStat-1.1-beta

 

3、svn co 一份svn项目,例如

# svn co http://svn.mimvp.com/trunk/demo   /var/www/html/demo

 

4、svnstat 生成数据

SvnStat -r <repository/logfile> [-d ] [-config ] [-begin ] [-end ]

# cd /var/www/html/demo/                # svn 项目绝对路径
# svn log /var/www/html/demo -v --xml --non-interactive > /var/www/html/demo/project.log
#
# cd /home/data/tool-server/SvnStat-1.1-beta/        
# 重回 svnstat 目录
# mkdir -p /var/www/html/svnstat                              # 创建生成结果的目标路径
# java  -classpath  SvnStat-all.jar  de.agentlab.svnstat.SvnStat  -jar  SvnStat-all.jar  -r  /var/www/html/demo/project.log  -d  /var/www/html/svnstat/      # 生成结果命令

 

5,浏览器查看

看到许多统计出来的图表,如下图:

centeros-build-svn-server-05

 

八,statsvn 分析SVN数据

1,下载statsvn

官方网址: http://statsvn.org/downloads.html (statsvn v0.7.0

# wget http://downloads.sourceforge.net/project/statsvn/statsvn/0.7.0/statsvn-0.7.0.zip

# unzip statsvn-0.7.0.zip
# cd statsvn-0.7.0
# vim readme.txt

  Quick Start

      * Download the latest release from http://sourceforge.net/projects/statsvn/
      * Expand the zip file into some directory, e.g c:\statsvn
      * Check out a working copy of the desired SVN module into
        some directory, e.g. c:\myproject.
      * Change into that directory and type
        'svn log --xml -v > svn.log'
      * Change back to the c:\statsvn directory
      * type 'java -jar statsvn.jar c:\myproject\svn.log c:\myproject'
      * Open c:\statsvn\index.html in your web browser

      You can tweak the output of StatSVN in various ways. Run
      'java -jar statsvn.jar' for an overview of the command line
      parameters, and check the manual for full information.

2,生成statsvn数据,操作步骤如下:

a)  svn co 一份svn项目,例如:

svn co http://svn.mimvp.com/trunk/demo   /var/www/html/demo

b)  进入svn项目,生成 svn log 日志的xml文件

cd /var/www/html/demo/                 # svn 项目路径
svn log --xml -v > project.log             # 绝对路径为 /var/www/html/demo/project.log

c) 回到statsvn目录,导出svn统计的结果

# cd /home/data/tool-server/statsvn-0.7.0/
# mkdir /var/www/html/statsvn
# java -jar statsvn.jar -verbose -output-dir /var/www/html/demo/statsvn/
/var/www/html/demo/project.log /var/www/html/demo/

3,用浏览器测试效果如下图:

centeros-build-svn-server-011

 

九,配置codestriker

CodeStriker 是一款支持在线代码review的协作工具,官方介绍:

Codestriker is a web application supporting online code reviewing, typically diffs generated by a Source Code Management system or plain unidiff patches. There are integration points with CVS, Subversion, Clearcase, Perforce and Visual SourceSafe.

CodeStriker 是基于Perl语言的工具,和其他工具一样,需要安装在你自己的服务器上。它支持广泛的多种类型,包括CVS, Subversion, Clearcase, Perforce, Visual SourceSafe and Bugzilla等内置式融合。

官方网址: http://codestriker.sourceforge.net

1. 安装codestriker依赖的perl包

# /usr/bin/perl -MCPAN -e 'install "Template"'

    /usr/bin/perl -MCPAN -e 'install "LWP::UserAgent"'
    /usr/bin/perl -MCPAN -e 'install "HTML::Entities"'
    /usr/bin/perl -MCPAN -e 'install "Template"'
   Minimum version required: 2.07
    /usr/bin/perl -MCPAN -e 'install "CGI"'
   Minimum version required: 2.56

 

2. 下载codestriker

# wget http://downloads.sourceforge.net/project/codestriker/codestriker/1.9.10/codestriker-1.9.10.tar.gz?use_mirror=jaist&ts=1279246587

# wget http://jaist.dl.sourceforge.net/project/codestriker/codestriker/1.9.10/codestriker-1.9.10.tar.gz

# tar xvf /path/codestriker-1.9.10.tar.gz

mv codestriker-1.9.10 /home/data/SVN/myproject/codestriker-1.9.10

# cd /home/data/SVN/myproject/

# chown -R apache:apache codestriker-1.9.10

 

3. 配置数据库

# service mysqld restart

# mysql -uroot mysql

执行:

CREATE DATABASE codestrikerdb CHARACTER SET utf8;
GRANT SELECT,INSERT,UPDATE,DELETE,INDEX,ALTER,CREATE,DROP,REFERENCES ON codestrikerdb.* TO codestriker@localhost IDENTIFIED BY ‘cspasswd’;
FLUSH PRIVILEGES;
quit

 

4. 配置codestriker

# cd codestriker/

# vim codestriker.conf

注意以下几点(详细可查看codestriker的安装文档)

a) 数据库的用户名密码要配对

b) svn的数据仓库要配对,我的如下:

@valid_repositories =
(
‘svn:file:///home/data/SVN/project’,
)

 

5. 执行codestriker的安装脚本

# cd codestriker-1.9.10/

# ./bin/install.pl

 

6. 配置http支持

1) httpd 添加 perl_mod

yum -y install mod_perl

2) httpd.conf 添加 mod_perl 模块

LoadModule perl_module modules/mod_perl.so

3) httpd.conf 添加域名访问配置

# vim /etc/httpd/conf/httpd.conf

在最后面加上如下内容:

Alias /codestriker/  /home/data/SVN/myproject/codestriker-1.9.10/cgi-bin/
Alias /codestrikerhtml/  /home/data/SVN/myproject/codestriker-1.9.10/html/

<Directory "/home/data/SVN/myproject/codestriker-1.9.10/cgi-bin/">
    SetHandler perl-script
    PerlHandler ModPerl::Registry
    Options +ExecCGI
</Directory>

<Directory "/home/data/SVN/myproject/codestriker-1.9.10/html/">
    AllowOverride None
    Allow from all
</Directory>

 

7. 重启Web服务

# service httpd restart

 

8. 在浏览器中输入http://115.29.237.28/codestriker/codestriker.pl ,如下图:

centeros-build-svn-server-07

 

 

疑难杂症的诊断与解决

问题1:

在目录 /home/data/SVN/repository/hooks/ 里,执行

/home/data/SVN/repository/hooks
sh post-commit

出现错误信息:

You need version 1.5.0 or better of the Subversion Python bindings.

解决:

此问题不是大问题,若直接 sh post-commit 一直才会出现,因为没有参数传入

若一定要解决,stackoverflow上的大佬给的两种解释是1) svn.core cannot be imported, or 2) the version number in svn.core is too low.

因此,可以安装: yum -y install subversion-python

 

问题2

svn ci -m "xxx" 提交代码是总是报如下错误

E170013 E125006: contains invalid filesystem format option 'addressing logical'

解决:

网上很多解答是因为服务端svn创建版本库 repository 和 客户端下载svn版本不一致造成的,建议两者版本升级到一致即可

但是,在实际测试用发现,自定义安装的 subversion 运用 svnadmin create repository 创建版本库时,其文件自带 addressing logical

查看创建的文件 vim /home/data/SVN/repository/db/format

cat /home/data/SVN/repository/db/format
8
layout sharded 1000
addressing logical

应该是自定义安装 subversion 有一些地方不对造成的,解决方案是 yum 命令安装 subversion 问题解决(subversion版本可能不是最新的)

yum -y install subversion

 

 

参考推荐

Subversion on CentOS

CentOS 搭建SVN Server

CentOS 7.2 / 6.5 系统安装指引

Ubuntu 配置 Apache

Centos7 使用 sendmail 发送邮件