portmasterによるPortsのアップグレード手順

portmasterやportupgradeを使わず、portauditによる対象portsのアップグレードを行ってきたマシンにおいて、portmasterを使い始めるには色々注意点があるので、いろいろ纏めて見る。

一番大きなリスクは、共通の依存先portsに関する問題で、このことを何も考えずにportmasterを動かすと痛い目に遭う可能性がある。portmasterは依存先のportsが古い場合には、アップデート対象に指定したportsより先にアップグレードを行う。このとき依存先のportsが共有ライブラリでバージョンアップにより互換性が失われるケースがごく稀にある*1

こういった依存先portsがアップデートされたportsも(バイナリ依存性が失われている場合には)、再ビルドが必要になる。もしバイナリ依存性が失われていない場合でも、デーモンの類なら再起動しておいた方が望ましい。

こういた問題をフォローするには、portmasterを動かす前にUPDATINGをきちんと読んでバイナリ互換性が失われているものがないかどうかチェックし、portmasterでアップグレードされるports一つ一つについて、UPDATINGに上げられたportsがないかどうか、あるいは依存するportsがないかどうかチェックしてやる必要がある。

このあたりをフォローした作業手順を以下に纏めて見る。

まずソースを最新にして、インデックスを更新する
 # csup ports-supfile
 # (cd /usr/ports; make fetchindex)

まず、依存関係をマトモにする。恐らく何度か走らせる必要がある。

 # portmaster --check-depends

この過程で、メンテナが居なくなったり既存のportsにマージされて既に無くなっているportsがいくつか出てくる。こういったportsは pkg_delete で消す。インストール先のファイルが別のportsで上書きされているので、大概実際にファイルは消されず、パッケージ登録だけが抹消される。一つの目安は、pkg_tree で怪しいエラーが無くなれば万々歳。portmaster -L で問題がでないのが望ましい。

次にportupgradeの設定ファイルを /usr/local/etc/portmaster.rc に置く。現在の手元のファイル設定はこんな感じ。interplinkerのにっき [FreeBSD] portmaster (1)では、どのportsをアップグレードするのかの確認もかねて FORCE_CONFIG を付けていたけど外した。

# -b
BACKUP=yes
# --force-config
# FORCE_CONFIG=yes
# don't delete dist-files
DONT_SCRUB_DISTFILES=yes

次にアップグレードしたい ports に対してportmasterを -F オプション付きで起動させる。-F オプションを付けると、依存関係のチェックとdistfileのダウンロードだけを行う。

# portmaster -F -p hogehoge/foobar | grep 'to update'
===>>> Launching child to update libiconv-1.9.2_2 to libiconv-1.13.1
===>>> Launching child to update libtool-1.5.22_2 to libtool-1.5.26
===>>> Launching child to update libexecinfo-1.1_1 to libexecinfo-1.1_3
===>>> Launching child to update popt-1.7_1 to popt-1.14
===>>> Launching child to update gettext-0.14.5_2 to gettext-0.17_1

これらの依存先のportsについて、一つ一つチェックする。

# pkg_info -r gettext-0.14.5_2
Information for gettext-0.14.5_2:

Depends on:
Dependency: libiconv-1.9.2_2

# pkg_info -R gettext-0.14.5_2
Information for gettext-0.14.5_2:

Required by:
(snip)
ja-samba-3.0.28,1
postgresql-server-8.0.15
subversion-1.6.4

このgettextの場合、相当の昔に UPDATING に出ているように、バイナリ依存性が失われている。そのため、postgresql-serverやsubversionもアップグレードしてやる必要がある*2。もしアップグレードを怠ると、portmasterで纏めて入れ替えられた後に、共有ライブラリが見つからなくてバイナリが動かない!という自体に遭遇する*3

ここまで準備ができればOK。あとは -F オプションを外して

 portmaster -p hogehoge/foobar

で無事に終わるのを待つ。

そして、デーモンなら再起動して動作チェックを行う。共通の依存先を持ち影響を受けるportsも動作チェックをする。もしうまく動かないなら、パッチを書くなりなんなり。ま、もっとも普段からちゃんと UPDATING を読んでいればここで書いたような問題を含めてたいがいの問題は自然とクリアできているはずではあるのだが。

*1:例: gettext, libgcrypt

*2:で、portmasterを使う場合には同じようにチェックすることが望ましい

*3:デーモンの類でしかも動作中に入れ替えてたりすると、マシンの再起動するまで気付かないとかもありそう