torutkのブログ

ソフトウェア・エンジニアのブログ

RedmineとGitを連携させる(認証統合)

第4回shinagawa.redmine勉強会に参加してきた - torutkの日記にて、岡本隆史さんの発表にRedmineとGitの連携(認証統合)がありました。この参加レポートで次のように書いていました。

中央リポジトリRedmineでも、Git利用OKとのことです。Redmine 2.1ではGit認証統合が搭載され、Redmineのロールに基づきリポジトリのread権・write権の制御ができるそうです。この話は知りませんでした。gitoliteでssh鍵を使ってユーザー管理するの大変だなぁと思ってました。なお、設定は、Apacheの設定ファイルにいろいろ記載するようです。Gitリポジトリ名に制約があるようです。

しかし、Gitは軽くさわってみた程度です。Gitサーバーの立て方が未知のままです(gioliteは途中で挫折)。が、意を決して構築してみました。ので、たぶんに試行錯誤が含まれます。

環境は、CentOS 6.3、Redmine 2.2.1、GitとApacheCentOS標準搭載のものです。

RedmineとGitの連携に関する前提条件

ざっと調べてみると、

Gitリポジトリを作成

リモートからはHTTPでアクセスできるようなので、/var/www/html配下に作ってみます*1

以下、Redmineのプロジェクト識別子をmabinogionとします。

# mkdir /var/www/html/gitrepos
# cd /var/www/html/gitrepos
# git init --bare --shared mabinogion.pwyll
HTTPでリード・アクセスするための設定

ここで、リモートのPC(Windows機、TortoiseGit)からアクセスしてみます。
エクスプローラコンテキストメニューから[Gitクローン...]を選び、URLに、http:///gitrepos/mabinogion.pwyll を指定したところ、次のエラーが発生しました。

fatal: http://<Redmine稼動マシン>/gitrepo/mabinogion.pwyll/info/refs?service=git-upload-pack
 not found: did you run git update-server-info on the server?

件のRedmine勉強会でのプレゼン資料「RedmineとGitとスクラム」をよく読むと、「共有リポジトリの作成」ページにHTTPを利用する場合の設定がちゃんと記載されていました。

# cd mabinogion.pwyll
# git update-server-info

複数ユーザーから同時アクセスされたときの排他処理用にフックスクリプトpost-updateを設置します。

# mv hooks/post-update.sample hooks/post-update
  • 勉強会プレゼン資料では.git/hooksというディレクトリになっていましたが、.gitがないので(sharedだから?)、hooksディレクトリを対象にしました。

Apacheでアクセスするのでファイル・ディレクトリの所有者/グループを変更。

# chown -R apache.apache /var/www/html/gitrepos

これで、リモートでcloneできるようになりました。

HTTPでライト・アクセスするための設定

上述の設定は、ApacheでGitリポジトリディレクトリをそのまま静的なコンテンツとして見ているだけなので、リモートで変更した内容をgit pushしようとするとエラーとなります。

error: Cannot access URL http://<Redmine稼動マシン>/gitrepos/mabinogion.pwyll/, return code 22
fatal: git-http-push failed

Gitの場合、WebDAVでライト・アクセスする方法と、CGIでライト・アクセスする方法があるようです。

WebDAV

httpd.confでGitリポジトリディレクトリ(の親ディレクトリ)にDav Onを指定したらgit pushが可能になりました。

<Directory "/var/www/html">
  Dav On
  ...

認証指定してないので匿名アクセスで書き込みできてます。が、WebDAVはあまり推奨ではないようです。

CGI

gitのパッケージに含まれるgit-http-backendを使ってCGIでライトアクセスします。

今回は、このCGIを使って、Redmine認証を行う設定をします。

git-http-backendを使ってRedmine認証をする

勉強会プレゼン資料にある設定を参考に、Apacheの設定ファイルを新規作成します。

PerlLoadModule Apache::Authn::Redmine

SetEnv GIT_PROJECT_ROOT /var/www/html/gitrepos
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /gitrepos/ /usr/libexec/git-core/git-http-backend/

<LocationMatch /gitrepos/>
  PerlAccessHandler Apache::Authn::Redmine::access_handler
  PerlAuthenHandler Apache::Authn::Redmine::authen_handler
  AuthType Basic
  AuthName Git

# for Redmine Authentication
  RedmineDSN "DBI:mysql:database=redmine;host=localhost" 
  RedmineDbUser "redmine" 
  RedmineDbPass "password" 
  RedmineGitSmartHttp yes

  Require valid-user
</LocationMatch>

Redmine認証で使用するPerlのモジュールファイルは、Redmine標準配布に含まれており、/extra/svn/Redmine.pm に提供されています。これを、ApacheからCGIで実行するPerlが検索対象とするパスにおく必要があります。検索対象パスの1つが/etc/httpdなので、その下にパッケージ名に基づき/etc/httpd/Apache/Authn/Redmine.pmとして置きます。

# mkdir -p /etc/httpd/Apache/Authn
# ln -s /var/lib/redmine-2.2.1/extra/svn/Redmine.pm /etc/httpd/Apache/Authn/Redmine.pm

ここで、httpdサービス(Apache)を再起動するとエラーとなります。

# service httpd restart
httpd を停止中:                                            [  OK  ]
httpd を起動中: Syntax error on line 1 of /etc/httpd/conf.d/redmine_git.conf:
Invalid command 'PerlLoadModule', perhaps misspelled or defined by a module not included in the server configuration
                                                           [失敗]

パッケージmod_perlが必要です。

# yum install mod_perl
...
# service httpd start
httpd を起動中: Syntax error on line 1 of /etc/httpd/conf.d/redmine_git.conf:
Can't locate Digest/SHA.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/l
ocal/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/
lib64/perl5 /usr/share/perl5 . /etc/httpd) at /etc/httpd/Apache/Authn/Redmine.pm
 line 188.\nBEGIN failed--compilation aborted at /etc/httpd/Apache/Authn/Redmine
.pm line 188.\nCompilation failed in require at (eval 2) line 3.\n
                                                           [失敗]

パッケージperl-Digest-SHAが必要です。

# yum install perl-Digest-SHA
...

httpd(Apache)は起動できるようになりました。

リモートからgit push

リモートマシンからgit push すると、ユーザー名とパスワードを聞いてきます。

  • Username for 'http://':
  • Password for 'http://<ユーザー名>@':

ここに、Redmineで対象プロジェクトにメンバーとして追加されているユーザー名とパスワードを入れると、Gitリポジトリを更新できるようになります。

注:CentOS 6の標準搭載git 1.7.1は、httpでのBasic認証でユーザー名とパスワードを聞いてこない問題があるようです。手元のCentOS 6環境ではいずれも同じ振る舞いでした。CentOS 6ではgitをバージョンアップした方がよいです。方法は次のURLに記載しています。(2013-01-30追記)

日本語ファイル名を表示する

試しに日本語ファイル名をGitリポジトリにコミットしてみたところ、Redmineリポジトリ表示でファイル名が符号化されて表示されてしまいました。

  • 例:「ソフト構成.txt」というファイル名をリポジトリにコミットしたところ、Redmine上では"\343\202\275\343\203\225\343\203\210\346\247\213\346\210\220.txt"と表示された。

対策は、次を実行

# cd /var/www/html/gitrepos/mabinogion.pwyll
# git config --system core.quotepath false

RedmineLDAP認証しているユーザーをGitで認証するには

追加の設定、Perlモジュールが必要となります。
これについては後日記載予定です。→ 次のURLに記載しました。
http://www.02.246.ne.jp/~torutk/git/githttpserver.html

後日追記

Apache用の設定ファイルに次が必要という記述をいくつかのサイトで見かけました。

SetEnv REMOTE_USER=$REDIRECT_REMOTE_USER

Basic認証をしたユーザーをCGIに伝えるといったことらしいのですが、いまのことろこの設定が不足していることが原因のエラーには会っていないので細部は不明です。

*1:Apache CGIでアクセスするので/var/www/html配下のディレクトリではなくても可です。別ディレクトリとした場合、SELinux有効下ではapacheからアクセスできるよう設定しておく必要があります。