您的位置:首页 > 运维架构 > Linux

CENTOS 搭建SVN服务器(附自动部署到远程WEB)

2016-04-12 14:10 746 查看

安装subversion服务端

# 安装
yum install -y subversion

# 测试是否安装成功 如果显示了版本信息则表示安装成功
svnserve --version;sleep 5s

# svn配置建立svn版本库目录可建多个:
PATHSSS="/home/svn"
echo SVN仓库将创建在:$PATHSSS;sleep 5s

# 新建一个版本库目录
mkdir -p $PATHSSS
cd $PATHSSS
# 建立svn版本库:
svnadmin create $PATHSSS

# 先设置passwd
cat >$PATHSSS/conf/passwd<<ANGIE.K
[users]
jianglinzhi = jianglinzhi
root1 = root
ANGIE.K

# 再设置权限authz
cat >$PATHSSS/conf/authz<<ANGIE.K
[groups] #用户组
admin = jianglinzhi,root1
coder = coders1,coders2,coders3
ui_and_ue = ui1,ui2,ui3
[/] #/仓库权限
@admin = rw
@coder = rw
@ui_and_ue = rw
ANGIE.K

# 最后设定svnserve.conf
cat >$PATHSSS/conf/svnserve.conf<<ANGIE.K
[general]
# 使非授权用户无法访问
anon-access = none
# 使授权用户有写权限
auth-access = write
# 用户密码文件
password-db = passwd
# 访问控制文件
authz-db = authz
# 认证命名空间,subversion会在认证提示里显示,并且作为凭证缓存的关键字。
realm = 姜林志的第一个SNV服务器 欢迎你.
ANGIE.K

# 启动 默认端口 3690
killall svnserve
svnserve -d -r $PATHSSS

# 加入开机启动
echo svnserve -d -r $PATHSSS >> /etc/rc.local


导入工程和第一次检出

导入到仓库

cd 进入工程目录上一级
执行:

#导入前先处理下WIN不支持的文件名 如  : * ? " < > |
# find ./ -name "*\?*" #查找
# find ./ -name "*\?*" -print -exec rm -rf {} \; #删除
# find ./ -name "*\:*" -print -exec rm -rf {} \; #删除
# find ./ -name "*\"*" -print -exec rm -rf {} \; #删除
# find ./ -name "*\<*" -print -exec rm -rf {} \; #删除
# find ./ -name "*\>*" -print -exec rm -rf {} \; #删除
# find ./ -name "*\|*" -print -exec rm -rf {} \; #删除

提示:如果你设置了pre-commit钩子(比如:强制要求注释,请先解除这个钩子,以免导入失败)

svn import 待导入工程路径(目录) svn://127.0.0.1/定义工程在仓库的目录名字 -m "对于本次操作的注释"
或者 切换到待导入目录
svn import ./ svn://127.0.0.1/定义工程在仓库的目录名字 -m "对于本次操作的注释"


将在仓库中新建工程目录和文件

检出到工程

cd 进入工程目录 执行即可

svn co svn://127.0.0.1 ./


判定程序员是否为补丁添加注释(per-commit)

这个钩子脚本,在每次commit之后会执行,格式是SHELL脚本,是从网上收集来的测试可用
这个文件的详细路径请看下面的cd命令

cd $PATHSSS/hooks
cp per-commit.tmpl per-commit
chmod 755 per-commit
vi $PATHSSS/hooks/per-commit
###############################################
#!/bin/sh
# PRE-COMMIT HOOK
# .... 中间省略
# http://svn.apache.org/repos/asf/subversion/trunk/contrib/hook-scripts/ REPOS="$1"
TXN="$2"
SVNLOOK=/usr/bin/svnlook

LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" | wc -c`
if [ "$LOGMSG" -lt 8 ];#要求注释不能少于8个字符,您可自定义
then
echo -e "\n======================================================" 1>&2
echo -e "\n请在Commit(提交)前为您的补丁添加必要的注释。\n本次提交被忽略。" 1>&2
echo -e "\n======================================================" 1>&2
exit 1
fi


自动同步到WEB服务器(post-commit)

这个钩子脚本,在每次commit之后会执行,格式是SHELL脚本,是从网上收集来的测试可用
这个文件的详细路径请看下面的cd命令

# 配置自动发布到WEB服务器 编辑 post-commit 文件
cd $PATHSSS/hooks
cp post-commit.tmpl post-commit
chmod 755 post-commit
vi $PATHSSS/hooks/post-commit
###############################################
#!/bin/sh
# -------------------------------------------------------------------------------
# Filename:    post-commit
# Description: WEB server with synchronization code by SVN
# -------------------------------------------------------------------------------
#Version 1.0
#当用戶把代碼提交完成时,把代碼中的最新更改同步到 WEB服務器,同時注意不包括刪除操作。

#Set variable
SVN=/home/svn
SVNUSER=root1
SVNPASD=root
WEB=/home/ftp/svn #待上传到WEB服务器的文件存放路径 第一次 需要先到该目录检出一次svn co svn://127.0.0.1 ./

WEBIP="192.168.0.23"
RSYNC=rsync
LOG=/home/svn/post-commit.log
export LANG=en_US.UTF-8

mkdir -p $SVN
mkdir -p $WEB

#更新文件到本地文件夹
svn update $WEB --username $SVNUSER --password $SVNPASD
#如果前面的代码成功完成,会继续执行下面的代码
if [ $? == 0 ]
then
echo ""     >> $LOG
echo `date` >> $LOG
echo "##############################" >> $LOG
chown -R nobody:nobody $WEB
#同步代码从SVN服务器到WEB服务器 通过RSYNC
$RSYNC -vaztpH  --timeout=90   --exclude-from=$SVN/exclude.list $WEB root@$WEBIP:$WEB/ >> $LOG
fi


完善后的另外一个版本

#!/bin/sh

# POST-COMMIT HOOK
# ... 省略
# http://svn.apache.org/repos/asf/subversion/trunk/contrib/hook-scripts/ 
# mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf
echo -e "[1 fo 6]================================\n`date`:这次更新将发布到测试和WEB。" 1>&2

# 库的路径
REPOS="$1"

# 新提交的版本号
REV="$2"

changed=$(svnlook changed -r $REV $REPOS)
echo $changed > /home/svn/hooks/last_changed
echo $REPOS >> /home/svn/hooks/last_changed
echo $REV >> /home/svn/hooks/last_changed

######################################################################################
# 配置自动发布到WEB服务器 编辑 post-commit 文件 ######################################
######################################################################################
# -------------------------------------------------------------------------------
# Filename:    post-commit
# Description: WEB server with synchronization code by SVN
# -------------------------------------------------------------------------------
#Version 1.1
#当用戶把代碼提交完成时,把代碼中的最新更改同步到 WEB服務器,同時注意不包括刪除操作。

#Set variable
SVN=/home/svn
SVNUSER=root1
SVNPASD=root

# 测试服务器路径
WEB1=/home/ftp/e/ecshop_2013/wwwroot
WEB2=/home/ftp/c/customer/wwwroot

# 远端服务器IP
WEBIP="192.168.1.1"

# 同步方式
RSYNC=rsync

# 同步日志
LOG=/home/svn/post-commit.log

# 避免乱码
export LANG=en_US.UTF-8

mkdir -p $SVN

#更新文件到本地文件夹
svn update $WEB1  --username $SVNUSER --password $SVNPASD
svn update $WEB2  --username $SVNUSER --password $SVNPASD

# 必须要检出成功才开始执行下面的 #####################################################
if [ $? == 0 ]
then
echo -e "[2 fo 6]================================\n`date`:文件顺利检出到测试项目。" 1>&2

######################################################################################
# 这里是解析本次操作的文件名 用于提高修改权限的速度 ##################################
######################################################################################
echo -e "[3 fo 6]================================\n`date`:正在改变文件归属,为上传到WEB服务器准备。" 1>&2
str=$changed

# 字符串变成类似数组的东西,下面的for可以一次打印一个出来
var=`echo $str | awk -F',' '{print $0}' | sed "s/,/ /g"`

# list为文件名和SVN标记码一次搞一个出来
for list in $var
do
# 获取每次list字符串的长度
filesneme_len=`expr length $list`
# 这个if对长度小于1的文件名过滤掉>符号需要转义
if [ "$filesneme_len" \> "1" ]
then
# 这里取得的是字符串的第一个/前后的字符串 分别为仓库名字和带路径文件名
#echo 仓库:${list%%/*}
#echo 文件:/${list#*/}

# 根据仓库名字给文件分派权限
if [ "${list%%/*}" == "ec_qiuyi" ]
then
#设定检出文件为用户组1
echo 设定检出文件为用户组1
echo 仓库:${list%%/*}
echo 文件:/${list#*/}
chown 1000:1100 $WEB1/${list#*/}
# 只同步修改的内容
rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB1/${list#*/}" "root@$WEBIP:$WEB1\_svn/${list#*/}" >> $LOG
fi

if [ "${list%%/*}" == "customer" ]
then
#设定检出文件为用户组2
echo 设定检出文件为用户组2
echo 仓库:${list%%/*}
echo 文件:/${list#*/}
chown 1002:1100 $WEB2/${list#*/}
# 只同步修改的内容
rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB2/${list#*/}" "root@$WEBIP:$WEB2\_svn/${list#*/}" >> $LOG
fi
fi
done
echo -e "[4 fo 6]================================\n`date`:文件归属修改完成。" 1>&2

######################################################################################
# 记录日志和上传文件 #################################################################
######################################################################################

echo ""     >> $LOG;echo `date` >> $LOG;echo "##############################" >> $LOG
# 修改新检出文件的权限
# chown -R 1000:1100 $WEB
# chown -R 1002:1100 $WEB2
#同步代码从SVN服务器到WEB服务器 通过RSYNC
#$RSYNC -vaztpH  --timeout=90   --exclude-from=$SVN/exclude.list $WEB root@$WEBIP:$WEB/ >> $LOG

echo -e "[5 fo 6]================================\n`date`:正上传到WEB服务器,并检查文件完整。" 1>&2

# 同步完整内容 如目录删除文件删除之类..

rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB1/" "root@$WEBIP:$WEB1\_svn/" >> $LOG
rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB2/" "root@$WEBIP:$WEB2\_svn/" >> $LOG

echo -e "[6 fo 6]================================\n`date`:代码已经发布到远端WEB。" 1>&2

fi
# 利用钩子错误退出 输出过程信息
exit 1


完善后的另外二个版本

#!/bin/sh

######################################################################################
# 配置自动发布到WEB服务器 编辑 post-commit 文件 ######################################
######################################################################################
# -------------------------------------------------------------------------------
# Filename:    post-commit
# Description: WEB server with synchronization code by SVN
# -------------------------------------------------------------------------------
#Version 1.0
#当用戶把代碼提交完成时,把代碼中的最新更改同步到 WEB服務器,同時注意不包括刪除操作。

echo -e "[1 fo 6]================================\n`date`:这次更新将发布到测试和WEB。" 1>&2

# 库的路径
REPOS="$1"

# 新提交的版本号
REV="$2"

changed=$(svnlook changed -r $REV $REPOS)
echo $changed > /home/svn/hooks/last_changed
echo $REPOS >> /home/svn/hooks/last_changed
echo $REV >> /home/svn/hooks/last_changed

#Set variable
SVN=/home/svn
SVNUSER=本地管理员ID
SVNPASD=本地管理员密码

mkdir -p $SVN

# 测试服务器路径
WEB1=/home/ftp/e/ecshop_2013/wwwroot
WEB2=/home/ftp/c/customer/wwwroot
WEB3=/home/ftp/u/ugg_ecshop_2013/wwwroot
WEB4=/home/ftp/l/luck_ecshop_2013/wwwroot

# 同步标记
WEB1_SYNC=NO
WEB2_SYNC=NO
WEB3_SYNC=NO
WEB4_SYNC=NO

# 待同步操作数
WEB1_SYNC_NUM=0
WEB2_SYNC_NUM=0
WEB3_SYNC_NUM=0
WEB4_SYNC_NUM=0

# 同步方式
RSYNC=rsync

# 同步日志
LOG=/home/svn/post-commit.log
echo "================================================" > $LOG
echo `date`:这是最近一次SVN提交的信息。>> $LOG
echo "================================================" >> $LOG

mkdir -p $WEB1
mkdir -p $WEB2
mkdir -p $WEB3
mkdir -p $WEB4

# 第一次需要检出
# svn co svn://127.0.0.1/ec_ugg ./

# 远端服务器IP
WEBIP_QY="192.168.1.1"
WEBIP_UG="192.168.1.2"
WEBIP_LU="192.168.1.3"

# 避免乱码
export LANG=en_US.UTF-8

#更新文件到本地文件夹
echo "================================================" >> $LOG
echo "更新文件到本地文件夹" >> $LOG
svn update $WEB1  --username $SVNUSER --password $SVNPASD >> $LOG
svn update $WEB2  --username $SVNUSER --password $SVNPASD >> $LOG
svn update $WEB3  --username $SVNUSER --password $SVNPASD >> $LOG
svn update $WEB4  --username $SVNUSER --password $SVNPASD >> $LOG
echo "================================================" >> $LOG

# 必须要检出成功才开始执行下面的 #####################################################
if [ $? != 0 ] ; then
echo -e "项目检出失败,同步终止!" 1>&2
exit $?
fi
echo -e "[2 fo 6]================================\n`date`:文件顺利检出到测试项目。" 1>&2

######################################################################################
# 这里是解析本次操作的文件名 用于提高修改权限的速度 ##################################
######################################################################################
echo -e "[3 fo 6]================================\n`date`:正在改变文件归属,为上传到WEB服务器准备。" 1>&2
str=$changed

# 字符串变成类似数组的东西,下面的for可以一次打印一个出来
var=`echo $str | awk -F',' '{print $0}' | sed "s/,/ /g"`

# list为文件名和SVN标记码一次搞一个出来
for list in $var
do
# 获取每次list字符串的长度
filesneme_len=`expr length $list`
# 这个if对长度小于1的文件名过滤掉>符号需要转义
if [ "$filesneme_len" \> "1" ]
then
# 这里取得的是字符串的第一个/前后的字符串 分别为仓库名字和带路径文件名
#echo 仓库:${list%%/*}
#echo 文件:/${list#*/}

# 根据仓库名字给文件分派权限

# 项目0
if [ "${list%%/*}" == "ec_qiuyi" ]
then
# 设定同步标记
WEB1_SYNC="YES"
# 累加标记
WEB1_SYNC_NUM=$[$WEB1_SYNC_NUM+1]
#设定检出文件为用户组1
echo 设定检出文件为用户组1
echo 仓库:${list%%/*}
echo 文件:/${list#*/}
chown 1000:1100 $WEB1/${list#*/}
# 只同步修改的内容
#rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB1/${list#*/}" "root@$WEBIP_QY:$WEB1\_svn/${list#*/}" >> $LOG
# 同步完整内容 如目录删除文件删除之类..
#rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB1/" "root@$WEBIP_QY:$WEB1\_svn/" >> $LOG # 项目0
fi

# 项目1
if [ "${list%%/*}" == "customer" ]
then
# 设定同步标记
WEB2_SYNC="YES"
# 累加标记
WEB2_SYNC_NUM=$[$WEB1_SYNC_NUM+1]
#设定检出文件为用户组2
echo 设定检出文件为用户组2
echo 仓库:${list%%/*}
echo 文件:/${list#*/}
chown 1002:1100 $WEB2/${list#*/}
# 只同步修改的内容
#rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB2/${list#*/}" "root@$WEBIP_QY:$WEB2\_svn/${list#*/}" >> $LOG
# 同步完整内容 如目录删除文件删除之类..
#rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB2/" "root@$WEBIP_QY:$WEB2\_svn/" >> $LOG # 项目1
fi

# 项目2
if [ "${list%%/*}" == "ec_ugg" ]
then
# 设定同步标记
WEB3_SYNC="YES"
# 累加标记
WEB3_SYNC_NUM=$[$WEB1_SYNC_NUM+1]
#设定检出文件为用户组3
echo 设定检出文件为用户组3
echo 仓库:${list%%/*}
echo 文件:/${list#*/}
chown 1000:1100 $WEB3/${list#*/}
# 只同步修改的内容
#rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB3/${list#*/}" "root@$WEBIP_UG:$WEB3\_svn/${list#*/}" >> $LOG
# 同步完整内容 如目录删除文件删除之类..
#rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB3/" "root@$WEBIP_UG:$WEB3\_svn/" >> $LOG # 项目2

fi

# 项目3
if [ "${list%%/*}" == "ec_luck" ]
then
# 设定同步标记
WEB4_SYNC="YES"
# 累加标记
WEB4_SYNC_NUM=$[$WEB1_SYNC_NUM+1]
#设定检出文件为用户组4
echo 设定检出文件为用户组4
echo 仓库:${list%%/*}
echo 文件:/${list#*/}
chown 1000:1100 $WEB4/${list#*/}
# 只同步修改的内容
#rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB4/${list#*/}" "root@$WEBIP_LU:$WEB1\_svn/${list#*/}" >> $LOG
# 同步完整内容 如目录删除文件删除之类..
#rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB4/" "root@$WEBIP_LU:$WEB1\_svn/" >> $LOG # 项目3
fi

fi
done
echo -e "[4 fo 6]================================\n`date`:文件归属修改完成。" 1>&2

######################################################################################
# 记录日志和上传文件 #################################################################
######################################################################################

echo ""     >> $LOG;echo `date` >> $LOG;echo "##############################" >> $LOG
# 修改新检出文件的权限
# chown -R 1000:1100 $WEB
# chown -R 1002:1100 $WEB2
#同步代码从SVN服务器到WEB服务器 通过RSYNC
#$RSYNC -vaztpH  --timeout=90   --exclude-from=$SVN/exclude.list $WEB root@$WEBIP:$WEB/ >> $LOG

echo -e "[5 fo 6]================================\n`date`:正上传到WEB服务器,并检查文件完整。" 1>&2

# 同步完整内容 如目录删除文件删除之类..
echo "================================================" >> $LOG
echo "同步完整内容 如目录删除文件删除之类.." >> $LOG

if [ "$WEB1_SYNC" == "YES" ]
then
echo -e "正同步($WEB1_SYNC_NUM个操作记录)到 球衣服务器" 1>&2
time rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB1/" "root@$WEBIP_QY:$WEB1\_svn/" >> $LOG # 球衣
fi

if [ "$WEB2_SYNC" == "YES" ]
then
echo -e "正同步($WEB2_SYNC_NUM个操作记录)到 客服系统服务器" 1>&2
time rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB2/" "root@$WEBIP_QY:$WEB2\_svn/" >> $LOG # 客服系统
fi

if [ "$WEB3_SYNC" == "YES" ]
then
echo -e "正同步($WEB3_SYNC_NUM个操作记录)到 UGG孩子服务器" 1>&2
time rsync -vzurtopg --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB3/" "root@$WEBIP_UG:$WEB3\_svn/" >> $LOG # UGG鞋子
fi

if [ "$WEB4_SYNC" == "YES" ]
then
echo -e "正同步($WEB4_SYNC_NUM个操作记录)到 吉祥符服务器" 1>&2
time rsync -vzurtopg '-e ssh -p 10079' --delete --timeout=60 --exclude-from=$SVN/exclude.list "$WEB4/" "root@$WEBIP_LU:$WEB1\_svn/" >> $LOG # 吉祥符
fi

echo -e "[6 fo 6]================================\n`date`:代码已经发布到远端WEB。" 1>&2
echo "================================================" >> $LOG

# 利用钩子错误退出 输出过程信息
exit 1


一个强制要求程序员为自己的上传注释的钩子(pre-commit)

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

LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" | wc -c`
if [ "$LOGMSG" -lt 8 ];#要求注释不能少于8个字符,您可自定义
then
echo -e "\n======================================================" 1>&2
echo -e "\n请在Commit(提交)前为您的补丁添加必要的注释。\n本次提交被忽略。" 1>&2
echo -e "\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

# All checks passed, so allow the commit.
# exit 0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: