Linuxの設定ファイルをSubversionで管理する
サンフラットGAMESは、遠隔のLinuxサーバで管理してるのだが(id:sunflat:20071108)、テストサーバ(ローカルのVMWare上)で更新した設定ファイルを本番サーバへコピーするのが、結構大変。
rootではsshログインできないように設定しているので、scpやsftpでは転送できないし、できれば設定ファイルの履歴も保存しておきたい。
というわけで、Linuxの設定ファイルをSubversion(svn)で管理するスクリプトを作ってみた。
最初は、etcディレクトリ以下をそのままsvnリポジトリと同期できないかなぁと思ったけど、そこらじゅうに.svnディレクトリが出来るのもいやなので、リポジトリとの同期用のディレクトリを別に用意して、
という3段階で同期することにした。
以下のようなファイルリストを書いておくと、その設定ファイルが同期される。
filelist
process_file /etc/httpd/conf/httpd.conf process_file /etc/httpd/conf/vhosts.conf process_file /etc/httpd/conf/ssl.conf process_file /etc/pound.cfg process_file /etc/postfix/main.cf process_file /etc/postfix/virtual exec_when_update postmap /etc/postfix/virtual process_file /root/tools/*
※ exec_when_update は、直前のファイルが更新したときに実行されるコマンド
まず、/root/configsなどに以下のディレクトリ構成を作成し、そのディレクトリ全体をsubversionリポジトリにcommitしておく。
- commit_configs
- update_configs
- common.sh
- filelist
- rootdir/ (同期用ディレクトリ。最初は空)
テストサーバ上で、設定をcommit(リポジトリへ保存)したい場合は cd /root/configs; ./commit_configs を実行する。
※更新されたファイルが表示されるので、良ければ y を押す
本番サーバ上で、設定をupdate(リポジトリから更新)したい場合は cd /root/configs; ./update_configs を実行する。
※元のファイルと上書きするファイルのdiffが表示されるので、良ければ y を押す。元のファイルは.bakとして残る。
以下、スクリプト一覧
commit_configs
#!/bin/bash # commit to repository source common.sh function process_file { updated=0 while [ -n "$1" ]; do # skip backup file if [ ${1##*.} = "bak" ]; then shift continue fi # copy to repository cp -u --parent $1 $fdir shift done } mode='c' source filelist [ -f filelist_commit_only ] && source filelist_commit_only # commit to svn repository result=`svn status $fdir` if [ -z "$result" ]; then echo "no update" exit fi echo "$result" read -p "Ready? (y/n):" -n 1 inp echo [ "$inp" = "y" ] || exit svn add --force $fdir svn commit -m "commit configs" $fdir
update_configs
#!/bin/bash # update from repository source common.sh function process_file { updated=0 while [ -n "$1" ]; do # update only when a repository file is newer if [ ! -f "$1" ]; then read -p "create $1 ? (y/n):" -n 1 inp echo if [ "$inp" = "y" ]; then cp "$fdir$1" "$1" updated=1 fi elif [ "$fdir$1" -nt "$1" ]; then diff -u "$1" "$fdir$1" diffret=$? if [ $diffret -eq 1 ]; then read -p "update $1 ? (y/n):" -n 1 inp echo if [ "$inp" = "y" ]; then cp -p "$1" "$1.bak" cp "$fdir$1" "$1" updated=1 fi elif [ $diffret -eq 0 ]; then # update timestamp to skip doing diff on the next time touch -r "$fdir$1" "$1" fi fi shift done } mode='u' svn update $fdir source filelist [ -f filelist_update_only ] && source filelist_update_only
common.sh
function exec_when_update { if [ $mode = 'u' ] && [ $updated -eq 1 ]; then echo exec on update: $* $* fi } fdir='rootdir'
※ CentOS 4.6上で動かしました。
※ ファイルの上書き等行いますので、万が一使いたい場合は、十分動作確認してからお願いします。