Hatena::ブログ(Diary)

Emacs ひきこもり生活 このページをアンテナに追加 RSSフィード

2013-09-24

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

| 02:34 |  Gentooビルドクラスタを作りたいということ 多分次のGenTwooに向けて - Emacs ひきこもり生活 を含むブックマーク

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の出力が全部とれる。

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

f:id:meech:20130925023302p:image




で、なんでこんなのを作った(作っている)のかというと、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で書いてていいのか(

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

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

2013-07-01

PulseAudio使ってるならカーネルのSND_HDA_PREALLOC_SIZEは2048にしとけよ?って話

| 02:11 |  PulseAudio使ってるならカーネルのSND_HDA_PREALLOC_SIZEは2048にしとけよ?って話 - Emacs ひきこもり生活 を含むブックマーク

ここに書いてあるのそんまんまなんだけど

https://bugs.gentoo.org/show_bug.cgi?id=409625

PulseAudio使ってて、しかもサウンドがHDA IntelだったらSND_HDA_PREALLOC_SIZEってのをdefaultが64なのを2048にした方がいいらしい。

当該kernel configの説明にもそのように書いてあるのでGentoo使ってて、HDA Intelで、PulseAudio使っている人はいますぐ設定書きかえてカーネルビルドしよう。 3.10も出たしちょうどいいタイミングだよね。

2013-03-07

Ustした

| 01:16 |  Ustした - Emacs ひきこもり生活 を含むブックマーク

Ustでxyzshのebuild書きましたよ。 なんでかって、その、いい題材だったんで・・・・

録画はこちらー ってしたかったけど録画ボタンおしてなかったよ、ふへへへへへ

まとめ

  • autotools-utilsでautotoolsなpackageは楽にできるよ
    • PATCHES変数
    • AUTOTOOLS_AUTORECONF
    • AUTOTOOLS_IN_SOURCE_BUILD
  • QAは直そう
    • CFLAGSがうまくあたってない
    • LDFLAGSがうまくあたってない
    • ライブラリにSONAMEが設定されてない
    • stripされている
    • makeが直接呼ばれている ( $(MAKE) にする)
  • ライブラリのリンクはちゃんとしよう
    • libdlとかもちゃんとね。 (underlinkingされやすい)
    • ncursesは最近ライブラリの場所変わったりしてるよ (pkg-configでとれるからそれ使ってね)

定期的にできたらなーって思うけど、ネタが多分ないよう、的なあれもあるんで、こんなネタがいいなとかこんなのほしいとかこのバグ直せよ、とかどうぞどうぞ

2012-11-29

REQUIRED_USE

| 16:18 |  REQUIRED_USE - Emacs ひきこもり生活 を含むブックマーク

こんな emerge エラーを見たことはあるだろうか

Calculating dependencies \

!!! Problem resolving dependencies for sys-kernel/dracut
... done!

!!! The ebuild selected to satisfy "dracut" has unmet requirements.
- sys-kernel/dracut-024-r2::gentoo USE="(multilib) -debug -device-mapper -net -optimization (-selinux)" DRACUT_MODULES="btrfs lvm ssh-client syslogame -bootchart -caps -cifs -crypt -crypt-gpg -crypt-loop -dmraid -dmsquash-live -gensplash -iscsi -livenet -mdraid -multipath -nbd -nfs -plymouth -

  The following REQUIRED_USE flag constraints are unsatisfied:
    dracut_modules_lvm? ( device-mapper ) dracut_modules_ssh-client? ( net )

  The above constraints are a subset of the following complete expression:
    dracut_modules_crypt-gpg? ( dracut_modules_crypt ) dracut_modules_crypt-loop? ( dracut_modules_crypt ) dracut_modules_livenet? ( dracut_moduleslive ) dracut_modules_crypt? ( device-mapper ) dracut_modules_dmraid? ( device-mapper ) dracut_modules_dmsquash-live? ( device-mapper ) dracut_modut? ( device-mapper ) dracut_modules_lvm? ( device-mapper ) dracut_modules_cifs? ( net ) dracut_modules_iscsi? ( net ) dracut_modules_livenet? ( netmodules_nbd? ( net ) dracut_modules_nfs? ( net ) dracut_modules_ssh-client? ( net )

これには EAPI=4 から使える REQUIRED_USE というものが関係している。

けど、とりあえずどーすれば emerge できるんよ? という話から

注目するのは真ん中の

  The following REQUIRED_USE flag constraints are unsatisfied:
    dracut_modules_lvm? ( device-mapper ) dracut_modules_ssh-client? ( net )

読み方は

  • USE=dracut_modules_lvm がある時は USE=device-mapper も必要だよ。(でも、指定されてないよ)
  • USE=dracut_modules_ssh_client がある時は USE=net も必要だよ。(でも、指定されてないよ)

なので、 USE=device-mapperと USE=netを有効にしてあげるといい。 flaggie でやるならこんな感じ。

# flaggie dracut +device-mapper +net

そして、本題の REQUIRED_USE について

dracutには一番下に書いてあるように

    dracut_modules_crypt-gpg? ( dracut_modules_crypt ) dracut_modules_crypt-loop? ( dracut_modules_crypt ) dracut_modules_livenet? ( dracut_moduleslive ) dracut_modules_crypt? ( device-mapper ) dracut_modules_dmraid? ( device-mapper ) dracut_modules_dmsquash-live? ( device-mapper ) dracut_modut? ( device-mapper ) dracut_modules_lvm? ( device-mapper ) dracut_modules_cifs? ( net ) dracut_modules_iscsi? ( net ) dracut_modules_livenet? ( netmodules_nbd? ( net ) dracut_modules_nfs? ( net ) dracut_modules_ssh-client? ( net )

といった REQUIRED_USE が指定されている。 REQUIRED_USE はようするに、USE関係間の依存関係をしめすもの。

上の例だと全て、 "foo? ( bar )" の形をしていて 「USE=fooなら、 USE=barも必ず必要」という形式になっているが、他にも使えるフォーマットはある。

  • "foo? ( !bar )"
    • USE=foo なら、 USE=barはあってはならない
  • "foo? ( || ( bar baz quux ) )"
    • USE=foo なら bar,baz,quuxの少なくとも一つは有効になっていないといけない
  • "^^ ( foo bar baz )"
    • foo, bar, bazのどれが一つは有効になっていないといけない。 なおかつ、二つ以上有効にすることはできない
  • "|| ( foo bar baz )"
    • 上の 「USE=fooなら」がない版。 foo, bar, bazの少なくとも一つは有効になっていないといけない

さらに EAPI=5 からは "?? ( foo bar baz )" として、foo, bar, bazの中でどれか一つだけが有効・もしくは全て無効にならなければいけない、といった指定ができるようになっている。

結局のところ、ebuildがこれらを使って指定している中で、満たされていないものを Portageが真ん中のところに表示してくれていた、というわけ。

この指定を覚えておいて、適宜USEフラグをいじっていけばよい。

参考

EAPI Usage and Description ? Gentoo Development Guide

2012-11-09

新APIGentoo山盛り

| 02:49 |  新APIGentoo山盛り - Emacs ひきこもり生活 を含むブックマーク

はじめに

一部で人気を博しているというこの記事から二年もたったのでいい加減いろいろと新しくしていこうと思うんですね。新時代Gentooの福音的な感じでね。

やっぱり想定的にはインストールしたけど、これからどうすんべ? とか、なんとなーくわかってきたけどもう少し楽な方法はなかとかね?ってあたり。

ちなみに環境は testingなので紹介する機能の中にはまだstableでは使えないものもあるかもしれないですね。そのへんはご容赦を。

/etc/make.conf

やっぱり基本となるのはこのファイル。だけど /etc/make.confは/etc/portage/make.confに移動されています。知ってましたか? 新規インストールだけなんでとりあえずそんなに気にすることもないでしょう

*FLAGS
CFLAGS="-O2 -pipe -fomit-frame-pointer -march=corei7-avx -mcx16 -msahf -mno-movbe -maes -mpclmul -mpopcnt -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mavx -mavx2 -msse4.2 -msse4.1 -mno-lz-cnt -mrdrnd -mf16c -mfsgsbase --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=3072 -mtune=generic -frecord-gcc-switches"
CXXFLAGS="${CFLAGS}"
FFLAGS=${CFLAGS}
FCFLAGS=${CFLAGS}

昔と大きく変わってはいませんね。あいかわらず、 "-march=native -O2 -pipe -fomit-frame-pointer"を展開したものです。それと最後に "-frecord-gcc-switches"をつけています。これがあると、gccがどんなオプションでビルドされたかを記録してくれるので、portageがそれを見て、ユーザの設定したCFLAGSが反映されていないよ?といったチェックができるようになります。まあ、これは開発者用ですね

USE
USE="mmx sse sse2 X emacs ssse3 -ldap xft fbcon xinerama wifi midi cjk xcomposite -bluetooth policykit cdda m17n-lib hddtemp python perl v4l v4l2 threads nsplugin sse3 llvm vaapi vdpau dga win32codecs bash-completion pulseaudio avahi xattr zsh-completion gtk3 -cups alsa infinality"

昔よりだいぶコンパクトになりました。最近はUSEフラグは手動でいじるのではなく、"flaggie"というツールを使うことにしています。

たとえば、 media-libs/freetypeでUSE='infinality'したいなーと思ったら

# flaggie media-libs/freetype +infinality

と、することで、いちいち/etc/portage/package.useを開かなくてもコマンド一つで編集できます。もし typoしちゃっても

# flaggie media-libs/freetype +infinity
At argv[2]='+infinity': infinity seems to be an incorrect flag for media-libs/freetype

と聞いてくれるので安心です。パッケージごとではなく、グローバルに変えたい時には

# flaggie +cjk
# flaggie -cjk

のようにすればOKです。

FEATURES
FEATURES='-stricter parallel-install parallel-fetch preserve-libs'

portageのさまざまな機能をON/OFFするFEATUESです。開発者用のプロファイルでデフォルトになってる "stricter"を切ってます。これがあるといろんなものがemerge通らなくなるのでね orz

FEATURES='parallel-install'を使うことで、より細かいロックを使うことで、インストールをいままでよりも並列度を上げて実行しています。

そして、 FEATURES='preserved-libs' これはなかなか大事な機能。

まずはこの機能が動いてない時の話をします。

libBを使っているpkgAをemergeします。すると

pkgA-0.1 -> libB-0.1

こんなふうに、AからBへの実行時リンクが"libB-0.1"という名前で行なわれます。ここで、libBがアップデートされます。 emergeはlibB-0.2をインストールし、libB-0.1が削除されます。

pkgA-0.1 -> (libB-0.1)
             libB-0.2

すると、pkgAは実行時リンクするべき"libB-0.1"が見つからないので、実行できなくなります。解決するには、再度pkgAをemergeして、pkgAのリンクをlibB-0.2へと張りかえなければいけません。

こういった、「リンクが壊れたパッケージ」を捜し出してリビルドするツールが "revdep-rebuild"でした。しかし、このプログラムは確かに便利で確実ではあるものの、システムの全バイナリをスキャンするために遅いという問題点がありました。

また、ebuildではpreserve_old_libを呼び出して、残しておくべきライブラリを指定すると、昔のライブラリをコピーして残しておいてくれました。昔のライブラリが残っていれば、コマンドはいままで通りに動きます。あとは適宜revdep-ebuildではりかえるだけです。しかし、残ったライブラリは、リンクをはりかえた後にユーザが手動で削除する必要があり、忘れさられることがありました。

さて、そこでこんな仕事はportageに自動的にやらせればいい、ということになります。 FEATURES='preserved-libs' しておくことで

  • 過去のライブラリを残しておく
  • 新しいライブラリにはりかえるべきパッケージを認識する
  • それらをemerge @preserved-rebuildでリビルドする
  • ビルドが完了した時点で、過去のライブラリを削除する

といったことができるようになります。

この preserved-libsの機能はだいぶ前から portage-2.2系列には入っていたものの、portage-2.1系列には入っていませんでした。しかし、EAPI=5の変更の影響もあって、portage-2.1にもコードが入ることとなりました。とはいえ、デフォルトでは無効になっていますから、 FEATURES='preserved-libs' が必要になる、というわけです。

Rubyのこと
RUBY_TARGETS="ruby19"

rubyのパッケージでターゲットにしたい、rubyのvariantを列挙します。 いまのところ

  • ruby18
  • ruby19
  • ree18
  • jruby
  • rbx

が使えるみたいですね。

ちなみにいまでは ruby-1.9がデフォルトになっています。 Project:Ruby/Ruby 1.9 migration - Gentoo Wiki

起動あたりのこと
DRACUT_MODULES="btrfs syslog ssh"
GRUB_PLATFORMS="efi-64

もうすっかりGRUB2とinitrdを使っています。initrdは/usrが/と別パーティションであれば、必須です。udevが/usrがmountされてないと動かなくなっちゃったんですよねえ。

で、initrd作りには distro-neutralなinitrdを作ってくれるツールのdracutを使っています。上の DRACUT_MODULES はdracutのUSEフラグですね。

そして、下の方はGRUB2のUSEフラグ。 efi bootしています。

dracutの使い方は簡単で

# dracut /boot/initrd-<kernel version> <kernel version> --force

こんな感じ。 dracutは上書きをしてくれないので、--forceをつけていますが、そこはお好みで。

そして、grub2は

# grub2-mkconfig -o /boot/grub2/grub.cfg

とかしていると、インストールされているカーネルを見つけだしてgrub.cfgを勝手に作ってくれますね。便利なもんです。

このへんをカーネルをインストールするごとにやれば、いいわけですがまあめんどいですしうっかり忘れそうですよね。そこで、/root/bin/installkernel というファイルを使います。ここにスクリプトをおいておけば、カーネルでの make instalがこいつを実行してくれます。うちでは

#!/bin/bash

make modules_install # モジュールインストールする

/sbin/installkernel "$@" # カーネルインストールする

# initramfsの作成
[ -f /boot/initramfs-$1.img ] && mv /boot/initramfs-$1.img /boot/initramfs-$1.old.img
dracut /boot/initramfs-$1.img $1
ln -sf initramfs-$1.img /boot/initramfs.img

# Grubのメニュー更新
grub2-mkconfig -o /boot/grub2/grub.cfg       

こんな感じで実行しています。これで、一通りのカーネル更新時の作業が全て実行されます。

EAPI=5

最初に書いた通りこの記事は「新時代Gentooの福音的」ってことで、新しく採択されたEAPI=5についても書いていきます。 EAPIはebuild全体の書式とかを統括してるAPIですね。新しくなるとなにがいいの? 新しい革新的な機能がふえます。

Sub-SLOT

Sub-SLOTがユーザから見ると一番大きな変更となります。これは上でも書いた revdep-rebuild, preserved-libs の進化系です。 preserved-libs は確かにライブラリに起因するリビルドを楽にしてくれます。しかし、

  • emerge @preserved-rebuild が必要である
  • ライブラリに起因する問題しか解決できない

この2つの問題があります。1つ目は解説しなくてもわかるでしょうが、2つ目はどういうことでしょうか。 たとえば、現状、GentooではPerlの本体が更新された時に perl-cleanerコマンドを使って全てのperlのパッケージを新しいバージョンのものへリビルドしています。emergeでperlが更新されてから、perl-cleanerを実行するまでの間はperlのプログラムがうまく動かなかったりしますし、さらにはいっぱい更新した時なんかはうっかりperl-cleanerの実行を忘れているかもしれません。

そこで、Sub-SLOTというものが導入されます。SLOTは「同一パッケージでSLOTが異なるものを共存させる」ための仕組みですが、Sub-SLOTは「同一SLOTでAPIの変更(など)を指定する」ための仕組みです。たとえばdev-lang/perl-5.16.1でこれを使うなら

SLOT="0/${PV}"

のように書きます。一方で、perlのパッケージは

RDEPEND="dev-lang/perl:="
DEPEND="${RDEPEND}"

のように、":="をつけておきます。これをつけると、emergeした時に、その時のdev-lang/perlのSub-SLOTへの依存が記録されます。すなわち、ここでは "dev-lang/perl:0/5.16.1=" というように記録されます。

さて、この後perl本体が更新され、"dev-lang/perl-5.16.2"がemergeされる、とします。この時、package managerはさきほどの "dev-lang/perl:0/5.16.1=" をチェックし、「dev-lang/perl-5.16.2をインストールすることで、この依存関係が壊れること」を認識します。すると、package managerは依存が壊れるものをリビルドする形で解決しようとします。これによって、いままで python-udater, perl-cleaner, haskell-updater, revdep-rebuildなどなど、壊れた依存を直すためのコマンドの役割が全てemergeに吸収され、emergeだけでなにもかもすむようになります。(実際のところは、haskell-updaterは結構使いますが…haskellの依存はいろいろ特殊…)

ということで、このSub-SLOTですがまだまだportageのメインツリーにはそこまで入ってきていません。gentoo-hasekllのツリーでは積極的にとりいれていて、新しいものはどんどんと":=" を使ったものに書きかわっているようです。

その他?

他にもebuildを書く側としては newhogeが標準入力を使えるようになったり、use.stable.maskというstableな時だけmaskされるUSEを指定したりと便利なものは入っているのだけれど、これは開発者むけだからね…。ユーザ向けには結局、Sub-SLOTだけかも。

ネットワークのこと

wicdがコマンドから使えるし、いいよねー?とか思ってたけど、最近はGentooサポートらしきものもnetworkmanagerに入ったようなので、NetworkManagerを(ノートPCでは)使っています。

そして、NetworkManagerのコマンドラインツール nmcliがあるのでこれでつないだりする。

# nmcli dev wifi connect <SSID> password <password>

依存衝突のこと

emergeするとこんなのが出てくる日もある

WARNING: One or more updates have been skipped due to a dependency conflict:

net-misc/curl:0

  (net-misc/curl-7.28.0-r1::gentoo, ebuild scheduled for merge) conflicts with
    <net-misc/curl-7.27.0 required by (dev-cpp/libcmis-0.1.0-r1::gentoo, installed)

これは

  • net-misc/curl-7.28.0-r1::gentoo を emergeしたい (ebuild scheduled for merge)
  • けど、 インストールしてある "dev-cpp/libcmis-0.1.0-r1::gentoo"が "<net-misc/curl-7.27.0" に依存してる</li>

から、無理だよーってことを言ってる。

libcmisなんてこころあたりがないので、これがどのパッケージから呼ばれているのかを検索かけます。

# equery d libcmis
 * These packages depend on libcmis:
app-office/libreoffice-bin-3.5.5.3 (=dev-cpp/libcmis-0.1*)
                                   (<dev-cpp/libcmis-0.2)

というわけで、libreoffice-binのせいでした。 libreofficeにしたらいいのかもしれないけれども、めんどいのでこのconflictは放置、といったところですかね。

別のケース

dev-haskell/authenticate:0

  (dev-haskell/authenticate-1.3.1.2::gentoo-haskell, installed) pulled in by
    =dev-haskell/authenticate-1.3*:0/1.3.1.2= required by (dev-haskell/yesod-auth-1.1.1.4::gentoo-haskell, installed)

  (dev-haskell/authenticate-1.3.2::gentoo-haskell, ebuild scheduled for merge) pulled in by
    (no parents that aren't satisfied by other packages in this slot)
  • インストールされているyesod-authが "=dev-haskell/authenticate-1.3*:0/1.3.1.2="に依存
  • でも、dev-haskell/authenticate-1.3.2が更新でインストールされようとしている

これは上のSub-SLOTの例でpackage managerが自動的にyesod-authのrebuildをかけてくれるべきなんだけれど、推測に失敗している。

なので、手動で

emerge -1 authenticate yesod-auth

としてやると解決

依存のコンフリクトは結構迷うところなのでこれからも随時blogに書いていきたいところ。ただ、基本的なパターンは上の2つだと思う。

つまり

  • 心当たりがないなら、equeryを使ってどのパッケージがひっぱってきているかつきとめる
  • 仕方ないならあきらめる
  • とりあえずコンフリクトの登場人物を emerge -1 に渡してみる