その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

OS X で Jenkins 公式の docker イメージを起動する

Jenkins の plugin を開発するにあたってローカルに Jenkins を立てる必要が出てきて,さてどうしたものかと思っていたら Jenkins が公式で docker イメージを出しているのでこれを使えば良いじゃん! ってことで使うことにしました.以下メモ.

前提

VirtualBox がマシンに入っている.

docker と boot2docker 入れる
$ brew install docker boot2docker
boot2docker を立ち上げる
$ boot2docker download
$ boot2docker init
$ boot2docker up
VirtualBox の App から boot2docker の仮想マシンの Port Forwarding の設定をする

スクリーンショット参照

f:id:moznion:20150804000830p:plain

Jenkins の docker イメージを立ち上げる
$ git clone git@github.com:jenkinsci/docker.git
$ pushd docker
$ docker run -p 8080:8080 -p 50000:50000 jenkins

そしてブラウザで localhost:8080 にアクセス

f:id:moznion:20150804000919p:plain

動いた,簡単!
とは言えローカルのプラグイン開発ならまだしも,これを実戦で運用していくとなるとまた話は変わってくるのでしょうね.大変そう……

その他

docker run 時に "Error response from daemon: client and server don't have same version (client : 1.19, server: 1.15)" みたいなエラーが出ることがありますが,こういう時は boot2docker の iso を新しくすれば良いので,

$ boot2docker stop
$ boot2docker delete
$ boot2docker download
$ boot2docker init
$ boot2docker up

としてやると OK.

Groovyで複数のコマンドを一気に実行したいんですけど〜って時

&& でつなげて複数のコマンドを実行したいみたいなことがままあって,まあ gradle とか書いてれば頻繁にあると思うんですけど,

'git add -u . && git ci -m "Yeah"'.execute()

みたいにやってみるもののこれは上手くいかない.
そこでどうするかというと

['sh', '-c',  'git add -u . && git ci -m "Yeah"'].execute()

という風にしてやればよろしい.sh にコマンドをグワッと押し込んで実行させるという男気! Windows? 適宜頑張りましょう.
便利ですね,以上です.

Groovyで特定のパス上でコマンド実行したいんですけど〜って時

特定のパスに移動してから外部コマンドを実行したいみたいなことがままあって,まあ gradle とか書いてれば頻繁にあると思うんですけど,

'cd /dokoka/no/path && rm foo'.execute()

みたいにやってみるもののこれは上手くいかない.
そこでどうするかというと

'rm foo'.execute([], new File('/dokka/no/path')

という風にしてやればよろしい.便利!


資料
ProcessGroovyMethods (Groovy 2.4.3)

Javaでkamipo traditionalを有効にする

kamipo traditional については以下の記事が詳しい.
ルーク!MySQLではkamipo TRADITIONALを使え! | おそらくはそれさえも平凡な日々

ところでこれをJava,というかJDBCで有効にするには以下のように書いてやるとよろしい.

try (final PreparedStatement preparedStatement = connection.prepareStatement(
    "SET SESSION sql_mode = 'TRADITIONAL,NO_AUTO_VALUE_ON_ZERO,ONLY_FULL_GROUP_BY';")) {
    // This is "kamipo TRADITIONAL". More strict, healthy, nice.
    // https://github.com/kamipo/etcfiles/blob/b8d7f2dc93567cb3de486197952ac8b048641d31/etc/my.cnf#L28
    preparedStatement.executeUpdate();
}

簡単ですね!!

plenv で stableperl を利用するの術 & stableperl の話

[追記]
(旧タイトル) Perl::Build (plenv) で stableperl が利用できるようになりました & stableperl の話

色々あって方法が変わったので内容を修正します


Perl::Build (plenv) で stableperl が利用できるようになりました & stableperl の話

Perl::Build 及び plenv で stableperl を取り扱うことが可能になりました.
Perl::Build 1.11 以降で stableperl 対応が有効になっています.

Perl::Build 側に Perl::Build->install_from_stableperl() というメソッドが追加されているので,
それを利用すると stableperl の tar玉をダウンロードして展開してビルドしてインストール,という事ができます.

また,最新の Perl::Build を plenv の build plugin として使用すると stableperl を plenv から
取り扱うことが可能となります.
こんな感じ;

$plenv install -l
Available versions:
 5.6.0
 5.6.1-TRIAL1
 5.6.1-TRIAL2
 5.6.1-TRIAL3
 5.6.1
 5.6.2
 ...
 stableperl-5.22.0-1.001

ご利用される方はご利用下さい.

そんなことをしなくても

$ plenv install --as=stableperl-5.22.0 http://stableperl.schmorp.de/dist/stableperl-5.22.0-1.001.tar.gz

このようにすれば入ります!!!!!!
(Thank you @miyagawa)

[追記ここまで]

stableperl について

stableperl の日本語の資料があんまり無いので併記しておきます.


stableperl についての情報は以下のウェブページを見るのが手っ取り早いと思います.


最初の一文を借用して stableperl を説明するならば
perlの安定性と互換性をオフィシャルのPerlポリシーに記載されたレベルにまで引き上げる (取り戻す)」
ことを目的とした distribution と言うことが出来るでしょう.
stableperl は standard perl の fork であり,AnyEvent や Coro, JSON::XS の作者で知られるところの
Marc Lehmann さんがメンテナを務めています.


特徴としては

  • 通常のメンテナンス期限を超えてもサポートされる *1
  • 後方互換性を *大変* 重視している
  • standard perl が修正を放棄したいくつかのバグを修正する (つもり)
  • 新機能の導入に対する意欲は低い.重要な修正については行う

というものが挙げられるでしょう.


こうした fork 版が出るに至った経緯ですが,これは上掲の記事中で再三示されているように
perl の互換性が (standard) perl 5.22 で損なわれたためです.
perl 5.22 は PP のレベルでは互換性が保たれていますが,内部実装に大きく手が加わったため,
内部 API を利用しているような凝った XS モジュールの中には正常に動作しなくなったものが出てきました.
例としては,Lehmann 氏の Coro や gfx 氏の Mouse (ただし ithread 環境下での話),
またそうした Mouse の問題に伴い Text::Xslate などが挙げられます.恐らく他にもあることでしょう.

そうした状況に Lehmann 氏が業を煮やした為に *2 *3
この度 stableperl という互換性維持を旗印にした fork 版が出たというのが経緯と見ることができます.


さて,そうした状況になってきたので我々はどうするべきかを考える必要があります.

stableperl は互換性が維持され,重要な修正 (fatal なバグ修正などでしょう) が入ることもアナウンスされ,
なおかつ通常の EOL 期日を超えてもサポートされることがポリシーとして掲げられていますから,
これを使っていくというのはひとつの手かもしれません.

しかしながら,「新機能を導入するモチベーションが低い」と書かれていることからも,
今後の standard perl との乖離が進んでいくことは必至でしょう.
なおかつ現状は stableperl は Lehmann 氏が1人でメンテナンスしているようなので *4
Lehmann 氏にがこの活動に飽きたり,あるいは何らかの事情でメンテナンスを続行できない状況になってしまったらゲームセットとなってしまいます.
そうなってしまった時に,じゃあ stableperl から standard perl に戻すぞ! となっても
その時の移行コストやリスクは決して低いものではないことが予想されます.


ので,

  • どうしても Coro (とかその他の動かないモジュール) を動かしたい時は stableperl を使う (あるいは standard perl の 5.20 以前を使う)
  • 動かないモジュールを別の代替モジュールに切り替えていく (standard perl に寄せていく)
  • Coro (とかその他の動かないモジュール) を動くように直す,あるいはそれらが直る事を祈る (standard perl に寄せていく)
  • あきらめる

あたりが落とし所なのかな〜という見方をしています (しかし Coro が直る未来が見えない).
個人的には動かないモジュールを別のモジュールに切り替えていくのが現実的な線なのかなあ,という気がしています (なお Text::Xslate は次の Major バージョンアップで Moo 化される見込みで,Mouse 由来の問題は解消される予定とのこと).


しかしながら今後 stableperl がどうなっていくかは分からないので,動静を見守る必要があるでしょう.
以上です.

*1:予定だと思います

*2:業を煮やした様子については上掲記事のこのパラグラフが分かりやすいでしょう; "Simply because the new set of perl 5 porters (the people maintaining the standard version of perl 5) have an abysmal track record of providing stable releases. They ignore the long-standing policy of keeping compatibility to existing code, and regularly break dozens or even hundreds of modules in new releases, often at a whim, stating they break things as they wish."

*3:とはいえ内部 API を触っているんだから……という意見もある

*4:映画 300 <スリーハンドレッド> を彷彿とさせますね

YAPC::Asia Tokyo 2015にて"Yet Another Perl Cooking"というタイトルで発表します

発表する運びとなりました.
主に上に書いてあるような事を話しますから,興味のある方は是非いらして下さい!!!


ところで,個人スポンサーのチケットが1枚余った風味なので誰か欲しい人いたら「YAPC行きたい!!!」というキーワードを添えてご連絡下さい.参加券だけ差し上げます(ノベルティは欲しいので……).

fluent-logger-mock-sender 書いた

fluentd (td-agent) をプロジェクトで使う際に,開発途中で「fluentd に対して正しい内容のログを飛ばせてるのかどうか」みたいな事をテストしたくなる瞬間というのがあると思います.

td-agent のモックサーバ的なものを立てて,そこに実際に payload を投げつけて内容を確認するというのでも良いとは思うんですが,もっとお手軽な感じで「送信自体しないで,インターナルなデータ構造に対してログをスタックしておく」という風にすることでテストやデバッグを簡単に出来るのではないか,ということでそういう動きをするSenderを書きました.Maven Central にも上げています.

使い方は synopsis に書いてある通りです.MockSender 経由で put したログについては fluentd に対して送信されず,代わりに MockSender 自体がメンバーとして保持している List に対してログが積まれていくという動作をします.そして然る後,MockSender#getFluentLogs() でそのリストを取ってきたり MockSender#clearFluentLogs() で全消去出来たり,ということができます.

Perl 時代は実行時に動的にFluent::Loggerのメソッドを書き換えることでこのような処理を実現していたのですが,Java ではそうした行いが困難なので書いた次第.

ところで fluent-logger-java の新しいバージョンでは logger が利用している Sender が簡単に取れるようになって便利ですね! ありがとうございます.