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

安装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

配置和管理svn

1). 每个仓库的配置文件在$repos/conf/下,vi svnserve.conf,
    配置项在[general]下: 
        anon-access:匿名用户的权限,可以为read,write和none,默认值read。不允许匿名用户访问:anon-access = none 
        auth-access:认证用户的权限,可以为read,write和none,默认值write。 
        password-db:密码数据库的路径,去掉前边的# 
        authz-db:认证规则库的路径,去掉前边的#。 
  注意:这些配置项的行都要顶格,否则会报错。修改配置后需要重启svn才能生效。

2). 配置passwd文件 
    这是每个用户的密码文件,比较简单,就是“用户名=密码”,采用的是明码。如allen=111111 
    
3). 配置authz文件 
    1. [groups] section:为了便于管理,可以将一些用户放到一个组里边,比如:owner=allen,ellen 
    2. groups下边的sections表示对一个目录的认证规则,比如对根目录的认证规则的section为[/]。
        设置单用户的认证规则时一个用户一行,如: 
            [/] 
            allen=rw  #allen对根目录的权限为rw 
      ellen=r   #ellen对根目录的权限为r 
      如果使用group,需要在group名字前加@,如 
      @owner=rw  #group owner中的用户均为rw,等价于上边的两句话 
    启动时如果从/home/.svn/astar启动,/就是astar目录,用如上方式以astar目录为根设置权限。 
    如果从/home/.svn/启动,每个仓库根还是自己的起始目录。可以采用如上方式设置astar的权限,也可以采用如下方式: 
      [astar:/] 
      @owner=rw 
    设置test的权限如下: 
      [test:/] 
      @harry_and_sally = rw 
            简言之,每个仓库的根目录(/)就是自己的起始目录;[repos:/]这种方式只适用于多仓库的情况;[/]适合于单仓库和单仓库的方式。 
    3. 不能跨越仓库设置权限。
配置和管理

导入工程和第一次检出

导入到仓库

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
View Code

完善后的另外二个版本

#!/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
View Code

一个强制要求程序员为自己的上传注释的钩子(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
View Code

 

posted on 2016-04-12 14:10  yhdsir  阅读(2210)  评论(0编辑  收藏  举报

导航