利用SVN的post-commit鉤子實現多項目自動同步

    svn的post-commit鉤子腳本在每次提交(commit)以後運行,咱們能夠在這個腳本里實現一些比較實用的功能,好比發送郵件提醒、自動備份版本庫,自動同步代碼到web服務器等。nginx

    這裏用post-commit實現多項目自動同步,思路:在svn版本倉庫根目錄下劃分多個項目文件夾,項目組成員在提交文件時,post-commit自動判斷文件所屬的項目,而後同步到相應的WEB服務器上。web

測試環境配置:
shell

SVN服務器:172.16.4.234apache

項目1WEB服務器:172.16.4.235bash

項目1代碼庫:svn://172.16.4.234/project1服務器

項目2WEB服務器:172.16.4.236app

項目2代碼庫:svn://172.16.4.234/project2ssh

下面是操做步驟:
ide

1、WEB服務器svn

    WEB服務器做爲SVN客戶端,從SVN服務器上checkout一份代碼到本地。注意要先切換到www用戶再checkout,由於www是apache或nginx的執行用戶(你的環境可能不同)。

    項目1WEB服務器,站點根目錄爲/data/apps/project1:

shell# su www
shell$ cd /data/apps/
shell$ svn co --username zb --password 123456 svn://172.16.4.234/project1

    項目2WEB服務器,站點根目錄爲/data/apps/project2:

shell# su www
shell$ cd /data/apps/
shell$ svn co --username zb --password 123456 svn://172.16.4.234/project2

2、配置ssh無密碼訪問

    SVN服務器須要無密碼ssh訪問WEB服務器,方便post-commit腳本ssh到WEB服務器上執行svn up。注意這裏設置www用戶無密碼訪問,由於WEB服務器上代碼是www用戶checkout出來的。

    在SVN服務器上執行ssh-keygen -t rsa,而後一直按回車鍵,生成公鑰和私鑰保存在/root/.ssh/。

    而後在WEB服務器上先切換到www用戶,創建authorized_keys文件:

[root@localhost ~]# su www
[www@localhost root]$ cd
[www@localhost ~]$ mkdir .ssh
[www@localhost ~]$ chmod 755 .ssh/
[www@localhost ~]$ vi .ssh/authorized_keys

    把SVN服務器上/root/.ssh/id_rsa.pub公鑰文件的內容拷貝到authorized_keys文件裏。而後設置authorized_keys文件權限爲600。

[www@localhost ~]$ chmod 600 .ssh/authorized_keys

    測試,SVN服務器登陸項目1WEB服務器:

[root@localhost ~]# ssh www@172.16.4.235
[www@localhost ~]$

3、SVN服務器post-commit

    post-commit在SVN的hooks目錄下。

    post-commit腳本內容:

#!/bin/sh

REPOS="$1"                  # 倉庫的路徑
REV="$2"                    # 新提交的版本號
LOGFILE=/var/log/svn.log    # 鉤子腳本的日誌
# 腳本的標準輸出和標準錯誤輸出都打印到日誌文件裏
exec 1>>"$LOGFILE"
exec 2>&1

SVNLOOK=/usr/bin/svnlook
TIME=$(date "+%Y-%m-%d %H:%M:%S")
AUTHOR=$($SVNLOOK author -r $REV "$REPOS")  #提交做者
CHANGEDDIRS=$($SVNLOOK dirs-changed $REPOS) #修改的目錄集合
MESSAGE=$($SVNLOOK log -r $REV "$REPOS")    #提交時的備註信息,不建議用中文

# SVN客戶端配置,須要自行修改**********************************
CLIENT1=172.16.4.235        #project1的服務器
CLIENT2=172.16.4.236        #project2的服務器
CLIENTSVNROOT=/data/apps    #WEB服務器的代碼根目錄
SVNUSER="zb"
SVNPASSWD="123456"
#**************************************************************

function myecho() {
    echo "$TIME" "$*"
}

myecho "**************************************************************"
myecho "提交版本:$REV 做者:$AUTHOR"
myecho "提交備註:$MESSAGE"
myecho "修改目錄:$(echo $CHANGEDDIRS | tr '\n' ' ')"

MASTERDIR=$(echo "$CHANGEDDIRS" | head -1)  #CHANGEDDIRS裏的最上級目錄
# 遍歷提交的代碼目錄,同步到WEB服務器上
while [ "$CHANGEDDIRS" != "" ];do
    PROJECT=$(echo $MASTERDIR | awk -F / '{print $1}')
    # 判斷項目文件夾
    if [ "$PROJECT" == "project1" ];then
        myecho
        myecho "項目:$PROJECT 同步目錄:$MASTERDIR"
        myecho "同步 $MASTERDIR 到 $CLIENT1:$CLIENTSVNROOT/$MASTERDIR"
        # 無密碼ssh鏈接到客戶端服務器,執行svn up
        /usr/bin/ssh www@$CLIENT1 "export LANG=en_US.UTF-8; svn up --non-interactive --username $SVNUSER --password $SVNPASSWD '$CLIENTSVNROOT/$MASTERDIR'"
    elif [ "$PROJECT" == "project2" ];then
        myecho
        myecho "項目:$PROJECT 同步目錄:$MASTERDIR"
        myecho "同步 $MASTERDIR 到 $CLIENT2:$CLIENTSVNROOT/$MASTERDIR"
        /usr/bin/ssh www@$CLIENT2 "export LANG=en_US.UTF-8; svn up --non-interactive --username $SVNUSER --password $SVNPASSWD '$CLIENTSVNROOT/$MASTERDIR'"
    else
        :
    fi
    # 在目錄集合裏刪除子目錄
    CHANGEDDIRS=$(echo "$CHANGEDDIRS" | grep -v "^$MASTERDIR")
    # 獲取新的須要同步的最上級目錄
    MASTERDIR=$(echo "$CHANGEDDIRS" | head -1)
done

    不要忘記給post-commit可執行權限。

4、測試

    在項目1的"project1/client"和"project1/server"目錄下分別上傳一個"新建文本文檔.txt",查看日誌文件/var/log/svn.log:    wKiom1Q7UJTw7rTBAANxx5IVbGM785.jpg

    日誌顯示文件已經同步到項目1WEB服務器上了。

相關文章
相關標籤/搜索