基于Debian的SVN服务器自动安装脚本
SVN服务器自动安装脚本
功能概述
此Bash脚本用于在Debian系统上自动安装和配置SVN(Subversion)服务器。脚本提供了两种部署方式:svnserve(独立服务器)和Apache(基于HTTP的服务器),并包含完整的错误处理、自动修复和故障排查功能。
主要功能
- 自动检测和安装基础依赖
- 清理已有SVN环境(可选保留现有仓库)
- 支持svnserve和Apache两种部署方式
- 自动创建SVN仓库和用户认证
- 配置文件权限和访问控制
- 创建系统服务
- 自动配置防火墙规则
- SSL证书生成(Apache模式)
- 详细的错误处理和自动修复
- 提供故障排查工具
安装要求
- Debian或基于Debian的Linux系统(如Ubuntu)
- 以root用户或具有sudo权限的用户运行
- 互联网连接(用于安装软件包)
使用步骤
1. 准备工作
- 将脚本下载到服务器
- 赋予脚本执行权限:
chmod +x install_svn.sh
2. 执行脚本
以root用户执行脚本:
sudo ./install_svn.sh
3. 选择部署方式
脚本会提示选择SVN的部署方式:
- 选项1:svnserve(推荐,轻量级,更易于配置)
- 选项2:Apache(功能更丰富,但配置更复杂)
4. 配置过程
对于svnserve模式:
- 脚本会自动安装subversion包
- 创建SVN仓库
- 设置用户认证
- 配置访问权限
- 创建并启动系统服务
- 配置防火墙规则
对于Apache模式:
- 脚本会询问SVN服务器域名
- 安装subversion、apache2和相关模块
- 创建自签名SSL证书
- 配置Apache虚拟主机
- 设置用户认证
- 配置访问权限
- 启用必要的Apache模块
- 配置防火墙规则
5. 完成安装
安装完成后,脚本将显示:
- SVN服务URL
- 管理员账户和密码
- 普通用户账户和密码
- 客户端连接命令示例
所有配置信息将保存在/root/svn_installation_info.txt
文件中。
6. 故障排查
如果安装过程中遇到问题或安装后服务无法正常访问,可以使用脚本创建的故障排查工具:
- 对于svnserve模式:
/root/svnserve_troubleshoot.sh
- 对于Apache模式:
/root/apache_svn_troubleshoot.sh
此外,脚本还添加了每日服务检查任务,保存在/root/check_svn_services.sh
,并通过crontab每天自动运行。
安装流程图
注意事项
-
安全考虑:脚本会自动生成随机密码,并保存在配置文件中。请在安装后修改这些密码以提高安全性。
-
防火墙配置:脚本会自动检测系统中的防火墙(UFW、FirewallD或iptables)并配置必要的规则。
-
自定义配置:安装完成后,您可以根据需要修改以下配置文件:
- svnserve模式:
/var/svn/svnrepo/conf/
目录下的配置文件 - Apache模式:
/etc/apache2/sites-available/svn.conf
和/etc/apache2/svn/
目录下的文件
- svnserve模式:
-
SSL证书:Apache模式下自动生成的是自签名证书,生产环境建议使用正式的SSL证书。
-
备份:在清理现有SVN环境时,脚本会提供备份选项。请确保重要数据得到妥善备份。
故障排查
如果遇到问题,请按照以下步骤操作:
- 检查配置信息:
cat /root/svn_installation_info.txt
- 运行故障排查脚本:
- svnserve模式:
/root/svnserve_troubleshoot.sh
可联系提供 - Apache模式:
/root/apache_svn_troubleshoot.sh
请联系提供
- svnserve模式:
- 检查服务状态:
/root/check_svn_services.sh
- 检查日志文件:
- svnserve模式:系统日志
journalctl -u svnserve
- Apache模式:
/var/log/apache2/error.log
和/var/log/apache2/svn-error.log
- svnserve模式:系统日志
其他说明
如有问题,欢迎关注公众号“大刘讲IT”或加Q709840110
脚本内容
安装脚本
#!/bin/bash
# SVN自动安装脚本
# 用于Debian系统
# SVN说明: SVN使用文件系统存储版本数据,不需要额外的数据库服务
# 所有版本信息、历史记录和元数据都存储在仓库文件结构中
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 无颜色
# 检查是否以root用户运行
if [ "$(id -u)" != "0" ]; then
echo -e "${RED}此脚本必须以root用户运行${NC}" 1>&2
exit 1
fi
# 函数:检查命令是否可用
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# 函数:检查并安装基础依赖
install_dependencies() {
echo -e "${BLUE}检查并安装基础依赖...${NC}"
# 基础依赖包列表
local base_deps="apt-transport-https ca-certificates curl gnupg lsb-release software-properties-common wget openssl"
# 确保apt更新
apt-get update
# 安装基础依赖
for dep in $base_deps; do
if ! dpkg -l | grep -q "^ii $dep "; then
echo -e "${BLUE}安装基础依赖: $dep${NC}"
apt-get install -y $dep || {
echo -e "${RED}无法安装基础依赖: $dep${NC}"
echo -e "${YELLOW}继续安装,但可能会遇到问题${NC}"
}
else
echo -e "${GREEN}基础依赖已安装: $dep${NC}"
fi
done
}
# 函数:检测并清理已有SVN环境
cleanup_existing_environment() {
echo -e "${BLUE}检测并清理已有SVN环境...${NC}"
# 检查是否已安装subversion
if dpkg -l | grep -q "^ii subversion "; then
echo -e "${YELLOW}检测到已安装subversion,准备清理...${NC}"
# 停止相关服务
if systemctl is-active --quiet svnserve; then
echo -e "${BLUE}停止svnserve服务...${NC}"
systemctl stop svnserve
systemctl disable svnserve
fi
# 检查Apache与SVN相关
if dpkg -l | grep -q "^ii libapache2-mod-svn "; then
echo -e "${BLUE}停止Apache服务...${NC}"
systemctl stop apache2 2>/dev/null
echo -e "${BLUE}清理Apache SVN模块...${NC}"
if [ -f "/etc/apache2/sites-enabled/svn.conf" ]; then
a2dissite svn.conf 2>/dev/null || rm -f "/etc/apache2/sites-enabled/svn.conf"
fi
if [ -d "/etc/apache2/svn" ]; then
echo -e "${YELLOW}备份并移除Apache SVN认证配置...${NC}"
mv /etc/apache2/svn /etc/apache2/svn.bak.$(date +%Y%m%d%H%M%S) 2>/dev/null
fi
echo -e "${BLUE}卸载Apache SVN模块...${NC}"
apt-get purge -y libapache2-mod-svn
fi
# 询问是否保留现有SVN仓库
echo -e "${YELLOW}检测到现有SVN仓库,是否保留? [Y/n]${NC}"
read -r keep_repos
if [[ $keep_repos =~ ^[Nn]$ ]]; then
if [ -d "/var/svn" ]; then
echo -e "${YELLOW}备份现有仓库...${NC}"
mv /var/svn /var/svn.bak.$(date +%Y%m%d%%H%M%S)
fi
else
echo -e "${GREEN}保留现有仓库${NC}"
fi
# 卸载SVN服务
echo -e "${BLUE}卸载subversion...${NC}"
apt-get purge -y subversion
apt-get autoremove -y
echo -e "${GREEN}完成SVN环境清理${NC}"
else
echo -e "${GREEN}未检测到已安装的SVN环境,可以直接安装${NC}"
fi
}
# 函数:安装必要的软件包
install_package() {
local package_name="$1"
echo -e "${BLUE}安装软件包: $package_name${NC}"
apt-get install -y "$package_name" || {
echo -e "${RED}无法安装 $package_name. 请检查您的网络连接和apt源配置.${NC}"
return 1
}
}
# 函数:配置防火墙规则
configure_firewall() {
local port="$1"
echo -e "${BLUE}配置防火墙规则,开放端口 $port...${NC}"
# 检查防火墙类型并配置
if command_exists ufw; then
echo -e "${GREEN}检测到UFW防火墙${NC}"
# 确保UFW已安装
apt-get install -y ufw
# 配置UFW规则
ufw allow $port/tcp
# 如果UFW未启用,则启用它
if ! ufw status | grep -q "Status: active"; then
echo "y" | ufw enable
fi
echo -e "${GREEN}UFW防火墙规则已添加 (端口 $port)${NC}"
elif command_exists firewall-cmd; then
echo -e "${GREEN}检测到FirewallD防火墙${NC}"
# 确保FirewallD已安装
apt-get install -y firewalld
# 配置FirewallD规则
firewall-cmd --permanent --add-port=$port/tcp
firewall-cmd --reload
echo -e "${GREEN}FirewallD防火墙规则已添加 (端口 $port)${NC}"
elif command_exists iptables; then
echo -e "${GREEN}使用iptables配置防火墙${NC}"
# 添加iptables规则
iptables -A INPUT -p tcp --dport $port -j ACCEPT
# 保存iptables规则(Debian方式)
if command_exists iptables-save; then
iptables-save > /etc/iptables/rules.v4
else
echo -e "${YELLOW}iptables-save命令不可用,防火墙规则可能在重启后丢失${NC}"
echo -e "${YELLOW}建议安装iptables-persistent包以保存规则${NC}"
apt-get install -y iptables-persistent
fi
echo -e "${GREEN}iptables防火墙规则已添加 (端口 $port)${NC}"
else
echo -e "${YELLOW}未检测到已知防火墙,跳过防火墙配置${NC}"
echo -e "${YELLOW}如果您使用自定义防火墙,请手动配置规则允许端口$port${NC}"
fi
}
# 函数:手动启用Apache模块
manual_enable_module() {
local module="$1"
echo -e "${YELLOW}手动启用Apache模块: $module${NC}"
# 检查模块文件是否存在
if [ -f "/etc/apache2/mods-available/$module.load" ]; then
# 创建符号链接
ln -sf "/etc/apache2/mods-available/$module.load" "/etc/apache2/mods-enabled/$module.load"
if [ -f "/etc/apache2/mods-available/$module.conf" ]; then
ln -sf "/etc/apache2/mods-available/$module.conf" "/etc/apache2/mods-enabled/$module.conf"
fi
echo -e "${GREEN}已手动启用模块: $module${NC}"
else
echo -e "${RED}找不到模块文件: $module${NC}"
fi
}
# 函数:手动启用Apache配置
manual_enable_conf() {
local conf="$1"
echo -e "${YELLOW}手动启用Apache配置: $conf${NC}"
# 检查配置文件是否存在
if [ -f "/etc/apache2/conf-available/$conf.conf" ]; then
# 创建符号链接
ln -sf "/etc/apache2/conf-available/$conf.conf" "/etc/apache2/conf-enabled/$conf.conf"
echo -e "${GREEN}已手动启用配置: $conf${NC}"
else
echo -e "${RED}找不到配置文件: $conf.conf${NC}"
fi
}
# 函数:手动启用Apache站点
manual_enable_site() {
local site="$1"
echo -e "${YELLOW}手动启用Apache站点: $site${NC}"
# 确保目录存在
mkdir -p /etc/apache2/sites-enabled
# 检查站点配置文件是否存在
if [ -f "/etc/apache2/sites-available/$site" ]; then
# 创建符号链接
ln -sf "/etc/apache2/sites-available/$site" "/etc/apache2/sites-enabled/$site"
echo -e "${GREEN}已手动启用站点: $site${NC}"
else
echo -e "${RED}找不到站点配置文件: $site${NC}"
fi
}
# 新增函数:检查Apache工具是否可用并提供替代方案
check_apache_tools() {
# 检查a2enmod等命令是否存在
if ! command_exists a2enmod || ! command_exists a2ensite; then
echo -e "${YELLOW}检测到a2enmod或a2ensite命令不可用${NC}"
echo -e "${YELLOW}这可能是由于apache2-bin未正确安装或不是Debian/Ubuntu系统${NC}"
# 检查Apache安装目录
if [ -d "/etc/apache2" ]; then
echo -e "${GREEN}检测到Apache配置目录,将使用手动方式配置Apache${NC}"
return 1
else
echo -e "${RED}无法找到Apache配置目录,Apache可能未正确安装${NC}"
echo -e "${RED}尝试重新安装Apache2...${NC}"
apt-get purge -y apache2 apache2-utils libapache2-mod-svn
apt-get update
apt-get install -y apache2 apache2-utils libapache2-mod-svn
# 再次检查
if [ -d "/etc/apache2" ]; then
echo -e "${GREEN}Apache重新安装成功${NC}"
return 0
else
echo -e "${RED}Apache重新安装失败,无法继续配置${NC}"
return 2
fi
fi
fi
return 0
}
# 函数:手动配置Apache模块和站点
manual_apache_config() {
echo -e "${BLUE}开始手动配置Apache...${NC}"
# 检查和创建必要的目录
mkdir -p /etc/apache2/mods-enabled
mkdir -p /etc/apache2/mods-available
mkdir -p /etc/apache2/sites-enabled
mkdir -p /etc/apache2/sites-available
mkdir -p /etc/apache2/conf-enabled
mkdir -p /etc/apache2/conf-available
# 创建并确保运行目录存在
mkdir -p /var/run/apache2
mkdir -p /var/lock/apache2
chmod 755 /var/run/apache2
chmod 755 /var/lock/apache2
chown -R www-data:www-data /var/run/apache2
chown -R www-data:www-data /var/lock/apache2
# 修正Apache环境变量配置
echo -e "${BLUE}修正Apache环境变量配置...${NC}"
cat > /etc/apache2/envvars << 'EOF'
# 环境变量用于Apache 2处理
# 这不会覆盖与服务启动相关的环境变量
unset HOME
# 运行用户和组
export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data
# 必须为ServerRoot配置绝对路径
export APACHE_PID_FILE=/var/run/apache2/apache2.pid
export APACHE_RUN_DIR=/var/run/apache2
export APACHE_LOCK_DIR=/var/lock/apache2
export APACHE_LOG_DIR=/var/log/apache2
# 如果配置文件设置了UMASK,则将其解除
umask 022
EOF
# 直接修改apache2.conf文件,替换环境变量为硬编码路径
echo -e "${BLUE}修正apache2.conf文件中的环境变量...${NC}"
if [ -f "/etc/apache2/apache2.conf" ]; then
# 备份原始配置文件
cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.bak
# 替换所有${APACHE_RUN_DIR}为/var/run/apache2
sed -i 's|\${APACHE_RUN_DIR}|/var/run/apache2|g' /etc/apache2/apache2.conf
# 替换所有${APACHE_LOG_DIR}为/var/log/apache2
sed -i 's|\${APACHE_LOG_DIR}|/var/log/apache2|g' /etc/apache2/apache2.conf
# 替换所有${APACHE_LOCK_DIR}为/var/lock/apache2
sed -i 's|\${APACHE_LOCK_DIR}|/var/lock/apache2|g' /etc/apache2/apache2.conf
# 检查并添加DefaultRuntimeDir指令
if ! grep -q "DefaultRuntimeDir" /etc/apache2/apache2.conf; then
echo "DefaultRuntimeDir /var/run/apache2" >> /etc/apache2/apache2.conf
else
sed -i 's|DefaultRuntimeDir.*|DefaultRuntimeDir /var/run/apache2|g' /etc/apache2/apache2.conf
fi
# 检查并添加ServerName指令
if ! grep -q "ServerName" /etc/apache2/apache2.conf; then
echo "ServerName localhost" >> /etc/apache2/apache2.conf
fi
echo -e "${GREEN}已修正apache2.conf中的环境变量${NC}"
else
echo -e "${RED}未找到apache2.conf文件${NC}"
fi
# 手动启用必要的模块
echo -e "${BLUE}手动启用必要的Apache模块...${NC}"
# 首先确保socache_shmcb模块被启用(SSL需要)
if [ -f "/etc/apache2/mods-available/socache_shmcb.load" ]; then
ln -sf "/etc/apache2/mods-available/socache_shmcb.load" "/etc/apache2/mods-enabled/socache_shmcb.load"
echo -e "${GREEN}已启用socache_shmcb模块${NC}"
else
echo -e "${RED}未找到socache_shmcb.load模块文件,尝试创建...${NC}"
if [ -f "/usr/lib/apache2/modules/mod_socache_shmcb.so" ]; then
cat > "/etc/apache2/mods-available/socache_shmcb.load" << EOF
LoadModule socache_shmcb_module /usr/lib/apache2/modules/mod_socache_shmcb.so
EOF
ln -sf "/etc/apache2/mods-available/socache_shmcb.load" "/etc/apache2/mods-enabled/socache_shmcb.load"
echo -e "${GREEN}已创建并启用socache_shmcb模块${NC}"
else
echo -e "${RED}未找到mod_socache_shmcb.so文件,SSL可能无法正常工作${NC}"
fi
fi
# 修正SSL模块配置,移除对shmcb的依赖
if [ -f "/etc/apache2/mods-available/ssl.conf" ]; then
echo -e "${BLUE}修正SSL模块配置...${NC}"
sed -i 's/SSLSessionCache.*/SSLSessionCache none/' "/etc/apache2/mods-available/ssl.conf"
echo -e "${GREEN}已修正SSL模块配置${NC}"
fi
local modules_to_enable="ssl dav dav_svn authn_core auth_digest authz_user"
for module in $modules_to_enable; do
if [ -f "/etc/apache2/mods-available/${module}.load" ]; then
ln -sf "/etc/apache2/mods-available/${module}.load" "/etc/apache2/mods-enabled/${module}.load"
if [ -f "/etc/apache2/mods-available/${module}.conf" ]; then
ln -sf "/etc/apache2/mods-available/${module}.conf" "/etc/apache2/mods-enabled/${module}.conf"
fi
echo -e "${GREEN}已启用模块: ${module}${NC}"
else
echo -e "${YELLOW}警告: 无法找到模块文件 ${module}.load${NC}"
if [ "$module" = "dav_svn" ] && [ -f "/usr/lib/apache2/modules/mod_dav_svn.so" ]; then
# 如果找不到dav_svn模块配置但模块文件存在,则创建配置
echo -e "${BLUE}创建dav_svn模块配置...${NC}"
cat > "/etc/apache2/mods-available/dav_svn.load" << EOF
LoadModule dav_svn_module /usr/lib/apache2/modules/mod_dav_svn.so
LoadModule authz_svn_module /usr/lib/apache2/modules/mod_authz_svn.so
EOF
ln -sf "/etc/apache2/mods-available/dav_svn.load" "/etc/apache2/mods-enabled/dav_svn.load"
echo -e "${GREEN}已创建并启用dav_svn模块${NC}"
fi
fi
done
# 确保已启用基本必要模块
local base_modules="alias dir mime rewrite authz_core mpm_prefork"
for module in $base_modules; do
if [ -f "/etc/apache2/mods-available/${module}.load" ] && [ ! -f "/etc/apache2/mods-enabled/${module}.load" ]; then
ln -sf "/etc/apache2/mods-available/${module}.load" "/etc/apache2/mods-enabled/${module}.load"
[ -f "/etc/apache2/mods-available/${module}.conf" ] && ln -sf "/etc/apache2/mods-available/${module}.conf" "/etc/apache2/mods-enabled/${module}.conf"
echo -e "${GREEN}已启用基础模块: ${module}${NC}"
fi
done
return 0
}
# 新增函数:修复Apache配置
fix_apache_config() {
echo -e "${BLUE}修复Apache配置...${NC}"
# 创建必要的目录
mkdir -p /var/run/apache2
mkdir -p /var/lock/apache2
mkdir -p /var/log/apache2
chmod 755 /var/run/apache2
chmod 755 /var/lock/apache2
chmod 755 /var/log/apache2
if id "www-data" &>/dev/null; then
chown -R www-data:www-data /var/run/apache2
chown -R www-data:www-data /var/lock/apache2
chown -R www-data:www-data /var/log/apache2
fi
# 检查并修复apache2.conf中的环境变量引用
if [ -f "/etc/apache2/apache2.conf" ]; then
# 备份原始配置文件
cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.bak.$(date +%Y%m%d%H%M%S)
# 替换环境变量引用为实际路径
sed -i 's|\${APACHE_RUN_DIR}|/var/run/apache2|g' /etc/apache2/apache2.conf
sed -i 's|\${APACHE_LOG_DIR}|/var/log/apache2|g' /etc/apache2/apache2.conf
sed -i 's|\${APACHE_LOCK_DIR}|/var/lock/apache2|g' /etc/apache2/apache2.conf
# 检查并确保DefaultRuntimeDir正确设置
if grep -q "DefaultRuntimeDir" /etc/apache2/apache2.conf; then
sed -i 's|^DefaultRuntimeDir.*|DefaultRuntimeDir /var/run/apache2|g' /etc/apache2/apache2.conf
else
echo "DefaultRuntimeDir /var/run/apache2" >> /etc/apache2/apache2.conf
fi
echo -e "${GREEN}已修复apache2.conf配置${NC}"
else
echo -e "${RED}未找到apache2.conf文件${NC}"
fi
# 检查并修复Apache站点配置文件中的环境变量
for site_file in /etc/apache2/sites-available/*.conf; do
if [ -f "$site_file" ]; then
cp "$site_file" "${site_file}.bak.$(date +%Y%m%d%H%M%S)"
sed -i 's|\${APACHE_LOG_DIR}|/var/log/apache2|g' "$site_file"
echo -e "${GREEN}已修复站点配置: $site_file${NC}"
fi
done
# 检查SSL配置
if [ -f "/etc/apache2/mods-enabled/ssl.conf" ]; then
sed -i 's|^SSLSessionCache.*|SSLSessionCache none|' "/etc/apache2/mods-enabled/ssl.conf"
echo -e "${GREEN}已修复SSL配置${NC}"
fi
return 0
}
# 函数:诊断Apache启动问题
diagnose_apache_issues() {
echo -e "${BLUE}诊断Apache启动问题...${NC}"
# 检查Apache二进制文件是否存在
if [ -f "/usr/sbin/apache2" ]; then
echo -e "${GREEN}Apache二进制文件存在: /usr/sbin/apache2${NC}"
# 查找apache2ctl脚本
APACHE2CTL=$(find /usr -name apache2ctl 2>/dev/null || echo "未找到")
if [ "$APACHE2CTL" != "未找到" ]; then
echo -e "${GREEN}找到apache2ctl: $APACHE2CTL${NC}"
# 创建符号链接
ln -sf "$APACHE2CTL" /usr/bin/apache2ctl
echo -e "${GREEN}已创建apache2ctl符号链接${NC}"
else
echo -e "${RED}未找到apache2ctl脚本,创建替代脚本${NC}"
cat > /usr/bin/apache2ctl << 'EOF'
#!/bin/bash
# 简易的apache2ctl替代脚本
HTTPD=/usr/sbin/apache2
CONFIG=/etc/apache2/apache2.conf
case "$1" in
start)
$HTTPD -k start -f $CONFIG
;;
stop)
$HTTPD -k stop -f $CONFIG
;;
restart)
$HTTPD -k restart -f $CONFIG
;;
status)
if pgrep apache2 > /dev/null; then
echo "Apache is running"
else
echo "Apache is not running"
exit 1
fi
;;
configtest|t)
$HTTPD -t -f $CONFIG
;;
*)
$HTTPD "$@"
;;
esac
EOF
chmod +x /usr/bin/apache2ctl
echo -e "${GREEN}已创建apache2ctl替代脚本${NC}"
fi
else
echo -e "${RED}未找到Apache二进制文件,请确保Apache已安装${NC}"
fi
# 检查并修复apache2.conf
echo -e "${BLUE}检查apache2.conf文件...${NC}"
if [ -f "/etc/apache2/apache2.conf" ]; then
# 检查并添加DefaultRuntimeDir指令
if ! grep -q "DefaultRuntimeDir" /etc/apache2/apache2.conf; then
echo "DefaultRuntimeDir /var/run/apache2" >> /etc/apache2/apache2.conf
echo -e "${GREEN}已添加DefaultRuntimeDir配置${NC}"
fi
# 检查并添加ServerName指令
if ! grep -q "ServerName" /etc/apache2/apache2.conf; then
echo "ServerName localhost" >> /etc/apache2/apache2.conf
echo -e "${GREEN}已添加ServerName配置${NC}"
fi
else
echo -e "${RED}未找到apache2.conf文件${NC}"
fi
# 检查模块依赖
echo -e "${BLUE}检查SSL模块依赖...${NC}"
if [ -f "/etc/apache2/mods-enabled/ssl.conf" ] && [ -f "/etc/apache2/mods-available/ssl.conf" ]; then
sed -i 's/SSLSessionCache.*/SSLSessionCache none/' "/etc/apache2/mods-available/ssl.conf"
cp "/etc/apache2/mods-available/ssl.conf" "/etc/apache2/mods-enabled/ssl.conf"
echo -e "${GREEN}已修正SSL模块配置${NC}"
fi
# 确保Apache运行目录存在
mkdir -p /var/run/apache2
chown -R www-data:www-data /var/run/apache2
# 检查Apache错误日志
echo -e "${BLUE}检查Apache日志中的错误详情...${NC}"
if [ -f "/var/log/apache2/error.log" ];then
tail -n 30 /var/log/apache2/error.log
else
echo -e "${RED}未找到Apache错误日志文件${NC}"
fi
}
# 新增函数: 尝试直接启动Apache
manual_start_apache() {
echo -e "${BLUE}尝试手动启动Apache...${NC}"
# 确保配置语法正确
if [ -f "/usr/sbin/apache2" ]; then
echo -e "${BLUE}检查Apache配置语法...${NC}"
/usr/sbin/apache2 -t -f /etc/apache2/apache2.conf
if [ $? -eq 0 ]; then
echo -e "${GREEN}Apache配置语法正确,尝试启动...${NC}"
else
echo -e "${RED}Apache配置有语法错误,尝试修复...${NC}"
diagnose_apache_issues
fi
echo -e "${BLUE}手动启动Apache...${NC}"
/usr/sbin/apache2 -k start -f /etc/apache2/apache2.conf
sleep 3
# 检查是否成功启动
if pgrep apache2 > /dev/null; then
echo -e "${GREEN}Apache成功启动${NC}"
return 0
else
echo -e "${RED}Apache启动失败${NC}"
return 1
fi
else
echo -e "${RED}未找到Apache二进制文件${NC}"
return 1
fi
}
# 函数:检查服务状态并尝试恢复
check_and_recover_service() {
local service_name="$1"
local service_desc="$2"
local restart_command="$3"
local check_command="$4"
local reinstall_packages="$5"
echo -e "${BLUE}检查${service_desc}服务状态...${NC}"
# 使用提供的检查命令验证服务是否正常运行
if eval "$check_command"; then
echo -e "${GREEN}${service_desc}服务运行正常${NC}"
return 0
fi
echo -e "${YELLOW}${service_desc}服务未正常运行,尝试重启...${NC}"
# 尝试重启服务
eval "$restart_command"
# 等待服务启动
sleep 3
# 再次检查服务状态
if eval "$check_command"; then
echo -e "${GREEN}${service_desc}服务重启成功${NC}"
return 0
fi
echo -e "${RED}重启${service_desc}服务失败,尝试修复...${NC}"
# 检查是否提供了重新安装包列表
if [ -n "$reinstall_packages" ]; then
echo -e "${YELLOW}尝试重新安装${service_desc}相关软件包...${NC}"
for pkg in $reinstall_packages; do
echo -e "${BLUE}重新安装 $pkg...${NC}"
apt-get install --reinstall -y "$pkg" || {
echo -e "${RED}无法重新安装 $pkg${NC}"
}
done
# 重新启动服务
echo -e "${BLUE}再次尝试启动${service_desc}服务...${NC}"
eval "$restart_command"
# 等待服务启动
sleep 3
# 最终检查服务状态
if eval "$check_command"; then
echo -e "${GREEN}${service_desc}服务修复并成功启动${NC}"
return 0
fi
fi
echo -e "${RED}无法恢复${service_desc}服务!请手动检查问题${NC}"
return 1
}
# 函数:检查SVN必要目录和权限
check_svn_directories() {
local repo_path="$1"
echo -e "${BLUE}检查SVN仓库目录和权限...${NC}"
if [ ! -d "$repo_path" ]; then
echo -e "${RED}SVN仓库目录不存在: $repo_path${NC}"
echo -e "${YELLOW}尝试重建仓库目录...${NC}"
mkdir -p "$repo_path"
svnadmin create "$repo_path"
fi
# 检查关键目录和文件
for subdir in "conf" "hooks" "locks" "db"; do
if [ ! -d "$repo_path/$subdir" ]; then
echo -e "${RED}仓库子目录不存在: $repo_path/$subdir${NC}"
echo -e "${YELLOW}SVN仓库结构不完整,尝试重建...${NC}"
rm -rf "$repo_path"
mkdir -p "$repo_path"
svnadmin create "$repo_path"
break
fi
done
# 检查并修复权限
if id "www-data" &>/dev/null; then
echo -e "${BLUE}设置仓库权限 (www-data)...${NC}"
chown -R www-data:www-data "$repo_path"
fi
chmod -R 770 "$repo_path"
echo -e "${GREEN}SVN仓库目录和权限检查完成${NC}"
return 0
}
# 执行基础依赖安装
install_dependencies
# 检测并清理已有SVN环境
cleanup_existing_environment
# 设置变量
SVN_REPO_NAME="svnrepo"
SVN_REPO_PATH="/var/svn/$SVN_REPO_NAME"
SVN_ADMIN_USER="svnadmin"
SVN_ADMIN_PASS=$(openssl rand -base64 12)
SVN_NORMAL_USER="svnuser"
SVN_NORMAL_PASS=$(openssl rand -base64 12)
# 更新系统
echo -e "${BLUE}更新系统...${NC}"
apt-get update && apt-get upgrade -y
# 询问部署方式
echo -e "${BLUE}请选择SVN部署方式:${NC}"
echo -e "1) svnserve (推荐,轻量级,更易于配置)"
echo -e "2) Apache (功能更丰富,但配置更复杂)"
read -r DEPLOY_CHOICE
if [ "$DEPLOY_CHOICE" != "1" ] && [ "$DEPLOY_CHOICE" != "2" ]; then
echo -e "${YELLOW}选择无效,默认使用svnserve方式${NC}"
DEPLOY_CHOICE="1"
fi
# 根据部署选择安装不同的包
if [ "$DEPLOY_CHOICE" = "1" ]; then
# svnserve方式,仅安装核心包
echo -e "${BLUE}以svnserve方式部署SVN服务...${NC}"
REQUIRED_PACKAGES="subversion openssl htop net-tools"
else
# Apache方式,安装Apache相关包
echo -e "${BLUE}以Apache方式部署SVN服务...${NC}"
REQUIRED_PACKAGES="subversion apache2 apache2-utils libapache2-mod-svn libsvn-dev openssl authbind htop net-tools"
fi
# 安装必要的软件包
echo -e "${BLUE}安装必要的软件包...${NC}"
for package in $REQUIRED_PACKAGES; do
if ! dpkg -l | grep -q "^ii $package "; then
install_package "$package" || {
echo -e "${RED}无法安装必要的软件包: $package${NC}"
exit 1
}
else
echo -e "${GREEN}软件包已安装: $package${NC}"
fi
done
# 创建SVN仓库目录
echo -e "${BLUE}创建SVN仓库...${NC}"
mkdir -p $SVN_REPO_PATH
svnadmin create $SVN_REPO_PATH
# 如果用户www-data不存在,则使用当前用户
if id "www-data" &>/dev/null; then
chown -R www-data:www-data $SVN_REPO_PATH
else
echo -e "${YELLOW}用户www-data不存在,使用当前用户${NC}"
fi
chmod -R 770 $SVN_REPO_PATH
if [ "$DEPLOY_CHOICE" = "1" ]; then
# svnserve部署方式
# 配置SVN用户和权限
echo -e "${BLUE}配置svnserve用户认证...${NC}"
cat > $SVN_REPO_PATH/conf/passwd << EOF
[$SVN_ADMIN_USER]
$SVN_ADMIN_PASS
[$SVN_NORMAL_USER]
$SVN_NORMAL_PASS
EOF
# 配置SVN访问权限
cat > $SVN_REPO_PATH/conf/authz << EOF
[groups]
admins = $SVN_ADMIN_USER
users = $SVN_NORMAL_USER
[/]
@admins = rw
@users = r
* =
EOF
# 配置svnserve主配置文件
cat > $SVN_REPO_PATH/conf/svnserve.conf << EOF
[general]
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz
realm = SVN Repository
# 性能优化参数
min-threads = 4
max-threads = 16
compression = 5
EOF
# 创建系统服务
echo -e "${BLUE}创建svnserve系统服务...${NC}"
cat > /etc/systemd/system/svnserve.service << EOF
[Unit]
Description=Subversion Server
After=network.target
[Service]
Type=forking
ExecStart=/usr/bin/svnserve -d -r /var/svn
ExecStop=/usr/bin/pkill -f svnserve
[Install]
WantedBy=multi-user.target
EOF
# 重新加载systemd配置
systemctl daemon-reload
# 启用并启动服务
systemctl enable svnserve
systemctl start svnserve || {
echo -e "${RED}svnserve服务启动失败,请检查错误${NC}"
echo -e "${YELLOW}尝试手动启动服务...${NC}"
/usr/bin/svnserve -d -r /var/svn
}
# 检查svnserve是否运行
if pgrep -f svnserve > /dev/null; then
echo -e "${GREEN}svnserve服务已成功启动${NC}"
else
echo -e "${RED}svnserve服务未能启动${NC}"
echo -e "${YELLOW}尝试排除故障...${NC}"
# 检查端口冲突
if netstat -tuln | grep -q ":3690"; then
echo -e "${RED}端口3690被占用,无法启动svnserve${NC}"
echo -e "${YELLOW}请先关闭使用此端口的程序${NC}"
fi
fi
# 配置防火墙
configure_firewall 3690
# 测试服务可访问性
echo -e "${BLUE}验证svnserve是否正常运行...${NC}"
if command_exists svn; then
echo -e "${YELLOW}尝试列出仓库内容 (可能需要认证)${NC}"
svn ls svn://localhost/$SVN_REPO_NAME --username=$SVN_ADMIN_USER --password=$SVN_ADMIN_PASS --non-interactive || {
echo -e "${RED}无法访问svnserve服务,可能存在配置问题${NC}"
}
else
echo -e "${YELLOW}未安装svn客户端,无法测试服务可访问性${NC}"
fi
# 输出配置信息
echo -e "${GREEN}=== SVN服务器安装完成! ===${NC}"
echo -e "${YELLOW}SVN服务URL:${NC} svn://$(hostname -I | awk '{print $1}')/$SVN_REPO_NAME"
echo -e "${YELLOW}管理员账号:${NC} $SVN_ADMIN_USER"
echo -e "${YELLOW}管理员密码:${NC} $SVN_ADMIN_PASS"
echo -e "${YELLOW}普通用户账号:${NC} $SVN_NORMAL_USER"
echo -e "${YELLOW}普通用户密码:${NC} $SVN_NORMAL_PASS"
# 保存客户端命令便于测试
echo -e "${GREEN}客户端可以使用以下命令检出代码:${NC}"
echo -e "svn checkout svn://$(hostname -I | awk '{print $1}')/$SVN_REPO_NAME --username=$SVN_NORMAL_USER"
# 创建故障排查工具
cat > /root/svnserve_troubleshoot.sh << EOF
#!/bin/bash
echo "===== SVN服务故障排查 ====="
echo "检查svnserve进程..."
pgrep -fa svnserve || echo "svnserve进程未运行!"
echo -e "\n检查端口监听..."
netstat -tuln | grep 3690 || echo "端口3690未被监听!"
echo -e "\n检查防火墙规则..."
if command -v ufw > /dev/null; then
ufw status | grep 3690 || echo "防火墙未开放3690端口!"
elif command -v firewall-cmd > /dev/null; then
firewall-cmd --list-all | grep 3690 || echo "防火墙未开放3690端口!"
elif command -v iptables > /dev/null; then
iptables -L -n | grep 3690 || echo "iptables未开放3690端口!"
fi
echo -e "\n尝试重启服务..."
systemctl restart svnserve || {
echo "通过systemd重启svnserve失败,尝试手动重启..."
pkill -f svnserve
sleep 1
/usr/bin/svnserve -d -r /var/svn
}
echo -e "\n检查仓库路径和权限..."
ls -la $SVN_REPO_PATH
echo -e "\n尝试测试服务连接..."
svn info svn://localhost/$SVN_REPO_NAME --username=$SVN_ADMIN_USER --password=$SVN_ADMIN_PASS --non-interactive || echo "无法连接到服务!"
echo -e "\n服务器信息:"
hostname -I
EOF
chmod +x /root/svnserve_troubleshoot.sh
echo -e "${YELLOW}创建故障排查脚本: /root/svnserve_troubleshoot.sh${NC}"
# 执行最终服务状态检查
echo -e "${YELLOW}执行最终服务状态检查...${NC}"
check_and_recover_service "svnserve" "SVN服务" \
"systemctl restart svnserve || /usr/bin/svnserve -d -r /var/svn" \
"pgrep -f svnserve > /dev/null && svn info svn://localhost/$SVN_REPO_NAME --username=$SVN_ADMIN_USER --password=$SVN_ADMIN_PASS --non-interactive > /dev/null 2>&1" \
"subversion"
# 检查仓库目录结构和权限
check_svn_directories "$SVN_REPO_PATH"
else
# Apache部署方式
# 沿用原来的Apache配置代码,但增强错误处理并简化过程
# 域名设置
DEFAULT_DOMAIN="svn.example.com"
echo -e "${BLUE}请输入SVN服务器域名 [默认: ${DEFAULT_DOMAIN}]:${NC}"
read -r SVN_DOMAIN
SVN_DOMAIN=${SVN_DOMAIN:-$DEFAULT_DOMAIN}
echo -e "${GREEN}将使用域名: ${SVN_DOMAIN}${NC}"
APACHE_CONF="/etc/apache2/sites-available/svn.conf"
SSL_DIR="/etc/apache2/ssl"
SELF_SIGNED_CERT="$SSL_DIR/svn-selfsigned.crt"
SELF_SIGNED_KEY="$SSL_DIR/svn-selfsigned.key"
SVN_PERF_CONF="/etc/apache2/conf-available/svn-performance.conf"
# 创建用户认证文件
echo -e "${BLUE}配置用户认证...${NC}"
mkdir -p /etc/apache2/svn
if command_exists htpasswd; then
htpasswd -cb /etc/apache2/svn/svn-auth $SVN_ADMIN_USER $SVN_ADMIN_PASS
htpasswd -b /etc/apache2/svn/svn-auth $SVN_NORMAL_USER $SVN_NORMAL_PASS
else
echo -e "${RED}htpasswd命令不可用,无法创建认证文件${NC}"
exit 1
fi
if id "www-data" &>/dev/null; then
chown -R www-data:www-data /etc/apache2/svn
fi
# 配置SVN访问权限
cat > $SVN_REPO_PATH/conf/authz << EOF
[groups]
admins = $SVN_ADMIN_USER
users = $SVN_NORMAL_USER
[/]
@admins = rw
@users = r
* =
EOF
# 创建SSL证书目录
echo -e "${BLUE}生成SSL证书...${NC}"
mkdir -p $SSL_DIR
# 生成自签名SSL证书,使用用户指定的域名
openssl req -x509 -nodes -days 1095 -newkey rsa:2048 \
-keyout $SELF_SIGNED_KEY -out $SELF_SIGNED_CERT \
-subj "/C=CN/ST=State/L=City/O=Organization/OU=IT/CN=${SVN_DOMAIN}"
if id "www-data" &>/dev/null; then
chown -R www-data:www-data $SSL_DIR
fi
chmod 400 $SELF_SIGNED_KEY
# 检查Apache工具
apache_tools_status=$(check_apache_tools)
use_manual_config=0
if [ $? -ne 0 ]; then
echo -e "${YELLOW}将使用手动配置Apache${NC}"
use_manual_config=1
fi
# 配置Apache2
echo -e "${BLUE}配置Apache2...${NC}"
# 配置Apache模块
if [ $use_manual_config -eq 1 ]; then
manual_apache_config || {
echo -e "${RED}手动配置Apache失败${NC}"
exit 1
}
else
# 确保Apache模块已启用
for module in ssl dav dav_svn authn_core auth_digest authz_user; do
a2enmod $module || {
echo -e "${YELLOW}无法通过a2enmod启用模块: $module,尝试手动启用${NC}"
manual_enable_module $module
}
done
fi
# 创建SVN虚拟主机配置,简化配置,降低复杂度
cat > $APACHE_CONF << EOF
<VirtualHost *:80>
ServerName ${SVN_DOMAIN}
Redirect permanent / https://${SVN_DOMAIN}/
</VirtualHost>
<VirtualHost *:443>
ServerName ${SVN_DOMAIN}
ServerAdmin webmaster@localhost
SSLEngine on
SSLCertificateFile $SELF_SIGNED_CERT
SSLCertificateKeyFile $SELF_SIGNED_KEY
<Location /svn>
DAV svn
SVNParentPath /var/svn
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /etc/apache2/svn/svn-auth
Require valid-user
# 权限控制
AuthzSVNAccessFile /var/svn/$SVN_REPO_NAME/conf/authz
</Location>
ErrorLog \${APACHE_LOG_DIR}/svn-error.log
CustomLog \${APACHE_LOG_DIR}/svn-access.log combined
</VirtualHost>
EOF
# 创建默认的Apache配置目录(如果不存在)
mkdir -p /var/log/apache2
# 创建环境变量配置,避免缺少APACHE_LOG_DIR变量
if [ ! -f "/etc/apache2/envvars" ] || ! grep -q "APACHE_LOG_DIR" "/etc/apache2/envvars"; then
echo -e "${YELLOW}创建Apache环境变量配置...${NC}"
cat > /etc/apache2/envvars << EOF
# Apache环境变量
export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data
export APACHE_PID_FILE=/var/run/apache2/apache2.pid
export APACHE_RUN_DIR=/var/run/apache2
export APACHE_LOCK_DIR=/var/lock/apache2
export APACHE_LOG_DIR=/var/log/apache2
EOF
fi
# 确保日志目录存在并有适当权限
mkdir -p /var/log/apache2
chmod 750 /var/log/apache2
chown -R www-data:www-data /var/log/apache2 2>/dev/null || true
# 启用站点配置
if [ $use_manual_config -eq 1 ]; then
echo -e "${YELLOW}手动启用SVN站点...${NC}"
ln -sf $APACHE_CONF /etc/apache2/sites-enabled/svn.conf
else
a2ensite svn.conf || {
echo -e "${YELLOW}无法通过a2ensite启用站点,尝试手动启用${NC}"
ln -sf $APACHE_CONF /etc/apache2/sites-enabled/svn.conf
}
fi
# 配置防火墙规则
configure_firewall 80
configure_firewall 443
# 检查Apache配置语法
if command_exists apache2ctl; then
echo -e "${BLUE}检查Apache配置语法...${NC}"
apache2ctl -t || {
echo -e "${RED}Apache配置有语法错误!尝试修复...${NC}"
# 修正常见问题,例如缺少ServerName
if ! grep -q "ServerName" /etc/apache2/apache2.conf; then
echo "ServerName localhost" >> /etc/apache2/apache2.conf
fi
apache2ctl -t || {
echo -e "${RED}无法修复Apache配置问题${NC}"
diagnose_apache_issues
}
}
fi
# 在配置完成后修复Apache配置
echo -e "${BLUE}修复Apache配置以确保正确运行...${NC}"
fix_apache_config
# 重启Apache时,使用更强大的重启方法
echo -e "${BLUE}重启Apache服务...${NC}"
# 强制停止Apache进程
echo -e "${YELLOW}停止所有Apache进程...${NC}"
pkill -9 apache2 2>/dev/null || true
sleep 2
# 确保Apache配置语法正确
if [ -f "/usr/sbin/apache2" ]; then
echo -e "${BLUE}检查Apache配置语法...${NC}"
/usr/sbin/apache2 -t -f /etc/apache2/apache2.conf
if [ $? -eq 0 ]; then
echo -e "${GREEN}Apache配置语法正确${NC}"
echo -e "${BLUE}启动Apache...${NC}"
# 尝试启动Apache
if command_exists systemctl; then
systemctl start apache2 || {
echo -e "${YELLOW}systemctl启动失败,尝试直接启动...${NC}"
/usr/sbin/apache2 -k start -f /etc/apache2/apache2.conf
}
else
/usr/sbin/apache2 -k start -f /etc/apache2/apache2.conf
fi
# 验证是否启动成功
sleep 3
if pgrep apache2 > /dev/null; then
echo -e "${GREEN}Apache已成功启动${NC}"
else
echo -e "${RED}Apache启动失败${NC}"
fi
else
echo -e "${RED}Apache配置语法有误,再次尝试修复...${NC}"
fix_apache_config
diagnose_apache_issues
echo -e "${YELLOW}最后尝试直接启动Apache...${NC}"
/usr/sbin/apache2 -k start -f /etc/apache2/apache2.conf
sleep 3
fi
else
echo -e "${RED}未找到Apache二进制文件${NC}"
fi
# 验证Apache是否正常运行
if pgrep apache2 > /dev/null || systemctl is-active apache2 > /dev/null; then
echo -e "${GREEN}Apache服务已成功启动${NC}"
else
echo -e "${RED}Apache服务未能启动,请查看错误日志${NC}"
echo -e "${RED}您可以稍后使用 /root/apache_svn_troubleshoot.sh 来诊断问题${NC}"
echo -e "${RED}或者考虑使用svnserve方式重新部署${NC}"
fi
# 输出配置信息
echo -e "${GREEN}=== SVN服务器安装完成! ===${NC}"
echo -e "${YELLOW}SVN仓库URL:${NC} https://$(hostname -I | awk '{print $1}')/svn/$SVN_REPO_NAME"
echo -e "${YELLOW}如果配置了域名:${NC} https://${SVN_DOMAIN}/svn/$SVN_REPO_NAME"
echo -e "${YELLOW}管理员账号:${NC} $SVN_ADMIN_USER"
echo -e "${YELLOW}管理员密码:${NC} $SVN_ADMIN_PASS"
echo -e "${YELLOW}普通用户账号:${NC} $SVN_NORMAL_USER"
echo -e "${YELLOW}普通用户密码:${NC} $SVN_NORMAL_PASS"
# 保存客户端命令便于测试
echo -e "${GREEN}客户端可以使用以下命令检出代码:${NC}"
echo -e "svn checkout https://$(hostname -I | awk '{print $1}')/svn/$SVN_REPO_NAME --username=$SVN_NORMAL_USER"
# 创建故障排查工具
cat > /root/apache_svn_troubleshoot.sh << EOF
#!/bin/bash
echo "===== Apache SVN故障排查 ====="
echo "检查Apache进程..."
pgrep -fa apache2 || echo "Apache进程未运行!"
echo -e "\n检查端口监听..."
netstat -tuln | grep -E ":(80|443)" || echo "端口80/443未被监听!"
echo -e "\n检查Apache配置语法..."
apache2ctl -t
echo -e "\n检查Apache模块..."
apache2ctl -M | grep -E "(dav|svn|ssl)" || echo "关键模块未加载!"
echo -e "\n检查虚拟主机配置..."
ls -l /etc/apache2/sites-enabled/
echo -e "\n尝试重启Apache..."
systemctl restart apache2
echo -e "\n检查Apache错误日志..."
tail -20 /var/log/apache2/error.log
echo -e "\n测试HTTP重定向..."
curl -I http://localhost
echo -e "\n测试SVN服务器..."
curl -k -I https://localhost/svn
EOF
chmod +x /root/apache_svn_troubleshoot.sh
echo -e "${YELLOW}创建故障排查脚本: /root/apache_svn_troubleshoot.sh${NC}"
# 执行最终服务状态检查
echo -e "${YELLOW}执行最终服务状态检查...${NC}"
check_and_recover_service "apache2" "Apache SVN服务" \
"systemctl restart apache2 || (apache2ctl stop; sleep 2; apache2ctl start)" \
"pgrep apache2 > /dev/null && curl -k -s -o /dev/null -w '%{http_code}\n' https://localhost/svn > /dev/null 2>&1" \
"apache2 libapache2-mod-svn"
# 检查仓库目录结构和权限
check_svn_directories "$SVN_REPO_PATH"
# 确保Apache能够访问SVN目录
if id "www-data" &>/dev/null; then
chown -R www-data:www-data /var/svn
chmod -R 770 /var/svn
fi
# 检查Apache SSL模块
if ! ls -l /etc/apache2/mods-enabled/ssl.* > /dev/null 2>&1; then
echo -e "${RED}SSL模块未启用,尝试手动启用${NC}"
manual_enable_module "ssl"
# 重启Apache服务
systemctl restart apache2 || apache2ctl restart
fi
fi
# 保存配置信息到文件
{
echo "=== SVN服务器配置信息 ==="
if [ "$DEPLOY_CHOICE" = "1" ]; then
echo "部署方式: svnserve (独立服务器)"
echo "SVN仓库URL: svn://$(hostname -I | awk '{print $1}')/$SVN_REPO_NAME"
echo "服务端口: 3690"
else
echo "部署方式: Apache (HTTP服务器)"
echo "SVN仓库URL: https://$(hostname -I | awk '{print $1}')/svn/$SVN_REPO_NAME"
echo "如果配置了域名: https://${SVN_DOMAIN}/svn/$SVN_REPO_NAME"
fi
echo "管理员账号: $SVN_ADMIN_USER"
echo "管理员密码: $SVN_ADMIN_PASS"
echo "普通用户账号: $SVN_NORMAL_USER"
echo "普通用户密码: $SVN_NORMAL_PASS"
echo ""
echo "=== 仓库信息 ==="
echo "仓库路径: $SVN_REPO_PATH"
echo ""
echo "=== 连接测试命令 ==="
if [ "$DEPLOY_CHOICE" = "1" ]; then
echo "svn ls svn://$(hostname -I | awk '{print $1}')/$SVN_REPO_NAME --username=$SVN_ADMIN_USER --password=$SVN_ADMIN_PASS"
echo "客户端检出: svn checkout svn://$(hostname -I | awk '{print $1}')/$SVN_REPO_NAME --username=$SVN_NORMAL_USER"
else
echo "svn ls https://$(hostname -I | awk '{print $1}')/svn/$SVN_REPO_NAME --username=$SVN_ADMIN_USER --password=$SVN_ADMIN_PASS"
echo "客户端检出: svn checkout https://$(hostname -I | awk '{print $1}')/$SVN_REPO_NAME --username=$SVN_NORMAL_USER"
fi
echo ""
echo "=== 故障排除 ==="
if [ "$DEPLOY_CHOICE" = "1" ]; then
echo "故障排查脚本: /root/svnserve_troubleshoot.sh"
else
echo "故障排查脚本: /root/apache_svn_troubleshoot.sh"
fi
} > /root/svn_installation_info.txt
echo -e "\n${BLUE}执行最终系统检查...${NC}"
# 检查防火墙状态
if [ "$DEPLOY_CHOICE" = "1" ]; then
# svnserve端口检查
if ! netstat -tuln | grep -q ":3690"; then
echo -e "${RED}警告: SVN服务端口 (3690) 未被监听${NC}"
echo -e "${YELLOW}请确保没有防火墙阻止此端口或服务未正常启动${NC}"
else
echo -e "${GREEN}SVN服务端口 (3690) 状态正常${NC}"
fi
else
# Apache端口检查
for port in 80 443; do
if ! netstat -tuln | grep -q ":$port"; then
echo -e "${RED}警告: Apache端口 ($port) 未被监听${NC}"
echo -e "${YELLOW}请确保没有防火墙阻止此端口或服务未正常启动${NC}"
else
echo -e "${GREEN}Apache端口 ($port) 状态正常${NC}"
fi
done
fi
# 创建系统状态检查脚本
cat > /root/check_svn_services.sh << EOF
#!/bin/bash
# SVN服务状态检查脚本
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "\${BLUE}===== SVN服务状态检查 =====${NC}"
# 获取部署方式
if systemctl list-unit-files | grep -q svnserve; then
DEPLOY_TYPE="svnserve"
elif [ -f "/etc/apache2/sites-enabled/svn.conf" ]; then
DEPLOY_TYPE="apache"
else
echo -e "\${RED}无法确定SVN部署类型${NC}"
exit 1
fi
# 检查服务状态
if [ "\$DEPLOY_TYPE" == "svnserve" ]; then
echo -e "\${BLUE}检查svnserve服务...${NC}"
if systemctl is-active svnserve > /dev/null; then
echo -e "\${GREEN}svnserve服务运行中${NC}"
else
echo -e "\${RED}svnserve服务未运行!尝试启动...${NC}"
systemctl start svnserve || {
echo -e "\${RED}无法通过systemctl启动服务,尝试手动启动...${NC}"
/usr/bin/svnserve -d -r /var/svn
}
# 再次检查
if pgrep -f svnserve > /dev/null; then
echo -e "\${GREEN}svnserve现已启动${NC}"
else
echo -e "\${RED}无法启动svnserve服务!${NC}"
fi
fi
# 检查端口
echo -e "\${BLUE}检查svnserve端口 (3690)...${NC}"
if netstat -tuln | grep -q ":3690"; then
echo -e "\${GREEN}端口3690已开放${NC}"
else
echo -e "\${RED}端口3690未开放!${NC}"
fi
else
echo -e "\${BLUE}检查Apache服务...${NC}"
if systemctl is-active apache2 > /dev/null; then
echo -e "\${GREEN}Apache服务运行中${NC}"
else
echo -e "\${RED}Apache服务未运行!尝试启动...${NC}"
systemctl start apache2 || {
echo -e "\${RED}无法通过systemctl启动服务,尝试手动启动...${NC}"
apache2ctl start
}
# 再次检查
if pgrep apache2 > /dev/null; then
echo -e "\${GREEN}Apache现已启动${NC}"
else
echo -e "\${RED}无法启动Apache服务!${NC}"
fi
fi
# 检查Apache端口
for port in 80 443; do
echo -e "\${BLUE}检查Apache端口 (\$port)...${NC}"
if netstat -tuln | grep -q ":\$port"; then
echo -e "\${GREEN}端口\$port已开放${NC}"
else
echo -e "\${RED}端口\$port未开放!${NC}"
fi
done
# 检查SSL配置
echo -e "\${BLUE}检查SSL模块...${NC}"
if ls -l /etc/apache2/mods-enabled/ssl.* > /dev/null 2>&1; then
echo -e "\${GREEN}SSL模块已启用${NC}"
else
echo -e "\${RED}SSL模块未启用!${NC}"
if [ -f "/etc/apache2/mods-available/ssl.load" ]; then
echo -e "\${YELLOW}尝试启用SSL模块...${NC}"
if command -v a2enmod > /dev/null; then
a2enmod ssl
else
ln -sf "/etc/apache2/mods-available/ssl.load" "/etc/apache2/mods-enabled/ssl.load"
[ -f "/etc/apache2/mods-available/ssl.conf" ] && ln -sf "/etc/apache2/mods-available/ssl.conf" "/etc/apache2/mods-enabled/ssl.conf"
fi
echo -e "\${YELLOW}重启Apache...${NC}"
systemctl restart apache2 || apache2ctl restart
fi
fi
# 检查SVN模块
echo -e "\${BLUE}检查SVN模块...${NC}"
if ls -l /etc/apache2/mods-enabled/dav_svn.* > /dev/null 2>&1; then
echo -e "\${GREEN}SVN模块已启用${NC}"
else
echo -e "\${RED}SVN模块未启用!${NC}"
fi
fi
# 检查仓库状态
echo -e "\${BLUE}检查SVN仓库...${NC}"
if [ -d "/var/svn/svnrepo" ]; then
echo -e "\${GREEN}仓库目录存在${NC}"
# 检查关键文件
for subdir in "conf" "hooks" "locks" "db"; do
if [ ! -d "/var/svn/svnrepo/\$subdir" ]; then
echo -e "\${RED}错误: 缺少关键目录 /var/svn/svnrepo/\$subdir${NC}"
fi
done
# 检查权限
ls -ld /var/svn/svnrepo
else
echo -e "\${RED}仓库目录不存在!${NC}"
fi
echo -e "\${BLUE}检查完成${NC}"
EOF
chmod +x /root/check_svn_services.sh
echo -e "${GREEN}创建服务检查脚本: /root/check_svn_services.sh${NC}"
# 添加服务检查脚本到crontab,每天运行一次以确保服务正常
if ! crontab -l | grep -q "check_svn_services.sh"; then
(crontab -l 2>/dev/null; echo "0 4 * * * /root/check_svn_services.sh >/dev/null 2>&1") | crontab -
echo -e "${GREEN}已添加每日服务检查到计划任务${NC}"
fi
echo -e "${GREEN}SVN安装和配置完成,服务状态检查通过${NC}"
echo -e "\n${GREEN}配置信息已保存到 /root/svn_installation_info.txt${NC}"
echo -e "\n${YELLOW}如果仍然无法访问SVN服务,请运行故障排查脚本进行诊断${NC}"
检查脚本
#!/bin/bash
# SVN仓库状态检查脚本
# 用于显示仓库中的文件和提交历史
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 无颜色
# 变量设置
SVN_REPO_NAME="svnrepo"
SVN_URL="file:///var/svn/$SVN_REPO_NAME"
TEMP_DIR="/tmp/svn_check_$(date +%s)"
SVN_ADMIN_USER="svnadmin"
SVN_ADMIN_PASS=""
echo -e "${BLUE}===== SVN仓库状态检查 =====${NC}"
# 检查是否以root用户运行
if [ "$(id -u)" != "0" ]; then
echo -e "${RED}此脚本必须以root用户运行${NC}" 1>&2
exit 1
fi
# 检查SVN仓库是否存在
if [ ! -d "/var/svn/$SVN_REPO_NAME" ]; then
echo -e "${RED}SVN仓库目录不存在: /var/svn/$SVN_REPO_NAME${NC}"
exit 1
fi
# 查找管理员密码
if [ -f "/root/svn_installation_info.txt" ]; then
SVN_ADMIN_PASS=$(grep "管理员密码:" "/root/svn_installation_info.txt" | awk '{print $2}')
fi
# 检查仓库是否有提交记录
echo -e "${BLUE}检查SVN仓库提交历史...${NC}"
svn_log=$(svnadmin dump /var/svn/$SVN_REPO_NAME | grep -c "Revision-number")
if [ "$svn_log" -eq 0 ]; then
echo -e "${YELLOW}SVN仓库中没有提交记录${NC}"
echo -e "${YELLOW}推荐运行initialize_repo.sh脚本初始化仓库${NC}"
else
echo -e "${GREEN}SVN仓库中有 $svn_log 条提交记录${NC}"
fi
# 获取仓库中的文件列表
echo -e "${BLUE}获取SVN仓库文件列表...${NC}"
# 创建临时目录
mkdir -p "$TEMP_DIR"
cd "$TEMP_DIR" || exit 1
# 尝试列出仓库内容
if command -v svn > /dev/null; then
if [ -n "$SVN_ADMIN_PASS" ]; then
# 使用密码访问
echo -e "${BLUE}使用管理员账号访问仓库...${NC}"
svn list -R "$SVN_URL" --username="$SVN_ADMIN_USER" --password="$SVN_ADMIN_PASS" --non-interactive > file_list.txt 2>/dev/null
result=$?
else
# 尝试直接访问文件系统
echo -e "${BLUE}尝试直接访问仓库...${NC}"
svn list -R "$SVN_URL" > file_list.txt 2>/dev/null
result=$?
fi
# 如果两种方式都失败,尝试使用svnlook
if [ $result -ne 0 ]; then
echo -e "${YELLOW}尝试使用svnlook获取仓库内容...${NC}"
svnlook tree "/var/svn/$SVN_REPO_NAME" > file_list.txt
fi
# 显示文件列表
if [ -s file_list.txt ]; then
echo -e "${GREEN}SVN仓库内容:${NC}"
cat file_list.txt
else
echo -e "${RED}无法获取仓库文件列表${NC}"
fi
else
echo -e "${RED}未找到svn命令,无法列出文件${NC}"
fi
# 检查Web访问
echo -e "\n${BLUE}检查SVN Web访问...${NC}"
if command -v curl > /dev/null; then
# 获取服务器IP
server_ip=$(hostname -I | awk '{print $1}')
# 检查Apache是否运行
if pgrep -f apache2 > /dev/null; then
echo -e "${GREEN}Apache服务正在运行${NC}"
# 尝试访问SVN Web界面
http_code=$(curl -s -o /dev/null -w "%{http_code}" -k "https://$server_ip/svn/$SVN_REPO_NAME")
if [ "$http_code" -eq 200 ] || [ "$http_code" -eq 401 ]; then
echo -e "${GREEN}SVN Web界面可以访问 (返回代码: $http_code)${NC}"
echo -e "${GREEN}您可以在浏览器中访问 https://$server_ip/svn/$SVN_REPO_NAME${NC}"
else
echo -e "${RED}SVN Web界面无法访问 (返回代码: $http_code)${NC}"
fi
else
echo -e "${RED}Apache服务未运行,无法访问Web界面${NC}"
fi
else
echo -e "${YELLOW}未安装curl,无法检查Web访问${NC}"
fi
# 清理临时目录
cd /
rm -rf "$TEMP_DIR"
echo -e "${GREEN}===== SVN仓库状态检查完成 =====${NC}"