svn server その1

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 server その2

次、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コマンドを 使っても送れないのでこうする。

  1. 送るべきテキストを一時ファイルに保存する

  2. そのファイル名と送るべき宛先、などを本体(chroot外)環境から 見えるパイプファイルに書き出す。

  3. 本体環境ではパイプファイルを読み続けるスクリプトを動かしておき、 一時ファイルと宛先を読み取って、得られた宛先に中味を送る。

例えば、パイプファイルを /chroot/svn/var/run/svnlog と仮定する。

  1. パイプファイルを作っておく

    mkfifo /chroot/svn/var/run/svnlog
    chown svnlog:comitter /chroot/svn/var/run/svnlog
    chmod 420 /chroot/svn/var/run/svnlog
    

    ここでsvnlogは本体環境でメイルを送信するユーザ、 comitterはchroot環境内でコミッターが属するグループ。

  2. 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
    
  3. 本体環境でパイプファイルを読み続けてコミットログを送信する スクリプト(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
    
  4. svnlogsendスクリプトを daemontoolsで走らせっぱなしにしておけばOK。そのrunスクリプト。

    #!/bin/sh
    exec setuidgid svnlog ./svnlogsend 2>&1
    

コミットと同時にsvnlogsendが動いてメイルが来る…はず。

こんな感じで名前つきパイプを使うとchroot内でできないようにしてある ことを外から補助できるのでなかなかええ感じ。


叱咤激励感想ツッコミはゲストブック

Generated with mkdiary.rb
yuuji@example.org
Fingerprint16 = FF F9 FF CC E0 FE 5C F7 19 97 28 24 EC 5D 39 BA
HIROSE Yuuji - ASTROLOGY / BIKE / EPO / GUEST BOOK / YaTeX [Tweet]