Slide 1

Slide 1 text

mrubyについて調べたはなし mrubyについて調べたはなし [email protected]

Slide 2

Slide 2 text

お品書き お品書き mrubyについて mruby使用事例 H2Oでmruby

Slide 3

Slide 3 text

mrubyについて mrubyについて

Slide 4

Slide 4 text

mruby mruby ISO標準(の一部)に準拠したRuby言語の軽量実装 ISO/IEC 30170:2012 組込での利用を想定して開発された mrubyのmは「embed(組込み)」の「m」 「Minimalistic」の「m」でもあるらしい https://www.iso.org/standard/59579.html

Slide 5

Slide 5 text

mruby mruby JIS/ISOに準拠することを意識して設計されている これは組込の領域では標準規格が非常に重視され る、という話があった為らしい 完全準拠ではないのは、JIS規格には組込環境に存在し ないかもしれないファイル入出力の規格が含まれている 為

Slide 6

Slide 6 text

mruby mruby 1.0.0のリリースは2014/02/09 CRuby 1.9系の構文と互換性があるように作られてい た 2018/07時点での最新バージョンは1.4.1 CRuby 2.0以降に追加された機能も追加されている

Slide 7

Slide 7 text

mruby mruby rbenv install mruby-1.4.1 $ mirb mirb - Embeddable Interactive Ruby Shell > MRUBY_VERSION => "1.4.1" > nil&.to_s => nil > {"a" => 1}.transform_values {|v| v * 2 } => {"a"=>2}

Slide 8

Slide 8 text

CRubyとの違い CRubyとの違い 言語仕様的にはほぼ同じ ただ、特殊変数が無効、Hashのキーに順序が無い、整数除 の結果が違う、require / loadが無い等々の違いがある Limitations and Differences: にまとまっている https://github.com/mruby/mruby/blob/master/doc/limitation

Slide 9

Slide 9 text

require / loadが無い require / loadが無い 実行時にライブラリを追加して機能拡張する事は出来 ない mrubyでは、機能拡張をしたい場合、mrubyのコンパイル 時に指定する必要がある 拡張ライブラリを組み込む為の仕組みとして、mrbgems というのがある

Slide 10

Slide 10 text

mrbgems mrbgems 名前でお察しのとおりgem的なもの mrubyに拡張ライブラリを組み込む為の仕組み mrubyビルド時に組み込みたいライブラリを指定する mruby本体に含まれているが、デフォルトでは含まれな い機能(evalやio等)もmrbgemsで追加出来る GitHubにあるファイルを直接指定する事も出来る

Slide 11

Slide 11 text

mrbgems mrbgems # build_config.rb conf.gem :core => 'mruby-eval' conf.gem :mgem => 'mruby-io' conf.gem :mgem => 'mruby-dir' conf.gem :mgem => 'mruby-mtest' conf.gem :mgem => 'mruby-onig-regexp' conf.gem :github => 'iij/mruby-require'

Slide 12

Slide 12 text

mrbgems mrbgems mruby本体に含まれているgemはcoreというキーで指定 する mgem-listに登録されているgemはmgemというキーで指 定する mgem-listに登録されていると依存関係の自動解決を よしなにやってくれる Gitリポジトリを直接指定する事も可能 github、bitbucket、gitが指定出来る https://github.com/mruby/mruby/tree/master/mrbgems https://github.com/mruby/mgem-list

Slide 13

Slide 13 text

mrbgems mrbgems require / loadを提供するgemもある 当然build時に追加する必要がある build_config.rbを編集して機能拡張したmrubyを使う rbenv等でmrubyをインストールしてそのまま使う、とい う事は無さそう https://github.com/iij/mruby-require

Slide 14

Slide 14 text

ここでのまとめ ここでのまとめ mrubyは組込での利用を想定して開発された 文法的にはCRubyと基本的には同じ ただ、コンパイル時にライブラリを指定する必要がある、 等の違いがある

Slide 15

Slide 15 text

ちなみに ちなみに

Slide 16

Slide 16 text

mruby/c mruby/c 「mruby/c」というプロダクトもある 「Rubyの特徴を引き継ぎつつ、プログラム実行時に必要 なメモリ消費量が従来のmrubyより少ないmrubyの実 装」 しまねソフト研究開発センターと国立大学法人九州工 業大学が共同で開発している

Slide 17

Slide 17 text

mruby/c mruby/c https://www.slideshare.net/shimane-itoc/et2017-mrubymrubyciot#15

Slide 18

Slide 18 text

mruby/c mruby/c 旭日酒造で使われている温度変化を測定するIoTシス テムはmruby/cを使っている 老舗酒造にて温度変化を測定するIoTシステムを開 発いたしました: RubyKaigi 2018での発表資料 Firmware programming with mruby/c: https://monstar- lab.com/shimane_iot_180426/ https://slide.rabbit- shocker.org/authors/hasumikin/rubykaigi2018/

Slide 19

Slide 19 text

mruby使用事例 mruby使用事例

Slide 20

Slide 20 text

※個人的に知っているツールについて記載しています。もっ ※個人的に知っているツールについて記載しています。もっ とこういうのもありますよ、というのがありましたらご教授下 とこういうのもありますよ、というのがありましたらご教授下 さい。 さい。

Slide 21

Slide 21 text

Itamaeのmruby実装 mrbgemとして実装されている mruby-cliを使ってシングルバイナリにしている シングルバイナリなので実行時にRubyがいらない Rubyがいらないので開発環境の構築にも便利 MItamae MItamae https://github.com/itamae-kitchen/mitamae https://github.com/hone/mruby-cli

Slide 22

Slide 22 text

"A utility for setting up a CLI with mruby that compiles binaries to Linux, OS X, and Windows." mrubyでCLIを作る為のボイラープレート 複数プラットフォーム向けのバイナリが作成出来る クロスコンパイル用のDockerイメージが提供されており Docker上でビルドを行う mruby-cli mruby-cli

Slide 23

Slide 23 text

mruby-cli-docker mruby-cli-docker ... # install osx cross compiling tools RUN cd /opt/ && \ git clone https://github.com/tpoechtrager/osxcross.git COPY MacOSX10.10.sdk.tar.bz2 /opt/osxcross/tarballs/ RUN echo "\n" | bash /opt/osxcross/build.sh RUN rm /opt/osxcross/tarballs/* ENV PATH /opt/osxcross/target/bin:$PATH ENV SHELL /bin/bash # install msitools RUN cd /tmp && wget https://launchpad.net/ubuntu/+archive/primary/+files/gcab_0.6.ori && tar -xf gcab_0.6.orig.tar.xz && cd gcab-0.6 && ./configure && make && make install https://github.com/hone/mruby-cli- docker/blob/master/Dockerfile

Slide 24

Slide 24 text

コンテナランタイム コンテナに関するLinux Kernelの機能を、選択・組み合 わせてコンテナを作成出来るようになっている こちらもmruby-cliを使用してシングルバイナリ haconiwa haconiwa https://github.com/haconiwa/haconiwa

Slide 25

Slide 25 text

Dockerが独自のDSL(Dockerfile)でコンテナを作成する のに対して、haconiwaではコンテナを作成するのに mruby(RubyのDSL)を使える それにより、プログラマブルに作成出来る mrubyでフック機能も定義出来る コンテナ終了後にメールを投げたい、特定のシグナル をうけた際に処理を実行したい、等々 haconiwa haconiwa

Slide 26

Slide 26 text

haconiwa haconiwa Namespace.unshare(Namespace::CLONE_NEWNS) Namespace.unshare(Namespace::CLONE_NEWPID) Mount.make_private "/" Mount.bind_mount "/var/lib/myroot", "/var/lib/haconiwa/root" Dir.chroot "/var/lib/haconiwa" Dir.chdir "/" c = Process.fork { Mount.mount "proc", "/proc", :type => "proc" Exec.exec "/bin/sh" } pid, ret = Process.waitpid2 c puts "Container exited with: #{ret.inspect}" https://github.com/haconiwa/haconiwa#programming-the- container-world-by-mruby

Slide 27

Slide 27 text

"H2O is a new generation HTTP server." mrubyが組み込まれており、リクエストハンドラとして mrubyのコードが実行出来るようになっている mrubyのソースがまるっとH2Oのソースに含まれてお り、H2Oビルド時にmrubyもbuildされる H2O H2O https://github.com/h2o/h2o/tree/master/deps/mruby

Slide 28

Slide 28 text

apacheやnginxにもmrubyを使えるようにする為の拡張が ある H2O H2O https://github.com/matsumotory/mod_mruby https://github.com/matsumotory/ngx_mruby

Slide 29

Slide 29 text

apacheやnginxの拡張と異なり、H2Oはコアに付属してお り、デフォルトでONになっている H2O自身でmruby向けの機能を提供してたりもする この辺りの話は後半で H2O H2O

Slide 30

Slide 30 text

組み込み系 組み込み系 mruby を搭載したマイコンボードがある(らしい) GR-CITRUS: enzi - mrubyラピッドプロトタイピングプラットフォーム: IoTアプリ開発フレームワークもある Plato - mruby IoT Framework: この辺り詳しい方がいたらお話うかがいたいです :pray: http://gadget.renesas.com/ja/product/citrus.html http://enzi.cc/ http://plato.click/

Slide 31

Slide 31 text

ここまでのまとめ ここまでのまとめ 組み込み系以外でもmrubyが使われているケースは割 とある 例えばプラグイン機能を提供するツールで、そのプラグ インをRubyで書けるようにしたい、というようなケースで も使えそう

Slide 32

Slide 32 text

H2Oでmruby H2Oでmruby

Slide 33

Slide 33 text

H2Oでmruby H2Oでmruby ここからはH2Oでmrubyを使う方法について説明します 普段Web系の仕事をしている身からすると、これが現 実的にmrubyを使うユースケースになりそうだった為 あと個人的に試したかったから

Slide 34

Slide 34 text

H2O/mruby H2O/mruby 先に説明した通り、H2Oではmrubyが組み込まれて(コン パイル時にmrubyを有効にした場合)おり、リクエストハン ドラとしてmrubyのコードを実行出来る リクエストハンドラのインターフェースはRackのSPECに 準拠

Slide 35

Slide 35 text

H2O/mruby H2O/mruby # h2o.conf(H2Oの設定ファイル) hosts: default: listen: port: 8080 paths: /hello: mruby.handler-file: /etc/h2o/scripts/hello.rb /: file.dir: /var/www/html file.dirlisting: ON access-log: /dev/stdout error-log: /dev/stderr # /etc/h2o/scripts/hello.rb Proc.new do |env| # HTTP status, Headers, Body [200, {'content-type' => 'text/plain'}, ["Hello world\n"]] end

Slide 36

Slide 36 text

H2O/mruby H2O/mruby コードはこちら $ docker run -p "8080:8080" -ti yyagi/h2o-mruby-server $ curl http://localhost:8080/hello https://github.com/y-yagi/h2o-mruby-server

Slide 37

Slide 37 text

mrubyでリクエストハンドラを書けると mrubyでリクエストハンドラを書けると 何が嬉しいか? 何が嬉しいか?

Slide 38

Slide 38 text

テストがかける テストがかける

Slide 39

Slide 39 text

H2O/mruby H2O/mruby 特定のIPからのアクセスのみ許容する、というハンドラを書く場合 # /etc/h2o/scripts/access_controler.rb class AccessController def call(env) if /\A172\.17\./.match(env["REMOTE_ADDR"]) # 399を返すと次のハンドラに処理をdelegate出来る [399, {}, []] else [403, {'content-type' => 'text/plain'}, ["access forbidden\n"]] end end end AccessController.new

Slide 40

Slide 40 text

H2O/mruby H2O/mruby # h2o.conf hosts: default: listen: port: 8080 paths: /: mruby.handler-file: /etc/h2o/scripts/access_controler.rb /hello: mruby.handler-file: /etc/h2o/scripts/hello.rb /: file.dir: /var/www/html file.dirlisting: ON

Slide 41

Slide 41 text

H2O/mrubyでテスト H2O/mrubyでテスト というmruby用のテス トフレームワークがある テストをするには、上記mrbgemを組み込んだmrubyが必 要 H2Oで使われているmrubyとバージョンを合わせる必要 もある https://github.com/iij/mruby-mtest

Slide 42

Slide 42 text

H2O/mrubyでテスト H2O/mrubyでテスト require "../scripts/access_controler" class AccessControllerTest < MTest::Unit::TestCase def test_access_allowed result = AccessController.new.call({"REMOTE_ADDR" => "172.17.0.1"}) assert_equal [399, {}, []], result end def test_access_forbidden result = AccessController.new.call({"REMOTE_ADDR" => "127.0.0.1"}) assert_equal [403, {'content-type' => 'text/plain'}, ["access forbidden\n"]], result end end

Slide 43

Slide 43 text

H2O/mrubyでテスト H2O/mrubyでテスト $ /path/to/mruby access_controler_test.rb # Running tests: .. Finished tests in 0.000389s, 5141.3882 tests/s, 5141.3882 assertions/s. 2 tests, 2 assertions, 0 failures, 0 errors, 0 skips

Slide 44

Slide 44 text

H2O/mruby H2O/mruby nginx / apacheのconfig fileでアクセス制御を記載してい た場合と比べて、テストが書ける事により安心感が得ら れる 普通にRubyのコードなので読みやすい(個人差がありま す)

Slide 45

Slide 45 text

H2O/mruby H2O/mruby 他にも、レスポンスの変更、DoS検出、リクエストの delegate等も出来る また、H2O本体でmruby用のメソッド・クラスを提供してお り、ハンドラの中でHTTP request(ノンブロックキング)を 投げたり、Redisに接続したりも出来る

Slide 46

Slide 46 text

H2O/mruby H2O/mruby H2Oが提供するHTTP request + RedisのAPIを作って、 郵便番号をキーに住所を返すAPIを作成 郵便番号はGETパラメータに指定する(e.g: /address?postcode=1000001) 住所の取得は、郵便番号住所検索API( )を利用 一度上記APIで結果を取得したら、その結果をRedisにキ ャッシュし、使いまわせるようにする https://postcode-jp.appspot.com

Slide 47

Slide 47 text

H2O/mruby H2O/mruby class Addresser def call(env) query = env["QUERY_STRING"] return unprocessable_entity if query.empty? postcode = query.split("=")[1] return unprocessable_entity if postcode.to_i.zero? [200, {"content-type" => "application/json"}, [fetch(postcode)]] end def unprocessable_entity res = "invalid request".to_json [422, {"content-type" => "application/json"}, [res]] end https://github.com/y-yagi/h2o-mruby- server/blob/master/scripts/addresser.rb

Slide 48

Slide 48 text

H2O/mruby H2O/mruby def fetch(postcode) redis = H2O::Redis.new(host: 'redis', port: 16379) redis.connect cached = redis.get(postcode.to_s).join if cached.nil? url = "https://postcode-jp.appspot.com/api/postcode? general=true&office=false&postcode=#{postcode}" status, _, body = http_request(url).join cached = body.join if status == 200 redis.set(postcode, cached.to_s).join end end cached end https://github.com/y-yagi/h2o-mruby- server/blob/master/scripts/addresser.rb

Slide 49

Slide 49 text

H2O/mruby H2O/mruby アプリケーションサーバより前にレスポンスを返せる、か つ、そのコードをRubyで書くことが出来る JSONじゃなく、静的なHTMLをまるまるキャッシュする、 みたいな事もやれそう

Slide 50

Slide 50 text

H2O/mruby H2O/mruby H2O組込みのクラスやメソッドはテストの際に直接呼べ ないので注意が必要 テストダブルを独自に準備する必要がある H2Oにmruby test modeを追加する、という構想があるら しいのでそれに期待 https://www.slideshare.net/ichitonagata/how-happy- they-became-with-h2omruby-and-the-future-of-http#31

Slide 51

Slide 51 text

まとめ まとめ

Slide 52

Slide 52 text

参考資料 参考資料 未来のサーバ基盤へのHaconiwa/mrubyの関わり / haconiwa-and-future-os H2O x mrubyで人はどれだけ幸せになれるのか How happy they became with H2O/mruby and the future of HTTP https://speakerdeck.com/udzura/haconiwa-and-future-os https://www.slideshare.net/ichitonagata/h2o-x-mruby- 72949986 https://www.slideshare.net/ichitonagata/how- happy-they-became-with-h2omruby-and-the-future-of- http

Slide 53

Slide 53 text

まとめ まとめ mrubyについて調べた内容をまとめました 使いどころが意外とあると思うのでやっていきましょう