ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux离线安装SVN实践:基于本地yum源的完整配置

Linux离线安装SVN实践:基于本地yum源的完整配置 前阵子接手一台内网隔离的Linux服务器需求很直接在这台机器上把SVN服务端搭起来供团队提交代码和文档。原本以为半小时能搞定结果踩了不少坑——没有外网、yum源连不通、rpm包依赖一环扣一环如果直接盲目rpm安装几乎必然报依赖缺失。折腾完整个流程之后我想把这套“离线安装SVN”的完整操作记录下来从准备安装包、梳理依赖到配置用户权限、注册系统服务一路上会遇到什么问题、怎么排查全部捋清楚。这套方法不依赖特定发行版只要你的机器是CentOS 7/8、Rocky、AlmaLinux这类RHEL系基本可以照着复现真正适合内网环境和离线部署场景。1. 离线安装的整体思路先解决“包”的问题再谈SVN配置1.1 离线环境装软件最怕的不是软件本身而是依赖链很多人第一次接触离线安装下意识会去网上找一个subversion的rpm包或者tar.gz源码包然后拷到服务器上直接装。这个过程通常会碰到三个问题单个rpm包往往不完整SVN依赖apr、apr-util、sqlite、neon等一长串库少一个都装不上。源码编译虽然能绕开rpm依赖但需要gcc、make等编译工具链离线环境下连这些工具都未必齐全而且编译耗时长、容易因为缺少某个开发库报警告。版本不匹配问题尤其是Java相关工具链场景下SVN版本差异会直接影响客户端兼容性。我推荐的方案是在一台能联网的同版本Linux机器上用包管理器把SVN及其全部依赖rpm包拉下来然后拷到内网机器做成本地yum源来安装。这个方案的核心思路是“把在线安装的依赖解析结果原封不动搬到离线环境”本质上和在线yum install一模一样只是把下载环节提前了。1.2 对比一下几种常用离线方案选哪种更省事我实际中评估过三类做法这里直接说结论方案优点缺点适合场景下载rpm包 本地yum源依赖自动解析安装快可复现需要提前准备包制作yum源需要createrepo工具大多数内网服务器强烈推荐rpm -ivh 手动逐个安装简单粗暴依赖关系处理非常痛苦经常需要加--nodeps容易留下隐患只装单个无依赖的rpm时应急源码编译安装灵活、可定制编译时间长依赖编译环境后续维护麻烦没有对应rpm包或需要定制功能时从运维角度说本地yum源是性价比最高的做法。它不仅能用于SVN以后内网机器要装其他软件、打安全补丁都可以复用这套机制。所以本篇主线就用“下载rpm包—制作本地yum源—yum安装”这条路径。2. 安装前准备先摸清系统底细再梳理依赖清单2.1 确认系统版本、架构和自带软件情况在动手之前先要在目标机器上执行几条命令确认基础信息。这一步千万别省因为不同系统版本对应的rpm包来源差别很大架构不同更是完全不能通用。# 查看操作系统版本 cat /etc/redhat-release # 查看内核和CPU架构 uname -m # 查看是否已经装了SVN相关组件 rpm -qa | grep subversion svnserve --version我那次操作的机器是CentOS 7.9x86_64架构系统里没有任何subversion相关包。如果你的机器已经装过旧版本建议先rpm -e统一卸载干净再走离线安装流程否则可能出现库文件版本冲突。2.2 梳理Subversion的完整依赖链这是离线安装里最重要的功课。SVN不是单打独斗的软件它依赖一套底层的运行时库。用yum安装的时候系统会自动解决这些依赖但离线环境下你必须提前准备好这里列出CentOS 7上最常见的依赖清单subversion主程序subversion-libs核心运行库几乎所有SVN功能都依赖它aprApache可移植运行库提供跨平台底层接口apr-utilapr的扩展库sqliteSVN用于存储FSFS格式元数据的数据库引擎cyrus-sasl当使用svnserve的SASL认证时会用到expatXML解析库SVN的配置解析依赖它neonWebDAV客户端库使用http://协议访问仓库时需要其中subversion、subversion-libs、apr、apr-util、sqlite是核心链路缺一个都起不来。这些包在联网机器上通过repotrack命令可以一次性全部拉取不需要逐个去网上找。2.3 确定安装包的获取来源联网机器“下载包”这一步怎么做准备离线rpm包最稳定的方式是在一台与目标机器系统版本一致的联网机器上执行repotrack或yumdownloader。repotrack在yum-utils工具包里可以递归地下载包及其全部依赖yumdownloader配合--resolve参数也能达到类似效果但有时会漏掉一些“推荐安装”的依赖所以优先用repotrack。# 在联网机器上先安装yum-utils yum install -y yum-utils # 创建存放rpm包的目录 mkdir -p /root/svn-offline-rpms cd /root/svn-offline-rpms # 下载subversion及其全部依赖包 repotrack subversion执行完之后这个目录下会有一大堆rpm文件。这时候把它们打包成一个tar.gz传到内网机器上就可以了tar czf svn-offline-rpms.tar.gz /root/svn-offline-rpms内部传文件的办法常见有scp、ftp、U盘拷贝、内网共享目录怎么方便怎么来。我那次是打包后拷到跳板机再上传注意文件权限即可。注意下载rpm包时一定确认联网机器和目标机器的系统大版本一致。CentOS 7的包不要在CentOS 8上装反之亦然否则会遇到glibc版本不兼容的问题。3. 核心操作制作本地yum源并完成离线安装3.1 目标机器上创建本地yum仓库rpm包到位之后接下来要把它们变成yum能识别的仓库。如果目标机器之前没有安装createrepo命令可以在下载rpm包时顺手把createrepo这个包也一起拉下来或者直接在临时目录里用rpm强制安装一个独立的createrepo rpm包。准备本地仓库的步骤# 1. 把离线包解压到目标机器比如/opt/svn-offline-rpms目录 mkdir -p /opt/svn-offline-rpms tar zxf svn-offline-rpms.tar.gz -C /opt/svn-offline-rpms # 2. 如果系统没有createrepo先用rpm方式装一个 # 在联网机器上提前下载 createrepo 包及其依赖拷过来 rpm -ivh createrepo-*.rpm # 3. 生成仓库元数据 cd /opt/svn-offline-rpms createrepo .createrepo执行完之后目录下会出现一个repodata文件夹这就是yum检索元数据的地方。此时可以新建一个yum源配置文件来指向它vi /etc/yum.repos.d/local-svn.repo # 文件内容如下 [local-svn] nameLocal SVN Repository baseurlfile:///opt/svn-offline-rpms enabled1 gpgcheck0保存后执行yum clean all和yum makecache让yum重新读取仓库信息。提示gpgcheck建议设成0因为我们用的是自己下载的rpm包签名校验没有实际意义如果强行设成1而缺少公钥反而会报GPG key相关错误。3.2 用yum命令执行离线安装让依赖自动解析本地源就绪之后安装就变得非常简单了yum install -y subversionyum会从/opt/svn-offline-rpms这个本地源里把所有依赖包一次性装完不需要再额外处理依赖问题。安装完成后验证一下svnserve --version正常会输出版本信息和编译参数比如svnserve, version 1.7.14 (r1542130) compiled Apr 29 2018, 20:45:40到这一步SVN本体已经安装成功。整个过程的核心就是把在线安装时的依赖下载环节前置然后用本地源“欺骗”yum让它在离线状态下也能正常解析依赖。3.3 如果不想做yum源能不能直接rpm安装有读者会问既然rpm包都在目录里了我能不能rpm -ivh *.rpm一把梭理论上可以但我踩过一次坑rpm安装有顺序问题必须先装底层依赖库再装subversion主体。直接rpm -ivh *.rpm时如果shell通配符展开的顺序不对非常容易报“需要被依赖”的错误。如果实在不想做yum源有一个折中办法rpm -ivh apr-*.rpm apr-util-*.rpm sqlite-*.rpm subversion-libs-*.rpm subversion-*.rpm也就是手动控制安装顺序。但这样做一旦某个包版本不匹配排查起来很痛苦。做本地yum源才是正统做法多花5分钟省下后面一堆麻烦。4. 配置SVN服务端创建仓库和用户权限体系4.1 创建代码仓库并确认权限归属SVN装好之后第一件事是规划仓库目录。我习惯把仓库统一放在/opt/svn下每个项目一个仓库或者用一个大仓库再分目录。两种方式各有优劣这里我先用“仓库目录”方式演示# 创建仓库根目录 mkdir -p /opt/svn # 创建项目仓库这里以demo为例 svnadmin create /opt/svn/demo创建完成后/opt/svn/demo目录下会出现conf、db、hooks等子目录。如果SVN服务是以root身份启动的那么仓库目录权限默认没问题如果以后要切换为普通用户启动svnserve必须chown -R svnuser:svnuser /opt/svn/demo否则客户端提交时会疯狂报Permission denied。注意svnadmin create这个命令创建的仓库默认是FSFS格式这是SVN官方推荐的存储模式不要随便改成BDB格式维护难度大且稳定性差。4.2 核心配置文件svnserve.conf到底要改哪些参数仓库的配置目录是/opt/svn/demo/conf里面有三个核心文件svnserve.conf、passwd、authz。svnserve.conf是整个服务端的“总开关”里面很多配置项默认被注释掉必须手动打开并指定authz和passwd路径。我一般把svnserve.conf改成这样[general] anon-access none auth-access write password-db passwd authz-db authz realm my-svn-realm逐行解释一下anon-access none禁止匿名访问。不设成none的话别人不输密码也能读取仓库这对代码仓库来说很危险。auth-access write认证用户有读写权限。password-db passwd账号密码文件指向当前目录下的passwd文件。authz-db authz授权规则文件指向当前目录下的authz文件。realm my-svn-realm认证域名称只要是纯svnserve方式这个名字通常不会影响使用但多个仓库时建议区分开避免缓存串台。改完之后重启svnserve服务才生效。注意svnserve.conf里的配置项等号两边不要乱加空格有些SVN版本解析非常严格空格会导致配置项被忽略。4.3 用户密码文件和权限文件最简单的授权实践passwd文件格式很直白就是“用户名 密码”的列表。我建议至少创建一个管理员账号和一个普通成员账号方便测试不同权限[users] admin Admin123456 zhangsan zhangsan123456 lisi lisi123456authz文件控制“谁能访问哪个仓库的哪个目录”。SVN的权限核心是“先写继承规则再写例外规则”常用的写法如下[groups] devteam zhangsan,lisi [/] admin rw devteam r * [/trunk] devteam rw这个规则含义是根目录下admin可读写devteam组只读其他人没有任何权限但trunk目录下devteam组提升为读写权限。注意* 这行星号表示“所有人”等号右边留空表示无权限这是安全基线写法建议每一段都加上。保存好passwd和authz之后再手动启动svnserve进行第一次验证svnserve -d -r /opt/svn-r参数指定仓库根目录这样客户端访问路径不用带上完整的物理路径直接用svn://服务器IP/demo就能连上demo仓库。5. 把SVN注册为系统服务并放行防火墙5.1 使用systemd管理svnserve进程告别手动启动前面用svnserve -d启动只是临时进程一旦机器重启进程就没了。要让它随开机自启必须写一个systemd服务文件。我通常在/etc/systemd/system/svnserve.service路径下创建[Unit] DescriptionSubversion Server Afternetwork.target [Service] Typeforking ExecStart/usr/bin/svnserve --daemon --root /opt/svn ExecReload/bin/kill -HUP $MAINPID PIDFile/run/svnserve.pid Restarton-failure [Install] WantedBymulti-user.target写完之后依次执行systemctl daemon-reload systemctl enable svnserve systemctl start svnserve systemctl status svnserve如果status显示active (running)就说明服务已经跑起来了。注意Typeforking是因为svnserve加--daemon参数后会fork出后台进程所以systemd需要PIDFile来定位主进程如果不想写PIDFile可以把启动方式改成ExecStart/usr/bin/svnserve -d -r /opt/svn并且去掉Typeforking。5.2 防火墙端口放行与客户端连通性检查SVN默认走3690端口内网环境通常开着firewalld或iptables不放行的话客户端连接必失败。CentOS 7用firewalld的放行命令firewall-cmd --permanent --add-port3690/tcp firewall-cmd --reload firewall-cmd --list-ports如果用的是旧版iptables可以临时加一条规则iptables -I INPUT -p tcp --dport 3690 -j ACCEPT service iptables save之后在另一台机器上用svn客户端测试基本的仓库访问svn list svn://服务器IP/demo --username admin --password Admin123456如果配置正确会列出仓库当前的空目录第一次创建时什么内容都没有。这一步能通说明服务端、权限、防火墙全链路已经打通。5.3 客户端导入项目与日常提交命令服务端通路没问题后最后一步就是把代码导入仓库。假设本地有一个项目目录/root/myproject要提交到demo仓库的trunk目录下# 1. 初始化项目目录结构 cd /root/myproject mkdir -p trunk branches tags # 2. 将项目导入仓库 svn import /root/myproject svn://服务器IP/demo --username admin --password Admin123456 -m 初始化项目结构这时再执行svn list svn://服务器IP/demo就能看到trunk、branches、tags三个目录。团队其他同事则可以用svn checkout把仓库拉下来svn checkout svn://服务器IP/demo/trunk --username zhangsan关于客户端Windows上常用TortoiseSVNLinux终端直接用svn命令IDEA里配置Subversion时填入svn://服务器IP/demo即可。这几种方式都是走同一个svnserve服务只要服务端配置好客户端几乎不用额外设置。6. 排障与避坑离线安装SVN常见的几类问题6.1 依赖错误rpm工具本身缺createrepo怎么办很多时候目标机器是一个精简系统连createrepo都没装。解决办法是在联网机器上提前用yumdownloader --resolve --destdir/root/createrepo-rpms createrepo把createrepo及其依赖全拉下来再拷到内网机器上rpm -ivh一次性安装。这是我在“离线装离线工具”时最常用的方法本质上仍是“提前下载依赖包”的思路。6.2 E000013 Permission denied根源往往在目录权限svnserve启动之后客户端checkout时报svn: E000013: Cant open file /opt/svn/demo/format: Permission denied这一般不是SVN配置问题而是svnserve运行用户对仓库目录没有写权限。排查方法先用ps -ef | grep svnserve查看svnserve是什么用户启动的。再用ls -ld /opt/svn/demo查看仓库目录owner。如果svnserve是root启动但仓库目录被chown成了别的用户root反而可能因为SELinux策略限制而报权限问题。最稳妥的做法是统一用root启动就把仓库owner设成root或者干脆创建一个svn用户管理仓库。如果是SELinux导致的权限问题可以先看一下/var/log/audit/audit.log有没有相关记录临时用setenforce 0验证一下确认是SELinux拦截再用chcon或semanage放行。6.3 authentication failed密码文件与权限配置不同步客户端提示认证失败90%是以下三种原因passwd文件里用户被误加了空格或中文字符。authz文件中用户名大小写与passwd不一致。svnserve.conf里password-db路径不对导致SVN没读到passwd文件直接拒绝认证。排错时最简单的办法是把svnserve.conf里的anon-access改成readauth-access改成write暂时注释authz-db然后客户端用svn list试一次。如果能匿名访问说明问题出在认证配置如果仍然失败那就是服务端没读到配置重启svnserve再看。6.4 防火墙/SELinux导致连不上端口客户端报svn: E670008: Cannot connect to host服务端却显示进程正常这通常是防火墙或SELinux的问题。先用telnet 127.0.0.1 3690在服务器本机测一下端口如果本机通、远程不通那就是防火墙没放行如果本机都不通检查服务监听地址ss -lntp | grep 3690确认svnserve监听的是0.0.0.0:3690而不是只有127.0.0.1。6.5 快速排查速查表现象可能原因排查命令/操作yum install找不到包本地yum源没生效yum repolist检查repo文件baseurlrpm安装有依赖冲突使用方式不对改用本地yum源安装svnserve启动报错配置文件语法问题svnserve -d -r /opt/svn -X 前台运行看输出客户端无法连接防火墙/服务未启动systemctl status svnservefirewall-cmd --list-ports提交时Permission denied目录权限或SELinuxls -ld /opt/svnsetenforce 0临时验证认证失败passwd/authz配置问题检查空格、大小写、路径7. 我实际维护中的几点经验7.1 保留离线rpm包后续版本升级和补丁全靠它们离线环境最怕反复“找包”。这次为SVN准备的rpm目录我建议单独放一份到内网公共存储上同时把这个local-svn.repo文件保存好。以后内网机器再加节点直接把这个repo配置和rpm目录拷过去就能复用不用重新上网找。7.2 仓库备份用hotcopy随手就能做SVN仓库的备份首推svnadmin hotcopy它能在仓库运行状态下做出一份一致性的物理备份svnadmin hotcopy /opt/svn/demo /backup/svn/demo-$(date %F)这个命令比直接cp -r更安全因为它会把当前仓库的db目录状态强制落盘避免复制过程中产生不一致。如果是日常定时备份放在crontab里执行即可。7.3 仓库目录规划越早想清楚后面越省心我最初图简单把SVN根目录直接当作仓库后来项目多了才发现问题权限控制、备份、迁移都不方便。后来统一改成/opt/svn/仓库名这种结构每个仓库独立svnadmin create权限用authz统筹管理备份时按仓库粒度操作清晰得多。如果你预计团队会有多个项目并行强烈建议一开始就用“多仓库”结构。7.4 关于版本选择我在这篇记录里以CentOS 7 SVN 1.7为例因为这是内网存量系统里最常见的组合之一。如果你的系统是Rocky Linux 9或Ubuntu 22.04原理完全一样只是包管理器命令不同Ubuntu离线安装可以用apt-offline或下载.deb包配置方式依然是svnserve.conf/passwd/authz那套。SVN版本不必追求最新稳定和兼容性优先很多老项目的客户端工具链仍然停留在1.7/1.8时代贸然升级高版本服务端反而容易引入兼容性问题。离线安装SVN这件事本身并不难真正考验人的是对依赖链的梳理和对配置细节的耐心。把“提前准备rpm包”和“本地yum源”这两步做扎实后面就是svnadmin create和改三个配置文件的事。希望这篇记录能让你在遇到同样场景时少走几步弯路。
返回列表