ローファイ日記

出てくるコード片、ぼくが書いたものは断りがない場合 MIT License としています http://udzura.mit-license.org/

RbBCC + RubyGems で手軽に eBPF ツールを配布できるようにした

BCCRubyバインディングを開発しています。

udzura.hatenablog.jp

で、RbBCCを omnibus を使ってOSパッケージに固めて、配布することにしました(TODO: 今度ちゃんとGitHub Packagesにする)。

github.com

このパッケージはlibbccとそれが依存するライブラリを同梱した形で配布しているので、インストールしたらいきなり動かせると思います。 Ubuntu Focalであれば...。 Fedora 向けrpmはそのうち追加します。

なお、もしかしたら libgcc-s1 を追加でインストールしないと動かないかも。

インストール

GitHub release に上げている deb をそのまま入れられると思います。

$ sudo apt install libgcc-s1
$ wget https://github.com/udzura/omnibus-rbbcc/releases/download/0.6.3/rbbcc_0.6.3-1_amd64.deb
$ sudo apt install ./rbbcc_0.6.3-1_amd64.deb

rbbcc というコマンドが見えるようになります。 rbbcc は基本的には、パッケージ同梱のRubyバイナリのラッパーなので、rubyと同じオプションを認識し、同じようにスクリプトを渡せば動きます。

$ rbbcc --version
RbBCC: version 0.6.3
Using ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]

$ sudo rbbcc examples/bitehist.rb 
Tracing... Hit Ctrl-C to end. 
^C 
log2 histogram 
~~~~~~~~~~~~~~   
     kbytes              : count     distribution
         0 -> 1          : 3        |*                                       |
         2 -> 3          : 0        |                                        |
         4 -> 7          : 113      |****************************************|
         8 -> 15         : 31       |**********                              |
        16 -> 31         : 5        |*                                       |
        32 -> 63         : 7        |**                                      |
        64 -> 127        : 2        |                                        |
       128 -> 255        : 3        |*                                       |
...

RubyGemを用いたプラグイン機構

実はここが本題なんですが、Rubyっぽく拡張できるよう、RubyGemのプロジェクトを一定の規約で作成すればそのままインストールできるようにしました。RubyGemをプラグインとして使えるような機構を導入しています。

サンプルプラグインです。

github.com

やり方としては、まず、以下のようなRubyGemプロジェクトを作ります

  • gem名を rbbcc-* にして、rbbccをdependencyに加える
  • lib/rbbcc-*.rb で以下のように RbBCC::Plugin.register! を呼ぶ
require 'rbbcc/plugin'

RbBCC::Plugin.register!

パッケージ版rbbccから使う場合、以下のように同梱のgemコマンドで普通のgemとして入れてください。 specific_install を有効にしてるのでリポジトリを直接指定もできます。

$ sudo /opt/rbbcc/embedded/bin/gem specific_install https://github.com/udzura/rbbcc-hello.git
/usr/bin/git
git installing from https://github.com/udzura/rbbcc-hello.git
Cloning into '/tmp/d20201121-3347-1vqut3k'...
remote: Enumerating objects: 18, done.
remote: Counting objects: 100% (18/18), done.
remote: Compressing objects: 100% (15/15), done.
remote: Total 18 (delta 0), reused 18 (delta 0), pack-reused 0
Unpacking objects: 100% (18/18), 2.95 KiB | 1.48 MiB/s, done.
WARNING:  licenses is empty, but is recommended.  Use a license identifier from
http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.
WARNING:  description and summary are identical
WARNING:  open-ended dependency on rbbcc (>= 0) is not recommended
  use a bounded requirement, such as '~> x.y'
WARNING:  See http://guides.rubygems.org/specification-reference/ for help
  Successfully built RubyGem
  Name: rbbcc-hello
  Version: 0.1.0
  File: rbbcc-hello-0.1.0.gem
Successfully installed

これであとは、 rbbcc コマンドに --invoke オプションを渡せばgemに含んだスクリプトを簡単に起動することができます。

# さっきの `script/hello_plugin.rb` のbasenameを指定すればOK
$ sudo rbbcc --invoke hello_plugin
TIME(s)            COMM             PID    MESSAGE
1284.942654000     <...>            881    Hello, World!
1284.949131000     sshd             3397   Hello, World!
1284.994503000     sshd             3397   Hello, World!
1284.994642000     <...>            528    Hello, World!
1284.994938000     systemd-udevd    528    Hello, World!
1284.995183000     systemd-udevd    528    Hello, World!
1284.995399000     systemd-udevd    528    Hello, World!
1284.995604000     <...>            3400   Hello, World!
1284.995741000     systemd-udevd    528    Hello, World!
1284.996082000     systemd-udevd    528    Hello, World!
1284.996582000     systemd-udevd    528    Hello, World!
...

BCC は、運用開発のためのスクリプトを作っても配布したり共有したりについてうまい方法がなさそうな感想がありますが(まあ、単独のスクリプトを落とせばいいという話なんですが...) RubyGemsの仕組みに乗っかって手軽に公開とインストールができるようにしてみました。なので、Ruby版も使ってください(真顔)。


動作しない! 等あればIssueでお知らせください。

私もこれから本番投入しますので...。

github.com

[PR] BCC を使ったコンテナ単位のシステムコール呼び出し集計のツールのサンプル実装を解説しています。Python版ですが...

gihyo.jp