Gentooビルドクラスタを作りたいということ 多分次のGenTwooに向けて

https://github.com/naota/portage-daemon

最近こんなのを作ってた。

linux.yaml

master:
  address: localhost
builder:
  command: sudo emerge -1 %s 2>&1 || true
  target: linux.amd64

fbsd.yaml

master:
  address: localhost
builder:
  command: ssh root@<IP> emerge -1 %s 2>&1 || true
  target: fbsd.x86

manager.yaml

master:
  address: localhost
manager:
  builder: Builder
  command: Command
  state-file: manager-state.dump

とかして、RabbitMQを起動してから "./builder linux.yaml", "./builder fbsd.yaml", "./manager manager.yaml"を起動する。

そして "./control manager.yaml build linux.amd64 newt"とかするとローカルで"emerge -1 newt"が走るし、"./control manager.yaml build fbsd.x86 freebsd-lib"とすると、どこかのIPのホストでsshこしに"emerge -1 freebsd-lib"が走る。今回はbuilderを"linux.amd64"と"fbsd.x86"を1つずつしか立ちあげてないけれど、別のyaml書いて、たとえば"linux.amd64"をうけつけてsshでどっかのGentoo Linux上でemerge -1するように書くとそっちにも適当に(たしかラウンドロビンに?)分散される。

emergeの結果はこのように確認できる。

% ./control manager.yaml jobs                  
86d3c69a-d35d-400e-b5fe-43131eb4bd94 New      linux.amd64       newt
e00c060f-7baf-4846-8100-fb7ab605d4e6 Done     linux.amd64       newt

左端がジョブのUUIDになっているので、これを使って結果を取得する。

% ./control manager.yaml result e00c060f-7baf-4846-8100-fb7ab605d4e6
Calculating dependencies  .. ... .. .. ... done!

>>> Verifying ebuild manifests

>>> Emerging (1 of 1) dev-libs/newt-0.52.15
 * newt-0.52.15.tar.gz SHA256 SHA512 WHIRLPOOL size ;-) ...              [ ok ]
...
ecompressdir: bzip2 -9 /usr/share/man
ecompressdir: bzip2 -9 /usr/share/doc

>>> Installing (1 of 1) dev-libs/newt-0.52.15
>>> Auto-cleaning packages...

>>> No outdated packages were found on your system.

 * GNU info directory index is up-to-date.

と、こんな感じでemergeの出力が全部とれる。

まあ、わかりにくいので図にしておくとこんな感じ




で、なんでこんなのを作った(作っている)のかというと、1つはGentooのbugzillaにバグレポがいっぱい来て自分の手元で再現実験したり、patch書いてそれが直ってるか確認したりするんだけど、いくつも平行でやってるとどれがどういう状況だったのか忘れてしまったり、emergeが多くなりすぎて重くなったりして困ることである。これを使えば1つのマシンで走るemergeは高々1つになるし、出力もちゃんと(一応)永続的に確認できる。

もう1つは「次の世代のGenTwoo」を実現するため。GenTwooはもともともっとバグレポなどのコラボレーションの敷居というのを下げたいという目的で作っている。最終的にはとりあえず起動しているだけでなにかしらの貢献ができる、という形にしたいのだ。たとえば、新しく入ったebuildが本当にビルドできるのかどうかチェックしたり、ビルドしてエラーが出たらその出力を開発者のところに送りかえしたり、うまくビルドできたという情報・エラーが出ているという情報を集めて統計をとってどのぐらいebuildが安定しているのかの指標にしたり、その指標に従って自動アップデートがかかるかどうかの参考にしたり、バイナリパッケージを提供したりする。そのようなつながりを持ったdistroを実現したいのだ。

その第一歩として、とりあえずビルド命令を受け付けるプロセスは全てローカルで動く(だからsshでemergeの走るマシンにつなぐ)・標準出力がそのまんま結果としてとれる・実行の指定はシェルコマンドそのまんまという大変に原始的な形だが一応クラスタにできそーなものを作ってみた。

これから

  • emerge出力の解析によるエラー判定
    • それを使ったUSEフラグの調整など
  • リモートでビルド命令を受け付けできる
  • ebuildにこのpatchをあてた状態でemergeとかUSEをこうしてなど、編集を加えたemergeの実現
  • バイナリパッケージをキャッシュしクラスタ上のマシンに提供するプログラム
  • 隔離された環境(kvmlxrなど)でのemergeを実現する
  • SQLiteとかDBを使う
  • ほんとにHaskellで書いてていいのか(

などとやりたいことは多いし、実際にインターネット越しに展開しようとするとセキュリティ面で考慮することはもっと多いだろう。

まあ、でもこんなことをやりたいしやれたらおもしれーんじゃないかな、と思っている。