2012-12-21

RubyMine + Jenkins Control Plugin

この記事を書いている時点で、なにやらJetBrainsでは、大変な賑わいとなっていたようですが、それはさておき。
やっぱりJenkinsとの連携もしたくなります。
IntelliJのプラグインとしては、下記のものがありました。
IntelliJ専用だから追加できないかな?と思ったのですが、よく見ると Products: IntelliJ IDEA, ..... RubyMine と書いてあります。どうやら大丈夫な模様。
ということで、初の追加Pluginは、Jenkins Control Pluginとなりました。

追加してみます

まずは、上記のサイトからダウンロードし、RubyMineの設定 -> プラグインで追加となりました。特に再起動も必要なく、シンプルにインストールできました。
Jenkins Control Plugin
そんなに設定するところはありません。

 

設定&表示させてみます

localhostで起動しているJenkinsさんを設定してみました。
Jenkinsさんは左端に表示されました。また、画面右隅には、ビルドのステータスが表示されました。
JenkinsさんとHectorさん(らしい)
Jenkinsは1サイトだけ登録できるようです。ビルドの実行、表示(ブラウザで開く)といった基本的なことができます。
これくらいシンプルでも、IDEとブラウザを切り替えたりしないで良いので、十分かと思います。

ということで、今回はJenkinsのみ入れましたが、IntelliJ IDEA用のプラグインだと、たくさんあるんですね!
お遊び(息抜き)用のものもあって、見ていて面白いですね :)
そんなに使えないので偉そうなことは言えませんが、SQL& PL/SQL用のプラグインは入れてみようと思います。(BashSupport Pluginは、どうもRubyMineはNGなのかな....?)

2012-12-18

#jbugj RubyMineがとても良い件。

はじめに:Rubyのデバッグ環境に困ったこと

またまたRedmineの関係ですが、Redmineのプラグインを書くうちに公開したくなってきて、でも、コードも綺麗じゃない、しせめてデバッグやテストはちゃんと出来るようになりたいな...と思うようになり、今年のはじめ、Windowsの環境にRuby, NetBeansを入れて、なんちゃってながらもデバッグとテストができるようにしました。(注:偉そうなことは言えず、フルスクラッチでコードを書く能力はありません....)

その後、RedmineがRuby1.9, Rails3.2対応になってしまったので、また環境を作りなおさなくっちゃ...と思っていたところ、NetBeansがバージョン7からRubyの公式サポートを止めてしまったとのこと。

プラグインを使えばもちろん利用はできますが、デバッグをしようにも、テストしようにも、どうにも面倒...。AptanaというIDEも教えてもらったのですが、こちらはeclipseがベースらしく、個人的にはあまり相性が良くないので、やっぱり止めました。

そうこうしているうちに、Macに乗り換えることになりました。
改めてNetBeans7.1 + Ruby1.9の環境を作ったのですが、デバッグは出来るものの、とにかく重い!途中でハングしたような状態になってしまいます。

世の中のMac userがこんな環境でコード書いている訳が無い!と思ってRedmineの関係の方に聞いてみたところ、春からRubyMineを使ってます、とのコメントを頂きました。それがRubyMineを知るきっかけでした。

RubyMineを入れてみたよ



ということで、早速インストール。

基本的には、『プロジェクト』という単位でコードを扱いますので、eclipseやNetBeansとそんなに変わりません。わたしの場合は、いつも通りRedmineをプロジェクトとして設定してみたところ、問題なくRailsアプリケーションとして認識してもらえ、起動/デバッグのメニューもすんなり起動してくれました!

さて、その後、ターミナルからプロジェクトフォルダを眺めてみると、フォルダ直下に、.idea というフォルダがあるのを発見しました。
こちら、Jenkins繋がりで、IntelliJラブな今井さんのお話を聞いたときに耳にしたフレーズです。(修正:『イデア』と読むと思い込んでいたら、やっぱり『アイディア』らしいです、すみません... )
あれれーと思ってTweet してみると、今井さんと山本さんから、さっそくそのあたりを教えていただきました。


  • RubyMine入れてみたら、対象のフォルダに.idea っていうフォルダができてるんですが、どっかで聞いたなーと思ったら IntelliJ。IntelliJの親戚なのでしょうか??
  • IntelliJから機能削ってRubyプラグイン仕込んだのがRubymineです。d.hatena.ne.jp/masanobuimai/2
  • 親戚ですよー。IntelliJ IDEAからRuby用の機能だけ抜き出したのがRubyMineです
IntelliJが奥様のお小遣いではとっても買えない額だとは今井さんに聞いていたので、さぞかしRubyMineも高いんだろうな〜と思いつつ、ひとまず使ってみることにしました。

全然ハングしませんよ!

さて、実際の稼働ですが、IDE慣れている方なら、ほぼ意識せず、普通に使えます。(ただし、残念ながら表示/メッセージは英語です)
しばらく使っていて「あれれ?」と思ったのが、全然ハングしないこと!NetBeansのアレは何だったのか?と思いくらいに快適です。その旨つぶやいたら、また今井さんに怒られました(^^;


  • あやまれ、RubyMineにあやまれ!:-P RT @akiko_pusu: NetBeansにくらべると、RubyMine動作軽いですね…

 

謎のおじさんがいる!

そうこうしているうちに、画面の右隅に、帽子をかぶったおじさんを発見しました。


なんですか?これってJenkinsさんの親戚?と思って、またもつぶやいてみたところ、これまた今井さんからのお言葉が。


  • @akiko_pusu Hectorおじさんです。ナメたコードを書くとビシバシ文句言って来ます。:-)
なるほど、改めて見てみると、RubyMineのコードインスペクションがもの凄い事になっています....。コーディング規約から外れたもの、スペルミス、Deprecatedなものを使ってたりすると、黄色いマークがコードの右にいっぱい付きます。自分の書いたもので問題ないのは、Readmeくらいでした..... orz

このInspectionがうざい!という方は、レベルを調整したり、OFFにしたりできるようです。

 

スクリーンショットを載せます

以下は、RubyMineのスクリーンショットです。基本的にSCMと連携して、RubyMine内でコミットやpush/pull/ブランチ作成など出来ます。


コード中のTODO:も別画面で抽出/チェックできます。コミット前のタスクなど、コメントはいっぱい書く気がでます〜!



心配していたデバッグ、テストもちゃんと出来ます。良かった!



Coverageも取ってくれます。(ソースフォルダとかにcoverageが生成されず、RubyMineの中で閉じてくれるみたいです)




ただいま、rbenvを使ってRubyの環境を切り替えて使っていますが、こちらも問題なさそうです。

ライセンスは?

そんなこんなで、もうすぐ評価期間が終わってしまいます。IntelliJにくらべると、個人ユースなら69$ってとこなので、奥様のお小遣いでも大丈夫かとは思います:)

ちなみに、IntelliJをはじめ、JetBrainsのツールは、オープンソースプロジェクト用ライセンスというものがあって、オープンソースで活動しているプロジェクトには、無料でライセンスを提供してくれるそうです。素晴らしい!

そして、『これは良いなー』としみじみ思っていた矢先に、JetBrainsユーザーグループの勉強会の件を知りました。
残念ながら、平日夜も含め勉強会は出られないので、みなさんのTweetや資料を拝見しつつ、なるほど〜と勉強させていただいているところです。

Jenkins由来でIntelliJのことは知っていましたが、自分には全く縁の無いツールだと思っていたので、少しだけその世界を覗く事ができて、自分でも意外に思っています。
そして、名も無いユーザのTweetにもお返事を下さった今井 () さん、山本 () さん、どうもありがとうございました!

個人的に、とても良いツールだというのが実感できましたので、会社でもちょっとずつ宣伝していこうかと思っています。

記事の修正など

.ideaは、アイディアという指導をいただきましたので、訂正を行いました。
 

2012-12-13

チケットを復旧する

消えたチケット

先日、『Redmineのチケットを間違って削除してしまいました、どうしましょう』というお問い合わせをいただきました。残念ながら、Redminの場合はデータは物理削除されてしまうので、そのままでは復旧できません...。

生まれて間もないチケットなら、新規作成しなおして貰うという方法が一番早いのですが、今回は自分も参照していたチケットで、本文に加えて注記も40件くらい溜まっていました。削除してしまった直前までの状況を聞いたところ、最終更新が前日で、今回は更新時の自分の注記を修正しようとしてチケット毎削除してしまったとのこと。

幸い、日々のバックアップ&前日時点のレプリカのRedmineがあるので、そちらでチケットを確認していただき、前日までの記録を戻せば大丈夫との印象でした。(各テーブルのモデルは連番で採番されるので、チケット番号に基づくデータがごっそり抜けちゃった状態です)

 

削除前のデータを取り出す

開発環境サーバへは、毎朝4時に、バックアップデータをもとにDBへ再インポートを行っています。
さらに、それに加えて、次回バージョンアップ予定のRedmineを使って、標準的な状態でうまくマイグレーションを実施し、Redmineのサービスを起動できるかを確認しています。(テストコードを書いている訳ではありませんが、実質、バージョンアッップ時に問題が発生しないかどうか、バックアップデータが健全で正しくリストアできるかを、継続的に検証できるようにしています


ということで、開発環境でレプリカとして公開しているRedmineは、メインに使っていただいているバージョンよりも1つもしくは複数進んだもので稼働させています。

基本的には構造に大きな変更はありませんので、ブラウザから削除されていない時点のチケットがどんなふうに表示されているかを確認しつつ、MySQLから削除されてしまったIDにまつわるチケットのデータ一式を抽出しました。

 

抽出にはMySQL WorkBench


MacにはMySQLとクライアント一式はインストールしていません。コマンドラインで操作するためにインストールしようかとも思いましたが、誤操作も心配なので、GUIのMySQL Workbenchをインストールして、そこからデータの確認や操作を行うことにしました。

開発機のMySQLポートはアクセス制限を行っているので、ここは便利になったMacの環境を利用して、localhost:3306にポートフォワードして確認します。

MySQL WorkBenchだと、抽出したレコードをcsvの形でなく、Insert文のようなSQLに書き出す機能があるので、今回はこちらを使って復旧用SQLを用意しました。

 

復元にもMySQL WorkBench


復旧用のSQLが出来たので、こんどは本番のMySQLにつなぎ直します。これもポートフォワードで。Redmineの作業用DBに接続し、Insert文でデータを戻してあげて、Redmineのweb画面からチケットが復活していることが確認できればOKです。

 

ファイルはscpで戻します

チケットはほぼ戻りましたが、添付ファイルの場合は実際のファイルを、Redmineのファイル格納用フォルダに戻してあげないといけません。また、フォルダ上のファイル名と、チケットで表示されるファイル名は違いがあります。(タイムスタンプとハッシュ値、拡張子で生成されています)

こちらは、issue_attachements テーブルで定義された、実際のファイル名を指定して、リストアしてあげます。これも直接はscpできないサーバなので、ポートフォワード+ scp で対応しました。

Redmineの添付ファイルは、わたしの環境の場合、config.ymlで/data/redmine_binary/と指定してあるので、ここに転送します。まず、localhostの4321番を、転送先のscp port 22番に繋がるようにして、そのあと localhost:4321 を指定すると転送先に繋がってくれます。
Exp.
$ ssh -p 22 -t -L 4321:localhost:1234 中継ユーザ@中継ホスト ssh -t -L 1234:localhost:22 転送先ユーザ@転送先ホスト
$ scp -P 4321  消しちゃったファイル.xls 転送先ユーザ@localhost:/data/redmine_binary/ハッシュ値で格納する名前.xls
以上でデータ復旧は完了です。
ちなみに、ファイルのパーミッションは注意!
Redmineのプロセスを稼働させているユーザに権限が無いと、チケットを本当に削除したいときにPermission Errorになります。(現環境だとredmine:redmineです)

* * *
今回はsqlを使ってInsertで復旧していますが、mysqlのコマンドラインツールでcsvに書き出してインポートするのでも問題はないと思いますので、再発するようなら自動化しておこうかなと考えています。

ちなみに、大規模な環境なら、こんな記事は全然目新しくもないでしょうけれど...(^^;
いちおう事例として、恥ずかしいですが公開してみます。

できるだけすぐに直前の環境を再現できるようにしておいたことで、ワークフローのおかしいところを見直したり、プラグインの評価をする際にも利用できたりと、いろいろメリットはありますので、なんにしても用意しておいて良かった、と思った次第です。

2012-12-03

TortoiseHgインストール (Mac編)

初めておたちよりのみなさま、こんにちは。
Redmineつながりで、@cointoss1973さんが募集されていた、TortoiseHg アドベントカレンダーに参加させていただくことになりました。
実はMercurialはあまり使いこなせてなくて(GitもSVNも似ようなものではありますが)、正直エントリするのはおこがましい位なのですが、ちょうどMacに環境を切り替えたところだったので、インストール話なら...ということで、3日目のエントリとして書かせていただきます。

結果からいうと、基本操作はできますが、まだ日本語化とかアプリケーションフォルダからの起動ができず、完璧とは言えない状態です。

[20121210 追記]

本エントリでは、インストールは出来たものの、アプリケーションフォルダからの起動と、日本語化が上手く行きませんでした。
日本語化が上手くできなかった件については、TortoiseHgビルドの前に、gettextがインストールされているということが前提だそうです。
本エントリの中で、この部分と、gettextを先に入れていなかった場合の対応手順を追加しています。

* * *

1. 本家に行ってダウンロード....ではないらしい

  • まずは、TortoiseHg本家に行きます。
  • アクセスすると、日本語画面に直行。TortoiseHgダウンロード(for Mac OS X)のバナーがさりげなく表示されており、迷うことはまずなさそうですね。この辺のサイトの作り手の皆さんのご配慮は大変ありがたいです。


が、いきなりパッケージダウンロードではありません。
「あれれ?」と思ったら、どうやらMac専用のインストール解説ページに移りました。(ここから先は英語です)
TortoiseHgのページのDownloadのページを見ると、Windows向けバイナリがリストアップされていますが、Macはどうかというと、やっぱり下のほうにあり、なにやら専用の手順が必要な模様です。
"To use the settings tool on Mac OS X, you must have http://code.google.com/p/iniparse/ installed."

2. Bitbucketへ行きました



リンクをたどった先は、Bitbucketです。何やら注意書きには、finkのunstable treeに置いてあると書いてあります。また、どうやらpythonのバージョンにも依存するようです。
この時点で、わたしのMacには、すでにMercurialのソースを取ってくる必要があったので、hgとSourceTreeが入れてあります。Pythonは確認すると2.7が入っています。あまり考え無しにいろいろ入れているので、ちょっと不安.....
ただし、Note: Also if you already use Homebrew there are steps at the end. という一文がありましたので、こちらに従うことにしました。せっかくお誘いを受けてエントリしているのでBlogにはレポートしたいですし、ちょうどBitbucketのリポジトリにpush したいものがありましたので....。
ただし、このパターンでも、brew install .....  で済む訳ではないらしく、GUIにQtを使っている関係で、Qtのソースも入れてビルドしないといけない模様です。ということで、まずは、Homebrew版のインストールをすべく、説明のページの一番下に移動。
途中、ソースからビルドする場合のStepが書かれてあり、やっぱりインストールしなおしになったり使うのを止めた場合の対応が大変そうだったので、決心は変えませんでした。
でも、ソースからビルドする説明の最後に、 "Happy Hacking!" の文字が書かれてありましたので、達成感はありそうですね〜(^^;

3. Homebrewでインストール

ガイドでは、まずXcodeとHomebrew野インストールをしてね、という説明があります。実は、XcodeとHomebrewのインストールは既に終わっていましたので、その次のステップから記載します。
20121210追記分:
TortoiseHgのビルドの前に、gettextを入れておきましょう!(日本語化ファイルが生成できません!)Homebrewならすぐに入ります。
$ brew install gettext
$ brew link gettxt
単純に、順番に下記のコマンドを実行していきました。
$ brew install pyqt
$ brew install qscintilla2

$ brew update
$ easy_install pip $ pip install Pygments iniparse Mercurial
pyqtはソースからビルドしていくので、結構時間がかかりました。体感で10分くらいかかったような...(かなり心配でした)
それでも一応make installが出来たので、次々とガイドに従ってセットアップ作業を進めていきます。

途中で下記のように環境変数を設定してね、といったメッセージが出ましたが、何かハマりポイントなのかもと思って無視 :)
For non-homebrew Python, you need to amend your PYTHONPATH like so:
  export PYTHONPATH=/usr/local/lib/python2.7/site-packages:$PYTHONPATH
環境変数を設定しなくても、実はここまではうまくいきました。
さて、最後にbitbucketのリポジトリからTortoiseHgを一式チェックアウトとなります。
$ hg clone http://bitbucket.org/tortoisehg/thg/ ~/Documents/TortoiseHg
なぜ /tmp  とか /usr/local/src とかじゃないのかしら...と思いながらもチェックアウトが完了して、フォルダを見てみると、いろいろ入っています。
さて、最後のコマンドを実行してみると.....

$ ./thg log
Traceback (most recent call last):
  File "./thg", line 44, in
    build_qt(Distribution()).run()
  File "/Users/takano/Documents/TortoiseHg/setup.py", line 215, in run
    self._wrapuic()
  File "/Users/takano/Documents/TortoiseHg/setup.py", line 236, in _wrapuic
    from PyQt4.uic.Compiler import compiler, qtproxies, indenter
ImportError: No module named PyQt4.uic.Compiler
「あらあらどうしよう...」と思ったところで、「環境変数を設定してね」というNoteがあったことを思い出し、.bashrc に設定を追加して、source ~/.bashrc してから再度 ./thg log を実行しました。

4. 起動しましたよ!

./thg log で何が起こるかと思ったら、TortoiseHgが起動しました!


SourceTreeがブルーをベースにしているのに対し、TortoiseHgはグリーンです。見慣れたカメさんのアイコンもDocに表示されました!よくよく考えたら、thg = TortoiseHg のことなんですね。
thgのオプションの"log" は、TortoiseHgのリポジトリのログをデフォルトで表示しているんですね。「へえ〜」と思いながら画面を眺めました。

個人的には、これで十分な位なのですが、ドキュメントの最後にはTortoiseHgをアプリケーションから起動させるための方法が書かれてありました。一応挑戦してみたのですが、/Applications/ フォルダに出来たTortoiseHg.app を入れても、うまく起動してくれません...。
どうも、要求しているPythonのバージョンが違う、前提にしているTortoiseHgのバージョンが違うんじゃないかと思うのですが、ここはひとまず諦めました...。(いくつかIssueに報告が上がっているようです)

5. そういえば日本語化されてない&なにか変....

20121210: 追記
gettextを先に入れてインストールしていれば、多分大丈夫です。下記は、入れ忘れてしまった場合に起きる症状と、対応となります。
アプリケーションからの起動はあきらめ、とりあえずコマンドラインから thg  で起動できるように、パスとシンボリックリンクを調整。
これでいざpushを!と思ったのですが、メニューが日本語化されていないことに気がつきました。設定メニューで調整できるのかなと思ったのですが、選択可能だったのが、en  のみ。
環境変数を切り替えたりしてみましたが、これもうまく行きませんでした。
TortoiseHgをはじめとする、TortoiseXXシリーズは、Windows環境側でもちょこちょこ使っていたので、ここは諦めて、目標のBitbucketにpushするところまで進めます。

5'. gettextを入れていなかった場合の対応方法 (20121210追記)

やっぱり日本語でないと....と思った方。まずはbrew install  gettext を実行します。あとは、TortoiseHgをビルドし直すか、日本語用のmoファイルだけを用意するといった2つの対応があります。今回は後者の対応を付加します。
1. 日本語用のメッセージファイルから moファイルを作成します。(~Documents/TortoiseHg以下にインストールした場合)
$ cd ~/Documents/TortoiseHg/
$ cd i18n/tortoisehg/
$ python ../msgfmt.py ja.po -o tortoisehg.mo

2. 所定のディレクトリに作成したmoファイルを配置します。
$ mkdir -p ~/Documents/TortoiseHg/locale/ja/LC_MESSAGES/
$ cp tortoisehg.mo !$

3.  あとは、LANGUAGE=ja もしくは TortoiseHgの言語設定でjaを指定すればOK。

6. Pushしたいんだけどhttpsからsshに切り替えたい!

だいたいはコードが修正済みで、SourceTree を使ってブランチを切ってpushしていました。あとはほんの少しの修正をし、defaultブランチにマージ、マージ後に、今回入れたTortoiseHgを使ってBitbucketにpushするのがゴールです。

まずはブランチ間のマージが成功。
次にリモートへのpushですが、これが上手く行きません!
どうやらhttpsでpushしに行ってしまうらしく、設定を変えないといけません。
こちらは、TortoiseHgからでも良いですが、ローカルリポジトリのフォルダから $ vi .hg/hgrc でhgrcファイルを編集すればOK。

これでようやく基本の操作ができました....。


* * *
という感じで、無理矢理TortoiseHgアドベントカレンダーに参加させていただく形となりました。結局中途半端で申し訳無いのですが、もう一回インストールしてみてちゃんと日本語メニューが使えそうになったら、再度ご報告したいと思います。
機会を下さった@cointoss1973さま、ありがとうございました!

念のため、現在のバージョン情報をご報告して、まとめとさせていただきます。-> 追記しました!
ちなみに、~Dcoments/TortoiseHg に入ったものは、インストールしたというよりは、リポジトリのソースをそのまま持ってきている感じなので、hg up 2.x  とかするとTortoiseHgのバージョンが切り替えできます。(依存するPythonの関係でちゃんと動くわけではないですが)

$ thg version
TortoiseHg Dialogs (version 2.5.1+29-1f7dfd2a0e6d), Mercurial (version 2.4+20121101)

Copyright (C) 2008-2012 Steve Borho and others.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

2012-11-30

多段SSHでRDP

通常は専用の環境や専用の接続クライアントを使ってリモートサーバの作業をするのですが、トラブルでうまく使えなかったり、環境がすぐに整えられなかったりした場合に、多段sshでの対応が必要。
今回はMacに切り替えた関係で、専用ツールがインストールできず、すぐにWindowsマシンも設定できないので、『ああ今日のメンテどうしよう!!』と慌てて足回りを用意しないといけなくなりました。

対象サーバはWindows Serverです。Webアプリの動作確認だけなら、標準的なhttp/httpsさえ通っていればいいのですが、今回は遠くのリモートサーバのサービスの起動やDBの確認をする必要があります。

手っ取り早くRemote Desktop接続できればいいので、標準で言うと3389番を飛ばせばOK。

しかし、これが毎回やり方忘れるのでメモ。

多段SSHでRDPのポート転送

$ ssh -t -L 13389:localhost:99999 user-A@server-A ssh -L 99999:server-C:3389 user-B@server-B

#みなさんの多段ssh記録とか、Tipsなんかも知りたいです。

2012-11-29

MacBook生活始めました。

Jenkinsシールを貼って愛用していたDELL Latitudeが諸事情により動かなくなってしまい、次はどうしたものかと考えていたのですが、周囲の薦めにより、Macに乗り換えることにしました。

私にとっては、実に1x年ぶりのMacです。最後に自分で買って使っていたのが、LC630(このことを書くと相当な年齢だとバレますが、まあ仕方がない...)。趣味+お勉強のために使っていた時期があったのです。
当時はターミナルも無しで、ほぼGUIだったので、逆に仕事で使い始めたWindowsマシンのほうが、もの凄〜く難しく思えました。

ですが、まあ仕事なので文句は言えませんので、それなりにWindows+一部Unixという生活で乗り切れるようになりました。

そんな自分は、もう二度とMacと付き合うことは無いだろうと思っていたのですが、なんだかんだ言ってもサーバに入ってターミナルは使うしShellも使うしで、そうなるとどうしてもrootで好き勝手できるUnixマシンが欲しくなります。(サーバのスクリプトを壊してしまったり、環境を壊すわけに行かないので...)

そんな折のMacOS Xです。
多分以前のMacOSだったら選択しなかったと思いますが、店頭でターミナルがササッと上がってシェルで操作できるのを見てしまうと、やっぱり良いな〜と思うようになりました。

周囲からも『たかのさんはMacがいいんじゃない?』と言われ、タイミング的にWindows8もどうかな〜と悩みつつ、MacBookProに決定しました。

なんというか、大正解(^^;

Windowsが嫌いな訳ではないし、業務アプリはWindowsでないとどうしても使えなかったりすることもあるし、自分が動作確認するためにもWindowsの環境は必要です。ただ、その環境はVMなどでまかなえる状態なので、メインが変わっても問題なしでした....。



2012-11-09

JenkinsからYammerに通知をしてみました。

そもそもはBuild通知というよりは、自分の部署のBlogにJenkinsがPOSTしたりすることがあるので、その通知をYammerに投げてくれると気がつくいて見にいけるんだけど…、みたいなコメントをスタッフからいただいたのが始まりです。

最初はSkypeAPIでの通知が良いなあと思ったのですが、Skypeの場合はSkypeクライアントを起動していないといけません。その点、Yammerだと基本はWebなので、APIをたたくかメール送信でPOSTができますので、幾分敷居が低くなります。
(とはいえ、社外のサービスではありますので、POSTする内容には十分配慮しないといけませんが…)

さて、どうやって通知させてみようかな…と思っていたら、ズバリ、Yammer Pluginというものがありました。

こちらのPluginのページ、とても丁寧な解説&スクリーンショットが載っています。英語がよくわからなくてもある程度は設定できてしまうのが有難い!

Jenkins yammer plugin 設定画面

しかし、それ以前に、こういったOAthを使ってアクセスするAPIを使うのは、実は初めてで、そもそもKeyやTokenを取得するところが敷居が高く、はてどうしたものか…というところでした(^^;

よくよくPluginのページを見ると、YammerでのOAthのtokenの取得方法が書かれていましたので、まずはこちらに従ってYammer上での作業を行いました。

1. Yammerに新しいアプリケーションを登録

その、「アプリケーション」ってほどのものじゃないんですけど…という申し訳無さを感じつつ、ひとまず “Register New App” をクリックして、登録画面を開きます。

名前は適当に入れました…。

jenkins-yammer-app-regist-form

Basic Configで設定したのは、下記の項目です。(よくわからなかったので…)

  • Application name
  • Organization
  • Website
  • Support e-mail

アイコンなんかも無しでも大丈夫で、この次、App Directory Config タブから、”Deploy to local App Directory” ボタンを押しました。Stepもまだまだ先にあるようですが、とりあえず下記のステップまででもTokenの取得は出来ています。(こちらは、下図のようにStatusタブで確認できます)

jenkins-yammer-app-regist

Deployしたら、Status Tabをクリックすると、下部にClient Key & Client Secretが表示されているのがわかります。

2. OAuth TokenをGETするには…

分かっている方には申し訳ないのですが、『わたしはこの後どうするんだー?』と悩むことしばし..。

やがてJenkins Yammer Pluginの説明を見返すと、『この get_auth.rb っていうスクリプトをダウンロードして、実行してね』と書かれているではありませんか!

ダウンロードしたスクリプトを ruby get_auth.rb で実行すると、ターミナルから対話形式でOAth Tokenの取得ができるようになっていました。ありがたや、ありがたや…。

処理は、下記のとおりです。

  • Client Key, Client Secretを入れる
  • 所定のURLにアクセスして、コードを取得してね、と言われる <- 実はここに気がつかなくてちょっと悩みました(^^;
  • 取得したコードを、再度コマンドラインにセットする
  • すると、スクリプトがOAuth Tokenを取ってきてくれて、yamlファイルに書き出してくれる!

おかげさまで、このPluginの利用に必要な、4つのパラメータが取得できました!

3. YammerにGroupを作ってPOSTしてみたよ!

さて、いよいよYammerにPOSTする準備が出来ました!
ですが、いきなり社内とはいえ自分のドメインのオープンなメッセージとしてPOSTするのは恥ずかしい…。

そこで、Pluginの図にもあったように、BuildNotificationという、ビルド通知専用のグループを作成してPOSTすることにしました。

せっかくなので@masanobuimaiさん作の、忍者Jenkinsをグループのアイコンに設定しました。(CacooストアでGETいたしました、ありがとうございます!)

jenkins-yammer-via-client

初POSTは、Sphinxドキュメントをビルドするジョブの通知。
『コンテンツのPublishingとか公開もビルドの一つ』と考えて、まずは差し障りのなさそうな、ドキュメントを生成するジョブが成功したらYammerにPOSTするものを設定してみました。

どうなるかなーと思いましたが、意外とあっさりYammerにPOST成功。

ただし、このPluginだと、複雑な文面をPOSTすることは出来なさそうです。かといってソースを見て自分で調整するのは未だできないので、RubyのYammer libraryを使ってもう少し遊びの文面をPOSTできるように企んでいます。
そもそも、OAuth Tokenの取得方法すら分からなかったのですが、このPluginを使うことで少しばかりやり方がわかったので、別Scriptで書いてみる気が出てきました(^^

おまけにもならないですが、ruby のYammerライブラリを使うと、こんな感じです。(Twitterライブラリとほぼおんなじ感じらしい)

require 'yammer'
# ログイン
Yammer.configure do |config|
config.consumer_key = 'アプリのatoken'
config.consumer_secret = 'アプリのsecret'
config.oauth_token = 'ユーザのatoken'
config.oauth_token_secret = 'ユーザのsecret'
end
Yammer.my_feed # タイムライン表示
Yammer.update(“POSTするよー”
)  #update メソッドでPOSTします

お願いなど:

ついつい浮かれて試してしまう性格なので、そもそもこんな使い方してはいけません!とか、これは危ないよ、といったご指摘もいただけると幸いです…。

2012-10-22

Jenkins勉強会#6でお話させていただきました。(スピーカー体験編)

「如何でしょうか?」と、お誘いをいただいたのが9月末。
LTでもいいから、いつか『こんなにお世話になってるんです!』という気持ちを伝えたいなあとは思っていたのですが、まさか一枠いただけるとは思っていませんでした…。

勉強会が夜なので、最大の難関は家人の協力を得ること。そして、子どもたち、家族みんなの当日のコンディションが万全であることでした。

幸いにも、家人に了解をもらうことがてきたので、この機会を無駄にしないように精一杯スライドを作ってみました。

#職場の皆様すみません…。この件でずいぶんエネルギー使ってしまってしまいました…。

それにしても、30分もお話するのは初めてでしたので、内容はともかく、お話をするという経験(体験)について書いてみます。
  • 18時会場ではありましたが、わたしの到着は17時45分くらい。川口さんはすでに会場でプロジェクタのチェック済みでした。
  • 川口さんへのご挨拶のあと、最前列に座らせていただき、電源確保、通信手段の確保のあと、プロジェクタ/スクリーンのチェックをしました。
    (時間ギリギリで会場入りして、会場の皆さんの前でスライド数枚を映す..というのは、さすがに恥ずかしかったし、ネタバレも恥ずかしかったので)
  • 恐れていた『スクリーンの縦横比が違っていた (16:9だった)』ということも無く、安心しました。
    ※ この件に関しては、パワポ職人の@tomohnさん(長沢さん)の資料が非常に参考になります
  • USTがあるということで、多分小さすぎて幾つかの図は潰れて見えないだろうと思いました。そのため、事前にスライドをSlideShareにアップして、同時にそちらも見ていただこうと思ったのですが、フォントの関係か、なかなかうまくSlideShareでの変換が出来ませんでした..。
  • 会場内スクリーンについては、後方にもう1つ設置して下さっていたので、そちらの写りもチェックしたところ、スタッフの方も一緒に確認して下さり、表示の微調整をして下さいました。
  • 自分の番になって、UST用のクリップ型マイクを付けて下さいと言われたのですが、うまい位置に付けられず、手間取ってしまいました…。
    結局首元にくっつける形で、みっともない思いをしてしまいました…。
    お話をする時には、胸ポケットのある服か、襟のついたシャツでないとダメですね(^^;
  • 実は、スライドはiPod touch(iPhoneじゃないのです) をリモコン代わりにして操作しようと考えていたのですが、前日に入れたi-Clickrを何度使っても途中のスライドでiPod側のi-Clickrが落ちてしまうので、欲は出さずに講演台でお話をすることにしました。
  • お話については、「もしかしたら時間あまるかな?」と思っていましたし、話す前に、23分でタイマーをセットしたのですが、ラスト1章のところでその時間を使い切っていました…。前半のんびりしすぎてしまったようです..。
残念だったのが、お話の最中に、会場の皆さんの表情とか様子を伺う余裕が持てなかったこと。

スライドのお話をするのが精いっぱいで、どうしても視線が手元のPCと、背後のスクリーンの方に行ってしまいました。(たぶん情けない姿をして話しているのではないかと…)

スライド棒読みではなくて、もっと余裕を持って、会場の皆さんの雰囲気や反応を掴みながらお話が出来るようになりたいなあ…としみじみ思いました。

想いを詰め込み過ぎたので、『継続的プレゼンテーション』はもちろんのこと、『継続的イベント参加』はでき無さそうです(^^;

* * *

備考になりますが….。今回のお話を頂く以前に、たまたま三省堂で目にした下記の本。 この本が、私の 『初めて勉強会で一枠話す』 ことへの不安に立ち向かうための、お守りみたいなものになってくれました。
なお、スライドの作り方や記述方法・話し方に関する本ではなく、プレゼンテーションに臨む際の心構え、不安・トラブルへの対応の仕方について書かれている本です。
  • 困った質問者がいたらどうしよう?
  • 突然PCの調子が悪くなり、スライドが映せなくなったらどうしよう?
  • 会場にほんの少ししか人がいなかったらどうしよう?
  • キャンセルしないといけなくなったらどうしよう?
  • どんな服装が良いだろう?
  • etc…
実際には、幸いトラブルもなく自分の枠をやり過ごすことができました。(時間とか自分の話はさておき…)
会場提供をして下さったNTTデータさまを始めとする、スタッフのみなさま、快適で立派な設備を利用させていただき、本当にありがとうございました!

2012-10-03

Oracle Application Testing Suiteハンズオンセミナー

先月、購読しているニュースレターで、Oracle社のハンズオンセミナーの案内を目にしました。

Oracleでは管理者系の無償セミナー、オンライントレーニングも多いので、そちらの面では以前お世話になりましたが、開発者向け・テストツールのセミナーは初めてです。やはりツールはデモやハンズオンでないとイメージがつかみにくいので、これは良いかも、と思い参加させていただくことにしました。

会場は青山のセンターで、人数は20名ほど。13時半~17時半の午後いっぱいのハンズオンでした。

実は、いつもお迎えの関係で、平日イベント等は17時15分には退出しないといけません。今回もとても面白いところだったのですが、中座する形となってしまい、主催して下さったOracleの方には大変申し訳ありませんでした…。
それでも、十分に『受けて良かった!』と思えるハンズオンでした。講師の方、スタッフの方、本当にありがとうございました!

では、以下レポートを。

* * *

Oracle Application Testing Suiteは、Enterprise Manager製品のうちの1つになります。

かいつまんでいうと、下記のことができます。(認識不足でしたらごめんなさい!)

1. Webアプリケーションの機能テスト/回帰テストの自動化

  1. シナリオに沿ったオペレータのWebからの操作をキャプチャ、解析し、テストコードに落とします。
  2. 落としたテストコードを、パラメータを調整したり、追加のテスト項目を加えたりして簡単に加工できます。
  3. CSVやDBなどのデータを元に、何十件もの機能テスト・回帰テストを自動実行できます。
    (コードを実行すると、Webブラウザが自動で起動し、入力やクリックといった操作を自動で行います)
  4. もちろんコマンドラインからの実行も出来ます。
  5. SoapやFlexのAMFプロトコルにも対応しています。

2. Webアプリケーションの負荷テスト

  1. シナリオに沿ったオペレータのWebからの操作を解析し、テストコードに落とします。
    (単純な負荷テストだと、いくつかの決まったURLを叩いてレスポンスを計測するといったものになりがち。このツールは、ユーザの操作に
    沿ったHTTPリクエストを発生させるコードを自動生成
    し、Javaのコードからリクエストを発生して負荷テストを行います)
  2. Cookieやセッション情報が必要なリクエストも生成できます。
  3. 段階的に負荷をかけていく(5分おきにリクエストを10%ずつ増加させていく)といったテストを実施できます。
  4. テストのソースコードを共有し、複数クライアントから効率的に多数の負荷を書けることができます。
  5. テストクライアントを拠点間に配置し実験することで、どの拠点・ネットワークがボトルネックになっているかもわかります。
  6. 負荷テスト中、対象サーバに対してSSHやSNMPのセッションを張り、サーバ側のCPUやIOといったメトリクスを収集することが出来ます
    この結果、テストの進行状況、結果とサーバ側のメトリクスを同時に時系列でチェックすることが出来ます。

あとは、ソースコード、テスト中のインシデント、不具合改修といった情報を一元管理できる情報共有基盤(コラボツール)としての機能もあります。

(MicrosoftのTFSのような機能?こちらはハンズオンでは紹介程度でした)

自分の社内でも、業務アプリがWebベースというものが少なくないので、これはなかなか良いかなと感じました。

ハンズオンの内容は、下記の通りです。

  1. ツールの紹介
  2. OpenScript(EclipseベースのIDE)を使ったWebの機能・回帰テストの作成
  3. OpenScript(EclipseベースのIDE)を使ったWebの負荷テストの作成

ハンズオン用のPC (Windows7) に、IDEとMedRecというデモ用のWebLogicが起動しており、このデモアプリに対してテストを行う形になっています。

下記に、簡単な図(メモ)をアップしておきます。残念ながらIDEは手元にありませんので、サンプル画面ではなくイラストで。見にくくてすみませんが…。


1. Webアプリケーションの機能テスト/回帰テストの自動化

まずはユーザ(テスター)が自然な流れに沿って入力を実施します。そこからキャプチャ、コードの自動生成をします。

まずはユーザ(テスター)が自然な流れに沿って、ブラウザで入力を実施します。そこからキャプチャ、コードの自動生成をします。

画面遷移するまでを1単位として、操作を記録しスクリーンショットも自動で所得されます。

ツールはEclipseをベースにしたものになっています。生成されるコードはJavaベースなので、Javaのソースコードとしてスクリプトを修正することも出来ます。(GUIでも問題無しです)

機能テストの自動実行

テストコードが生成されたら、条件を加えたり、テストを反復させたい場合のデータソースを指定して、あとは開始ボタンを押すだけ。テストがサクサク進みます!Seleniumでも同じことができますが、ポイントは、データソースを指定すれば、簡単に複数回のテストが自動で実行できる点です。


2. Webアプリケーションの負荷テスト

負荷テストのコード生成

負荷テストも、自然な操作に沿った順番でのリクエストを生成できます。まずはユーザ(テスター)が自然な流れに沿って入力を実施します。そこからコードの自動生成をします。

負荷テスト実施

負荷テストの場合はブラウザからの操作ではなく、JavaのプログラムがHTTPリクエストを生成し、流れに沿ってリクエストを発生させる事になります。

一気に負荷をかけたい場合、クライアント側でリクエストをたくさん発生させたくても、ネットワークインタフェースや帯域による制限で負荷をかけられないケースがあります。この場合は、テストコードをリポジトリに配置し、複数・異なる拠点から分散させて負荷をかけることが出来ます。

サーバの負荷は問題なけれど、ある拠点ではレスポンスが悪い…というパターンがあれば、ネットワーク的な問題を疑うことも出来ます。


3. 負荷テストといっしょにサーバのメトリクス収集・レポート

メトリクス集計

テスト担当者とサーバ管理者はふつう別々で、テスト実施後にログをもらって解析しないといけません…。
Oracle Application Testing Suiteの場合、テストを実行し、その記録をしつつ、ツールから対象サーバ側にSSHやパフォーマンスモニタ、SNMPといった方法でアクセスし、メトリクスを一緒に収集することが出来ます

ここは便利!

OSがLinuxだったらSSHで接続して、vmstatやiostatを実行する、OracleのDBならv$表のデータを収集する…といった定義がすでにあるので、対象OSと収集したいメトリクスを指定すればOKだったりします。

* * *

今回、内容ついていけるか心配だったのですが、前日にたまたまSeleniumを試していたことと、Jenkinsでの自動化にも慣れていたので、特に問題無しでした。

それどころか、負荷テストのコードが自動生成できてメトリクスも併せて収集できるというのは、非常に魅力的に思えました。ツールではありますがコマンドラインでの実行ができるので、Jenkinsと組み合わせて利用するといった例も紹介していただきました。

OracleとJenkinsか…と、なんとなく微妙なものも感じますが、それはさておき、こうなると、やってみたくなりますね。

* * *

また、こうしたツールの事例としては、『テスト』ではなく、『複雑なビジネスロジックを経由しないとデータを登録できないようなシステムに対して、大量のデータを手作業ではなく自動で登録するために使っている』、というようなケースもあるそうです。

私がなんとかうまく利用できないかな~と思っているのが、まさにここ。
ソフトウェア・プロダクト開発の現場が一番進んでいると思いますし、「そんなの当然じゃない!」と言う声が聞かれそうですが、そこから生まれたノウハウは、どこにでも応用できると思っています。

ヒューマンスキルで言えば、アジャイル開発とかスクラムの手法とか。
テクニカルスキルで言えば、テストや自動化の手法とか。

もちろんお値段もそれなりにしますので、実際に使うかどうかは判りませんが、Seleniumやその他のツールを利用して行くヒントにもなりました。

最後に、講師の方いわく、『4回同じことをする可能性があるなら、自動化するメリットがある』と仰っていました。この辺をキーにして、色々考えていけそうな気がしています。


なお、Oracleさまも含め、テストツールベンダがソフトウェアテストの普及のために立ち上げた、NPOの『ソフトウェアテスト技術振興協会』という団体があるそうです。

こちらで、「テストツールまるわかりガイド(入門編)」 (PDF) という資料も紹介していただきました。テスト関係の書籍は色々ありますが、ツールの視点ではあまりないので、わたしののような、ツールから興味を持つというタイプにはとてもいいかもしれません:)

2012-09-20

NetBeansがうまく起動しないとき

ほんのちょっとですが、久しぶりなのでメモエントリ。

JDKを入れ替えちゃったりして、古いJDKが無くなり、”jdkhomeが見つかりません” のようなエラーダイアログが出てNetBeansがうまく起動してくれなかった場合は、下記を調整。

${nb-install}/etc/netbeans.conf -> jdkhome=xxxxx の指定を正しいものに修正。

2012-07-14

Redmineのプラグインのポーティングメモ (to Redmine2.0.x)

今回の内容: Redmineのプラグインのポーティング情報、対応したプラグインは少しずつ増えてきているので、今回はテスト、Jenkins利用時にちょっと困った部分と自分なりの対応を書いてみます。ちょっと長いので、まとめを先に書くと、下記のとおりです。
  • 1. ポーティングのための参考URLはここが良いよ!
  • 2. RAILS_ENV=testのエラーの場合は、Redmine本体のGemfileを修正してみよう
  • 3. SimpleCovのレポートがCI上でできないときは、SimpleCov.start だけにしてみよう
ということで、もしポーティングでお悩みの方、これだけで解決できれば幸いです。
以下はこのポイント発見までの顛末です。
* * *

1. はじめに: ひとまずポーティング

必要に迫られて、少しずつ書くようになった、Redmineのプラグイン。これも、Redmine本体のバージョンが上がると、見直しをしないといけなくなります。
なぜなら、

Redmineのバージョンアップによる機能向上 >>>>>> 越えられない壁 >>>> プラグインによる機能追加

なので…。
自分の職場では、諸々の事情でまだRedmine1.3なので、そんなに困ってはいないのですが、いったん公開してしまったプラグインに関しては、ポーティングしないといけなくなります。特に、春先はRedmine1.4 –> Redmine2.0.xと、rubyのベースもRailsのバージョンも上がってさあ大変!

さすがにRedmine2.0のリリース近辺に対応することはできませんでした。
少し落ち着いてから、いろんなBlog上の情報,Redmine本家の情報,先行して対応しているプラグインのソースを頼りに対応開始。とくに下記のサイトは大変お世話になりました。ありがとうございます!
まずは小さいプラグイン (SiteFeedback / とくに公開してない) でポーティングの練習をし、その後 Banner, Issue Templateの順ですすめてみました。

2. RAILS_ENV=test にしてテストしたのだけれど…

ひとまずポーティングが完了したのですが、プラグインの幾つかはr-labsのJenkinsにお世話になっています。(RORもテストコードも良くわかっていないのですが、見よう見まねでテストコードを書き、Jenkinsでテストを通させていただいてます)
このジョブ、当然のことながら、いままでのステップを使ってソースだけ変わっても失敗…。せっかく勉強を兼ねてテストする習慣がついたのに、ここで挫折するのは勿体ない(?)
ということで、コマンドラインでのUnit Testから再度進めてみました。
そこで問題になったのが、ここ。

rake db:migrate RAILS_ENV=test が通らない!!

RAILS_ENV=production, RAILS_ENV=developmentは通るのですが、test の指定をすると、ことごとくrake taskが失敗してしまいます!
/usr/local/lib/ruby/1.9.1/test/unit.rb:167:in `block in non_options': file not found: db:migrate (ArgumentError)….
途中まではうまくいってたのに、上記のように、『そんなrake taskは無いよ(?)』といったメッセージが出てあえなく終了…。(おんなじrake taskはtest以外なら通ります)
こんな状態でどうやってテストしてるんだろう??r-labsのCode Reviewのジョブは通ってるのに??、と悩むこと一週間…。
やっと、Redmine本家で解決につながる情報を見つけました。
Toshi MARUYAMAさんのソースの通り、Gemfileを修正したところ、RAILS_ENV=test が通るようになりました…。(なお、RAILS_ENV=testのmigrationがNGなら、development or production用のDBを、そのままtest用に使うという方法もありなんですね)

3. CI(Jenkins)サーバ上で、SimpleCovのカバレッジレポートが出来ない!

RAILS_ENV=test 問題が解決しても、すぐにはテスト完璧!とは行かず、もちろん諸々直しています。書き方もちゃんと勉強してるわけではないし、RSpecとかって何?Fixturesでがんばります、な状態ですが、とにかく「カバレッジだけは高いパーセントを維持したい!」ということで、怪しいながら、ほぼほぼコードをカバーするようにテストコードを書いてみました。

#プラグインが既存のコントローラーに対するパッチだったりすると、全部カバーするには、テストコードも工夫しないといけないので、Redmine本体のtestディレクトリの中身も参考にするようになりました。

カバレッジについては、Rails3, ruby1.9, JenkinsなどのCIツールを使う場合は、SimpleCovを使うといいよ!という記事がたくさんあります。おかげ様で、その方法に従うと、自分のNotePC内で、コマンドラインでの実行では、綺麗なレポートが出てくれました。(Windows7, Ruby1.9です)
また、同じNotePC内で、Jenkinsを使ってテストを通した場合でも、綺麗なレポートが出てくれました。

ですが、r-labsのJenkinsを使ってみると、テストは通るものの、coverage/rcov 以下には、index.html しか生成されません!(で、テストは100%…)

なぜだろうと思い、ひとまず手近なCentOSで同じように組んでみたのですが、やっぱり、coverage/rcov 以下には、index.html のファイル1つしか出来ず、網羅しているコードについては何もなし。『こんな100%なんて嬉しくないよ~!!』という状態です。

なにかSimpleCovの問題に違いない....と思うこと一週間、ようやく同様の事例を発見!
コメントには『うちもだよー!』という書き込みが多数ありました。
対応としては、SimpleCov.start 'rails' じゃなくて、SimpleCov.start だけでオッケーというものが多く見受けられたので、その通りにすると、あっさり解決!
おかげさまで、サーバ上のJenkinsでもカバレッジレポートの表示が再度できるようになりました。

なお、Jenkinsに合わせた、SimpleCovの出力フォーマットだと、HTMLとしては地味な感じです。一方で、SimpleCovの標準のレポートは、それはそれは洒落ている感じです。

simplecov
わたしはデフォルトのほうがすきなので、JENKINSを使ってる(環境変数での切り替えですが)場合だけ、フォーマットを変えるという設定にしました。
if ENV['JENKINS'] == "true"
  SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
end
ということで、今回はここまで。
最後まで読んで下さった方、ありがとうございます!なにかの参考、ヒントになれば幸いです。

2012-07-12

Join Pluginを試す&Build pipline Pluginで表示してみる

 

とてもお世話になっているJenkinsさん、ほんとうにありがとうございます (_ _) 
さて、今回、こんな流れで処理を組んでみることになりました。

  • 『よーいドン!』で、処理時間の異なるジョブを同時に起動
  • 両方オッケーになったら後続のジョブにうつる。

このあたりの処理の組み方は、いろんな方法があるかと思います。

ただ、自分以外にも設定を調整してもらう必要があるので、ひとまずあんまりコードを書いたり、複雑な設定をしなくてもサクッと実現できそうなもの…と思って取り入れたのが、Join Pluginです。

せっかくなので、設定のスクリーンショットと、こんなふうに検証してみた、というのを載せてみます。

1. ジョブの準備

実際のジョブはいろんな処理をしますが、とにかくよーいドン、のあと時間差でジョブが終了するというものを確認するために、こんなジョブを用意しました。

試しているのはWindows Server上です。

  1. Nightly-1: 定時に起動する。ただし、後続の2、3のジョブを起動するだけで何もしない。
  2. Nightly-2: 1から起動。”ping –n 30 localhost” というWindowsバッチを起動するだけ。
  3. Nightly-3: 1から起動。”ping –n 20 localhost” というWindowsバッチを起動するだけ。問題なければ2よりも先に終わるハズ。
  4. Nightly-4: 2&3が両方成功した後に実行して欲しいジョブ。これも “ping –n 10 localhost” するだけ。
  5. Nightly-5: 4の終了後に実行。

2. Join Pluginでの設定

さて、実際の設定は、Nightly-1 で行います。

通常のように、後続ジョブとして2&3を設定しますが、さらに、Join Trigger というビルド後のオプションを使い、『全ての下流ジョブが完了したら実行するジョブ』を設定します。今回の例では、Nightly-4を設定します。

config

設定は、ほんとにこれだけです。なお、両方とも成功、というのではなく、両方不安定でもJoinさせるというオプションも選べます。(両方失敗してても、とにかく両方とも終わったらJoinさせる、ということも、いろんなプラグインを組み合わせれば可能です)

ちなみに、最初にこのプラグインを試したのは、1年以上前。説明は英語なので、文面は良く分からなかったのですが、プラグインのページに、スクリーンショットがたくさんあったのも決め手でした。
不明点は、とにかく設定して実際の動きを確かめるという、地味な?方法を取りました。

3. どんな動きになるのかな?

では、実際に処理を実行してみると…。
後続ジョブの追跡は、下記のようなプラグインを使うと判りやすくなります。

Dependencency Graph View を利用できればいいのですが、こちらは画像生成のために専用のライブラリ・バイナリ(graphviz)が必要で、マスタがWindows Serverの場合はちょっと無理?

ひとまず実績から流れをつかめればいいのであれば、後者2つはWindowsでも問題無しです。
とくにBuild Pipline Viewは、見ても楽しいし!

さらに、可視化された形でジョブの実行時間も把握できるし、いろんなアイコンをクリックすると、コンソール出力を表示できたり、途中からジョブを起動できたりと、おススメです。

4. Join Pluginを使ったケースでは?

お試しのケースでは、こんな表示になります。

Build No. 10では、Nightly-1を起点に、後続の2&3が並行して走ります。

設定上はどちらでもNightly-4を呼び出せるようになっていますが、最終的に、あとで完了するNightly-2が、Nightly-4を呼び出しているのが分かります。(Nightly-3からNightly-4の流れは設定としては存在していますが、水色になっていて、実行もされません)

jointrigger

次に、Build Number 11で、Nightly-3が必ず失敗するように設定を変えてみました。(Windowsサーバで、”ls-la” して失敗させる処理を追加)
Nightly-3が失敗すると、Nightly-2が成功しても、その後の処理には遷移していません。(水色になったままです)

ひとまず、検証目的で、pingを打つだけの簡単なジョブを組み合わせてみましたが、想定したような処理ができそうでした。

* * *

ここから実際に呼び出すプログラム、スクリプトをくっつけて、最終的に仕上げていくことになります。また、一連の処理を行っている時に、ほかのジョブが並行で走って欲しくはないケースもあるので、排他制御の設定を加えて行く感じになっています。(ビルドの同時実行数を制限したり、優先順位をつけたり、排他制御用のプラグインをつかったりします)

わたしはプログラムのビルド、テストという仕事ではJenkinsを使っていないので、今回も、ほんとにプラグインの紹介をするだけの内容になってしまいましたが、設定事例を載せてみましたので、何かのお役に立てたなら幸いです。

* * *

おわりに。

今月末には、Jenkinsユーザ・カンファレンス2012が開催されます。
わたしも申込みはしているのですが、ちょっと時間の工面が難しくなってきていて、怪しいです。でも、なんとか参加したいと思っています。

(話すのではなくて参加、というだけなので、偉そうなことは言えませんが…)

2012-07-06

運用ネタ: チケット削除しちゃったんですが…。

写真

技術ネタではないのですが、一応管理者としてRedmineを運用している中で、いろんな問い合わせやリクエストを受けます。
一応はご用件をお請けするものの、既存の仕組みやプラグインを使っていてもダメなケースもあります。

そんな中で、1件だけ、『チケット間違って削除しちゃいました!』という連絡がありました。

「ああ、そういえば削除されるとレコードはどうなるんだっけ?」と思い確認したのですが、destroy なので、やっぱり論理削除ではなくレコード的な削除でした。

「物理削除になっているので、バックアップから該当するデータをインポートしますか?」、と伺ったところ、その回については、ご本人がブラウザキャッシュから戻しましたとのことでご了解いただきました。(もちろんIDは変わっちゃってます)

『うっかり消した・間違った内容を書いちゃった』、という場合に、特にメールが出てしまう仕組みが仇になることもあります。なので、実はメールは嫌いです…(^^;

#その他にも、メール機能についてはいろんな理由があるのですが、管理者としては嫌いなのでした…。

2012-06-25

Jenkinsのプラグインのバイナリ(*.hpi) を手動で追加する場合

ネットワークに繋がらない場合は、Jenkinsのプラグインを追加する場合は、*.hpiを取得して所定のフォルダに格納します。(わたしの場合そういう環境も多いので…)

で、この際、公式のプラグインは、下記から取得できます。

Jenkins Wikiのプラグインのページには、このURLは書いてないみたいなので、メモ。

2012-05-26

nginxの設定調整

Skypeのbotを作りたい…という野望に関連して、BeProud社の方が書かれた、下記の本を参考にしていたところ…。

Webアプリケーションの性能を向上させるため、nginx+gunicornという組み合わせに置き換えるという章がありました。最初ここはサラッと読んで気が付いていなかったのですが、nginxのワーカプロセス (worker_process) は、CPU数に応じて調整できるとのこと…。

Redmineのサーバ(bulk) でもnginxを使っているのですが、この数字は調整した覚えがありません。

#unicornの方は、一応CPU数に応じたプロセスを設定しています。(ただしメモリとの兼ね合いで実際は数を調整です)

『あれ、Redmineのサーバではどうしてたっけ?』と気になって、設定を見ると、デフォルトの1のままでした(^^;

ここはまず調整。

Redmineの環境用としては、nginxはバックエンドのunicornへのアクセスを負荷分散させるだけの目的で動いている感じなので、そんなに細かい設定はしていません。

あと調整できる箇所と言えば、ログの書き込み場所とか、keepaliveとか。ひとまずここだけ調整して、再起動させています。

今回は、 worker_connections については1024のまま調整していません。こちらを増やす場合は、今の環境だとリソースの制限にひっかかるので、ulimitで確認、調整が要ります。

* * *

nginxについては、下記のURLで詳しく連載されているので、今後も参考にさせていただこうと思っています。

2012-05-02

まあ飲めや、なプラグイン

開発機のJenkinsのバージョンをそろそろ上げようかな、と思って、プラグイン周りの更新もチェックしていたところ…。

追加可能なプラグインに、Beer Pluginというのを発見。

説明がちょっとなので、まずは気軽にインストール。

その後、あるジョブの編集をしてみたのですが、Post build task以下のプラグインのチェックボックスには、それっぽいものは表れてきません…。

システム全体での設定が要るのかな、と思い、ふとサイドメニューを見たところ、”We need Beer” というリンクを発見。

beer

これかな、とおもってクリックすると、なにやら太字のメッセージと、ビールの画像が(^^;

『Emacs立ち上げたよー!ビールよこせー!』『RVMがおかしくなっちゃったよー!まあ飲めや!』みたいな文言です。

良いですね、こういうノリ…。

ランダムに出てくるメッセージと画像は募集中だそうです。
ここに追加すれば良いみたいですが、できればハードコードでなく設定で色々変えられるといいですね:) 

で、作者を見ると、@kohsukekawaさんだった…。

2012-05-01

Bitbucketにお引越しさせてみた。

既存のjQueryのライブラリを拡張して、適当に作ったので、あまり宣伝?していない小さなプラグインがあります。ただ、一番凄いのは、タブ用のjQueryライブラリを公開して下さった David Tang さんで、わたしはタブ用の画像をちょっと変えて、サイズ、位置を微調整したくらい..。

ライセンスとかもきちんと考えていなかったので、先方に確認しないといけない状態です。
※オリジナルのソースは、こちらです。 https://github.com/skaterdav85

さて、わたしのRedmineプラグインのソースを、GitからBitbucketに持っていくことにしました。
もちろん、Githubでも問題ないのですが、Bitbucketはプライベートリポジトリが無償で作れるということなので…。

お引越しには、WebのGUIを使ってみました。

import-bitbucket

そもそもGithub上でもプライベートではなかったので、URLを指定するくらいで、インポート作業が始まりました。

ステキなことに、インポート中のログが、黒いコンソールのような画面の上にバリバリと流れていきました。単純に…%進行中、といったプログレスバーだけでも出るのかな、と思っていたのですが、そういった想像の上を行っていて、見ていて楽しいものでした。

さらに、ご丁寧にも、インポート完了の旨は、メールでも通知がありました。

* * *

ちなみに、インポートの設定時、『やった~!うまくできそう!』と喜んでいたんですが、リポジトリのタイプにgitしか選択できないことに気が付いて、『あれ、gitのままじゃん』と首をかしげる自分…。

BitbucketというとMercurial、というイメージがあるせいで、git –> mercurialにインポートできると思い込んでおりました…orz

当然ながら、Github上のgitリポジトリなので、Bitbucketで取り込む際もgitになってしまいます。(というか、gitしか選べなかった)

参考までに、作っている小さなプラグインは、下記のような、単純な機能のプラグインです…。これを設置したおかげで、意外とユーザ共通のフォーラムが利用されるようになりました :)

sitefeedback

2012-04-19

Redmine1.4の準備 / 開発環境のメモ

Redmine1.4が先日リリースされました。

開発者向けには、複数リポジトリ対応が大きな目玉ですが、ベースも大きく変わり、Ruby1.8からRuby1.9対応になりました。
今すぐRedmineをアップグレードする必要は無いかもしれませんが、Rubyのバージョンが上がったことで、この流れについていけるようにしないと、どんどんその後のバージョンアップがしにくくなります。

UIの操作性、APIも改善されているので、バグレポートが上がってきて落ち着くと思われる5月の連休後くらいに、わたしの環境でも、バージョンアップをしたいなと考えています。
個人的には、この機能がとてもうれしい、と思っています。(チケットタイトルと本文の修正する方法が気が付きにくかったので)

  • Feature #7603: Please make editing issues more obvious than "Change properties (More)"

* * *

ご縁あって、プラグインの開発を本格的にするようになってから、NotePCにNetBeansというIDEを使い、さらにデバッグできる環境を用意しました。

この環境があるのとないのでは大違い。

さすがにスーパーエンジニアなみにはコードはかけませんが、プラグイン開発だけでない、Redmine本体で何か不具合報告があった際に、『どんな変数が来るんだろう』とか、『なにがエラーの原因なんだろう』というあたりが、断然分かりやすくなりました。

Redmineの開発サーバにもデータを同期させているので、より本番に近いデータで、問題を探ることもできるようになっています。

#欲を言えば、IDEでデバッグモードだと遅いので、マシンパワーが早いに越したことはないのですが、ログにトレースするだけのデバッグとは偉い違いです…。

この環境も、Windowsだと意外と整えにくく、Macが良いのか?と思いながら葛藤しています。

さて、この開発環境も、Rubyのバージョンアップに合わせて、調整しなおさないといけなくなりました。
Windows7 にRedmine1.4の環境を作る点は、@yohshiy さんの記事を参考にさせていただきました。ありがとうございます!

次はIDEです。
Windows7では、どうしてもmakeとかgccが無いので、ゴニョゴニョやらないと環境が整いません。Ruby1.9を入れて、NetBeansから起動することは意外と楽にできましたが、デバッガの利用がすぐにはできませんでした。

* * *

デバッグ環境のために必要なgemが、どうやらRuby本体の細かいバージョンにまで依存しているらしく、なかなかインストールできませんでした。
やっと入った組み合わせを、メモしておきます。

  • Ruby1.9のインストール先:C:\bin\ruby19
    • ruby 1.9.3p125 (2012-02-16) [i386-mingw32]
  • Redmine1.4に最低限必要なgemは、Bundlerで追加。
  • デバッグ環境の下準備に、DevKitをインストール。
  • デバッグ用のgem: C:\bin\ruby19\lib\ruby\gems\1.9.1\gems 以下に入れた
    • linecache19-0.5.13 (gem install linecache19-0.5.13.gem)
    • ruby-debug-base19-0.11.26 (gem install ruby-debug-base19-0.11.26.gem --with-include=C:\bin\ruby19\include\ruby-1.9.1\ruby-1.9.3-p125)
    • ruby-debug-ide19-0.4.12 (gem install ruby-debug-ide19)

ひとまず、この構成で、NetBeansからruby1.9を選択したときにも、FastDebuggerが有効になっていました。
ところが…。

NetBeans的にはデバッガが使える状態なのに、デバッグモードでRedmineを起動しようとすると、下記のエラーで上がってくれません..。

Fast Debugger (ruby-debug-ide 0.4.9) listens on :61055
script\server
C:/bin/ruby19/lib/ruby/gems/1.9.1/gems/ruby-debug-ide19-0.4.12/lib/ruby-debug-ide.rb:123:in `debug_load'
C:/bin/ruby19/lib/ruby/gems/1.9.1/gems/ruby-debug-ide19-0.4.12/lib/ruby-debug-ide.rb:123:in `debug_program'
C:/bin/ruby19/lib/ruby/gems/1.9.1/gems/ruby-debug-ide19-0.4.12/bin/rdebug-ide:90:in `<top (required)>'
C:/bin/ruby19/bin/rdebug-ide:23:in `load'
C:/bin/ruby19/bin/rdebug-ide:23:in `<main>'
Uncaught exception: cannot load such file -- script\server

どうも、script/server で起動するファイルを見つけられないようです。

いくつか検索したところ、それっぽい情報があり、ruby-debug-ide.rb をゴニョゴニョ修正したのですが、うまく行かず…。

しかたないので、エラーとして出てくる ruby-debug-ide.rb の 123行目あたりを、Redmineのパスにハードコードしたら動きました。

#bt = debug_load(Debugger::PROG_SCRIPT, options.stop, options.load_mode)
sr = "c:/bin/redmine-1.4.0/script/server" # d:/fourth is my project's root, obviously
bt = debug_load(sr, options.stop, options.load_mode)

ただ、これだとあんまりなので、

ps = Dir.pwd.chomp + '/script/server'
bt = debug_load(ps, options.stop, options.load_mode)

に修正してみました。script/server も、たしか script/rails server に変わるはずなので、Rails3のアプリだとここを直さないといけないでしょうか(^^;

[ FastDebuggerがうまく動かない件の参考URL ]

2012-03-14

Redmine REST API - 関連チケット、添付ファイル込み

あるチケットに関するPDF、添付ファイルと、同様に関連するチケットのPDF、添付ファイルをまとめて取得したいんだけど…みたいなリクエストを、ユーザさんからいただきました。

できれば、ボタン1つとか、コマンド1発で…(^^;

いろんな方法があるかと思いますが、思い浮かんだのはREST APIを使ってひたすらGETするのが良いかなあ、ということ。
RESTの機能もいろいろサポートされて来ているので、確認の意味でちょっとまとめます。

* * *

1. チケットのPDFをRESTで取ってくる
  • http://REDMINE_URL/issues/チケット番号.pdf?key=APIキー
2. チケットIDを指定し、添付ファイルと関連チケット情報込みのデータを取得する

チケットの基本のREST APIに include というパラメータをくっつけると、添付ファイル、関連チケット情報込みでデータが引っ張れます。journals をくっつけると、経過もくっつけます。

  • http://REDMINE_URL/issues/チケット番号?format=xml&include=relations,attachments&key=APIキー

[Redmine.org での例]

attachments 込みだと、下記のように、<content_url/>に添付ファイルの取得用のURLがくっついてきます。ここからダウンロードすれば良さそうかな?

<content_url>
http://www.redmine.org/attachments/download/6260/date_range_filter.png
</content_url
>

3. 関連チケット(だけ)を取得するURL

関連チケット『のみ』引っ張りたい場合はこちら。

  • http://REDMINE_URL/issues/チケット番号/relations?key=APIキー&format=xml (XMLの場合)
  • http://REDMINE_URL/issues/チケット番号/relations?key=APIキー&format=json (JSONの場合)

結果のXMLはこんな感じです。

<relations type="array">
<relation>
<id>7850</id>
<issue_id>197xx</issue_id>
<issue_to_id>73xx</issue_to_id>
<relation_type>relates</relation_type>
<delay/>
</relation>
<relation>
<id>7856</id>
<issue_id>19xxx</issue_id>
<issue_to_id>197xx</issue_to_id>
<relation_type>relates</relation_type>
<delay/>
</relation>
</relations>
チケット本体に include=relations と設定して取得したほうが良いかもしれませんね。
 

2012-02-24

第5回 Jenkins勉強会に参加させていただきました

Blogを書いたのが時間が経ってからなことと、内容も浅くて申し訳ありませんので、末尾の「参考」のところに、皆さんのBlogやTogetterのリンクを掲載させていただきました。

より深い情報をお探しの方は、参考の部分をご参照下さい。皆さんのお探しの情報に、無事たどり着けますように…。

* * *

では、はじまり。

Jenkinsさんのお誕生月の2月。勉強会があるということで、家族の許可を得る前にダメ元で申込み…。 意外にも許可が下り、参加できる運びとなりました。
まずは家族の協力に感謝しつつ、感想程度になってしまいますが、まとめを書かせていただきます。

はじまり:

さぼてんさん(@cactumanさん)の司会でスタート。
アイスブレイクでは、Jenkinsを何年くらい使っているかとか、どんな言語で利用しているか、挙手でのアンケート。
会場に限って言うと、LL言語では、RubyよりもPythonを使っている方が多い感じでした。(compass関連のせいでしょうか)
ビルド/CIメインではないので、『シェルは…?』と心の中で呟いていたのですが、さすがにその問いは無しでした(^^;

1. 川口さん :  「DEV@cloud Jenkins-as-a-Serviceの舞台裏」

  • DEV@CloudのJenkinsホスティング / Jenkinsのマスターは1000+
  • EC2がベース。個別のJVMで起動、個別のOSユーザ権限でマスターを稼働。
  • マスターに関しては個別のJVM上で稼働させたほうが、隔離が楽になる。
    また、一台の計算機上にたくさんのインスタンスを作ることが可能。
20111221-1
  • サービスの性質上、一般のJenkins(OSSで利用できるもの)とは違う形でカスタマイズが必要。
  • マスター上ではビルドができないようにする、SMTPサーバやJENKINS_URL、ドメイン設定などは固定なので、ユーザが変更できないように独自プラグインで対応。
  • JENKINS_HOMEはEBS上に配置。
  • APサーバとしてはTomcatを利用。
  • Jenkinsの外の世界(サーバ構成管理、監視といった部分)は、Chefを利用。Rubyの構成管理システム。
  • Chefはレシピと呼ばれる設定ファイルを書いて使う。ただ、ちょっと敷居が高いかも。
  • ただ、Chefから設定を流し込んでセットアップしてスレーブを起動…というのは時間がかかりすぎるので、あらかじめセットアップしたスレーブをAMI化しておく。
  • Chefは敷居が高いので、Puppetというツールも利用。少しずつ使っていこう。
  • スレーブの割り当てはProvidoreを利用。こちらもJenkinsの外側にある。
  • EC2からのスレーブの割り当ては時間がかかる。EBSのマウントも時間がかかる。
  • Linuxコンテナ(LXC)の話 => OSレベルの仮想化を行い、単一のカーネルで動いているんだけど、仮想化の中の仮想化の中の、さらに仮想化という形でスレーブとして稼働。
  • Jenkinsのモニタリングの勘所。
    モニタすべきはヒープ。nagiosをっ使って監視。
  • トラブル切り分け、対応、データ取集に、Groovyスクリプトが有効。
  • Scriptlet2.0からダウンロードして、Groovy Pluginを使って実際の運用に活用。
    良いScriptが出来たら、みんなContributeしてね!
  • 野良Jenkins増えていませんか?
と、ここまでメモを拾いだしたのですが、理解できる頭が無かったので、苦し紛れにイラストを…。勝手ながら申し訳ありません(_ _)

* * *

※Chefの話が紹介されていたので、『CloudBeesには、執事とシェフがいます』なんて呟きがあったような気がします。

でも、川口さんも仰っていた、Chefは敷居が高い…という点。確かデブサミで、DeNAの岩永さんも、同じように仰っていました。(岩永さんの場合は、そこから自分でTouryoというPerlのツールを作られていました!)

なにやら敷居が高そうなのと、同じ構成のサーバを量産する必要が今のところないのですが、確かにJenkinsは複数立ってきそうな感じなので、酷い目に合わないうちから、すこしづつ構成管理を覚えるのもいいのかもしれません。

2. 早瀬さん@楽天 : 「楽天での"Continuous Delivery"読書会について」

20120221-3

わたしは純粋なCIは行っていませんが、Jenkinsを通して、最近、Continuous Delivery, Continuous Feedback という言葉を知りました。
自分の部署は、社内の統計情報を集計加工し、必要な部署へレポートを作成し、届けるという仕事も行っています。Deliveryという意味で、もしかしたら今の仕事に持ち込んで、展開すべき考え方なのかも…と思って、興味を持った本だったので、タイムリーなお話しでした。

以下、ぱらぱらとしたキーワードですが、書きとめたことを。
  • その年のJolt Awordとして選ばれた本をぽっくアップして読書会をしようとYammerで呼びかけ。(なんと楽天のYammerでは、書き込みは英語、というスタイルだとか!ほんとですか~、中の人?)
  • なぜかすでに Continuous Delivery をGETした社員2名より、読むことになった。
  • Forth Railway Bridge という、イギリスで有名な橋の写真を使っている。
  • 橋はずっとメンテナンスが必要になるものであり、大量生産できる部品を使い、最初からメンテンスが発生することを前提として作られている。
    『開発』も、最初からメンテナンスのことを考えて行うべき –> Continuous Deliveryの考え方に。
  • 人間は『生産的』なことをすべきであり、そのためには『自動化』が鍵。継続的改善のための、『速い』フィードバックを得ることが大事。
    ここで自動化、CIにつながり、楽天内でのJenkins勉強会も開催となる。
  • 読書会という社内に閉じたイベントではあったものの、その事を社外に発信していったことで、色々良い方向に進んで行った。
  • Jenkins入門の佐藤さんに来てもらって、社内でイベントを行った。
  • 外国人を積極的に採用している企業の例として、TVの取材申し込みがあり、英語での読書会を取り上げてもらえた。
楽天での読書会に関しては、よしおかさんの記事もありましたので、合わせてリンクを掲載させていただきます。
早瀬さんの講演中、横から、『はやくアルコール!』といった雰囲気を醸し出していた、よしおかさんでした…。

3. 加藤さん@mixi : 「mixi における Jenkins の運用について」

いきなりの英語の自己紹介からスタート! 楽天様の英語の件は有名ですが、『mixi様も英語Onlyか~?』と、半分泣きそうになりましたが、本題は日本語で展開して下さいました(^^;

20120221-4

こちらも、ぱらぱらとしたキーワードですが、書きとめたことを。
  • ご自身は、「たんぽ」チームに所属。このチームは、『単純な、つまらない、簡単な仕事を無くす』のがミッションだ、とのこと。(ただ、これが『○○しましょう』みたいな標語、キャンペーンを展開するのではなく、本当に技術を駆使して自動化、効率化を図るお仕事です)
  • LL言語のケースでは、ビルドよりも『テストを通す』ことがメイン。
    構文チェック、単体テスト~インテグレーションテストはもちろん、テストのカバレッジ、構文チェック、メトリクス計測といった点にフォーカス。
  • mixiでのJenkinsマスターノードは3台。iOS, Android向け -> いわゆるBuild用。
  • mixiの(純粋な昔からの)サーバサイドはPerlがメイン。ビルドの必要のないLL言語だが、Jenkinsはたくさん使っている。 今回のお話は、Perl + Jenkins がメイン。
  • 分散してビルドするのではなく、マシンパワーの強いマスタ1本でテストを通す。(1時間~30分くらいでおわっちゃうらしい)
  • それでも長いので、recent job として、コミットした部分に関係するテストだけする、といった工夫もしている。
  • それも早く通して結果を確認するのが大事なので、テストサーバはVMじゃなく実機。(24コアとか) DBもローカルに持ったりしてテスト結果が早く判るようにしている。
  • ビルド結果はIRCで。最初はプラグインを使っていたが、メッセージをカスタマイズしたいので、Ikachanという仕組みを使っている。IkachanのhttpのエンドポイントにPOSTすれば、IRCへの通知を行ってくれる。
  • JenkinsはhttpのAPIがたくさんあるので、JavaやGroovyではない言語からでも利用しやすい。ここはとても好き。
  • レガシーコードであってもCIを。
    ただし、ただテストすれば良いというものではない。意味のあるテストをしよう
Perl+Jenkinsという組み合わせでのお話しは、とても新鮮でした。

紹介されていたPerlモジュールなどは、加藤さんご本人のBlogに記載してあるので、そちらをご覧いただいたほうが間違いがありませんので、下記の参考情報をどうぞ。

Perlはサーバの管理やテキストのちょっとした処理のためにちょこちょこ使って覚えていきました。
でも、テストコードを書く方法知らなかったので、これは今更申し訳ないですが、自分でもっと調べたいと思える内容でした。
Perlを始め、LL言語でのCIという方向でなら、今の環境でも勉強して少しづつ取り入れることが出来そうなので、これからのテーマにしていこうと思います。 そう思えた意味で、とてもためになったお話しでした!

LT. コ 文婷さん、胡 益さん@東大笹田研 : 「Smart Jenkins on Ruby」

Smart Jenkinsとは、昨年の電力不足 / 節電の影響でビルドできる時間が制限されてしまった、という難局から生み出された技術・プラグインです。
このLTで初めて知ったのですが、なるほど、電力事情が戻って来た今でも、応用できそうです。
上記のプラグイン自体はJavaのコードですが、さらに、こちらをRubyで書くということまで展開したとのこと。
ただ、質疑の中で、どうしてもJenkins本来のJavaのコードを呼び出す必要があるので、JRubyの方言みたいなものを使っています、とお話しされていました。

ちょうど当日の昼に、WEB+DB Pressの最新号を買っていて、ななめ読みした時に、『Rubyでプラグインが書けます』というコラムを発見。 ビルドに関しては無理そうですが、UIをカスタマイズする部分で、何かプラグイン書いてみたいな~と思っていたので、JavaではなくRubyで書けるというのは、とてもモチベーションが上るお話しでした。

なによりも、「逆境を転じて、その逆境をさえ、前進の一歩に加えて行く」という姿勢が素晴らしいと感じました。

ビアバッシュ:

自分の会社でも、内部での勉強会や技術報告会のようなものがあり、時間的に19時を超す場合は、ビアバッシュを開催していたりします。でも、わたしは時間制限で、自社のビアバッシュには参加したことがありません。

どういうわけか、外部のビアバッシュが最初になりました(^^;

ケータリング、飲み物の調達、テーブルのセッティングなどなど、楽天の皆さんが会の進行の間に、さりげなく行って下さっていました。(そしてビールは楽天様からのご提供!

生来うまくお話しするのが苦手なのと、開発現場にいる人間ではないので、お話しできるネタもなく、なかなかお声掛けすることができず..。フォローさせていただいている方も数名いらっしゃるはずなのですが、そこまでたどり着けず。

それでも、お話しして下さった方、有難うございました!

まとめ:

まずは、スタッフの皆様、会を支えて下さった楽天の皆様、本当に有難うございました! 久しぶりの夜のイベントで、また皆さんからのパワーを頂くことができました。
いつまでも『参加』という立場もどうかな…、いつかは何か(失敗しかないんだけど)お話ししてみたいなあ、と思うこのごろ。でも、発表者の皆さんの前に、やっぱりひるんでしまうのでした。

なかなか今後こうした会に参加できるかどうかは、先が見えてこないのですが、イラストネタ(?)とか、自分のできる方向で、自分が楽しんでいることや、とても助かっていることを、周りに伝えていけるようにしていこうと考えています。

最後に、ちょっとだけ笑わせてもらった一コマ。講演中、スライドとデモ(ブラウザ)の切り替えで、ちょっとMacの扱いに戸惑う川口さんでした。
20120221-2

参考:

ブログ / まとめ
技術 / サービス
プラグイン / スクリプト集
Jenkins Week関連
スピーカー資料

2012-02-03

バージョンアップの際に忘れていた..。

Redmine1.3へのバージョンアップが終わりました。先のバージョンアップよりは手順も分かっていて、そんなに問題ないかな…と思って数日。

ユーザさんからのエラーの指摘を受けて、ログを調査しようと思いました。

ログを参照する際に便利なのが、Logd plugin です。ターミナルでサーバに入らずとも便利…なのですが、問題のproduction.logをダウンロードしてじっくり眺めてみようと思ったところ、なにやら遅い。

ダウンロードしたファイルも、なにやら大きい。

…ログがローテートされていませんでした…orz

nginxのログはlogrotate.dにお任せしていますが、Redmineのログは、前回のバージョンアップ時から、railsの設定側にお任せすることにしていました。

logrotate.dでの設定の場合は、Redmineのディレクトリがシンボリックリンクで切替えられているなら問題なかったのですが、そうではなかったので、このログローテート用の**.rbを追加するのを忘れてしまっておりました!

気が付いた時点で、81MB…。

これくらいで済んで助かりました(^^;; いつになってもログ周りでなにか忘れてしまっています。チェックリストが本当に必要ですね。

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

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