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版本列表

svn 下载最新版

subversion-1.14.3.tar.gz (2023-12-28) 推荐 

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

subversion-1.7.14.tar.gz (2013-11-23)

 

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 命令安装(推荐方案

新建配置最新 yum.repo 源,可查看最新版本subversion为 1.42.2  (2022-10-25)

vim /etc/yum.repos.d/wandisco-svn.repo

[WandiscoSVN]
name=Wandisco SVN Repo
baseurl=http://opensource.wandisco.com/centos/$releasever/svn-1.14/RPMS/$basearch/
enabled=1
gpgcheck=0

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)下载源码

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

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

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

 

sqlite 官网:https://www.sqlite.org/download.html  , https://github.com/sqlite/sqlite

sqlite-autoconf-3460000.tar.gz  (version 3.46.0, 2024-05-23

sqlite-autoconf-3410200.tar.gz (version 3.41.2, 2023-03-22)

sqlite-amalgamation-3240000.zip (version 3.24.0, 2018-06-04)

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

The version is encoded so that filenames sort in order of increasing version number when viewed using "ls". For version 3.X.Y the filename encoding is 3XXYY00(7位,最后2位ZZ没用到). For branch version 3.X.Y.Z, the encoding is 3XXYYZZ.

 

neon-0.29.6.tar.gz

serf-1.3.9.zip

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

 

apr / apr-util / apr-iconv:官网 http://apr.apache.org/download.cgi

apr-1.7.4.tar.gz (2023-04-16)

apr-util-1.6.3.tar.gz (2023-02-01)

apr-iconv-1.2.2.tar.gz   (2017-10-22)

 

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

2.1)安装 sqlite3

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

 

2.2)安装 apr、apr-util、pcre

apr 和 apr-util一般会在 httpd 的安装包内,subversion安装会使用到apr和par-util

如果当前系统没有,则需自定义安装,请参见米扑博客:Ubuntu / CentOS 配置Apache、apr、apr-util、apr-iconv、sqlite

 

2.3)安装 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.4)安装 neonsubversion-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 / 7.6 / 7.7 + 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, MacOS 10.15.2 + svn-1.10.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.5)安装 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 OPENSSL=/usr/local/openssl
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.6)安装 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

或完整命令

/usr/local/subversion/bin/svnserve -d -r /home/data/SVN --listen-port=3690 --config-file=/home/data/SVN/repository/conf/svnserve.conf --log-file=/var/log/svnserve.log

查看 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:3690/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:3690/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/

 

SVN服务器的 HTTPS 支持  (推荐)

修改 httpd.conf 配置文件,基本原理:

1)http 80端口,强制跳转到 https 443端口,即 http 强制跳转到 https 访问

2)SVN 库 /repo 放在配置文件的 httpd.conf 的末尾,任意域名都可匹配,例如: svn.yourdomain.com/repo,svn123.yourdomain.com/repo 都可访问

3)为了防止任意域名都可访问,因此增加了用户名密码,需登录验证

vim  /etc/httpd/conf/httpd.conf

# svn 80 for http to https
<VirtualHost *:80>
    ServerAdmin yourname@yourdomain.com
    DocumentRoot /usr/local/httpd/htdocs/mimvp_svn
#    DocumentRoot /home/data/SVN/repo/
    ServerName svn.yourdomain.com
    
    RewriteEngine on
    RewriteCond   %{HTTPS} !=on
    RewriteRule   ^(.*)  https://%{SERVER_NAME}$1 [L,R]
    
    DirectoryIndex index.php index.html index.htm
    ErrorLog /var/log/svn.yourdomain.com-error_log
    CustomLog /var/log/svn.yourdomain.com-access_log customlog
</VirtualHost>

# svn 443 for https
<VirtualHost *:443>
    SSLEngine on
    SSLCertificateChainFile /usr/local/httpd/conf/1_svn_root_bundle.crt
    SSLCertificateFile /usr/local/httpd/conf/2_svn.yourdomain.com.crt
    SSLCertificateKeyFile /usr/local/httpd/conf/3_svn.yourdomain.com.key

    ServerAdmin yourname@yourdomain.com
    DocumentRoot /usr/local/httpd/htdocs/mimvp_svn
#    DocumentRoot /home/data/SVN/repo/
    ServerName svn.yourdomain.com
    
    DirectoryIndex index.php index.html index.htm
    ErrorLog /var/log/svn.yourdomain.com-error_log
    CustomLog /var/log/svn.yourdomain.com-access_log customlog
</VirtualHost>

# svn path for any xxx.domain.com 例如: svn.yourdomain.com (但配置了用户名密码,需登录)
# 放在最后匹配, https://svn.yourdomain.com/repo 找不到也会匹配上
<Location /repo>
    DAV svn
    SVNPath /home/data/SVN/repo/
    AuthType Basic
    AuthName "svn for repo"
    AuthUserFile /home/data/SVN/repo/conf/webpasswd
    AuthzSVNAccessFile /home/data/SVN/repo/conf/authz
    Satisfy all
    Require valid-user
    SSLRequireSSL
</Location>

 

四,配置邮件提醒支持

安装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 xxx@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: yourname\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: yourname\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

 

问题3:

在 CentOS 7.x 系统上执行 svn up ,svn --version,都报错如下:

# /bin/svn --version              
/bin/svn: symbol lookup error: /lib64/libsvn_ra_neon-1.so.0: undefined symbol: svn__apr_hash_index_val

# /usr/bin/svn --version     
svn: symbol lookup error: /usr/local/lib/libsvn_fs_x-1.so.0: undefined symbol: svn_fs_util__version

问题分析:undefined symbol 含义是软链接找不到,通过 ldd 查看软链接

# ldd /lib64/libsvn_ra_neon-1.so.0
        linux-vdso.so.1 =>  (0x00007ffc71dda000)
        libsvn_delta-1.so.0 => /usr/local/lib/libsvn_delta-1.so.0 (0x00007fb30c97c000)
        libsvn_subr-1.so.0 => /usr/local/lib/libsvn_subr-1.so.0 (0x00007fb30c6a2000)
        libz.so.1 => /lib64/libz.so.1 (0x00007fb30c48c000)
        libsqlite3.so.0 => /usr/local/lib/libsqlite3.so.0 (0x00007fb30c17e000)
        libmagic.so.1 => /lib64/libmagic.so.1 (0x00007fb30bf61000)
        libaprutil-1.so.0 => /lib64/libaprutil-1.so.0 (0x00007fb30bd38000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fb30bb01000)
        libexpat.so.1 => /lib64/libexpat.so.1 (0x00007fb30b8d7000)
        libdb-5.3.so => /lib64/libdb-5.3.so (0x00007fb30b518000)
        libapr-1.so.0 => /lib64/libapr-1.so.0 (0x00007fb30b2e9000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb30b0cd000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fb30aec9000)
        libneon.so.27 => /lib64/libneon.so.27 (0x00007fb30ac9e000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fb30a8d0000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fb30a5ce000)
        libuuid.so.1 => /lib64/libuuid.so.1 (0x00007fb30a3c9000)
        libfreebl3.so => /lib64/libfreebl3.so (0x00007fb30a1c6000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fb30cdc2000)
        libgnutls.so.28 => /lib64/libgnutls.so.28 (0x00007fb309e8c000)
        libpakchois.so.0 => /lib64/libpakchois.so.0 (0x00007fb309c85000)
        libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fb309a38000)
        libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fb30974f000)
        libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fb30951c000)
        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fb309318000)
        libproxy.so.1 => /lib64/libproxy.so.1 (0x00007fb3090f7000)
        libp11-kit.so.0 => /lib64/libp11-kit.so.0 (0x00007fb308dc8000)
        libtasn1.so.6 => /lib64/libtasn1.so.6 (0x00007fb308bb5000)
        libnettle.so.4 => /lib64/libnettle.so.4 (0x00007fb308984000)
        libhogweed.so.2 => /lib64/libhogweed.so.2 (0x00007fb30875d000)
        libgmp.so.10 => /lib64/libgmp.so.10 (0x00007fb3084e5000)
        libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fb3082d5000)
        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fb3080d1000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fb307eb8000)
        libmodman.so.1 => /lib64/libmodman.so.1 (0x00007fb307cb0000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fb3079a9000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fb307793000)
        libffi.so.6 => /lib64/libffi.so.6 (0x00007fb30758b000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fb307364000)
        libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fb307102000)

如上,实际上 /lib64/libsvn_ra_neon-1.so.0 的软链接是存在的,查看如下:

# ll /lib64/libsvn_ra_neon-1.so.0
lrwxrwxrwx 1 root root 25 Aug 23  2018 /lib64/libsvn_ra_neon-1.so.0 -> libsvn_ra_neon-1.so.0.0.0
# ll /lib64/libsvn_ra_neon-1.so.0.0.0 
-rwxr-xr-x 1 root root 160152 Apr 11  2018 /lib64/libsvn_ra_neon-1.so.0.0.0

网上很多说是 libapr-1.so.0 和 libaprutil-1.so.0 要用系统自带的(/lib64/),或太老了要自定义安装,或用了自定义安装的(/usr/local/lib/, /usr/lib64/)

详解网上的博客:

make subversion时出现neon报错 及 svn其他问题汇总

libsvn_subr-1.so.0: undefined symbol: apr_atomic_xchgptr 故障解决

symbol lookup error: /usr/local/lib/libsvn_subr-1.so.0: undefined symbol: apr_atomic_xchgptr

可能错误现象:/tools/svn/bin/svn: symbol lookup error: /tools/svn/lib/libsvn_subr-1.so.0: undefined symbol: apr_atomic_xchgptr

错误解决:新配置的服务器,在运行svn命令时,全部出错显示上面的错误信息。

在网上搜索发现,原来这个错误是由于系统已经安装了apr的库文件,而在编译svn时已经指定了httpd的apr库。

在执svn命令时,优先从系统自带的apr库载入,而引起不必要的错误。

只需要执行以下命令,将CentOS操作系统自带的 apr 和 apr-util 都卸载即可(亲测未解决问题

rpm -e --allmatches apr-util --nodeps
rpm -e --allmatches apr --nodeps

那么,问题到底出在哪里呢?

仔细研究上面的 ldd 软链接,可以发现有几个 /usr/local/lib/xxx 依赖,具体为:

# ldd /lib64/libsvn_ra_neon-1.so.0 | grep "/usr/local"
        libsvn_delta-1.so.0 => /usr/local/lib/libsvn_delta-1.so.0 (0x00007f61e04be000)
        libsvn_subr-1.so.0 => /usr/local/lib/libsvn_subr-1.so.0 (0x00007f61e01e4000)
        libsqlite3.so.0 => /usr/local/lib/libsqlite3.so.0 (0x00007f61dfcc0000)

为什么会出现这种情况呢?原因是有自定义安装(例如我就自定义安装了 sqlite3),或不知原因的出现了 /usr/local/lib/libsvn_delta-1.so.0 和 /usr/local/lib/libsvn_subr-1.so.0

于是乎,我去对比了正常CentOS 服务器上的 svn --version ,发现都没有 /usr/local/lib/xxx 依赖

正常CentOS 服务器上的 svn --version,如下:

# svn --version
svn, version 1.7.14 (r1542130)
   compiled Apr 11 2018, 02:40:28

Copyright (C) 2013 The Apache Software Foundation.
This software consists of contributions made by many people; see the NOTICE
file for more information.
Subversion is open source software, see http://subversion.apache.org/

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

# ldd /lib64/libsvn_ra_neon-1.so.0   
        linux-vdso.so.1 =>  (0x00007ffd00f8c000)
        libsvn_delta-1.so.0 => /lib64/libsvn_delta-1.so.0 (0x00007f75df4e8000)
        libsvn_subr-1.so.0 => /lib64/libsvn_subr-1.so.0 (0x00007f75df282000)
        libz.so.1 => /lib64/libz.so.1 (0x00007f75df06c000)
        libsqlite3.so.0 => /lib64/libsqlite3.so.0 (0x00007f75dedb7000)
        libmagic.so.1 => /lib64/libmagic.so.1 (0x00007f75deb9a000)
        libaprutil-1.so.0 => /lib64/libaprutil-1.so.0 (0x00007f75de971000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f75de73a000)
        libexpat.so.1 => /lib64/libexpat.so.1 (0x00007f75de510000)
        libdb-5.3.so => /lib64/libdb-5.3.so (0x00007f75de151000)
        libapr-1.so.0 => /lib64/libapr-1.so.0 (0x00007f75ddf22000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f75ddd06000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f75ddb02000)
        libneon.so.27 => /lib64/libneon.so.27 (0x00007f75dd8d7000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f75dd50a000)
        libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f75dd305000)
        libfreebl3.so => /lib64/libfreebl3.so (0x00007f75dd102000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f75df91d000)
        libgnutls.so.28 => /lib64/libgnutls.so.28 (0x00007f75dcdc8000)
        libpakchois.so.0 => /lib64/libpakchois.so.0 (0x00007f75dcbc1000)
        libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f75dc974000)
        libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f75dc68b000)
        libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f75dc470000)
        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f75dc26c000)
        libproxy.so.1 => /lib64/libproxy.so.1 (0x00007f75dc04b000)
        libp11-kit.so.0 => /lib64/libp11-kit.so.0 (0x00007f75dbd1c000)
        libtasn1.so.6 => /lib64/libtasn1.so.6 (0x00007f75dbb09000)
        libnettle.so.4 => /lib64/libnettle.so.4 (0x00007f75db8d8000)
        libhogweed.so.2 => /lib64/libhogweed.so.2 (0x00007f75db6b1000)
        libgmp.so.10 => /lib64/libgmp.so.10 (0x00007f75db439000)
        libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f75db22a000)
        libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f75dadc9000)
        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f75dabc5000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f75da9ac000)
        libmodman.so.1 => /lib64/libmodman.so.1 (0x00007f75da7a4000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f75da49d000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f75da19b000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f75d9f85000)
        libffi.so.6 => /lib64/libffi.so.6 (0x00007f75d9d7d000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f75d9b56000)
        libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f75d98f4000)

如上,正常的CentOS系统上,都是 /lib64/xxx 软链接

# ldd /lib64/libsvn_ra_neon-1.so.0 | grep -E "libsvn_delta|libsvn_subr|libsqlite3.so"
        libsvn_delta-1.so.0 => /lib64/libsvn_delta-1.so.0 (0x00007ff54541a000)
        libsvn_subr-1.so.0 => /lib64/libsvn_subr-1.so.0 (0x00007ff5451b4000)
        libsqlite3.so.0 => /lib64/libsqlite3.so.0 (0x00007ff544ce9000)

因此,初步判定问题出在了软链接上,但不是在 /lib64/libsvn_ra_neon-1.so.0 这个软链接上(报错不准确,可能是依赖造成的报错定位不准)

于是,我们来查找上面三个错误的软链接,并删除、软链接上正确的

1)查找,以 libsvn_delta-1.so.0 为例

# find / -name "libsvn_delta-1.so.0"
/usr/lib64/libsvn_delta-1.so.0
/usr/local/lib/libsvn_delta-1.so.0

2)删除现有的软链接(/usr/local/lib/libsvn_delta-1.so.0)

rm -f /lib64/libsvn_delta-1.so.0

3)链接上正确的软链接(/usr/lib64/libsvn_delta-1.so.0)

ln -s /lib64/libsvn_delta-1.so.0 -> /usr/lib64/libsvn_delta-1.so.0.0.0

同理,查找、删除、软链接上其它两个软链接 /lib64/libsvn_subr-1.so.0  和  /lib64/libsqlite3.so.0

最后,问题解决!

# ldd /lib64/libsvn_ra_neon-1.so.0       
        linux-vdso.so.1 =>  (0x00007fff56986000)
        libsvn_delta-1.so.0 => /lib64/libsvn_delta-1.so.0 (0x00007fbc04b65000)
        libsvn_subr-1.so.0 => /lib64/libsvn_subr-1.so.0 (0x00007fbc048ff000)
        libz.so.1 => /lib64/libz.so.1 (0x00007fbc046e9000)
        libsqlite3.so.0 => /lib64/libsqlite3.so.0 (0x00007fbc04434000)
        libmagic.so.1 => /lib64/libmagic.so.1 (0x00007fbc04217000)
        libaprutil-1.so.0 => /lib64/libaprutil-1.so.0 (0x00007fbc03fee000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fbc03db7000)
        libexpat.so.1 => /lib64/libexpat.so.1 (0x00007fbc03b8d000)
        libdb-5.3.so => /lib64/libdb-5.3.so (0x00007fbc037ce000)
        libapr-1.so.0 => /lib64/libapr-1.so.0 (0x00007fbc0359f000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fbc03383000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007fbc0317f000)
        libneon.so.27 => /lib64/libneon.so.27 (0x00007fbc02f54000)
        libc.so.6 => /lib64/libc.so.6 (0x00007fbc02b86000)
        libuuid.so.1 => /lib64/libuuid.so.1 (0x00007fbc02981000)
        libfreebl3.so => /lib64/libfreebl3.so (0x00007fbc0277e000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fbc04f9a000)
        libgnutls.so.28 => /lib64/libgnutls.so.28 (0x00007fbc02444000)
        libpakchois.so.0 => /lib64/libpakchois.so.0 (0x00007fbc0223d000)
        libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fbc01ff0000)
        libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fbc01d07000)
        libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fbc01ad4000)
        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fbc018d0000)
        libproxy.so.1 => /lib64/libproxy.so.1 (0x00007fbc016af000)
        libp11-kit.so.0 => /lib64/libp11-kit.so.0 (0x00007fbc01380000)
        libtasn1.so.6 => /lib64/libtasn1.so.6 (0x00007fbc0116d000)
        libnettle.so.4 => /lib64/libnettle.so.4 (0x00007fbc00f3c000)
        libhogweed.so.2 => /lib64/libhogweed.so.2 (0x00007fbc00d15000)
        libgmp.so.10 => /lib64/libgmp.so.10 (0x00007fbc00a9d000)
        libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fbc0088d000)
        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fbc00689000)
        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fbc00470000)
        libmodman.so.1 => /lib64/libmodman.so.1 (0x00007fbc00268000)
        libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fbbfff61000)
        libm.so.6 => /lib64/libm.so.6 (0x00007fbbffc5f000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fbbffa49000)
        libffi.so.6 => /lib64/libffi.so.6 (0x00007fbbff841000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fbbff61a000)
        libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fbbff3b8000)
# 
# svn --version                   
svn, version 1.7.14 (r1542130)
   compiled Apr 11 2018, 02:40:28

Copyright (C) 2013 The Apache Software Foundation.
This software consists of contributions made by many people; see the NOTICE
file for more information.
Subversion is open source software, see http://subversion.apache.org/

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

小结:

若只是下载 svn,则只需要安装系统默认的 yum -y install svn 即可,不需要自定义安装 apr、neon、sqlite3 等,避免自定义安装与系统安装的交叉、混乱导致的错误!

CentOS 安装 svn 有两种命令,选择其一即可:

1)yum -y install svn

2)yum -y install subverion subversion-devel  (推荐)

 

 

参考推荐

Subversion on CentOS

CentOS 搭建SVN Server

CentOS 7.2 / 6.5 系统安装指引

LNMP(CentOS+Nginx+Mysql+PHP)服务器环境配置

Ubuntu 配置 Apache

Centos7 使用 sendmail 发送邮件

Linux 使用 make install 安装的软件如何卸载