read only な subversion server のchroot環境内への設置。
既にchroot環境を持っているとして、daemontoolsのrunスクリプトを こんな風にした。
#!/bin/sh ulimit -c 0 exec env - \ PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/subversion/bin \ HOME=/svnsrv \ chroot /chroot/svn \ setuidgid svn \ tcpserver -vR -c4 -x/svnsrv/svn.cdb 0 3690 \ softlimit -d10000000 \ recordio svnserve -i -r /svn -R 2>&1
chrootしたあとsvnユーザにスイッチしてからtcpserverを起動。 おきまり。
次、svn+ssh の svn server。これはchrootしてから 起動するsshdを設定すればいいだけなので難しくない。ただ、 svnserveだけを起動できるようにchroot内のアカウント 保持者のログインシェルをこんなシェルスクリプトにする。
#!/bin/sh case "$2" in *svnserve*) exec /usr/local/subversion/bin/svnserve -r /svn -t ;; *) exec /usr/bin/cvs server ;; esac
これは cvs か svnserve しか起動できないようにしているもの。
sshd用の authorized_keys で制限するよりもっと直接的。あとは
各ユーザの ~/.ssh/authorized_keys
に公開鍵を入れ忘れなけれ
ばうまくいくはず。
さて、ポイントはここから。chroot環境内にはmail環境がない。
「ない」というか、chroot用環境で自由にメイルが送れては牢獄化している意味
がないのでMail環境はセットアップしない。そんな環境から
コミットログを送るにはどうしたらいいか。コミット(後)用フックは、
リポジトリのトップディレクトリの hooks/post-commit
に
作ればよい。サンプルがあるので見れば分かる。で、ここでMailコマンドを
使っても送れないのでこうする。
送るべきテキストを一時ファイルに保存する
そのファイル名と送るべき宛先、などを本体(chroot外)環境から 見えるパイプファイルに書き出す。
本体環境ではパイプファイルを読み続けるスクリプトを動かしておき、 一時ファイルと宛先を読み取って、得られた宛先に中味を送る。
例えば、パイプファイルを /chroot/svn/var/run/svnlog
と仮定する。
パイプファイルを作っておく
mkfifo /chroot/svn/var/run/svnlog chown svnlog:comitter /chroot/svn/var/run/svnlog chmod 420 /chroot/svn/var/run/svnlog
ここでsvnlogは本体環境でメイルを送信するユーザ、 comitterはchroot環境内でコミッターが属するグループ。
post-commit
フックスクリプトはこんな感じ。
#!/bin/sh PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/subversion/bin export PATH pipe=/chroot/svn/var/run/svnlog rep=`basename $1` rcpt=svnlog-$rep@example.com i=0 while [ $i -lt 10 ]; do tmpd=/tmp/svnlog-$$.$i mkdir -m 755 $tmpd && break i=`expr $i + 1` done if [ -d $tmpd ]; then tmpf=$tmpd/svnlog (svnlook changed $1; LC_CTYPE=ja_JP.eucJP svnlook info $1 $2) > $tmpf echo $tmpf $rcpt > $pipe (sleep 60; /bin/rm -rf $tmpd) & fi
本体環境でパイプファイルを読み続けてコミットログを送信する
スクリプト(svnlogsend
)。
#!/bin/sh PATH=$PATH:/usr/local/bin; export PATH chroot=/chroot/svn pipe=$chroot/var/run/svnlog while read file rcpt subj; do f=$chroot/$file if [ -s $f ]; then cat $chroot/$file | lv -Oj | Mail -s ${subj:-Commit Log} $rcpt fi done < $pipe
svnlogsend
スクリプトを
daemontoolsで走らせっぱなしにしておけばOK。そのrunスクリプト。
#!/bin/sh exec setuidgid svnlog ./svnlogsend 2>&1
コミットと同時にsvnlogsendが動いてメイルが来る…はず。
こんな感じで名前つきパイプを使うとchroot内でできないようにしてある ことを外から補助できるのでなかなかええ感じ。
叱咤激励感想ツッコミはゲストブックへ
Generated with mkdiary.rb