使用SVN sync 來同步兩個 Repository

使用SVN sync 來同步兩個 Repository


緣由:

最近我將 SVN server 轉移到 ARM 的開發版上, 但是又擔心這板子上SSD 壞掉, 於是開始思考資料備份的問題. 上網找了一下, 決定採用 svn sync 方式, 來做資料的即時鏡像備份.
因此需要額外再加一塊 ARM 開發版來放鏡像的資料.

環境

我的實作環境如下:

# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.6 (jessie)
Release:    8.6
Codename:   jessie

# uname -sorm
Linux 3.14.79-odroidc2 aarch64 GNU/Linux

實作流程 :

我們將原來使用中的SVN server稱為master, 鏡像的server 為slave.

Slave 相關設定

首先安裝 svn 相關套件

# apt-get install subversion

我們需先建立一個新的SVN Repository 當作slave server.注意, 他必須是空的, 不能對它做任何commit.

# svnadmin create /svn_slave/myrepo

並且新增一個SVN 帳號專門做 sync 用途, 比如叫做 mysvnsync

建立帳號範例如下

# cat << EOF > /svn_slave/myrepo/conf/authz
 [repos:/]
 mysvnsync = rw
 * = 
EOF

建立密碼範例如下

# htpasswd -c /svn_slave/myrepo/conf/passwd mysvnsync

/svn_slave/myrepo/hooks目錄中, 新增2個 hook程式, 分別是是start-commit 以及 pre-revprop-change 來檢查 SVN sync 時的帳號

start-commit 內容範例如下

# cat << EOF > /svn_slave/myrepo/hooks/start-commit

  #!/bin/bash

  set -e
  REPOS="$1"
  USER="$2"

  #
  # ALLOW_USERS="user1 user2 user3"
  #
  ALLOW_USERS="mysvnsync"

  #
  # Check USER account
  #
  found=0
  for i in $ALLOW_USERS
  do
    if [[ "$USER" == "$i" ]]; then
      found=1
      break
    fi
  done

  if [[ $found == 0 ]]; then
     echo "The '${USER}' is not allowed to commit new revisions" >&2
     exit 1
  fi

  # All checks passed, so allow the commit.
  exit 0
EOF

pre-revprop-change 內容範例如下

# cat << EOF > /svn_slave/myrepo/hooks/pre-revprop-change

  #!/bin/bash

  REPOS="$1"
  REV="$2"
  USER="$3"
  PROPNAME="$4"
  ACTION="$5"

  #
  # ALLOW_USERS="user1 user2 user3"
  #
  ALLOW_USERS="mysvnsync"

  #
  # Check USER account
  #
  found=0
  for i in $ALLOW_USERS
  do
    if [[ "$USER" == "$i" ]]; then
      found=1
      break
    fi
  done

  if [[ $found == 0 ]]; then
     echo "The '${USER}' is not allowed to change revision properties" >&2
     exit 1
  fi
  exit 0
EOF

將此兩個程式設定為可執行

# chmod +x /svn_slave/myrepo/hooks/start-commit
# chmod +x /svn_slave/myrepo/hooks/pre-revprop-change

由於我的SVN server 是使用 http 的 方式來連接, 所以還需要 apache 相關設定, 至於apache 相關設定, 以下僅供參考, 每個人的需求不一定相同.

首先安裝 apache 相關套件

# apt-get install apache2 libapache2-svn

首先將 /svn_slave 改為apache 可存取

# chown -R www-data:www-data /svn_slave

假設這個SVN slave 的位址是 http://san_slave.domain.name, 修改 /etc/apache2/sites-enabled/000-default.conf 如下

<VirtualHost *:80>
    ServerAdmin your_email@com
    ServerName svn_slave.domain.name

    DocumentRoot /svn_slave/myrepo

    <Location />
       DAV svn
       SVNParentPath     /svn_slave/myrepo
       SVNListParentPath on

       AuthType Basic
       AuthName "Authorization Realm"
       AuthzSVNAccessFile /svn_slave/myrepo/conf/authz
       AuthUserFile /svn_slave/myrepo/conf/passwd
       Require valid-user
   </Location>

    <Directory /svn_slave/myrepo>
        #AllowOverride None
        AllowOverride All

        <IfVersion >= 2.4>
          Require all granted
        </IfVersion>
        <IfVersion < 2.4>
          Order deny,allow
          Allow from all
        </IfVersion>
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

重新啟動apache

# /etc/init.d/apache2 restart

以上, SVN slave 的設定已經完成.

使用 http://svn_slave.domain.name 就可以查看 subversion repository 是否設置成功

Master 相關設定

我的 SVN Master 端早就已經使用很久了, 有許多資料都已經存放在 repository 裡面了. 基本上不需要做任何設定.

只是若要和SVN slave 同步, 則需要做一次 init 的動作.

假設我的SVN master 的位址是 http://svn_master.domain.name 指令如下:

# svnsync init --sync-username  mysvnsync --sync-password  slave_password http://svn_slave.domain.name  --source-username my_svn_account  --source-password http://svn_master.domain.name

上述的帳號, 密碼, 以及http 的位址請自行修改成符合你自己的值. 這個 init 的動作會在SVN slave 寫入一些初始參數, 這個動作只需做過一次就可以了.

開始同步資料

接下來就是要同步資料啦, 這可以有兩種方式.

一是手動下指令同步. 如下:

# svnsync sync --sync-username  mysvnsync --sync-password  slave_password http://svn_slave.domain.name  --source-username my_svn_account  --source-password http://svn_master.domain.name

跟上面的指令幾乎一模一樣, 只是把 init 改為 sync 即可. 你可以把這個指令加入到 crontab 裡面, 讓它定時自動執行即可.

第二種方式是, 每次對SVN master commit 時, 自動同步到 SVN slave 中. 這種方式需要修改 SVN master 裡面/svn_master/myrepo/hooks 目錄中的兩個 hook 程式.
分別是post-commitpost-revprop-change.

post-commit 內容範例如下

# cat << EOF > /svn_master/myrepo/hooks/post-commit

  #!/bin/bash

  set -e
  REPOS="$1"
  REV="$2"
  TXN_NAME="$3"

  #
  # Automatic sync to mirror site
  #
  SVNSYNC=/usr/bin/svnsync
  TO=http://svn_slave.domain.com
  SYNC_USER=mysvnsync
  SYNC_PASS=password_for_sync
  SOURCE_USER=my_svn_account
  SOURCE_PASS=my_svn_password

  $SVNSYNC --non-interactive sync $TO \
  --sync-username $SYNC_USER --sync-password $SYNC_PASS \
  --source-username $SOURCE_USER --source-password $SOURCE_PASS &

  exit 0
EOF

post-revprop-change 內容範例如下

# cat << EOF > /svn_master/myrepo/hooks/post-revprop-change

  #!/bin/bash

  set -e
  REPOS="$1"
  REV="$2"
  USER="$3"
  PROPNAME="$4"
  ACTION="$5"

  #
  # Automatic sync to mirror site
  #
  SVNSYNC=/usr/bin/svnsync
  TO=http://svn_slave.domain.com
  SYNC_USER=mysvnsync
  SYNC_PASS=password_for_sync
  SOURCE_USER=my_svn_account
  SOURCE_PASS=my_svn_password

  $SVNSYNC --non-interactive copy-revprops $TO \
  --sync-username $SYNC_USER --sync-password $SYNC_PASS \
  --source-username $SOURCE_USER --source-password $SOURCE_PASS &

  exit 0
EOF

將此兩個程式設定為可執行

# chmod +x /svn_master/myrepo/hooks/post-commit
# chmod +x /svn_master/myrepo/hooks/post-revprop-change

完成之後, 以後每次對於SVN master commit, 則post-commit 這個hook 程式就會自動執行, 然後對SVN slave 做 sync 動作了.


參考資料

  1. 用svnsync 做mirror repository
  2. HOW TO USE SVNSYNC TO CREATE A MIRROR BACKUP OF YOUR SUBVERSION REPOSITORY
  3. svnsync—Subversion Repository Mirroring
  4. svnsync 做 svn repository 的單向備份
This entry was posted in subversion, 架站 and tagged . Bookmark the permalink.

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *