Mercurialのインストールからsshとhttp(cgi)でリポジトリを読み書きできるようにするまで

debian etchのサーバにMercurialの最新版(1.1.2)をインストールし、リポジトリを公開した際の作業手順です。

思い通りになるまでが想像より面倒くさかったので、メモをまとめてみました。debian lennyやubuntuでも基本的な手順は変わらないと思います。

リポジトリsshとhttp(cgi)の双方から読み書きできるように設定します。Apacheリポジトリの所有者と異なるwww-data:www-dataで動作している状態を想定しています。本当はmod_userdirやsuEXECを使えば簡単なのかも知れません。

参考にしたウェブサイトは最後の参考リンクとしてまとめました。詳しくはリンク先や公式ドキュメントを参照して下さい。

ダウンロードと展開

debianリポジトリにあるのは古いので最新版をダウンロードした方が良いです。適当にtarボールを展開します。

wget http://www.selenic.com/mercurial/release/mercurial-1.1.2.tar.gz
tar zxvf mercurial-1.1.2.tar.gz

ビルドとインストール

MakefileはPREFIX=/usr/localとなっていたので、そのままmake installしてしまいます。必要であればPREFIXなどを自分の好きなように設定しましょう。

cd mercurial-1.1.2
make install

ビルドには恐らく以下のパッケージを入れておけば大丈夫だと思います。

apt-get install build-essential python-dev

/usr/local/binにパスが通っていればhgコマンドでバージョンが確認できます。

hg --version

リポジトリの作成と共有設定

ユーザ作成

Webとssh両方から叩くためにユーザとグループ(ここではhg:hg)を作成してしまいます。実際にはグループだけでも良いですが、わかりやすくユーザとグループを作ります。本来はここで公開鍵の設定をした方が良いと思いますが、割愛します。

useradd -m hg
passwd hg
リポジトリ作成

hgユーザになって適当なディレクトリ(/home/hg/repos)でリポジトリを作ります。

mkdir repos
cd repos
hg init

リポジトリの設定ファイルhgrc(/home/hg/repos/.hg/hgrc)でWebアクセスの許可を設定します。

[web]
push_ssl = false
allow_push = *
パーミッション設定

www-dataとの共有のためファイルとディレクトリにグループでの書き込み権限を与えます。また.hg、.hg/store、.hg/store/dataにはsetgidビットを付けてグループが引き継がれるようにします。

chmod g+w .hg .hg/* .hg/store/*
chmod g+s .hg .hg/store .hg/store/data

グループ設定

リポジトリに書き込み権限を与えるため、Apacheの実行ユーザwww-dataをhgグループに参加させておきます。

gpasswd -a www-data hg

Apacheの設定

CGIの設定

hgweb.cgi設置先のディレクトリ(ここでは/var/www/hg)でCGIを実行できるように設定します。AllowOverrideが使えるなら.htaccessで設定しても良いです。ScriptAliasの方が筋なような気もしますが、ここでは扱いません。アクセス制限をするなら、ここで必要に応じてBasic認証をかけます。

<Directory /var/www/hg>
    Options +ExecCGI
    AddHandler cgi-script .cgi
    Order allow,deny
    Allow from all
</Directory>
hgrcの作成

ApacheのためのMercurial設定を記述するhgrcファイルを作っておきます。とはいえApacheにはホームディレクトリはないのが一般的だと思います。

ここでは/etc/apache2/hgrcというファイルとして置くことにします。所有者はwww-data:www-dataでパーミッションは444あたりが無難です。

hgrcではhg:hgを信頼するよう設定します。

[trusted]
users = hg
groups = hg

後述するhgweb.cgiでこのhgrcを使うよう設定をしないと、ユーザと所有者の異なるhgrcは信頼できないというエラーが発生して動作しません(以下)。

Not trusting file /home/hg/repos/.hg/hgrc from untrusted user hg, group hg

hgweb.cgiの設置

hgweb.cgiのコピー

hgweb.cgiMercurialのtarボールを展開した中に入っています。Apacheのhtdocs以下の適当な場所にhgweb.cgiをコピーします。名前はindex.cgiとするとDirectoryIndexになって都合が良いかも知れません。

cp hgweb.cgi /var/www/hg/index.cgi
hgweb.cgiの修正

hgweb.cgiは以下のように変更しました。

  • import sysのコメントアウトを外して、次の行でmercurialがインストールされたパスを設定します。
    • 環境やインストールの方法によってパスは異なります、インストール先をきちんと確認しましょう。
  • import osのコメントアウトを外して、次の行は必要に応じてUTF-8を使うよう設定します。
  • HGRCPATHにApacheのために用意したhgrcファイルのパスを指定するよう行を追加します。
  • 最後の方の行でhgwebで扱うリポジトリと名前を指定します。
#!/usr/bin/env python
#
# An example CGI script to use hgweb, edit as necessary

# adjust python path if not a system-wide install:
import sys
sys.path.insert(0, "/usr/local/lib/python2.4/site-packages/")

# enable importing on demand to reduce startup time
from mercurial import demandimport; demandimport.enable()

# Uncomment to send python tracebacks to the browser if an error occurs:
#import cgitb
#cgitb.enable()

# If you'd like to serve pages with UTF-8 instead of your default
# locale charset, you can do so by uncommenting the following lines.
# Note that this will cause your .hgrc files to be interpreted in
# UTF-8 and all your repo files to be displayed using UTF-8.
#
import os
os.environ["HGENCODING"] = "UTF-8"
os.environ["HGRCPATH"] = "/etc/apache2/hgrc"

from mercurial.hgweb.hgweb_mod import hgweb
import mercurial.hgweb.wsgicgi as wsgicgi

application = hgweb("/home/hg/repos", "test repos")
wsgicgi.launch(application)


オリジナルのhgweb.cgiとの差分は以下です。

6,7c6,7
< #import sys
< #sys.path.insert(0, "/path/to/python/lib")
---
> import sys
> sys.path.insert(0, "/usr/local/lib/python2.4/site-packages/")
21,22c21,23
< #import os
< #os.environ["HGENCODING"] = "UTF-8"
---
> import os
> os.environ["HGENCODING"] = "UTF-8"
> os.environ["HGRCPATH"] = "/etc/apache2/hgrc"
27c28
< application = hgweb("/path/to/repo", "repository name")
---
> application = hgweb("/home/hg/repos", "test repos")

おわり

以上で設定は完了です。それぞれ以下のURLを指定して、リポジトリにアクセスできます。

僕の環境ではssh/httpでのclone/pushと、別の方でcommitしたファイルの変更とpushまで、きちんと動作しています。

公式のwikiにあるようにumaskを002に設定する必要があると思ったのですが、設定しなくてもファイルシステム上ではumask 002のように振る舞っていて、特に問題が出ていません。若干気にかかるところです。