使用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
如下
ServerAdmin your_email@com
ServerName svn_slave.domain.name
DocumentRoot /svn_slave/myrepo
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
#AllowOverride None
AllowOverride All
= 2.4>
Require all granted
Order deny,allow
Allow from all
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
重新啟動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-commit
及 post-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 動作了.