在linux上搭建svn服务器

背景

将部署在windows上的svn服务器迁移到linux

准备工作

linux服务器安装svn

1
yum -y install subversion

windows导出dump文件

1
svnadmin dump 项目地址 > 项目名.dump

linux创建版本库

1
svnadmin create /var/svn/test

linux导入dump文件

1
svnadmin load /svndata/项目名 < 项目名.dump

配置文件对照表

文件名 功能 windows linux
svnserve.conf svn服务配置 svnserve.conf svnserve.conf
authz 账号权限管理 VisualSVN-SvnAuthz.ini authz
passwd 密码配置文件 htpasswd passwd
根目录authz 所有库账号公共权限管理 VisualSVN-GlobalWinAuthz.ini 根目录authz
groups.conf svn用户群组信息 groups.conf 根目录authz

配置文件修改

svnserve.conf

1
2
3
4
anon-access = none (none匿名不可访问)
auth-access = write
password-db = /var/svn/passwd (修改为根目录的passwd)
authz-db = /var/svn/authz (修改为根目录的authz)

authz

1
2
3
4
5
6
7
8
[groups]
dev = dayi123,dayi

# windows
[/]
# linux (需要带根目录下的项目名)
[test:/]
test= rw

httpd支持

为了能通过web访问,以及兼容windows visualsvn的htpasswd,需要使用httpd服务

1
2
3
# 下载httpd和mod_dav_svn模块
yum install -y mod_dav_svn
yum install -y httpd

增加httpd的svn配置
vim /etc/httpd/conf.d/svn.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<Location /svn>
#开启svn
DAV svn
#指定父目录位置,以后所有版本库都将存放在该目录下
SVNParentPath /var/svn/
#开启svn版本库父目录功能
SVNListParentPath On
#指定授权模式
AuthType Basic
#登陆窗口标题显示提示文字
AuthName "Authorization Realm"
#指定访问版本库的账户和密码存放文件,该文件需要用apache的htpasswd命令创建
AuthUserFile /var/svn/htpasswd
#指定访问版本库的用户和组的权限控制文件
AuthzSVNAccessFile /var/svn/authz
#要求验证有效的用户才能访问
Require valid-user
</Location>

开启httpd服务

1
2
systemctl enable httpd
systemctl start httpd

如果不想使用httpd的默认端口80或者该端口被占用,则可以修改/etc/httpd/conf/httpd.conf中的默认端口

兼容windows的htpasswd
首先查看htpasswd文件中密码的格式
test:$apr1$uer$1txKFt7mXE/EV1ouN4xWK1

对比httpd官网给的几种加密方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
bcrypt
$ htpasswd -nbB myName myPassword
myName:$2y$05$c4WoMPo3SXsafkva.HHa6uXQZWr7oboPiC2bT/r7q1BB8I2s0BRqC

MD5
$ htpasswd -nbm myName myPassword
myName:$apr1$r31.....$HqJZimcKQFAMYayBlzkrA/

SHA1
$ htpasswd -nbs myName myPassword
myName:{SHA}VBPuJHI7uixaa6LQGWx4s+5GKNE=

CRYPT
$ htpasswd -nbd myName myPassword
myName:rqXexS6ZhobKA

可以看出使用的是MD5加密

使用htpasswd增加新用户

1
2
htpasswd -nbm myName myPassword
=> myName:$apr1$i/YRWA8N$sHsoGDljceyyIj5KTQJw/.

将其拷贝到httpd文件中,测试能否登陆svn即可

启动svn服务

基本命令

1
2
svnserve -d -r /var/svn/
killall svnserve

设置为systemctrl服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=svn-server
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/svnserve -d -r /var/svn
ExecStop=/usr/bin/killall svnserve
PrivateTmp=true
Restart=always
RestartSec=1min

[Install]
WantedBy=multi-user.target

systemctl daemon-reload
systemctl enable svn
systemctl start svn

更换svn库地址

右键=》TortoiseSVN=》重新定位

其它一些功能

添加提交时强制写日志功能
首先拷贝hooks下面的pre-commit.tmpl为pre-commit(windows下为’pre-commit.bat’ or ‘pre-commit.exe’) 并增加执行权限
chmod -R u+x,g+x,o+x hooks

代码

1
2
3
4
5
6
7
8
9
10
11
REPOS="$1"
TXN="$2"

# Make sure that the log message contains some text.
SVNLOOK=/usr/bin/svnlook
LOGMSG=$($SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" | wc -c)

if [ "$LOGMSG" -lt 10 ]; then
echo -e "\n Log message can't be empty! you must input change log. " 1>&2
exit 1
fi

在这里插入图片描述

增加备份功能
全量备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/bin/bash
# svn全量备份脚本

DATE=$(date +%Y%m%d:%H:%M:%S) #定义时间变量,用于文件名后缀
SVN_DIR=/var/svn #定义SVN库目录
SVN_BAK_DIR=/var/svndumpBak #定义备份文件存放目录

# 备份库列表
bakList=(test1 test2)

# 保留日志份数
keep_log_num=1

for rep in ${bakList[@]}
do
# 定义各个项目的初始版本号文件
svn_dir=$SVN_DIR/$rep
svn_bak_dir=$SVN_BAK_DIR/full_log/$rep
if [[ ! -d $svn_bak_dir ]]
then
mkdir -p $svn_bak_dir
fi

#开始备份
svnadmin dump $svn_dir > $svn_bak_dir/${rep}_$DATE.dump
if [ $? -eq 0 ];
then
echo "backup success...."
else
echo "backup fail...."
continue
fi

cd $svn_bak_dir
#清理过期备份
num=`expr $keep_log_num + 1`
ls -t | tail -n +$num | xargs rm -rf
done

增量备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/bin/bash
# svn增量备份脚本

DATE=$(date +%Y%m%d:%H:%M:%S) #定义时间变量,用于文件名后缀
SVN_DIR=/var/svn #定义SVN库目录
SVN_BAK_DIR=/var/svndumpBak #定义备份文件存放目录

# 备份库列表
bakList=(test1 test2)

# 保留日志份数
keep_log_num=7

for rep in ${bakList[@]}
do
# 定义各个项目的初始版本号文件
svn_dir=$SVN_DIR/$rep
svn_file=$svn_dir/conf/svn_ver_id
svn_bak_dir=$SVN_BAK_DIR/incr_log/$rep

if [[ ! -e $svn_file ]]
then
touch $svn_file
echo '0' > $svn_file
fi

if [[ ! -d $svn_bak_dir ]]
then
mkdir -p $svn_bak_dir
fi

NUM0=$(cat $svn_file)
NUM1=`expr $NUM0 + 1`
NUM2=$(svnlook youngest $svn_dir)

#没有新增跳过
if [[ NUM1 -eq NUM2 ]]
then
continue
fi

#开始备份
svnadmin dump $svn_dir -r $NUM1:$NUM2 --incremental > $svn_bak_dir/${rep}_${NUM1}_${NUM2}_$DATE.dump

#判断备份是否成功,若成功,则记录当前最新的版本号到临时文件中,用于下次增量备份使用
if [ $? -eq 0 ];
then
echo $NUM2 > $svn_file
else
echo "backup fail...."
continue
fi

#清理过期备份
cd $svn_bak_dir
num=`expr $keep_log_num + 1`
ls -t | tail -n +$num | xargs rm -rf
done

添加定时任务

1
2
3
4
# 每天3点增量备份
0 3 * * * sh /var/svn/dumpincr.sh >> /var/svndumpBak/incr_dump/incr.log 2>&1
#每周5 3点全量备份
0 3 * * 5 sh /var/svn/dumpfull.sh >> /var/svndumpBak/full_dump/full.log 2>&1

遇到的一些问题

svn could not begin a transaction svn 提交文件报错
在这里插入图片描述
原因是在svn服务器上创建仓库时使用了root身份登录服务器, 导致文件没有足够的写权限, 需更改仓库的组权限
chown -R apache:apache /var/svn

[Error output could not be translated from the native locale to UTF-8.] hooks里面有中文报错
在这里插入图片描述

经过查询是1.8之后才会解决的一个bug,可以升级到1.8以上的版本测试下下面的方法
vim /etc/httpd/conf/httpd.conf

1
2
3
4
5
<IfModule mod_dav_fs.c>
# Location of the WebDAV lock database.
DAVLockDB /var/lib/dav/lockdb
SVNUseUTF8 On
</IfModule>

重启httpd

参考

svn 从windows迁移到linux 记录