FreeBSD サーバ beatrice 復旧がやっと終わったと思ったら,バージョン管理システム Subversion の commit がエラーになってしまった。サーバに Subversion のリポジトリがあり,クライアント PC から自作プログラムや Web ページのバージョン管理を行っている。Web ページについては commit (新バージョンの登録) 操作を行うと,Subversion の post-
エラーはこの実行環境を復旧し忘れていたためだった。このリカバリには少し悩んだ。自分で組込んだのにその仕組みを完全に忘却してしまっていた。メモを残しておかないとこういうハメになる。そういうことで,改めてここで記しておくことにする。
自動更新の手続きは次のようなものである。
- post-
commit スクリプトは Web ページ更新シェルスクリプト webupdate スクリプト(自作)を呼び出す。 - webupdate は作業ユーザ user のホームディレクトリにある Subversion 管理下の Web サイトソースにおいて,svn update を実行し,新しい版を取り出す。
- webupdate は,前回 Web 更新実行時刻のタイムスタンプをもつタイムスタンプファイルよりも新しいファイル群だけを纏めて一時アーカイブファイルを作成する。
- webupdate は Apache22 ドキュメントルートにおいて一時アーカイブファイルを解凍し,公開 Web ドキュメントツリーを更新する。
- webupdate はタイムスタンプファイルを現在の時刻で更新する(touch コマンドによる)。
- webupdate は namazu 検索インデックス更新スクリプト mkwebidx(自作)を呼び出す。
- mkwebidx は,前回インデックス更新実行時刻のタイムスタンプをもつタイムスタンプファイルよりも新しく,かつインデックス作成対象のファイル群だけを,namazu インデックス更新用作業領域にコピーする。
- mkwebidx は,コピーしたファイルのうち UTF-8 エンコード文書を EUC-JP にコード変換する(namazu が EUC-JP 前提のため)。
- mkwebidx は namazu 検索インデックス更新プログラム mknmz コマンドで検索インデックスを更新する。
- mkwebidx はタイムスタンプファイルを現在の時刻で更新する(touch コマンドによる)。
この手続きは Web 環境で実行されるため,ユーザ権限は www のパーミションである。しかし,一連の操作において user, root 権限が必要なオペレーションがあり,www がこれらに成り代わる仕掛けが必要になる。もちろん関連するリソースすべてを www の所有とすればよいのだけれども,その他運用事情で www 専用とするわけにも行かなかった。このため,スクリプト内で対話操作を実現するために expect を利用する。www ユーザが expect コマンドで他のユーザでシステムにログインしてその権限の必要なオペレーションを実行するわけである。expect は FreeBSD ports /usr/
ただし,このためには www のアカウント設定を通常の nologin からログイン可能ユーザに変更しておかなくてはならない。www アカウント設定(vipw で編集)を以下のようにした。
www:パスワード:80:80::0:0:World Wide Web Owner:/nonexistent:/bin/tcsh
/nonexistent はもともとダミーなんだけど,www オーナで同名ディレクトリを作成しておく。これで一度,www ユーザとして user に slogin しておき,ssh が通るようにしておく。
beatrice:/home/user % su - xxxxxxx # mkdir -p /nonexistent # chown -R www:www /nonexistent # exit beatrice:/home/user % su - www xxxxxxx > slogin user@beatrice The authenticity of host 'beatrice (192.168.1.4)' can't be established. RSA key fingerprint is 62:35:a2:d5:e6:20:8f:91:6e:ce:e6:d2:a4:2b:5c:a7. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'beatrice,192.168.1.4' (RSA) to the list of known hosts. Password: xxxxxx beatrice:/home/user %
post-commit スクリプトは,Web ページソースの Subversion リポジトリが /usr/
以下に post-commit を示す。Subversion によって,引数としてリポジトリディレクトリ名とリビジョンが渡されて起動される。このスクリプトは /var/
#!/bin/sh REPOS="$1" REV="$2" LOG=/var/log/svnupdate.log /bin/echo "*** post-commit STARTED at `/bin/date` $REPOS $REV" >> $LOG /home/user/bin/webupdate >> $LOG /bin/echo "*** post-commit ENDED at `/bin/date` $REPOS $REV" >> $LOG
以下に,順次実行される webupdate, mkwebidx の両スクリプトも掲載しておく。
#!/bin/sh # # webupdate # # * HTML install for Beatrice # * will be called by post-commit of Subversion # Copyright (c) 1998-2011, isao yasuda, All Rights Reserved. # DATADIR="/home/user/src/noxinsomniae" STAMP="$DATADIR/stamp" EXPECT="/usr/local/bin/expect" echo "*** Web install start at `date` ***" # 新しい HTML の取り出し $EXPECT -c ' set timeout -1 spawn slogin user@beatrice expect "Password:" send "xxxxxx\r" expect "% " send "cd /home/user/src/noxinsomniae\r" expect "% " send "/usr/local/bin/svn update\r" expect "% " puts "End" exit ' # 更新ページのアーカイブ cd $DATADIR echo "*** $DATADIR archiving & Beatrice installing ..." find -L . \( -newer $STAMP \! -name .svn \! -name prop-base \! \ -name text-base \! -name props \! -name tmp \! -name all-wcprops \ \! -name entries \! -name "*svn-base*" -type f \) | \ xargs tar zcf /tmp/webarc.tar.gz echo "*** archive gen done. *** " ls -las /tmp/webarc.tar.gz # 公開 Web ツリーへの展開 $EXPECT -c ' set timeout -1 spawn slogin user@beatrice expect "Password:" send "xxxxxx\r" expect "% " send "su\r" expect "Password:" send "xxxxxx\r" expect "# " send "tar zxvf /tmp/webarc.tar.gz -C /usr/local/www/apache22/data\r" expect "# " puts "End" exit ' echo "*** extraction done. ***" rm -f /tmp/webarc.tar.gz echo "*** removed archive. ***" echo "*** Web install ended at `date` ***" # タイムスタンプの更新 touch $STAMP # # namazu 検索インデックスの更新 # echo "*** Search index generation ***" $EXPECT -c ' set timeout -1 spawn slogin user@beatrice expect "Password:" send "xxxxxx\r" expect "% " send "su\r" expect "Password:" send "xxxxxx\r" expect "# " send "/home/user/bin/mkwebidx\r" expect "# " puts "End" exit ' echo "*** done. ***"
#!/bin/sh # # mkwebidx # # * namazu Web 検索インデックス更新 # Copyright (c) 1998-2011, isao yasuda, All Rights Reserved. # LANG=ja_JP.eucJP export LANG SRCDIR=/usr/local/www/apache22/data TMPIDX=/tmp/webidx MKNMZRC=/usr/local/etc/namazu/web/mkwebidxrc IDXDIR=/usr/local/var/namazu/index/web MKNMZ=/usr/local/bin/mknmz STAMP=/tmp/webidx/stamp LIST=/tmp/UTF8LIST if [ `whoami` != "root" ]; then echo "Invoke as a superuser, `whoami`." exit fi # 更新ページの抽出 cd $SRCDIR find -L ./*.html ./bbs ./dl ./izhltndoc ./japlit ./lan \ ./oldslav ./profile ./pushkin ./rus2 ./russify ./slavonic \ ./tex ./misima ./cyr ./usconcord ./concordance \ \( -newer $STAMP \) -and \ \( -name "*.html" -or -name "*.shtml" -or -name \ "*.pdf" -or -name "*.txt" \) | \ xargs tar cf - | \ ( cd $TMPIDX; tar xvf - ) # UTF-8 to EUC-JP コード変換 find -L ./*.html ./bbs ./dl ./izhltndoc ./japlit ./lan \ ./oldslav ./profile ./pushkin ./rus2 ./russify ./slavonic \ ./tex ./misima ./cyr ./usconcord ./concordance \ \( -newer $STAMP \) -and \ \( -name "*.html" -or -name "*.shtml" \) | \ xargs grep -H -e "charset=[Uu][Tt][Ff]-8" | \ cut -d : -f 1 > $LIST for i in `cat $LIST` do iconv -c -f UTF-8 -t EUC-JP $i | \ sed 's/charset=[Uu][Tt][Ff]-8/charset=EUC-JP/g' > $TMPIDX/$i done # インデックス更新 $MKNMZ -f $MKNMZRC -a -O $IDXDIR -k $TMPIDX # タイムスタンプの更新 touch $STAMP rm -f $LIST echo "*** done. ***"