2015.4.21 WindowsでKallitheaを動かす の方に現時点でのセットアップ手順をまとめました。
Mercurial Advent Calender 22日目のエントリです。
RhodeCodeというのは、MercurialとGitに対応したGitHubライクなリポジトリブラウザ(hg serve相当のサーバ機能もあり)な訳ですが、このRhodeCodeをWindowsで動かした時の手順とか設定とかの話です。
基本的には ここ に書いてある通りなんですが。
前提条件とか
- アクセスするのは25人くらい。
- 既存の環境はできる限り汚したくない。
- リポジトリ内のファイルはUTF8とshift_jisが混在している。
- 今のところ日本語パスはないけど、一応日本語パスでも問題ないようにしておきたい。
- クライアントはすべてWindows。
- RhodeCodeとTracを同じポートで動かして、外からのアクセスはApacheでリバースプロキシを設定する。
- 認証はApache側で。
- Windowsサービス化する。
virtualenv環境の準備
既存の環境に影響が出ないように、すべてvirtualenv内にインストールするようにします。
C:\.virtualenvs>virtualenv galahad
C:\.virtualenvs>cd galahad
C:\.virtualenvs\galahad>Script\activate.bat
virtualenv内だけで有効な環境変数を設定するために、Lib\site-packages\sitecustomize.py を作成します。
Windows環境下で日本語パスをちゃんと扱うには HGENCODING = cp932
としておく必要があるのと、RhodeCode用に個別のhgrcを読み込ませるために HOME
を設定しています。
import os
os.environ["HGENCODING"] = "cp932"
os.environ["HOME"] = "C:/.virtualenvs/garahad/HOME"
os.environ["PYTHON_EGG_CACHE"] = "C:/.virtualenvs/garahad/.egg-cache"
モジュールのインストール
インストール自体は pip install rhodecode
でほぼ終わり。
non-asciiなファイルを扱うには追加で chardet が必要なのでそれも一緒に。
(galahad)C:\.virtualenvs\galahad>pip install rhodecode
(galahad)C:\.virtualenvs\galahad>pip install chardet
サービス化するために、Python win32 extensionが必要になりますが、これはpypiにはないのでここからインストーラをダウンロードして、 easy_install
でvirtualenvにインストールします。
http://sourceforge.net/projects/pywin32/files/pywin32/Build%20218/
(galahad)C:\.virtualenvs\galahad>easy_install pywin32-218.win32-py2.7.exe
ちなみに、Mercurialをvirtualenv環境下にインストールするとそのままではhgコマンドが動かないので、 Script\hg.bat
を少し修正しておきましょう。
@@ -8,5 +8,5 @@
rem install does not put python.exe on the PATH...
rem %~dp0 is the directory of this script
-"%~dp0..\python" "%~dp0hg" %*
+"%~dp0python" "%~dp0hg" %*
endlocal
RhodeCode環境の構築
paster make-config
と paster setup-rhodecode
で、環境を構築します。
アクセスするのが高々25人程度ということで、とりあえずsqliteのままで。
(galahad)C:\.virtualenvs\galahad>mkdir repositories
(galahad)C:\.virtualenvs\galahad>mkdir environ && cd environ
(galahad)C:\.virtualenvs\galahad\environ>paster make-config RhodeCode rhodecode.ini
(galahad)C:\.virtualenvs\galahad\environ>paster setup-rhodecode rhodecode.ini
...
Are you sure to destroy old database ? [y/n] y
...
Enter a valid absolute path to store repositories. All repositories in that path
will be added automatically: C:\.virtualenvs\garahad\repositories
...
Specify admin username:iwata
...
Specify admin password (min 6 chars):XXXXXX
Confirm password:XXXXXX
...
Specify admin email:iwata@dummy.local
...
ここでいったん、ちゃんと動くかどうか確認します。
(galahad)C:\.virtualenvs\galahad\environ>paster serve rhodecode.ini
日本語パスのための設定
日本語パスを扱うために、以下の設定が必要です。
-
win32mbcs エクステンションをインストールする
RhodeCode環境にもwin32mbcsエクステンションが必要になります。
適当な場所に win32mbcs.py を置いて、$HOME\hgrc
に記述してください。 -
default_encodingの設定
RhodeCodeのコンフィグファイル内で、default_encoding = cp932
に設定します。
[app:main]
use = egg:rhodecode
# 中略
default_encoding = cp932
日本語(というかnon-ascii文字)を含むファイルについては、基本的に chardet がよろしく処理してくれるのであまり気にする必要はありません。
cp932でもUTF8でも特に問題は無いと思います。
サービス化
とりあえず、wsgi applicationにします。
import os
home = os.path.dirname(__file__)
CONFIG_FILE = os.path.join(home, 'rhodecode.ini')
from paste.deploy import loadapp
from paste.script.util.logging_config import fileConfig
fileConfig(CONFIG_FILE)
application = loadapp("config:" + CONFIG_FILE)
あとはこれを mod_wsgiでApacheに載せればいいんですが、今回は先住民との住み分けの問題でApacheに直接載せられないので、スタンドアロンなサービスにしてApacheからリバースプロキシすることにします。
~/galahad/hg => RhodeCode
~/galahad/trac => Trac
という形でリバースプロキシ設定する予定なので、設定を簡単にするためにこっち側でも同じようにURLをマップしておきます。
で、サービスとして動かすために作ったのが以下のスクリプトです。
import win32serviceutil
from cherrypy.wsgiserver import WSGIPathInfoDispatcher, CherryPyWSGIServer
class Galahad(win32serviceutil.ServiceFramework):
_svc_name_ = "Galahad"
_svc_display_name_ = "Galahad Service"
_svc_description_ = "Finally, I have long-cherished Ice-sword."
_svc_deps_ = None
server = None
def SvcDoRun(self):
"""サービス開始"""
from rhodecodeapp import application as rhodecode_app
# tracapp.py についての説明は省略
from tracapp import application as trac_app
# Routingの設定
dispatcher = WSGIPathInfoDispatcher({
"/galahad/hg": rhodecode_app,
"/galahad/trac": trac_app,
})
self.server = CherryPyWSGIServer(('127.0.0.1', 5000), dispatcher)
self.server.start()
def SvcStop(self):
"""サービス終了"""
if self.server:
self.server.stop()
if __name__ == "__main__":
win32serviceutil.HandleCommandLine(Galahad)
このへん を参考にしました。
取り回しの簡単そうなCherryPyを使うことにしましたが、Werkzeug(何回見てもスペルが憶えられないw)とかでもよかったかも知れません。
※Windowsの場合、こういうときに手っ取り早くwsgiサーバを建てたいと思ったら何を使うのがいいんですかね?
サービスのインストールは以下のコマンドです
(galahad)C:\.virtualenvs\galahad\environ>python service.py install
デフォルトの設定だと標準エラー出力にログメッセージが流れるようになっていますが、サービス化すると標準エラー出力が無くてBad File Descriptorになってしまうので、ファイルに出力するように設定を変えておきます。
##############
## HANDLERS ##
##############
[handler_console]
class = handlers.RotatingFileHandler
args = ('C:/.virtualenvs/galahad/environ/log/service.log', 'a', 10000)
level = INFO
formatter = generic
[handler_console_sql]
class = handlers.RotatingFileHandler
args = ('C:/.virtualenvs/galahad/environ/log/service.log', 'a', 10000)
level = WARN
formatter = generic
リバースプロキシと認証
ここ の記述に従って、Apache側で、リバースプロキシと認証の設定を行います。
REMOTE_USERをX-FORWARDED-USERに乗せ替えて飛ばしている訳ですね。
<Location /galahad>
SetEnvIf X-Url-Scheme https HTTPS=1
ProxyPass http://127.0.0.1:5000/galahad
ProxyPassReverse http://127.0.0.1:5000/galahad
AuthType Digest
AuthName "Login to Galahad"
AuthDigestProvider file
AuthUserFile /path/to/digest/file
BrowserMatch "MSIE|Chrome" AuthDigestEnableQueryStringHack=On
Require valid-user
RequestHeader unset X-Forwarded-User
RewriteEngine On
RewriteCond %{LA-U:REMOTE_USER} (.+)
RewriteRule .* - [E=RU:%1]
RequestHeader set X-Forwarded-User %{RU}e
</Location>
RhodeCode側の設定は以下のようになります。上のURLの記述からは分かりづらいですが、Proxy-Passthroughモードで動かすときは container_auth_enabled
と proxypass_auth_enabled
の両方を true に設定する必要があるようです。
[app:main]
use = egg:rhodecode
# 中略
container_auth_enabled = true
proxypass_auth_enabled = true
これで晴れてRhodeCodeが動くようになりました。
リポジトリの作成と clone
、push
、pull
がちゃんと動くことを確認して〆。
いろいろ
Tracと共存させてみたところ、TracのURLに一度でもアクセスするとRhodeCodeがInternal Errorを返すようになるという現象がありました。
調べてみたところ、Tracが内部的に locale.setlocale
を実行しているのが問題らしく、Trac側で trac.locale = English
を設定することで回避。
RhodeCode上で、ファイルに対してshow as raw
やdownload as raw
を実行すると、cp932のファイルであってもUTF8で返されるみたいです。さすがに download as zip
はそんなことないので大した問題ではないですが。
まとめのようなそうでもないような
RhodeCodeは細かいところまでよく出来てて、開発のモチベーションが上がりますね。
別にPull Request運用をする訳じゃないって所でも(うちもそうです)、Mercurial使うならセットアップして損はないんじゃないでしょうか。
でもまあ、こういうのはLinux系の方が楽ですねえ。