Redmine 2.4 ではチケット更新時のフックポイントがモデルからコントローラに移った
細かい変更だけど、個人的には心待ちにしていた Redmine のアップデートの話。
どんな変更?
Redmine 2.4 はスルーしていたのですが、正月の暇な空気の中で眺めてたら、チケット更新時のフックポイントの位置が変更されていました。
もともとモデルにあったフックポイントがコントローラに移動されたという割と小さな変更です。
作成時のフックポイントはもとからコントローラにあったので、この変更で統一された事になります。
何がうれしいの?
チケット更新時のフックポイントで呼び出されるプラグインを書いた場合に、プラグイン側から Rails のコントローラの機能を使えるようになりました。
たとえば、コントローラのコンテキストでは Rails のルーティングの機能が使えるため、チケットの URL が簡単に取れたりします。
どうやって使うの?
Redmine のプラグインでは、フックポイント名をメソッド名としたクラスを実装します。
フックプラグインの作り方 → Hooks - Redmine
用意されているフックポイントの一覧 → Hooks List - Redmine
例えば、チケット更新時、変更が DB に保存された直後に呼び出されるフックポイント名は controller_issues_new_after_save なので、こんな感じになります。
class FooHook < Redmine::Hook::Listener def controller_issues_new_after_save(context) end end
上記フックポイントの一覧のリンク先には明記されていませんが、フックの呼び出し元がコントローラだった場合、引数の context に呼び出し元のコントローラのインスタンスが入っています。
例えば更新したチケットの URL が欲しいならこんなに簡単に。
class FooHook < Redmine::Hook::Listener def controller_issues_new_after_save(context) issue_controller = context[:controller] issue = context[:issue] # 更新したチケットの URL を取得 url = issue_controller.issue_url(issue) end end
これがチケット作成時には簡単にできてたのですが、チケット更新時はとても面倒な処理となっていました。
bash と curl だけで S3 の Tokyo リージョンにバケットを作る
cosmin/s3-bash がよさげだったのでこれを使う。
環境
ローカルに持ってくる
$ git clone https://github.com/cosmin/s3-bash.git
$ cd s3-bash
シークレットアクセスキーファイルを作る
$ echo -n "シークレットアクセスキー" > secret.txt
注意点:
s3-bash は実行時にこのファイルの内容が 40 文字かどうかをチェックする。
上記のコマンドで -n を忘れたり、エディタで編集してうっかり改行を入れたりすると以下のようなエラーメッセージが出る。
s3-put: We do not understand Amazon AWS secret keys which are not 40 bytes long. Have you included a carriage return or line feed by mistake at the end of the secret key file?
リージョンの指定
content.xml というファイルを以下の内容で作成する。
<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<LocationConstraint>ap-northeast-1</LocationConstraint>
</CreateBucketConfiguration>
他のリージョンで作成する場合は ap-northeast-1 の部分を変更すればよい。
実行
$ ./s3-put -k アクセスキー -s secret.txt -T content.xml /バケット名
Vagrant の .vagrant.d の場所を変更する
.vagrant.d フォルダを別の場所に変更したい場合は環境変数 VAGRANT_HOME をセットすればいいらしい。
vagrant.d outside of the home folder
Windows に msi で入れたら Vagrant の box とかが入っているフォルダが c:/Users/ユーザ名/.vagrant.d になったのだけれども、容量が空いている別のドライブに移動したくなったので。
Gitlab, AsakusaSatellite などの開発者向け Rails アプリを Redmine で OAuth 認証するための Omniauth プラグイン作った
Redmine・Gitlab・Jenkins のログインパスワードの管理が大変になったので OAuth 化した - すえひろがりっっっっ! で Redmine を OAuth プロバイダにできました。
Rails 製のクライアントアプリケーション側は Omniauth Strategy を都度 initializers 以下に設置するようにしていましたが、各アプリケーションに対して同じような作業をするのは DRY じゃないのでライブラリ化しました。
omniauth-redmine https://github.com/suer/omniauth-redmine
セットアップ
Gemfile に以下を追記します。
gem 'omniauth-redmine', :github => 'suer/omniauth-redmine'
設定
devise を利用している場合は RAILS_ROOT/config/initializers/devise.rb に
config.omniauth :redmine, "consumer key", "consumer secret", :redmine_base_url => "http://redmine.base.url/"
のように追記します。 :redmine_base_url オプションは必須項目です。
omniauth を生で扱ってる場合は RAILS_ROOT/config/initializers/omniauth.rb として以下の内容を記述します。
Rails.application.config.middleware.use OmniAuth::Builder do provider :redmine, "consumer key", "consumer secret", :redmine_base_url => "http://redmine.base.url/" end
Redmine・Gitlab・Jenkins のログインパスワードの管理が大変になったので OAuth 化した
開発環境として Gitlab、Jenkins、Redmine をセットで使っているのですが、それぞれにパスワードの設定が必要となって管理が面倒です。
アカウントを一つに統合したい。ということでやってみました。
環境
- Redmine 2.3.0
- Jenkins 1.499
- Gitlab 5.2
Redmine に OAuth プロバイダの機能をつける
やりたいことに近いプラグインがあったのですが、Rails3 以降の Redmine に対応していなかったので、fork して、ついでに日本語化しておきました。
http://redmine.root.url/oauth_clients/ にアクセスすると OAuth の consumer key を発行できるようになります。
Jenkins の認証を OAuth に対応する
@mallowlabs さんがあっさり作ってくれました。
Jenkins へログインしようとすると Redmine の OAuth へリダイレクトさるようになります。
Gitlab の認証を OAuth に対応する
Gitlab は Omniauth でのログインに対応しているので、Redmine の OAuth を使って認証するような Strategy を書いて config/initializers に突っ込みました。
こんなふうに書いています。
module OmniAuth module Strategies class Redmine < OmniAuth::Strategies::OAuth option :client_options, { :authorize_url => 'https://dev.example.com/redmine/oauth/authorize', :request_token_url => 'https://dev.example.com/redmine/oauth/request_token', :access_token_url => 'https://dev.example.com/redmine/oauth/access_token' } uid { raw_info['user']['id'] } info do { 'nickname' => raw_info['user']['mail'], 'email' => raw_info['user']['mail'], 'name' => "#{raw_info['user']['lastname']} #{raw_info['user']['firstname']}" } end def raw_info @raw_info ||= MultiJson.decode(access_token.get("https://dev.example.com/redmine/oauth/user_info.json").body) end end end end
Omniauth の Strategy の書き方はこちら。
さらに、assets/authbuttons/redmine_32.png に適当なアイコンを置いておくと、こんなふうにログインフォームの下に Redmine の OAuth へのリンクが設置されます。
Chef で rbenv + Passenger の環境を構築する
rbenv + Passenger な環境の構築におおいにハマったのでメモ。
環境
- CentOS 5.9
- Chef 11.4.4
- Berkshelf 1.4.3
Berksfile
rbenv と Apache のレシピは Berkshelf で取ってくる。
ここで注意点。 OpsCode Community サイトから取得できる rbenv のレシピ(http://community.opscode.com/cookbooks/rbenv) は rbenv 自体は入れられるが、
これで入れた rbenv 環境下で passenger をビルドすることができないっぽい。
rbenv 環境下でスクリプトを実行できるリソース定義はないものかと探したところ、
https://github.com/fnichol/chef-rbenv を使えばできそうだったのでこちらを採用する。
使い方は http://fnichol.github.io/chef-rbenv/ を参照。
# Berksfile site :opscode cookbook 'ruby_build' cookbook 'rbenv', github: "fnichol/chef-rbenv" ...
$ berks install --path cookbooks
passenger のレシピ
$ knife cookbook create passenger -o site-cookbooks
で cookbook を作成して以下のとおりレシピを記述する。
# site-cookbooks/passenger/recipes/default.rb # Ruby 2.0.0 をインストールし、デフォルトに設定する include_recipe "rbenv::system" rbenv_ruby "2.0.0-p0" rbenv_global "2.0.0-p0" # Passenger のインストール rbenv_gem "passenger" do version "4.0.2" end # Apache モジュールのビルドに必要なパッケージのインストール (注: CentOS のみ対応) include_recipe "build-essential" package "httpd-devel" if node['platform_version'].to_f < 6.0 package 'curl-devel' else package 'libcurl-devel' package 'openssl-devel' package 'zlib-devel' end # Apache モジュールのビルド・インストール conf_path = "/etc/httpd/conf.d/passenger.conf" unless File.exists?(conf_path) rbenv_script "passenger_module" do code <<-CODE passenger-install-apache2-module --auto echo LoadModule passenger_module `passenger-config --root`/libout/apache2/mod_passenger.so >> #{conf_path} echo PassengerRoot `passenger-config --root` >> #{conf_path} echo PassengerDefaultRuby `rbenv which ruby` >> #{conf_path} CODE end end
Apache のインストールなどは省略。
ちょっと大雑把な記述だけど、ここでは fnichol/chef-rbenv の cookbook を使うことで rbenv_script という resource が使えるようになるのがポイント。
rbenv_script の resource 内では指定した rbenv の環境下 (デフォルトでは global) でスクリプトが実行できる。
execute resource を使用した場合は、せっかく入れた rbenv が使われず、システムの ruby (入っていれば) が使われてハマる。
以上で rbenv + Passenger な環境が簡単に手に入るようになりました。