GentooからPortageを完全に削除してPaludisを使おう

前回はPortageの代替としてPaludisとpkgcoreを紹介しました。では、いっそGentooからPortageを消してしまうとどうなるの、という話です。

Portageを消してしまおう

PaludisのFAQを見ると、こう書いてあります。

Remove Portage from my Gentoo installation

The short answer is that you can't.

Several Gentoo packages wrongly depend on Portage, several depend on Portage because they use it and there really is no reason to try. Just leave Portage installed.

この文書は既に古いという意見もあります。そこにはこう書いてあります。

Are there still lots of packages that use Portage but don't say so? e.g. gcc-config...

とにかく色々と問題はありそうなわけですね。

でも消します。

消してしまってから考える

cave uninstall sys-apps/portage --uninstalls-may-break virtual/package-manager --uninstalls-may-break app-admin/python-updater -x
rm -rf /etc/make.conf /etc/make.profile /etc/make.globals /etc/portage /usr/portage /var/lib/portage /var/cache/portage /var/tmp/portage

virtual/package-managerとapp-admin/python-updaterのportageへのDEPENDはいずれもchoice dependencyだったので、無視させました。
Portageの設定ファイルなどが残っていると、それを利用するコマンドもありそうなので、全て消します。また、gentooリポジトリやworldファイルの配置場所なども全てPortageのデフォルトと別の場所になるようにPaludisを設定しています*1

では問題をひとつひとつ解決していきます。

設定ファイルの更新コマンドがない

パッケージアップグレードでCONFIG_PROTECTされた設定ファイルが置き替えられる場合、それをマージするためのコマンドが必要です。etc-update, dispatch-confはsys-apps/portageに含まれるコマンドなので、Portageを消すと当然使えなくなります。以下の代替コマンドがあります。

このうち、Portage以外のパッケージマネージャ対応という点ではcfg-updateが一番良いようです。オプション--paludisを付けることでPaludisの設定を利用して実行されます。

cfg-update -l --paludis
cfg-update -u --paludis
env-updateがない

/etc/profile.envおよび/etc/ld.so.confの生成を行うenv-updateもsys-apps/portageに含まれているので、当然使えなくなります。これはapp-admin/eselectの基本モジュール、eselect.envで代替できます。

eselect env update
eselect env update --noldconfig

gcc-configが動かない

sys-devel/gcc-configはPortageが無いと動かないらしいですね。やってみましょう。

amd64vbox ~ # gcc-config -l
 * gcc-config: Could not get portage CHOST!
 * gcc-config: You should verify that CHOST is set in one of these places:
 * gcc-config:  - //etc/portage/make.conf
 * gcc-config:  - active environment

はい動きません。
システムにpythonがある場合にはportageqコマンドでCHOSTを取得してますね。あとで書きますが、Pythonは消せないので他の手段を探します。変数REAL_CHOSTが定義されていればそれを使ってくれるみたいなので、やってみます。

amd64vbox ~ # REAL_CHOST="x86_64-pc-linux-gnu" gcc-config -l
 [1] x86_64-pc-linux-gnu-4.4.6 *
 [2] x86_64-pc-linux-gnu-4.5.3
amd64vbox ~ # REAL_CHOST="x86_64-pc-linux-gnu" gcc-config 2
 * Switching native-compiler to x86_64-pc-linux-gnu-4.5.3 ...
/usr/bin/gcc-config: line 362: env-update: command not found

 * env-update failed to work properly; making sure ld.so.conf paths
 * are setup properly.  Please rerun gcc-config with the -f option.
 [ ok ]

今度はエラーにはなりませんでしたが、env-updateが無いと言われています。eselect env updateで代替できるのはわかっているので、ごまかします。

/usr/local/sbin/env-update
#!/bin/bash
eselect env update
binutils-configも動かない

sys-devel/binutils-configもgcc-configと似たようなことになります。

amd64vbox ~ # binutils-config -c
/usr/bin/binutils-config: line 314: portageq: command not found
 * binutils-config: No binutils profile is active!

変数CHOSTが正しく定義されていれば実行できます。

amd64vbox ~ # CHOST="x86_64-pc-linux-gnu" binutils-config -c
x86_64-pc-linux-gnu-2.21.1

実際に設定を変更する場合には、gcc-configと同様にenv-updateが呼ばれます。これまたgcc-config同様、env-update実行が失敗しても警告を出すだけで正常終了します。

ちなみに、gcc-config, binutils-configはgccbinutilsのインストール時にtoolchain{-binutils}.eclassから呼ばれます。Paludisのebuild処理においてはCHOST及びREAL_CHOSTが定義済みなので、エラーにはなりません*2

どこかで問題が出るかもしれませんが、REAL_CHOSTとCHOSTを環境変数にしてしまえば毎回指定しなくても済みますね。

/etc/env.d/00real-chost
REAL_CHOST="x86_64-pc-linux-gnu"
CHOST="${REAL_CHOST}"

Gentoo黒魔術の大物、Java

Java周りはかなりやっかいです。

dev-java/java-config-wrapperに含まれるjava-1.5-fixerはemergeを使用します。java-check-environmentはportageqを使用します。なので、Portageを削除すると色々と動かなくなります。
dev-java/java-configに含まれるdepend-java-queryはPortagePython Moduleを利用するので、正常に動かなくなります。

それだけなら別にいいんですが(よくない)、この辺りのコマンド類はjava-*.eclassで利用されるため、Java関係のパッケージのインストールが軒並み失敗するようになります。
例えばこんな感じ。

>>> Starting pkg_setup
!!! ERROR: No module named portage_dep
 * Unable to determine VM for building from dependencies:

Error:
  * In program cave perform install --hooks --managed-output --output-exclusivity with-others =media-libs/libjpeg-turbo-1.2.0-r1:0::gentoo --destination installed --replacing =media-libs/libjpeg-turbo-1.2.0-r1:0::installed --x-of-y 15 of 15:
  * When installing 'media-libs/libjpeg-turbo-1.2.0-r1:0::gentoo' replacing { 'media-libs/libjpeg-turbo-1.2.0-r1:0::installed' }:
  * When running an ebuild command on 'media-libs/libjpeg-turbo-1.2.0-r1:0::gentoo':
  * Install failed for 'media-libs/libjpeg-turbo-1.2.0-r1:0::gentoo' (paludis::ActionFailedError)

NV_DEPEND: !media-libs/jpeg:0
	amd64? ( || ( dev-lang/nasm dev-lang/yasm ) )
	x86? ( || ( dev-lang/nasm dev-lang/yasm ) )
	amd64-linux? ( || ( dev-lang/nasm dev-lang/yasm ) )
	x86-linux? ( || ( dev-lang/nasm dev-lang/yasm ) )
	java? ( >=virtual/jdk-1.5 )           java? ( >=dev-java/java-config-2.1.9-r1  )    

!!! ERROR in media-libs/libjpeg-turbo-1.2.0-r1::gentoo:
!!! In java-pkg_switch-vm at line 4473
!!! Failed to determine VM for building.

!!! Call stack:
!!!    * java-pkg_switch-vm (/var/tmp/paludis/media-libs-libjpeg-turbo-1.2.0-r1/temp/loadsaveenv:4473)
!!!    * java-pkg_init (/var/tmp/paludis/media-libs-libjpeg-turbo-1.2.0-r1/temp/loadsaveenv:3950)
!!!    * java-pkg-opt-2_pkg_setup (/var/tmp/paludis/media-libs-libjpeg-turbo-1.2.0-r1/temp/loadsaveenv:3211)
!!!    * pkg_setup (/var/tmp/paludis/media-libs-libjpeg-turbo-1.2.0-r1/temp/loadsaveenv:5188)
!!!    * ebuild_f_setup (/usr/libexec/paludis/0/pkg_setup.bash:43)
!!!    * ebuild_main (/usr/libexec/paludis/ebuild.bash:646)
!!!    * main (/usr/libexec/paludis/ebuild.bash:672)

diefunc: making ebuild PID 11027 exit with error
die trap: exiting with error.

Failed install to / for media-libs/libjpeg-turbo-1.2.0-r1:0::gentoo replacing 1.2.0-r1:0::installed

このエラーに関しては、depend-java-queryはPortageのモジュールを利用しなくても実はちゃんと動いている(ように見える)ので、豪快にごまかしてみました。

--- src/java_config_2/VersionManager.py.orig
+++ src/java_config_2/VersionManager.py
@@ -132,7 +132,7 @@
 
             # Remove conditional depends that are not turned on
             atoms = " ".join(flatten(use_reduce(paren_reduce(atoms),uselist=use)))
-        except KeyError:
+        except (ImportError, KeyError):
             pass
         return atoms

上記のエラーはmedia-libs/libjpeg-turbo[java]で発生したものですが、取り敢えずこれでインストールはできるようになりました。

取り敢えず他にも試そうということで、dev-java/icedtea6-binとdev-java/sun-jdkの両方を入れて切り替えつつapp-editors/jeditをインストールしてみたりしましたが、今のところ問題は出ていません。
私が普段使っている環境ではJavaを利用するパッケージが少ないので、問題に遭遇することも少なかったのですが、ガシガシJava関連パッケージを利用する場合にはどこかでドツボに嵌りそうな予感がひしひしとします。

その他、特に問題のないところ

  • app-admin/perl-updater, app-admin/*-updater

perl-cleaner, *-updaterなどのコマンドは、対象のアップグレードが行われたあとに実行すると、更新が必要なパッケージを自動的に再インストールしてくれます。perl-cleanerは>=2.8からPaludis(caveコマンド)に対応しています。haskell-updater, python-updaterは現在gentooリポジトリにあるものは全てPaludisに対応しているようです。

  • sys-auth/pambase

pambaseのebuild内でqatomコマンドを使っているのでapp-portage/portage-utilsにDEPENDしています。幸い、qatomの動作はパッケージマネージャに依存しないので、Portaeを削除していてもちゃんと動作します。pambaseのインストールも問題ありません。

  • revdep-rebuild

前回の記事にも書きましたが、Paludisにはrevdep-rebuildに対応する機能が最初からあります。

cave fix-linkage

感想と結論

Portageを消すことで、「Gentooとは選択です」を実現するための黒魔術の一端に触れることができました。えっそんな結論。

Portageを消すことで色々と問題には遭遇しますが、なんとかごまかしつつ、使えています。私が普段使っている程度の環境を運用するのなら特に問題ない、と言えなくもないというところです。しかしこれまでは何とかなっていますが、次に遭遇するトラブルは解決できるとは限らないし……。

そして、実はPortageを消しても特にメリットはないので、まあやらなくても良いですかね。現状では基本的に自己満足の世界です。そして私的には結構満足なのです*3

そうだ、Portage消せるのならPythonも要らないんじゃね!?

と思ったのですが、sys-apps/paludisはdev-cpp/gtestにDEPENDしており、dev-cpp/gtestはdev-lang/pythonにDEPENDしていました……。つまりPortageを消してもPythonは必要でした。うーん残念。

cave importのご紹介

gcc-configが警告を出さなくなるように、/usr/local/sbin/env-updateというスクリプトを手動で用意しましたが、/以下のファイルは須らくパッケージマネージャの管理下にあるべし、という方にはcave importがオススメです。

まずinstalled_unpackagedリポジトリを用意しておきます。

amd64vbox ~ # cat /etc/paludis/repositories/installed_unpackaged.conf 
format = installed_unpackaged
location = /var/db/paludis/repositories/installed_unpackaged
amd64vbox ~ # mkdir -p /var/db/paludis/repositories/installed_unpackaged
amd64vbox ~ # chown paludisbuild:paludisbuild /var/db/paludis/repositories/installed_unpackaged

適当にディレクトリを掘って、インストールしたいファイルを配置します。

amd64vbox ~ # mkdir -p DESTDIR/usr/sbin
amd64vbox ~ # cp env-update DESTDIR/usr/sbin
amd64vbox ~ # mkdir -p DESTDIR/etc/env.d
amd64vbox ~ # cp 00real_chost DESTDIR/etc/env.d

適当なカテゴリ/パッケージ名を指定してcave importします*4

amd64vbox ~ # cave import --location ./DESTDIR sys-apps/portage-compat  -x

すると、こんな具合にPaludisで管理できます。

amd64vbox ~ # cave show sys-apps/portage-compat
* sys-apps/portage-compat
    ::installed-unpackaged    0 {:0}
    sys-apps/portage-compat-0:0::installed-unpackaged (world)
    Description               
    Installed time            Mon Mar 19 19:15:31 JST 2012
    Source repository         unpackaged

amd64vbox ~ # cave contents sys-apps/portage-compat
/usr
/usr/sbin
/usr/sbin/env-update
/etc
/etc/env.d
/etc/env.d/00real_chost

消したくなったらcave uninstallで消せます。cave importは依存関係も記述できるのですが、blockerには対応していない*5のがちょっぴり残念です。

*1:VDBはPMSの仕様なので/var/db/pkgのままです

*2:env-updateが無いというwarningは当然は出ます

*3:所詮自己満足の世界なので、現時点では関連するバグレポも投げていません

*4:注意! インストール対象のファイルはmvされますので、元のファイルは消えます

*5:DEPEND=!sys-apps/portageとかは実現できない