简介:面向银河麒麟操作系统的运维与开发人员,这份文档详实记录了在国产Linux环境下从零搭建SVN版本控制服务的完整流程。全文以实操为主线,涵盖Subversion及其依赖组件apr、apr-util、SQLite的源码下载、编译安装,环境变量配置、版本库目录初始化、svnserve.conf/passwd/authz三个配置文件的权限策略设置,以及服务启动、开机自启脚本编写等环节;同时给出Windows客户端访问地址示例和常见易错点提示(如配置文件首行不可留空)。资源共1个docx文件,约202KB,命令与说明对照排列,便于边看边操作、离线留存查阅。已有2787人学习,适合有一定Linux基础、需要在内网或未预置SVN服务的银河麒麟系统上完成部署的技术人员参考。
1. 银河麒麟安装 SVN 环境,最稳的做法是拿源码在自己机器上编译
银河麒麟这类国产系统虽然普遍预装了 yum/apt 软件源,但源里的 Subversion 版本往往和业务团队本地的 TortoiseSVN 版本对不上,或者干脆就没有可用的 rpm/deb 包。我遇到过几次直接yum install subversion装出来的 svnserve 在创建 1.8 格式的版本库时报E200030 database is locked,最后都改成源码编译才稳定。下面以 subversion-1.8.14、apr-1.6.5、apr-util-1.6.1 这套组合为例,从依赖编译讲到最后开机自启,适合内网无外网环境的运维人员和需要自建代码托管服务器的开发。
2. 编译前先理清 apr、apr-util、sqlite 三者的构建顺序
许多人在银河麒麟上编译 SVN 失败,问题不在 Subversion 本身,而在前置依赖。Subversion 是一个面向多操作系统的版本控制服务,它把文件系统、网络、内存池等底层能力委托给 APR(Apache Portable Runtime)和 APR-util 处理;从 1.7 开始,Subversion 的元数据又全部存在 SQLite 中。这三个组件之间没有独立的编译门槛,但 configure 阶段却有严格的顺序和路径要求,下面逐个说明。
2.1 apr 与 apr-util 的关系:apr-util 必须先看到 apr
APR 提供跨平台的原子操作、文件加锁、套接字封装,相当于 Subversion 对这些底层平台的“翻译层”。APR-util 依赖 APR 提供数据库抽象和资源池管理,所以编译顺序必须先 apr、后 apr-util。编译 apr-util 时要在configure参数里通过--with-apr=/usr/local/apr明确告诉它 apr 已经装在哪里,否则它默认去找系统自带的 apr,版本不对时会在后续 Subversion 编译中出现APR not found一类的报错。
2.2 版本组合与归档准备
这次使用的版本组合是:apr-1.6.5、apr-util-1.6.1、subversion-1.8.14,以及 sqlite-amalgamation-3071501。SQLite 版本不要直接用最新的,Subversion 1.8 对 SQLite API 的兼容性有要求,用 3.7.15.1 这个发布包最稳,它和 1.8.14 是在同一个发布周期内测过的。先把这些包放到目标的/home/dmdba/svn/目录,然后统一解压:
cd /home/dmdba/svn # 所有源码包先集中到同一下载目录,再统一解压 tar zxf apr-1.6.5.tar.gz tar zxf apr-util-1.6.1.tar.gz tar zxf subversion-1.8.14.tar.gz unzip sqlite-amalgamation-3071501.zip请用 root 用户执行后续所有命令。两个archive.apache.org页面的目录结构不一样,apr 在dist/apr/下,subversion 在dist/subversion/下,不要复制错,否则解压到一半发现是一个 HTML 错误页就浪费时间了。
2.3 apr 的 configure 参数:--prefix 决定后续路径
进入 apr 目录后,我一般先执行make clean清理一次,再从源码开始:
cd /home/dmdba/svn/apr-1.6.5 # --prefix 指定安装根目录,后续依赖方都用这个路径引用 ./configure --prefix=/usr/local/apr make && make install--prefix=/usr/local/apr指定安装根目录,后续 apr-util 与 subversion 都用绝对路径引用这里,避免污染系统/usr。如果编译过程中报缺gcc或make,先检查编译工具链:yum -y install gcc make gcc-c++ expat-devel perl。银河麒麟 v10 的源里一般都有,内网环境需要提前准备本地 rpm。
然后编译 apr-util:
cd /home/dmdba/svn/apr-util-1.6.1 # --with-apr 告诉 configure 到哪里找 apr 的头文件和编译脚本 ./configure \ --prefix=/usr/local/apr-util \ --with-apr=/usr/local/apr make && make install在 apr-util 的 configure 中,--with-apr=/usr/local/apr是走通这一步的关键。它让 apr-util 在头文件搜索路径里加入/usr/local/apr/include。如果你省略这个参数,而系统又恰好没有安装过 libapr,configure 会直接停止并提示APR could not be located。
2.4 sqlite-amalgamation 不要 configure,它是一份聚合源码
SQLite 的 amalgamation 文件把sqlite3.c、sqlite3.h、sqlite3ext.h等合并成少数几个 C 文件,方便其他项目直接内联编译。它不是一个独立可安装的软件包,不用执行 configure 和 make。Subversion 构建时会把这份源码编译进libsvn_fs_fs子系统中去,用来支撑 FSFS 格式仓库的后端。
为了让 SVN 的 configure 找到它,把解压后的目录改名并移动到 subversion 源码树内部,这是最省事的方式:
cd /home/dmdba/svn mv sqlite-amalgamation-3071501 sqlite-amalgamation mv sqlite-amalgamation subversion-1.8.14/如果你不想移动目录,也可以在稍后执行 subversion 的 configure 时手动增加--with-sqlite=/home/dmdba/svn/sqlite-amalgamation-3071501/sqlite3.c。两个方式二选一,移动目录方案的好处是:SVN 的构建脚本能在默认位置直接找到sqlite3.c,后续升级 patch 时路径关系更干净。
3. 编译 subversion 1.8.14,并把 svnserve 放进全局 PATH
前置依赖就位后,Subversion 本身的编译并不复杂,但 configure 的三组参数要理解到位,同时要避免连接器找不到共享库。这一步完成后,建议立刻用svnserve --version验证,不要等建完仓库再查。
3.1 configure 的 --with-apr 和 --with-apr-util 都填绝对路径
回到 subversion 源码目录,执行配置和编译:
cd /home/dmdba/svn/subversion-1.8.14 ./configure \ --prefix=/usr/local/svn \ --with-apr=/usr/local/apr \ --with-apr-util=/usr/local/apr-util make && make install如果刚才把sqlite-amalgamation移动到了 subversion 目录下,./configure会自动识别;如果发现仍然报SQLite is required,检查subversion-1.8.14/sqlite-amalgamation/下是否有sqlite3.c,并补上--with-sqlite=/home/dmdba/svn/subversion-1.8.14/sqlite-amalgamation/sqlite3.c后重新 configure。表格里整理了三个参数的用途:
| 参数 | 作用 | 填错时的典型报错 |
|---|---|---|
--prefix=/usr/local/svn | 指定 svn 可执行文件、配置目录、库文件的安装根目录 | make install 后/usr/local/svn/bin/svn不存在 |
--with-apr=/usr/local/apr | 指定 APR 头文件与apr-1-config的位置 | checking for APR... no |
--with-apr-util=/usr/local/apr-util | 指定 APR-util 头文件与apu-1-config的位置 | APR-UTIL could not be located |
编译期间如果遇到zlib.h not found,补装 zlib 开发包:yum install zlib-devel。不要拿系统已有的 subversion rpm 再覆盖,源码装出来的二进制和发行版包管理策略不同,容易在 PATH 里出现旧版本 svnserve 抢跑的现象。
3.2 修改 /etc/profile 而不是只用 export
临时export PATH=$PATH:/usr/local/svn/bin只能作用于当前 shell。SVN 服务一般由 rc.local、systemd 或登录 shell 启动,不写进全局 profile,过几个小时就会遇到svnserve: command not found的诡异问题。编辑/etc/profile,在末尾增加两行:
vim /etc/profile找到文件末尾后,追加以下内容:
PATH=$PATH:/usr/local/svn/bin export PATH保存后执行source /etc/profile,再用which svnserve确认路径已经落到/usr/local/svn/bin。这条环境变量要等新开终端或重启后才会完全传导给桌面应用和计划任务。如果你长期用 IntelliJ IDEA 这类 IDE 调用 SVN,记得让 IDE 重新登录用户会话,否则svn.path仍可能指向错误位置。
3.3 svnserve --version 验证安装结果
编译安装完成后,最直接的验证方式是查看版本信息:
svnserve --version如果输出有svnserve, version 1.8.14并列出可用的认证方式,说明安装成功。常见问题有三个:一是把--version误写成-version,会收到Unknown argument: -version;二是输入的是svn --version,那只能看客户端版本,和 svnserve 无直接关系;三是命令行从网页复制时,--两个横杠变成了类似–r的 Unicode 字符,导致启动失败。本节所有路径和参数建议手打一遍,避免粘贴引入不可见字符。
4. 创建版本库并完成 svnserve.conf、passwd、authz 三件套配置
版本库初始化最容易在配置阶段出错。我见到的多数问题不是命令不行,而是配置文件编码和控制字符不对,比如文件开头带上制表符、空行里有看不见的空格。这一章按“建目录 → 创建仓库 → 配置三个文件 → 校验权限”的顺序展开。
4.1 svnadmin create 之后,仓库目录下会多出哪些配置
先规划根目录。我习惯在/home/svn/下以项目名建一级目录,每个项目独立成一个 repository,后续接 Git 镜像也方便。命令如下:
mkdir -p /home/svn/project svnadmin create /home/svn/project ls -l /home/svn/project执行完svnadmin create后,project 目录下会出现conf、hooks、db、locks、format、README.txt等对象。db里是实际存储的文件与事务数据,format记录了仓库格式版本,conf就是要改的三个配置文件。这里有一个容易忽略的权限点:如果/home/svn对非 root 账号有写权限,建议把版本库目录权限收敛到 root,并确认/home/svn下没有编译时残留的临时文件,否则 svnserve 有时会读取目录下无关文件引起误判。
4.2 svnserve.conf 中四个选项和一个文件头问题
用 vim 打开版本库下的conf/svnserve.conf:
vim /home/svn/project/conf/svnserve.conf把原有注释行删除或替换为下面内容,四个选项都必须放在[general]标签之后,且每行左对齐顶格写:
[general] anon-access = none auth-access = write password-db = passwd authz-db = authzanon-access = none对匿名访问直接拒绝;auth-access = write让通过密码认证的用户可读可写;password-db = passwd指向同目录下的用户口令文件;authz-db = authz引入权限控制文件。这些配置不需要写绝对路径,svnserve 会自动以当前 conf 目录为基准。有个细节:passwd 与 authz 两个文件即使没有细分权限,也要在 svnserve.conf 中显式声明,否则默认不启用认证,匿名访问策略会很混乱。
注意:svnserve.conf 的
[general]必须出现在文件开头,首行不可以留空,也不要带 BOM 或行前空格,否则 SVN 会直接识别为配置错误。
4.3 passwd 和 authz 的写法,以及权限定义范围
编辑同目录下的passwd,配置用户 admin:
[users] admin=123456用户名在这里自由定义,密码不要沿用示例里的123456,接入业务团队后应该立即改成强密码。admin=123456中不要加空格,等于号后面加了空格虽然也可能通过,但在部分旧版 SVN 中会成为密码的一部分,统一成无空格格式最稳。
编辑authz:
[groups] g_admin = admin [/] @g_admin = rw *=[groups]定义群组,g_admin群内包含用户admin;[/]表示该权限段适用于版本库根路径,@g_admin = rw给群组授予读写权限,最后的*=代表其他用户无任何权限。这里与分支(trunk)概念无关,[/]不是 trunk,它只是仓库根路径。之后如果开了多个仓库,想要更细的管理,可以用[project:/]这样的段来限定仓库名,并配合-r设置的根目录理解权限范围。
配置完成后,先用错误账号验证拒绝访问,再换 admin 验证能列出目录:
svn list --username=guest --password=wrong svn://127.0.0.1/project svn list --username=admin --password=123456 svn://127.0.0.1/project第一条命令应返回认证失败,第二条能正常输出空目录或文件列表,说明三件套配置生效。
5. 启动 svnserve 与开机自启脚本的路径问题
服务启动命令很简单,但开机自启部分藏着一个与系统环境变量有关的坑,这一章把它单独说清楚。
5.1 以后台守护方式启动 svnserve
在版本库根目录/home/svn之上启动:
svnserve -d -r /home/svn-d表示 daemon 模式,以后台服务形式运行;-r /home/svn把 /home/svn 作为安全根目录,客户端 URL 只写到/project这一层,不需要知道宿主机的绝对路径。ps -ef | grep svnserve可以确认进程已经带-r参数运行。如果之前编辑过/etc/profile而新终端还没有开,建议这里直接用绝对路径/usr/local/svn/bin/svnserve -d -r /home/svn启动,排除 PATH 干扰。
5.2 把 /usr/local/svn/bin 写进自启脚本,而不是裸写 svnserve
在/root/下创建svn.sh,内容使用 svnserve 的绝对路径:
#!/bin/bash # rc.local 启动阶段还没有加载登录 profile,不能用裸写 svnserve /usr/local/svn/bin/svnserve -d -r /home/svn执行chmod +x /root/svn.sh,然后把它追加到/etc/rc.d/rc.local并给 rc.local 加执行位:
echo "/root/svn.sh" >> /etc/rc.d/rc.local chmod +x /etc/rc.d/rc.local如果你用的银河麒麟版本没有/etc/rc.d/rc.local,看看/etc/rc.local是否为符号链接,往实际存在的那个文件里追加即可。为什么自启脚本里不能用裸的svnserve?因为在系统启动脚本阶段,/etc/profile还没有被加载,PATH 里默认不会包含/usr/local/svn/bin,裸写命令经常得到svnserve: command not found。chmod 777不是必须的,给脚本和 rc.local 加上执行位就够了。重启后用ps -ef | grep svnserve | grep -v grep验证是否拉起成功。
5.3 用 svn ls 检查客户端 URL 容易漏掉的那一层目录
服务启动后,在 Windows 上用 TortoiseSVN 或命令行客户端访问,地址是svn://服务器IP/project。注意 URL 只写版本库名project,不要写成svn://IP/home/svn/project,也不要写成svn://IP/svn/project。正确地址取决于-r /home/svn的根目录和仓库文件夹名的拼接:根路径/home/svn加上版本库名project,拼出来就是svn://IP/project。出现认证失败时,先回看 svnserve.conf 首行是否留空,再用tail -f /var/log/syslog观察有没有Invalid config或E000061记录,这些细节能帮你在第一时间区分是密码问题还是配置文件语法问题。
本文还有配套的精品资源,点击获取