redmineの最近のブログ記事
UMLその他モデルの作図にJudeを愛用している。
・・・というかastah*か。
astah*で書いた図を、emfで(拡大縮小しても綺麗だから)ワードに張り付けるなどしているが、redmineのwikiに埋め込めるといいのにな~と思っていた。
もちろん画像で出力してからアップロードすることはできるが面倒。
せっかくリポジトリにastahのファイルを保管しているのだから、最新の図をwikiに自動反映できたら便利そう。
最近知ったのだけど、PlantUMLというのがあって、一定の記法で書いたUMLを画像にしてくれるOSSがあるそうだ。じゃあ、astah APIでモデルの情報を抜き出してPlantUML記法で吐きだしたらどうか?と一瞬考えたものの、レンダリング結果がastah上の図とはかなり変わってしまうし、APIで取得できない情報が多数あるのでそもそも再現度が低い。
やはり図の出力はastah*に任せたい。
jude時代から、コマンドラインで図出力を実行することができるので、これを呼び出したらいいだろう。
※細かいことは、インストール先のCommandRunner.htmlに書いてある。
自分ところで使っているredmineはどれもlinux上で動いているので、できればlinuxサーバで完結させたい。ということでまずは「linux上でコマンドラインで図出力」する手順を検討した。
ポイントは以下のとおり。
- コマンドライン図出力を実行するには、DISPLAY(Xサーバ)が必要。
- APIの場合はXサーバなしでも動くけど、図出力はdisplayが初期化できないと先に進まない。
- 図出力用のディスプレイという位置づけで、vncserverを使うことにした。
- astahライセンスをセットアップする必要がある
1. ディスプレイを用意
- 図出力を実行するユーザ向けにvncserverのディスプレイを作る。
- CentOSの場合、yumリポジトリにvnc-serverがあるのでこれをインストール。
- 実行ユーザで一回vncserverを起動しておく。
- 各種ファイルのひな型が作成されるのと、vncserverのパスワード設定を一度に出来るから。
% vncserver
You will require a password to access your desktops.
Password:
Verify:
New 'somehost:1 (someuser)' desktop is host:1
Creating default startup script /home/someuser/.vnc/xstartup
Starting applications specified in /home/someuser/.vnc/xstartup
Log file is /home/someuser/.vnc/somehost:1.log - 上で起動したvncserverはkillしちゃう。
で、ひな型をちょこっと編集。CentOSの場合、xstartupは以下の内容になっていた。
twmが動いていると、Xクライアントがウィンドウを作成するときに出現位置をユーザ操作で指定する流れになるので、図出力の自動化においては邪魔になってしまう。ので、twmの行を削除した。xtermも特に必要ないので削除。#!/bin/sh
# Uncomment the following two lines for normal desktop:
# unset SESSION_MANAGER
# exec /etc/X11/xinit/xinitrc
[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources
xsetroot -solid grey
vncconfig -iconic &
#xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &
#twm &
- システム起動時の自動起動を考慮して/etc/sysconfig/vncserverに設定
図出力を実行するユーザに合わせて編集。とりあえずディスプレイ番号は2のままにした。ジオメトリはもっと小さくてもいいはず。VNCSERVERS="2:someuser"
VNCSERVERARGS[2]="-geometry 800x600 -nohttpd -localhost"
- rootでrcスクリプトから起動
# /etc/init.d/vncserver start
- astah*のダウンロードサイトからzipを入手。「JREなし、インストーラなしのアーカイブ」と書かれているもの。
- 適当な場所にunzipする。
- 同梱されているastah-command.shは後半がちょいおかしい(pro 6.1.1)ので、ちびっと修正して、とりあえず同じディレクトリに「run.sh」という名前で保存した。実行権限を忘れない。
#!/bin/sh
ASTAH_HOME=`cd \`dirname $0\` && pwd`
INITIAL_HEAP_SIZE=64m
MAXIMUM_HEAP_SIZE=1024m
STACK_SIZE=3m
JAVA_OPTS="-Xms$INITIAL_HEAP_SIZE -Xmx$MAXIMUM_HEAP_SIZE -Xss$STACK_SIZE"
java $JAVA_OPTS -cp "$ASTAH_HOME/astah-pro.jar" com.change_vision.jude.cmdline.JudeCommandRunner $* - ライセンスを配置。
自分ところはJUDEのユーザライセンスがサポート時効前なのでJUDEのライセンスで。
$HOME/.astah/professional/JUDE_License_User_Professional.xml
- path上にjavaコマンドがあることを確認。なければ適宜pathを通す。
- 環境変数DISPLAYにvncserverを指定。
自分はtcshスキーなので以下の通りだが、他のシェルの場合は適宜% setenv DISPLAY 127.0.0.1:2
- 実行
% /path/to/astah/run.sh -image all -f /path/to/some.asta -o /path/to/dir
おわり
- で、出力されたのが冒頭のpng画像。
- Windowsで出力したときとフォントが異なるので、見た目の違いはあるけど、元の図がキープされていることに意義はありそう。
- 元の図が大きくなりがちなので、wikiに張り付けるのに向かないケースも多そう。
- 図出力にはかなり時間がかかる&出力したい図を指定できない(種類は指定出来る)ので、運用上はcronで出力しておいてどーこーみたいな仕組みも必要っぽい。
- wikiマクロ的には、.astaファイルと図のpath(名前空間+名前)を指定する感じか。
環境:
Windows 7 Ultimate x64
JRE6 x86
astah* professional 6.1.1
CentOS 5.4 x64
vnc-server-4.1.2-14.el5_3.1
JRE6 x64
astah* professional 6.1.1
Wiki Graphviz macro プラグイン
例によって無保証です。
自分ところのredmineはまだ0.8.7なんだけど、早食いな人はもう0.9を使っているらしく、0.9で動かないよ、というメッセージが来た。
せっせと自分のところでも環境を作って試してみると「Filter chain halted as [:authorize] rendered_or_redirected.」が出ている。
リンクの作り方がまずいと言えばまずいんだけど、0.8.x時代のWikiのURLと0.9からのURLが異なることが原因みたい。
どうもプラグインROOT/config/routes.rbに置かないと読んでくれないっぽい。
0.8系でも0.9系でも動くように二か所にroutes.rbを置くことにした。
プラグインROOT/
routes.rb ←(1):こっちは(2)をrequireするだけ
config/
routes.rb ←(2):redmineが0.9以降かどうかでURLマップを設定しわける
(1)
(2)
0.9もfeature freezeしたことだしリリースが待ち遠しい。
「バージョンに状態(進行中、ロック中、終了)を設定出来て、チケットの編集画面に終了済みバージョンがドロップダウンに表示されない」機能が地味にうれしい。
環境:
CentOS 5.4
ruby-1.8.7-p248(from source)
mysql-server-5.0.77-3.el5
graphviz-2.26.0(from source)
redmine-0.9-stable branch at 2010/01/07(JST)
例によって無保証です。
redmineの wikiマクロで graphviz その1上のwikiマクロをgihubに置いている。
redmineの wikiマクロで graphviz その2
redmineの wikiマクロで graphviz その3
tckz's redmine-wiki_graphviz_plugin at master - GitHub
自分ところのredmineはまだ0.8.7なんだけど、早食いな人はもう0.9を使っているらしく、0.9で動かないよ、というメッセージが来た。
せっせと自分のところでも環境を作って試してみると「Filter chain halted as [:authorize] rendered_or_redirected.」が出ている。
リンクの作り方がまずいと言えばまずいんだけど、0.8.x時代のWikiのURLと0.9からのURLが異なることが原因みたい。
0.8.7: http://example.com/wiki/project_id/WikiPageそれでは、とroutes.rbを書き換えてみるも反応なし。
0.9-stableブランチ: http://example.com/projects/project_id/wiki/WikiPage
どうもプラグインROOT/config/routes.rbに置かないと読んでくれないっぽい。
0.8系でも0.9系でも動くように二か所にroutes.rbを置くことにした。
プラグインROOT/
routes.rb ←(1):こっちは(2)をrequireするだけ
config/
routes.rb ←(2):redmineが0.9以降かどうかでURLマップを設定しわける
(1)
require File.join(File.dirname(__FILE__), "config", "routes.rb")
(2)
ActionController::Routing::Routes.draw do |map|
if (Redmine::VERSION.to_a <=> [0, 9, 0]) >= 0
# 0.9.0 or higher
map.connect 'projects/:id/wiki/:page/graphviz', :controller => 'wiki_graphviz', :action => 'graphviz'
else
map.connect 'wiki/:id/:page/graphviz', :controller => 'wiki_graphviz', :action => 'graphviz'
end
end
0.9もfeature freezeしたことだしリリースが待ち遠しい。
「バージョンに状態(進行中、ロック中、終了)を設定出来て、チケットの編集画面に終了済みバージョンがドロップダウンに表示されない」機能が地味にうれしい。
環境:
CentOS 5.4
ruby-1.8.7-p248(from source)
mysql-server-5.0.77-3.el5
graphviz-2.26.0(from source)
redmine-0.9-stable branch at 2010/01/07(JST)
Wiki Graphviz macro プラグイン
例によって無保証です。
説明はその2の方に。
今回はハマったことというか知ったこととか。
以下、redmine-0.8.0RC1前提で。
redmineのwikiマクロに関して
redmineプラグインに関して
プラグイン設定関係
Railsに関して
※redmine-0.8.0RC1同梱のもの。2.1?
キャッシュ関係
例によって無保証です。
説明はその2の方に。
今回はハマったことというか知ったこととか。
以下、redmine-0.8.0RC1前提で。
redmineのwikiマクロに関して
- ・{{macro_list}}マクロがデフォルトで入っていて、使えるマクロの一覧を表示できる。知らんかった。。
- マクロ名と登録時に「desc」で指定した内容が表示される
- {{include(Foo)}}マクロがデフォルトで入っていて、別ページをincludeできる。知らんかった。。
- wikiマクロの登録は、Redmine::WikiFormatting::Macros.registerにブロックを渡す。
- descにはwiki記法が使えるが、今にして思えばtextile以外のフォーマッタを使っている場合にマズイか・・・。
Redmine::WikiFormatting::Macros.register do
desc <<'EOF'
Render graph image from the wiki page which is specified by macro-args.
!{{graphviz(Foo)}}
!{{graphviz(option=value...,Foo)}}
* options are:
** format={png|jpg}
** layout={dot|neato|fdp|twopi|circo}
** target={_blank|any}
** with_source
EOF
macro :graphviz do |wiki_content_obj, args|
(略)
- マクロ本体はmacroにシンボルとブロックを指定する
- ブロックの引数はWikiContentモデルとマクロの引数に指定した文字列を「,」で分割したArray
- {{マクロ(引数)}}
- wiki中の{{マクロ}}の都度ブロックが呼び出される
- ブロックが返した文字列がマクロ展開後のHTMLとして出力される。
nilを返すと元のマクロ記述がそのまま表示される - プレビュー時、ブロックが呼び出されたときに「プレビュー中のテキスト」を得られない
- graphviz_meマクロで編集/プレビューしながら図を確認できたら便利だよなぁと思ったら渡ってくるのは保存済みのWikiContentモデルだった。
- 新しいwikiページをプレビューするとobjにはnilが渡ってくる
- ブロックはActionView::Baseのインスタンスから呼び出される
- ブロック内でself.to_sしたら"#<ActionView::Base:0xxxxxxxxx>"だった
- なのでself.controllerからキャッシュメソッドを呼び出したり出来る
- graphvizマクロの場合、マクロ展開時(Viewのコンテキスト)、画像表示時(コントローラのコンテキスト)のコードをできるだけ共有したかったので都合がよかった
- ブロックから例外を飛ばすとwikiビュー内にエラー表示できる
Error executing the マクロ名 macro (メッセージ)
redmineプラグインに関して
- プラグインROOTのinit.rbで登録すると利用可能になる
Redmine::Plugin.register :wiki_graphviz_plugin do
- プラグイン固有のコントローラのrouteはプラグインROOTのroutes.rbで追加定義できる
connect 'wiki/:id/:page/graphviz', :controller => 'wiki_graphviz', :action => 'graphviz'
プラグイン設定関係
- 管理→プラグイン→(プラグインごとの)設定で表示されるプラグイン設定画面
- Redmine::Plugin.register時に、settingsで:partialに指定した設定画面を表示できる。
settings :default => {'cache_seconds' => '0'}, :partial => 'wiki_graphviz/settings'
- テンプレートはvendor/plugins/プラグイン/app/views/に置く
- 簡単で便利だけど、:partialの指定を他のプラグインと同じにしてしまうと別のプラグインのテンプレートが適用されてしまうことがある。
- extra/sample_pluginをセットアップした状態で:partialに同じ値を設定しておいたらsample_pluginの設定ビューが出てきてかなり悩んだ。
- わざと存在しないテンプレート名を指定しておくとテンプレートの検索パスがログに出る。これを見る限り、プラグインの検索パスが連結された状態になっているようだ。
Missing template wiki_graphviz/_settingsi.html.erb in view path
・・・・/redmine-0.8.0_RC1/vendor/plugins/wiki_graphviz_plugin/app/views:
・・・・/redmine-0.8.0_RC1/vendor/plugins/sample_plugin/app/views:
・・・・/redmine-0.8.0_RC1/app/views stylesheet_link_tagみたいに:pluginを指定してなんとかしてくれんだろうか
- プラグインの名前が長すぎると、設定値を保存できるが再表示した際に値が正しく表示されない(デフォルト値が表示される)
mysql> desc settings;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | | | |
| value | text | YES | | NULL | |
| updated_on | datetime | YES | | NULL | |
+------------+-------------+------+-----+---------+----------------+
- 以前は「redmine_wiki_graphviz_plugin」という名前にしていた。redmine内部で「plugin_」が前置されて35文字になり、切れているのが原因っぽいが深追いしてない。プラグイン名を短くした。
mysql> select * from settings;
(中略)
| 24 | plugin_redmine_wiki_graphviz_p | --- !map:HashWithIndifferentAccess
cache_seconds: "2300"
| 25 | plugin_wiki_graphviz_plugin | --- !map:HashWithIndifferentAccess
cache_seconds: "3600"
(後略)
Railsに関して
※redmine-0.8.0RC1同梱のもの。2.1?
キャッシュ関係
- config/environments/環境.rbに設定することで有効になる
config.action_controller.perform_caching = true
config.action_controller.cache_store = :mem_cache_store, "localhost" - cache_storeの挙動が微妙に違う。
- デフォルトのActiveSupport::Cache::MemoryStoreはrubyオブジェクトを格納/取り出しできる。当然といえば当然。
- ActiveSupport::Cache::FileStoreは文字列前提
- ActiveSupport::Cache::MemCacheStoreは、(内部で使っているMemCacheの挙動で)値の格納/取り出し時にマーシャリングが行われるので結果的にrubyオブジェクトを(大体)格納できる。
- :rawオプションでマーシャリングをナシにできる。
- Catalyst::Plugin::CacheのイメージでいたのでFileStoreからHashが復元されず「おっかしいな~?」てことになった。結局Graphvizマクロプラグインではmemcachedだけ対応とした。
- ・viewからHEADに何か差し込みたい場合はcontent_forが使える。これは便利な仕組みだな~。
<% content_for :header_tags do %>
<%= stylesheet_link_tag "wiki_graphviz.css",
:plugin => "wiki_graphviz_plugin", :media => :all %>
<% end %> - 画像を出力するときは:text&:content_type指定かつlayoutナシのrender。
render :text => img, :layout => false, :content_type => "image/png"
- しかし、charsetをつけられてしまう。。。
ActionController::Baseのassign_default_content_type_and_charsetを見るにContent-Transfer-Encodingがbinaryに設定されていないとデフォルトのcharsetがついてしまうようだ・・。
クリッカブルマップを吐き出すところまでいけたので公開。
Wiki Graphviz macro プラグイン
例によって無保証です。
主なfeature
- wikiマクロ、{{graphviz}}と{{graphviz_me}}を追加
- wikiページをdot形式で記述し、これらのマクロから呼び出すことでグラフ画像をレンダリング
- ノードにURL属性を指定するとクリッカブルマップに
{{graphviz}} マクロ
{{graphviz(Foo)}}
{{graphviz(option=value,Foo)}}
{{graphviz(layout=neato,target=_blank,with_source,Foo)}}
- 指定したwikiページをdotテキストとみなしてグラフ画像をレンダリング。IMGタグを差し込む
- オプションは以下のとおり
- format={png|jpg}
- 画像形式。
- 現在のところpngとjpegだけ
- layout={dot|neato|fdp|twopi|circo}
- レイアウトエンジン指定。
- デフォルトはdot
- target={_blank|any}
- クリッカブルマップを生成する際のTARGET属性に指定する値
- 別ウィンドウで開くなら_blank
- with_source
- 画像の直後に読みこんだdotの内容をPREで出力
{{graphviz_me}} マクロ
// {{graphviz_me}}
// {{graphviz_me(option=value)}}
// {{graphviz_me(layout=neato,target=_blank,with_source)}}
- 別のwikiページを指定する代わりにこのマクロを含むwikiページをレンダリング対象とする。これ以外は{{graphviz}}マクロと同じ。
- 必然的に、dotフォーマット上のコメントアウトが必要。コメントアウトしないとレンダラがエラー終了する
dotの書式や指定できる値については、Graphvizチュートリアルがまとまっていて便利。
必要なもの
- Redmine 0.8.0 RC1 or later.
- Graphvizとrubyバインディング。本家でrpmを配布している。 http://www.graphviz.org
graphviz-2.20.3-1.el5
graphviz-gd-2.20.3-1.el5
graphviz-ruby-2.20.3-1.el5 - memcached (optional)
インストール
- redmine公式サイトの説明にもあるように、プラグインのアーカイブを展開してvendor/plugins/に配置してredmineを再起動するだけ(僕のところはmongrel+mod_proxy_balancerなので)
オプション
- レンダリングした画像をキャッシュしておくことができます。キャッシュを用いる場合は、memcachedとcache_storeを設定します。
- cache_storeの設定例
e.g.) config/environments/production.rb
config.action_controller.perform_caching = true
config.action_controller.cache_store = :mem_cache_store, "localhost"- redmineを再起動
- プラグインの設定ページ(管理→プラグイン→Wiki graphviz macro plugin)で、キャッシュ秒数を1以上に設定
僕の環境は以下のとおり。
CentOS 5.2
ruby-1.8.5-5.el5_2.6
mongrel-1.1.5
mongrel_cluster-1.0.5
redmine-0.8.0_RC1
memcached-1.2.6-1.el5.rf
MySQL-server-5.0.51a-tritonn.1.0.10
graphviz-2.20.3-1.el5
graphviz-gd-2.20.3-1.el5
graphviz-ruby-2.20.3-1.el5
既知の問題
- wikiのプレビューで編集中の内容をレンダリングできない
(wikiマクロに編集中の内容を受け取るI/Fがない。。。)
どんだけgraphviz好きなんだって感じだけど、まぁ好きだ。
実際は、別途webdot的なサービスを作って画像挿入のtextile記法、ってやり方で利用してはいたんだけどredmineプラグイン作成の習作も兼ねてやってみた。
wikiにdotを記述して、別のwikiページからgraphvizマクロで呼び出すとIMGに置き換わる、という流れ。
Wiki Graphviz macro プラグイン
例によって無保証です。
説明はその2の方に。
環境は以下のとおり
CentOS 5.2
MySQL-server-5.0.51a-tritonn.1.0.10
ruby-1.8.5-5.el5_2.6
mongrel-1.1.5
redmine-0.8.0_RC1
WikiControllerから地味に追いかけていったら元々マクロを拡張するI/Fを持っていて、lib/redmine/wiki_formatting/macros.rbに説明があった。
# Redmine::WikiFormatting::Macros.register do
# desc "This is my macro"
# macro :my_macro do |obj, args|
# "My macro output"
# end
# end
ということらしい。次はどこでマクロ登録を行うか。
redmineのプラグイン機構に乗っかってプラグインの初期化時にやったらよさそう、ということでscript/generateを使ってひな形を作成。
extraのsample_pluginを真似して上記プラグイン名にしたのだけど、これが元で後で痛い目に。「redmine_」が前置された結果、プラグインの名前が30文字を超えてしまいプラグイン設定の更新・参照に問題が発生。
% script/generate redmine_plugin wiki_graphviz_plugin
create vendor/plugins/redmine_wiki_graphviz_plugin/app/controllers
create vendor/plugins/redmine_wiki_graphviz_plugin/app/helpers
create vendor/plugins/redmine_wiki_graphviz_plugin/app/models
create vendor/plugins/redmine_wiki_graphviz_plugin/app/views
create vendor/plugins/redmine_wiki_graphviz_plugin/db/migrate
create vendor/plugins/redmine_wiki_graphviz_plugin/lib/tasks
create vendor/plugins/redmine_wiki_graphviz_plugin/assets/images
create vendor/plugins/redmine_wiki_graphviz_plugin/assets/javascripts
create vendor/plugins/redmine_wiki_graphviz_plugin/assets/stylesheets
create vendor/plugins/redmine_wiki_graphviz_plugin/lang
create vendor/plugins/redmine_wiki_graphviz_plugin/test
create vendor/plugins/redmine_wiki_graphviz_plugin/README.rdoc
create vendor/plugins/redmine_wiki_graphviz_plugin/init.rb
create vendor/plugins/redmine_wiki_graphviz_plugin/lang/en.yml
create vendor/plugins/redmine_wiki_graphviz_plugin/test/test_helper.rb
※settingsテーブルのname属性がvarchar(30)なことが原因っぽい
なので、手作業で「wiki_graphviz_plugin」に変更した。
※今にしてみれば_pluginを削ったらよかったのか。。。。
拡張マクロの登録は、プラグインのinit.rbでプラグイン登録と同時にやってみた。これが正しいかはわからない。
require 'redmine'
RAILS_DEFAULT_LOGGER.info 'Starting wiki_graphviz_plugin for Redmine'
Redmine::Plugin.register :wiki_graphviz_plugin do
name 'Graphviz Wiki-macro Plugin'
author 'tckz'
description 'Wiki macro to render the graph using graphviz'
version '0.0.1'
settings :default => {'cache_seconds' => '0'}, :partial => 'wiki_graphviz/settings'
Redmine::WikiFormatting::Macros.register do
desc "Render the wiki page into graph image using graphviz.\n\n" +
" !{{graphviz(Foo)}}\n" +
" {{graphviz(format={png|jpg},Foo)}}\n" +
" {{graphviz(layout={dot|neato|fdp|twopi|circo},Foo)}}\n"
macro :graphviz do |obj, args|
略
end
end
end
こんな感じで登録しておくと、wikiページ(view)のレンダリング中に呼び出される。マクロ展開後のHTMLを返せばOK。
dotの構文に誤りがあったときはwikiマクロのエラーとして表示する形にしたいからIMG要素出力時点で一度画像をレンダリングする方向で。dot解釈時点で一旦レンダリングしたものをrailsのキャッシュに置いておいて実際の出力時はキャッシュから返す(ない場合は改めて生成)という感じ。
その2につづく
ふと気がついたら0.6.0が出てた。
http://www.redmine.org/
doc/UPGRADINGを見ながらアップグレード。
「LDAP認証でADユーザを使ったredMineへのログイン」で書いたiconvの問題も、iconvを使わなくなったようで特に問題なし、と。
http://www.redmine.org/
doc/UPGRADINGを見ながらアップグレード。
- アーカイブredmine-0.6.0.tar.gzを展開
- config/database.ymlを以前のRAILS_ROOTからコピー
- config/environment.rbのSMTP周辺を編集
- rake db:migrate RAILS_ENV="production" でDB移行
- ちなみにバックアップは自動でとってるので特になし。
- RailsアプリはDB周辺の移行が自動化されてて偉いなー。
- files/は何も置いてなかったのでノータッチ。
- config/mongrel_cluster.ymlを以前のRAILS_ROOTからコピー
- mongrelを再起動
「LDAP認証でADユーザを使ったredMineへのログイン」で書いたiconvの問題も、iconvを使わなくなったようで特に問題なし、と。
プロジェクトをまたいで自分に関連するチケットをリストアップできる、という点に興味があり、巷でウワサのredMineをたててみる。
LDAPに既に存在するアカウントでログインできる、という点も魅力だ。
redMine環境は、FC5、ruby-1.8.5.35-2.fc5、rails (1.2.3)、mongrel (1.0.1)、mongrel_cluster (1.0.2)、redMine-0.5.1。
Active DirectoryはW2k3で動作。ユーザの姓名には日本語を指定しており、表示名が「赤峰 るび夫」のようになる運用をしている。ログオン名は姓名とは別の英数字IDを任意で指定している。
ADドメインはad.example.comとする。
production.logを見たらiconvがこけてるらしい。
認証モードの設定で、ログイン=sAMAccountNameとしていて日本語周辺は回避した、と思っていたのだが、内部的に以下のような流れらしい。
app/models/auth_source_ldap.rbをちょこっと書き換え。
ADユーザのログオン名+パスワードでredMineにログインできた。
ふー。
でも「あるAD上のグループに属しているユーザだけredMineを使える」みたいなコントロールはよくわからず。
うーん。
LDAPに既に存在するアカウントでログインできる、という点も魅力だ。
環境
redMine環境は、FC5、ruby-1.8.5.35-2.fc5、rails (1.2.3)、mongrel (1.0.1)、mongrel_cluster (1.0.2)、redMine-0.5.1。
Active DirectoryはW2k3で動作。ユーザの姓名には日本語を指定しており、表示名が「赤峰 るび夫」のようになる運用をしている。ログオン名は姓名とは別の英数字IDを任意で指定している。
ADドメインはad.example.comとする。
redMineの設定
- adminでredMineにログイン
- 管理>認証>新しい認証モード
名前:適宜。ADドメイン(のNTドメイン表現)と同じにした。
ホスト:ADサーバホスト名。
ポート:389
アカウント:cn=表示名, cn=Users, dc=ad, dc=example, dc=comパスワード:上記ユーザのパスワード
- このユーザはredmineの認証用に作成した。試行錯誤の過程で英字で姓のみのユーザを作成した。後述のinitialize_ldap_conの関係で日本語姓名だとbindできない様子。
- ディレクトリに対する匿名アクセス可能なアカウントを作った方がよかったかも。
BaseDN:cn=Users, dc=ad, dc=example, dc=com
あわせてユーザを作成:true
ログイン:sAMAccountName→ADユーザのプロパティでは、「アカウント ユーザログオン名」名前:givenName→ADユーザのプロパティでは、「名」苗字:sn→ADユーザのプロパティでは、「姓」メールアドレス:mail→ADユーザのプロパティでは、「電子メール」
- アスタリスクが必須項目マークだと思うんだけど、マークに従えば、ログインだけ指定すればいいことになる。のだけど、テーブルを見るとNotNull制約みたいなので、4項目とも設定した。
- AD側のユーザも合わせて上記項目を埋めた。
mysql> desc users;
+-------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| login | varchar(30) | NO | | | |
| hashed_password | varchar(40) | NO | | | |
| firstname | varchar(30) | NO | | | |
| lastname | varchar(30) | NO | | | |
| mail | varchar(60) | NO | | | |
| mail_notification | tinyint(1) | NO | | 1 | |
| admin | tinyint(1) | NO | | 0 | |
| status | int(11) | NO | | 1 | |
| last_login_on | datetime | YES | | NULL | |
| language | varchar(5) | YES | | | |
| auth_source_id | int(11) | YES | | NULL | |
| created_on | datetime | YES | | NULL | |
| updated_on | datetime | YES | | NULL | |
+-------------------+-------------+------+-----+---------+----------------+
- 認証モードを保存して一覧に戻る。
- 「テスト」をクリックして「接続しました。」が表示されることを確認する。
ログイン失敗
これで上手くいくかなーと思ったら、ログインできない。production.logを見たらiconvがこけてるらしい。
Processing AccountController#login (for *.*.*.* at 2007-09-19 18:43:52) [POST]
Session ID: feb2a36cbb1a47dd7b0396964d0185e3
Parameters: {"action"=>"login", "controller"=>"account", "password"=>"[FILTERED]", "login"=>"ログインID"}
Iconv::IllegalSequence ("姓 名,CN"...):
/app/models/auth_source_ldap.rb:72:in `iconv'
/app/models/auth_source_ldap.rb:72:in `initialize_ldap_con'
/app/models/auth_source_ldap.rb:47:in `authenticate'
(略)
認証モードの設定で、ログイン=sAMAccountNameとしていて日本語周辺は回避した、と思っていたのだが、内部的に以下のような流れらしい。
なので、(ここの運用だと)3のDNに日本語が含まれ、これをiso-8859-15→utf-8変換しようとしてiconvで死ぬ。ということみたい。
- 認証モードで「アカウント」に指定したDNとパスワードでLDAPに接続
- この接続を使って、redmineのログインID==sAMAccountNameとなるエントリを問い合わせる。
- 問い合わせた結果得られたDN+ログインフォームに入れたパスワードで再度LDAPに接続
- 接続できたら認証OK
とりあえず回避
場当たり的に、ADからの応答もutf-8だと決めてかかることに。app/models/auth_source_ldap.rbをちょこっと書き換え。
private
def initialize_ldap_con(ldap_user, ldap_password)
Net::LDAP.new( {:host => self.host,
:port => self.port,
#:auth => { :method => :simple, :username => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_user), :password => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_password) }}
:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }}
)
end
おわり
mongrel_clusterをrestartし、再度ログインフォーム。ADユーザのログオン名+パスワードでredMineにログインできた。
ふー。
でも「あるAD上のグループに属しているユーザだけredMineを使える」みたいなコントロールはよくわからず。
うーん。
