chimayというConsulと連動したmrubyスクリプトランナーを作っている
最近、takaishi/chimay というツールを作っていて結構形になってきたので、一度背景や目的などを整理する。
何これ?
Consul Eventをトリガーとし、渡されたURL(s3, http)からスクリプトをダウンロードしてきて実行するスクリプトランナー、それがchimayである(スクリプトランナーって用語は正しいのだろうか)。
たとえば、以下のようなmrubyスクリプトをS3に置いておく。
Chimay::Script.define do
run do
puts 'Chimay is peres trappistes!'
end
end
標準入力でchimayコマンドにURLを渡すと、URLからスクリプトをダウンロードして実行してくれる。
$ echo s3://example.com/script.rb | chimay
Chimay is peres trappistes!
Consul Event経由で実行する場合は以下のようにする。この場合、「run_script」イベントを監視している全ノードでS3からダウンロードしてスクリプトを実行する処理が走る。もちろん、consul eventコマンドで実行するノードを絞り込むことも可能だ。
$ consul event -name run_script s3://example.com/script.rb
Chimay is peres trappistes!
fujiwara/stretcher と似ていると思う方もいると思うが、アイデアはstretcherから貰ったもので、インターフェースも極力そろえたいと思っている。違いとしては、stretcherは基本的にデプロイのためのツールだが、chimayはmrubyスクリプトを実行するためのツールという点だろうか。
なぜ作っているのか
端的に書くと、以下のような背景がある。
- consul eventをトリガーとして、任意のスクリプトを動かしたい
- スクリプトの実装にはRubyを使いたい
- スクリプトを更新するコストが結構大きく、これを改善したい
Consulクラスタ上で何か処理を行う場合いくつか方法があって、eventというのはその中の1つ。クラスタの各ノードでイベントの発生を監視し、発生すると決められた処理を実行する。シェルスクリプトを動かしてもいいのだけど、自分の場合は少し複雑なことをやりたかったのでRubyでスクリプトを書いて、それを動かすようにした。
結構いい感じに動いていて、これはいいねということになったのだけど、しばらく使っているとちょっとずつ不便なところとか手を入れたいところがでてくる。普通に修正して各ノードにデプロイすればいいんだけど、ノード数が多いので「この修正量で全ノードにデプロイか…」とつい思ってしまうことがあった。デプロイフローを見直せばいいんだけど、せっかくなので別の方法でアプローチできないかな…ということでchimayを作り始めた。
目的は何?
Chimayを作り始めた目的だが、やはりConsulクラスタ上で実行するスクリプトのデプロイコストを下げるということが大きい。全ノードにAnsibleやChef、Puppetを当てるのは時間がかかる。特に、クラスタ内の任意の1台で何か処理をしたい、という場合だと、全ノードにスクリプトをデプロイするよりはS3からその都度ダウンロードした方が時間がかからなさそうだ。
後は、mruby-cliを使って1つツールを書いてみたかったというのもある。仕事で作った物を汎用化したいという願望があって、うまくうまくできそうなテーマが見つかったわけだ。
進捗どうですか
先週の土曜から始めたのだけど、スクリプトをダウンロードして実行する、というところは割と簡単に書けた。Consul Eventで動くようにするとか、実行するスクリプトに引数を渡すといったところでちょっと手間どった。特に引数は悩ましい。Consul Eventで渡せる値は1つだけで、foo arg1 arg2 のように引数を渡そうと思うとクォートで囲んだりする必要がある。今のところ、URLのクエリで渡す形にしているが、将来的に変更するかもしれない。
書いていて難しかったのは、mrbgemでどういうクラスやメソッドがあるのかを調べる方法がよくわからず、ソースを毎回見に行ってしまったところ。後、テストを動かすとどこかでSegmentationFaultしてしまい、原因がわかっていないのでテストを書けないところだ。テストが書けないのは非常に不便なので早めに原因を取り除きたい…
ある程度動くようになったとはいえまだまだ実装中で、テストもないので実際に使えるレベルになるのはもうちょっと先になりそう。