svn版本庫更新后自動同步到www


注意:www目錄一定要用SVN服務器 checkout出Repositories的代碼

 

步驟:

(1)新建www根目錄 mkdir -p /data/www/lehuo

(2)在www根目錄下檢出(checkout,co)倉庫中項目的代碼

svn co svn://ip/lehuo (遠程主機的SVN倉庫)

svn co file:///opt/svn/lehuo   (本地主機的SVN倉庫,若想使用ip地址同上)

chown -R www:www * (更改文件所有者)

(3)配置鈎子(hooks)實現代碼提交前和提交后的操作

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

 

# 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

 

LOGMSG=`$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" | wc -c`

if [ "$LOGMSG" -lt 10 ];#要求注釋不能少於5個漢字,您可自定義

then

echo -e "\n======================================================" 1>&2

echo -e "\n請在Commit(提交)前為您的補丁添加必要的注釋。\n本次提交被忽略。" 1>&2

echo -e "\n======================================================" 1>&2

exit 1

fi

 

 

2.post-commit (SVN服務器更新后自動同步到WWW目錄)

// 只更新同步修改的文件

分兩種情況,一種:svn版本庫和www在同一台服務器上,另一種是兩者在不同的服務器上(兩者之間能互相訪問)

 

第一種情況:hooks/post-commit

 

 1 #!/bin/sh
 2 
 3 export LANG="zh_CN.UTF-8"
 4 
 5 REPOS="$1"
 6 
 7 REV="$2"
 8 
 9 SVN_PATH=/usr/bin/svn
10 
11 SVNDATA_PATH=/opt/svn/oil  # 版本庫路徑
12 
13 WEB_PATH=/home/wwwroot/default/oil  # www根目錄路徑
14 
15 LOG_PATH=/var/log/svn_update.log
16 
17 echo "##########開始提交 " `date "+%Y-%m-%d %H:%M:%S"` '##################' >> $LOG_PATH
18 
19 for change_dir in `svnlook dirs-changed $SVNDATA_PATH`
20 
21     do
22 
23         $SVN_PATH update --username "test" --password "123" --no-auth-cache -N $WEB_PATH/$change_dir >> $LOG_PATH
24 
25 done
26 
27 echo `whoami`,$REPOS,$REV >> $LOG_PATH
28 
29 chown -R www:www $WEB_PATH/$change_dir

 

 

第二種情況:hooks/post-commit

(1)配置ssh無密碼訪問

SVN服務器需要無密碼ssh訪問WEB服務器,方便post-commit腳本ssh到WEB服務器上執行svn up。

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

把SVN服務器上/root/.ssh/id_rsa.pub公鑰文件的內容拷貝到www服務器的/root/.ssh/authorized_keys文件里。然后設置authorized_keys文件權限為600。

 

(2)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客戶端配置,需要自行修改**********************************

CLIENT=10.154.5.192   # www服務器的內網地址         

CLIENTSVNROOT=/data/www/www.halehuo.com/demo1/lehuo    # www根目錄

SVNUSER="lehuo"  # svn賬號

SVNPASSWD="lehuo"  # svn賬號

#**************************************************************

 

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}')

    myecho

    myecho "xiangmu:$PROJECT tongbumulu:$MASTERDIR"

    myecho "tongbu $MASTERDIR dao $CLIENT:$CLIENTSVNROOT/$MASTERDIR"

    /usr/bin/ssh root@$CLIENT "export LANG=en_US.UTF-8; svn up --non-interactive --username $SVNUSER --password $SVNPASSWD '$CLIENTSVNROOT/$MASTERDIR';chown -R www:www '$CLIENTSVNROOT/$MASTERDIR'"

    CHANGEDDIRS=$(echo "$CHANGEDDIRS" | grep -v "^$MASTERDIR")

    MASTERDIR=$(echo "$CHANGEDDIRS" | head -1)

done

 

參考內容:利用SVN的post-commit鈎子實現多項目自動同步

地址:http://qicheng0211.blog.51cto.com/3958621/1563159

 

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

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

測試環境配置:

SVN服務器:172.16.4.234

項目1WEB服務器:172.16.4.235

項目1代碼庫:svn://172.16.4.234/project1

項目2WEB服務器:172.16.4.236

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

下面是操作步驟:

一、WEB服務器

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

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

 

1

2

3

shell# su www

shell$ cd /data/apps/

shell$ svn co --username zb --password 123456 svn://172.16.4.234/project1

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

 

1

2

3

shell# su www

shell$ cd /data/apps/

shell$ svn co --username zb --password 123456 svn://172.16.4.234/project2

二、配置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文件:

1

2

3

4

5

[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。

1

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

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

1

2

[root@localhost ~]# ssh www@172.16.4.235

[www@localhost ~]$

三、SVN服務器post-commit

    post-commit在SVN的hooks目錄下。

    post-commit腳本內容:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

#!/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可執行權限。

四、測試

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM