以前、WindowsでRhodeCode という記事を書いたのですが、古くなりすぎて今では間違いだらけだし、最近またセットアップする機会があったので改めて手順をまとめておきます。
RhodeCode と Kallithea
RhodeCodeおよびKallitheaは、Git/Mercurial両対応のGitHubライクなアプリケーションです。
GitHub Issues相当の機能はありませんが、それ以外はPull Request、オンラインレビュー、Gistなどだいたい一通りの機能がそろっています。
RhodeCodeはもともとGPLv3下で開発されていたのですが、2.0からRhodeCode Enterpriseになり、条件によっては有償になりました。
かわりにRhodeCodeからForkされてGPLv3下で開発を継続しているのがKallitheaです。
今回はこのKallitheaのセットアップを行います。
前提条件とか
- アクセスするのは25人くらい。
- 既存の環境はできる限り汚したくない。
- リポジトリ内のファイルはUTF8とshift_jisが混在している。
- 今のところ日本語パスはないけど、一応日本語パスでも問題ないようにしておきたい。
- クライアントはすべてWindows。
- 外部からのアクセスはApacheでリバースプロキシを設定する。
- 認証はApache側で。
- Windowsサービス化する。
Python環境の準備
残念ながらまだPython3には対応していないので、Python 2.7(2015.4現在の最新は2.7.9)をインストールします。
また、拡張モジュールのビルドのために、Microsoft Visual C++ Compiler for Python 2.7 もインストールしておきます。
Kallitheaはvirtualenv環境下にインストールしたいので、virtualenvもインストールしておきます。
> pip install virtualenv
virtualenv環境の作成とモジュールのインストール
こんな感じで適当にディレクトリを作成します。
C:\Kallithea
├ HOME ・・・config、dbなどを配置するディレクトリ
├ kallithea.sys ・・・Pythonのモジュール類をインストールするディレクトリ(virtualenv)
└ repos ・・・Git/Mercurialのリポジトリを配置するディレクトリ
Kallithea用のvirtualenvを作成してアクティブにします。
> cd C:\Kallithea\kallithea.sys
> virtualenv .
> Script\activate
pip install kallithea
で、基本的に必要なモジュールはすべてインストールされます。
RhodeCode 1.xの頃は追加で chardet
をインストールしないとnon-asciiなファイルがうまく表示されなかったのですが、今でもそうなのかどうかは未確認なので一応それも入れておきます。
また、メンテナンス用のインタラクティブシェルを動かすために ipython
が必要なのでこれも。
> pip install kallithea chardet ipython
Lib\site-packages\sitecustomize.py を作成して、必要な環境変数の設定をしておきます。
import os
os.environ["HOME"] = 'C:/Kallithea/HOME'
os.environ["HGENCODING"] = 'cp932'
os.environ["PYTHON_EGG_CACHE"] = 'C:/Kallithea/.egg-cache'
Kallitheaのインスタンスの作成
HOMEに移動して、 paster make-config
と paster setup-db
でKallitheaのインスタンスを作成します。
> cd C:\Kallithea\HOME
> paster make-config Kallithea kallithea.ini
> paster setup-db kallithea.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:\Kallithea\repos
Specify admin username: iwata
Specify admin password (min 6 chars): ****
Confirm password: ****
Specify admin email: iwata@example.local
この段階で paster serve kallithea.ini
を実行して、ブラウザから http://localhost:5000
にアクセスすると、こんな感じで動いていることを確認できます。
IEで正しく表示されない場合は、とりあえず「イントラネットサイトを互換表示で表示する」設定をOFFにすると解決するかもしれません。
Windowsサービスにする
ここ からpywin32のインストーラをダウンロードして、easy_installでインストールします。
http serverはcherrypyのものを使うことにしてそれもpipでインストール。
> easy_install py2in32-xxx.xxx-py2.7.exe
> pip install cherrypy
こんな感じのスクリプトを用意して、
import os
import win32serviceutil
import cherrypy
def make_kallithea_app():
from paste.deploy import loadapp
return loadapp("config:kallithea.ini",
relative_to=os.path.dirname(__file__))
class KallitheaService(win32serviceutil.ServiceFramework):
_svc_name_ = "Kallithea"
_svc_display_name_ = "Kallithea service"
_svc_description_ = "Kallithea service"
def SvcDoRun(self):
cherrypy.config.update({'service.socket_port': 5000})
cherrypy.tree.graft(make_kallithea_app(), '/')
cherrypy.engine.start()
cherrypy.engine.block()
def SvcStop(self):
cherrypy.engine.exit()
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(KallitheaService)
こんな感じにインストール
> python service.py install
リバースプロキシと認証
フロントのApacheで認証して、Kallitheaにリバースプロキシするための設定をします。
この辺りRhodeCode 1.xの頃とは完全に別物ですね。
Kallithea側の設定
Admin -> Authenticationから、まずは kallithea.lib.auth_modules.auth_container
を enabled にして、save します。
話はそれるけどこの手のGUI、今の状態がenabledという意味なのか、クリックするとenabledになるという意味なのか分かりづらくてどうなんという感じ。
するとcontainer Authenticationプラグインの設定をするパネルが追加されるので、さらに Enabledにチェックを入れてもう一度save。
認証の設定をWEBからできるの便利なんですが、設定を間違えると「缶詰の中に缶切り」状態になって困ったことになるので注意。
Apache側の設定
Apache側でも、適当に認証とProxyの設定を。RewriteでREMOTE_USERの値をX-Forwarded-Userに設定してリクエストを転送するようにします。
ついでにヘッダにX-UA-Compatible="IE=Edge"を追加して、「イントラネットサイトを互換表示で表示する」設定のON/OFFにかかわらずIEで表示できるように。
<Location /kallithea>
SetEnvIf X-Url-Scheme https HTTPS=1
ProxyPass http://127.0.0.1:5000
ProxyPassReverse http://127.0.0.1:5000
AuthType Digest
AuthName "Login to Kallithea"
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
Header set X-UA-Compatible: IE=Edge
</Location>
ユーザの登録
さて、RhodeCode 1.xの頃はApache(もしくはその他のコンテナ)で認証する場合もRhodeCode側でユーザを作っておく必要があったのですが、今はApache側で認証した時点で自動的にユーザが登録されます。
逆に、Kallithea側でユーザを作ってしまうと、同じ名前のアカウントがコンテナ側にあってもコンテナ認証はできません。(コンテナで認証した後、もう一度Kallitheaのログイン画面での認証を求められる)
なので、
-
http://localhost/kallithea
にアクセスして(コンテナ認証になる)、Admin権限を付与したいユーザIDでApacheにログインする -
http://localhost:5000
にアクセスして(Kallithea認証になる)、setup-db時に作ったAdminユーザでログインし、今作ったユーザにAdmin権限を付与する
という手順で、コンテナ認証できるAdminユーザを一つ作っておくといいと思います。
ここまででとりあえずセットアップ完了。
(おまけ)困った時のはなし
認証の設定まちがえると困ったことになるという話をしました。
そういう場合はインタラクティブシェルからデータを修復する必要があります。(多分。他の手があるかもしれないけど。)
ishellコマンドでipythonベースのインタラクティブシェルを起動できるので、
> paster ishell kallithea.ini
認証の設定をデフォルトに戻すならこんな感じのスクリプトを実行します。
for k, v in (('auth_plugins', u'kallithea.lib.auth_modules.auth_internal'),
('auth_internal_enabled', False)):
Session().add(Setting.create_or_update(k, v))
Session().commit()
他にも、指定のユーザにAdmin権限をつけたり
u = User.get_by_username('iwata')
u.admin = True
Session().add(u)
Session().commit()
Kallitheaで登録したユーザをコンテナ認証できるようにに変えたり
u = User.get_by_username('iwata')
u.extern_type = u'container'
u.extern_name = u'iwata'
Session().add(u)
Session().commit()
色々。もちろんAt your own riskですが。