2012-01-30

Nginxの設定メモ

nginxは unicorn のフロントとしての利用がメインで、あまり使いこなしていないので、細かいことは分かりません…。ひとまず、メンテナンスのため errorページの調整をしたので、そのメモです。

* * *

Redmineをメンテナンスで停止している間は、全てのリクエストを nginx側で受ける形にするため、nginx.conf でRedmine用の設定をincludeしている部分をコメントアウトします。

#gzip  on;
#include /etc/nginx/conf.d/redmine.conf;

また、nginxのRedmineのDocumentRootのindex.html を、メンテナンスの文面を書いた maintenance.html に変更します。
(nginxのDocumentRootは、私の場合は /usr/local/nginx/html です)

location / {
            client_max_body_size 20M;
            root   html;
            index  maintenance.html; # maintenance.html にする
        }

エラーページ(Not FoundやInternal Server Error)も、maintenance.html に振ってしまいます。

error_page  404              /maintenance.html;
error_page   500 502 503 504  /maintenance.html;
location = /50x.html {
    root   html;
}

Unicornとのプロキシを停止している間は、RedmineのチケットやマイページのURLへアクセスした場合は、Not found (404) になるので、こちらも「メンテナンスのためだよ」とお知らせするために、上記の設定にしました。

もっとスマートな(カッコいい!)方法があるかと思いますが、最低限の対応はこのような感じでした。設定の反映は、nginx reload でOK。

今回は、エラーページはnginxのDocumentRoot以下にあるものを使いました。でも、RewriteやRedirectを使えたりするので、別途アナウンスを管理するWebサーバがあるなら、そちらに転送したりすることも可能かと思っています。

git / github 覚え書き

Redmine本体のソース、プラグインのソースがSubversionからgit (Guthub) や Mercurial (Bitbucket) に移行しつつあるので、強制的にこの辺のコマンドを利用するようになっています。

Redmine本体に関しては気が付いた点や要望はチケットにして報告しています。

あわせて、プラグインについても、動作確認してみてなんかうまく動かなかった場合に、修正方法が見つかったら、できるだけ作者さんにレポートするようにしています。

その方法ですが、一応 github や bitbucketにアカウントがあるので、オリジナルをフォークして、自分のところで検証して、まあうまくいきそうならpull requestを作者さんに送る、という流れになっています。

一回きりのpull requestなら、フォークしたリポジトリは用が済んでしまうので、削除しちゃってもいいのですが、フォーク元の変更に追従しつつ、自分でも少し検証をしながらリポジトリを温存する場合..。

こちらを参考にしました:

手順は、こんな感じ。

1. git clone …… (フォークして作った自分のリポジトリ)

2. git remote add honke git://github.com/xxxxx/xxxx.git (フォーク元を honke という短縮名で、remote に追加

3. git remote コマンドで確かめる

# git remote
honke <- remoteに追加された
origin <- こっちは自分のgithub上のorigin

4. 本家の更新を、ローカルに反映させる (ローカルリポジトリは master)

# git pull --rebase honke master

5. 自分のフォークしたリモートリポジトリから、いったん pull し、その上で push する。

# git pull origin master
# git push origin master

これで大丈夫らしい(^^;

GitもMergurial(hg)も、まだまだ良くわかりませんが、ブランチをその場で作ったり、ささっと切り替えたりできる点は、すごくSubversionよりも楽だ、ということは体感してきました。自分自身はこまめにコミットするけれど、本流のリポジトリには、コミットをまとめたものだけを反映させたりできるので、「とにかく書いてみよう、間違ってもだいじょうぶ!」な安心感もあります。

説明できるほどには身についてないですが、もう少し精進して、みんなが気軽に使えるような仕組みを用意してあげたいなあと思ってます..。

そして、間違った内容があれば、ぜひご指摘ください!

2012-01-25

Redmine勉強会 #2に参加 + 初LTしてきました。

この記事を書く前に、藤原さんご本人が発表についての記事を書かれて、皆さんももうすでにご存じかと思いますので、多くは触れません。ただひたすら、『こんなに詳しい事例、経験をお話しして下さって、ありがとうございます…』のひとことです…。

「運用面しか見ることができていない(それもまだまだ乏しい)自分がなんて小さいんだろう..」と思ってしまいました。

勉強会の案内、講演者の皆さんの資料等は、こちらからご参照下さい。

さて、『Blogを書くまでが勉強会』のお約束で、遅ればせながら私も書いてみます。
会の感想はたくさんの方がTweetされたりしていますので、自分だけにしか書けないものを書いてみようと思います。

ということで、『初めてLTしてみた』立場での、自分の振り返りとなります。

1. LTに手を上げたきっかけ

Redmine勉強会参加したいな…と思ったのですが、すでに枠がいっぱいになっていました。それでも、楽天の藤原さんのお話し、バージョンアップの際にお世話になった内藤さんのお話し、プラグイン開発のお話しを聞きたくて、どうにか考えた挙句…。

発表者(LT含む)枠なら空いている!ことに気が付きました。

そして、『発表するので参加申し込んじゃってるの!』と言って、家人を説得しました..。なかなか土日平日夜にお出かけできない身としては、(プチ)『許可を求めるな、謝罪せよ』 です。
(そういう意味で、5分間のためとは言え、家族の支えがないとできませんでした…。ありがとう!)

2. 何を話すか考える

技術的な話題ではとても足元にも及びません。そんな時に思い出したのが、昨年の5月に参加した、DevLoveの縦サミットの、和田さんのお話しでした。自分のBlogの中に、その時書きとめた言葉が残っていました。

そこで、『自分』の話をしよう、自分の経験からくることを話そう、ということで気持ちを落ち着けました。(5分ばかりなんですけどね)

ちょうど、バージョンアップに際してプラグインを作ってみる機会があったので、話題はそこに持っていきました。ちょうど一年前に、Redmineのプラグインのハンズオンを受けていたので、その成果も少しだけでも出したいなあと思い、取り組みはじめました。

3. 一番表現したいこと

突然ですが、宮崎駿監督の映画作成のドキュメンタリーを見た時に、『一番表現したいシーンが思い浮かぶ』と、そこから先はどんどん進む、というようなお話しがあり、わたしもそれに倣ってみました。

わたしの場合は、@mikoto20000さんからのメッセージをきっかけにした、あるアイディアが、その『一番表現したいシーン』になりました。(もちろん、「伝えたい」ことはもう少し別ですが)

はたして皆さんにその気持ちが届いたかどうかは判らないのですが、たしかに、そのシーンにたどり着くために、こんなふうに話をすすめてみよう…といったことも考えやすくなっていました。

4. 練習してみる

なんとか5分で収まるかなあ…というところで、『壁』を相手にいざ話をしようとすると、5分じゃ終わらない..。ついつい、書いていないことも話して(それは本題じゃないだろ!)みたいなことで時間がとられてしまうことが分かりました。

これじゃあだめだなあ…という矢先、@take3000 さんのLTに関する記事を目にすることができました。こちらを発表の前に読むことができて、(お読みになった方は判るとおもいますが)、いくつかそのメソッドに従って、スライドを作ってみました。

正直、とても気持ちが楽になりました。

5. 会場にて

さすがに大寒で寒い!しかも会場にも遅れてしまいました..。
そそくさと会場の一番後ろの席に座り、慌ててPCを開いてそもそも起動するかを確認。
無線もなかなかつながらず、マウスもうまく動かない、で焦ってしまい、せっかくのメインスピーカーの皆さんのお話しにも集中できませんでした…orz

「もっと早く来て、準備して、落ち着いてスピーカーの皆さんのお話しにも集中」すればいいのですが、自分も家庭の事情で早めには来れませんでした。

スピーカー、スタッフ、参加者の皆さんも、ほんとうに日々忙しい中、ギリギリの状態で頑張って会を作り上げているんだなあと、しみじみと感じました。

kaijo-1

さて、私の座った会場後方では、前の席に @TrinityTさん、右隣に @me_umechaさんと同席させていただきました。
発表の合間には、お2人とお話しをすることができ、おかげ様で少し緊張を和ませていただきました。

6. 実際に話してみる

スライドをぎりぎりまで調整していたので、発表は持ち込んだPCをプロジェクタにつなげて、となりました。自分の番になって、コードをつないで、トップページが映し出されたのですが…。

kaijo-2

LTの前にも、プロジェクタの動作確認、調整の時間をいただいたのですが、調整の仕方をうまく分かっていなかったので、映ることだけ確認して、いったん戻ってしまいました。

でも、画面が縦長に映ってしまい、「自分が見て、作ったもの」をお届けするにはほど遠く..。

『ああ、しまったー!』とは思いましたが、細かい文字や画像は無かったので、そのまま続けてしまいました。そのため、多々見難い画面が多かったと思います。(中継だとなおさら申し訳ありません)

トークはダメでも、画面くらいはきちんとお届けしたかったのですが、配慮が足りませんでした。事前チェック、大事なんですね..。

話す方は、頭が真っ白で、とにかくスライドの文字を追ってお話しするだけでした…。
それでも、最前列で「うんうん」という感じで頷いて下さっていた方(スタッフの方ですね?)のおかげで、少し気が楽になっていました。

肝心の、『一番表現したいこと』は、まあまあうまくいったのかな..。

7. 資料を公開してみる

さて、作った資料は(たいしたことないのですが)アップしないといけません。
今回は、フォントに『みかちゃんフォント』を使って、手書きの感じで見ていただこうと思いました。

でも、PPTだと、フォントが入っていないPCでは、その手書きの感じが再現できない~!仕方なく、PDFとPPTの資料を起こし、いったんGoogleにアップしました。

さらにその後、みなさんSlideShareを利用されているようなので、これも初めてですが、SlideShareに上げてみました。

案の定、PPTでアップすると、フォントは環境に依存する結果に..。
フォントに凝られている場合は、みなさんどうされているのでしょうか。

また資料をアップするような機会があるかは分からないのですが、いろいろ工夫できるといいなと思っています。

8. ひとまずこちら

慣れないですがSlideSshareにPDF版をアップしました。重いかもしれませんが、よかったらご覧いただければと思います。

また、わたしからのメッセージ、ということで、最後の2カットを載せておきます。

kaijo-4

kaijo-5

9. まとめ&勉強会に関して

勉強会のレポというより、LTの体験記になってしまい、申し訳ありません。

ただ、1人のRedmineユーザとしても、大変有意義な会でした。
5分のコマでこれだけヘロヘロになっているので、メインスピーカーの皆さんの準備はいかばかりか..。(そして、それだけのお話しをされる背景にあるものも)

この機会を大事にして、なんとか今後の運用、ユーザのみなさんのための環境づくりに活かせたらと思っています。

最後に、素晴らしいスピーカーの皆さん、スタッフの皆さんに紛れて、皆さんの貴重な5分+αをいただくことが出来きました。本当にありがとうございました!

昨年はいろいろありましたが、やっと、少しだけ前に進むことができた気がします。

2012-01-19

script/consoleでProjectモジュールを有効にする

Redmineのプラグインの評価で、テスト環境にデータを持ってきてチェックを行った時のメモ。

本番機はまだそのプラグインを入れていないので、まずは開発機にデータを投入し、 Pluginのmigrationが必要。

その上で、そのプラグインはプロジェクト単位でモジュールのActivateをしないといけません。

プロジェクトがたくさんあると、各プロジェクトの設定画面からプチプチ設定するのは面倒なので、バッチでできれば嬉しいな…。

ということで、今回は、script/console (で、しまいにはscript/runner) で実行しました。

# Activate IssueExtension
@projects = Project.all
for project in @projects
  project.enable_module!(:issue_extensions)
  project.save!
end

処理は上記のような感じです。ちょっと手間が省けたので助かりました。

2012-01-18

Select(プルダウン)のオプションをJavaScriptで書き換えるときのメモ。

今回のサマリ: 
IEだと new Ajax.Updater(element, …) を利用する際、elementがSelect(プルダウン)の場合は書き換えが行われなかった。
しかたがないので、IEのときは、いったんouterHTML & innerHTMLを使って書き換えた。

* * *

ユーザさんからのリクエストで、Redmineの本来のプルダウンを拡張して書き換えるプラグインを作っているところ。

最初はサーバサイドでの実装は要らず、クライアントサイドでJavaScriptだけでプルダウンを書き換えできると思い、そのコードを書いたのですが、IE / ChromeではOKだったものの、Firefoxでは思った通りに動作しませんでした…。

具体的には、”selected=selected (or selected=true)” で指定されたOptionのIndexが、Javascriptで上書きをし、別のOptionをselectedにしても、書き換え後のselectedが有効にならず、前のselectedのIndexをキャッシュしてしまうという症状。

検索すると、なにやらそれらしい情報もありました。

その後の追加のリクエストもあって、ブラウザだけでは対応は難しいのかな…と思い、プルダウンを書き換えるコードをサーバサイドで生成(コントローラで作成)し、Ajax.updaterで取得 –> 書き換えるように修正しました。

JavaScriptのコードは、<select id=”select1”><potion>…</option></select> というプルダウンの中身を、 new Ajax.Updater(‘select1’, 'コントローラのURL’ … )  …で書き換えるようにしました。

ところが!

今度はFirefox / Chromeでは大丈夫だったのに、IEでは書き換えが行われません!(データが欠損されるわけではなく、書き換えが行われないまま)

操作は不都合はないけれど、IEのユーザだけこのカスタマイズが有効になってくれません…。

あれこれ探ると、なんとかこれにHit。

Prototype.Browser.IE でIEかどうかを判断し、IEの場合は new AjaxUpdater() ではなく、new XMLHttpRequest() でコントローラのデータを取得し、返ってきたデータ (xmlhttp.responseText) を、innerHTML, outerHTML で処理するようにしました。

document.getElementById(‘xxxx’).innerHTML = '' + str;"
document.getElementById(‘xxxx’).outerHTML = document.getElementById(‘xxxx’).innerHTML;

クロスブラウザって大変なんですね..。

へなちょこですが、Flex使ってUIを作っていたときは、ブラウザで気になるのはサーバサイドへの通信の仕方くらい(キャッシュとか)で、あんまり気にしていませんでした(^^;;

2012-01-16

Redmine + ActionmailerJaの修正

わたしの環境では、Redmineのメール送信をUTF-8からISO-2022-JPに変換するために、ActionMailerJaを利用させていただいてます。

しばらくは問題なく利用していたのですが、ある時、ユーザさんからこんな指摘を受けました。

『HTMLメールの一部が切れてしまって、文字化けを起こしているんですけど…』

指摘のチケットのメールを転送してもらうと、text/plainのほうは問題ないのですが、text/htmlで下記のようなケースで、文字化けが起きていました。

  • <pre></pre>で文章を挟む形でデータを登録する。
  • 上記のタグで挟んだ文章のうち、1行当たりの文字数が長い場合、800バイト付近で改行が挟まれるようになっている。(ActionMailerJaでの処理のため?)
  • この800バイト近辺に日本語が該当すると、文字化けが発生する。

@haru_iidaさんもActionMailerJa + Redmineについて書かれていましたが、どうもここには該当しないようでした。

プラグインを宛てたり外したりしてチェックしたところ、本来の動作のUTF-8の場合は、text/htmlでの文字化けは発生しませんでした。

レアなケースではあるけれど、どうしたものかな…と考えたのですが、text/html + text/plain のマルチパートでメールが送信されているので、text/plain だけISO-2022-JPであれば十分じゃないか?と考えました。

コードは良く分かっていないのですが、printデバッグ(お恥ずかしい…)しながら下記のように調整すると、なんとか text/plain –> JIS/7bit, text/html –> UTF-8/Quoted-printable になってくれました。

diff --git a/lib/actionmailer_ja/base.rb b/lib/actionmailer_ja/base.rb
index 0b01434..bb2b414 100644
--- a/lib/actionmailer_ja/base.rb
+++ b/lib/actionmailer_ja/base.rb
@@ -55,7 +55,7 @@ module ActionMailer
     def create_mail_with_ja #:nodoc:
       create_mail_without_ja
       (@mail.parts.empty? ? [@mail] : @mail.parts).each { |part|
-        if part.content_type == 'text/plain' || part.content_type == 'text/html'
+        if part.content_type == 'text/plain'
           if ((!gettext?) || (gettext? && Locale.get.language == "ja"))
             if mobile_address? && @mobile_address.softbank?
               part.charset = 'utf-8'
@@ -67,6 +67,8 @@ module ActionMailer
               part.transfer_encoding = '7bit'
             end
           end
+        elsif part.content_type == 'text/html'
+          part.charset = 'utf-8' 
         end
       }
       @mail

あまりメールの部分は手をいれたくないのが本音ですが、いまのところ、これで大丈夫のようです。