2010-08-27

MacPorts を 1.8.x から 1.9.x へアップグレードした場合の注意点

port がアンインストールできない

きっかけは、Ruby 1.9.2p0 のインストール(とアンインストール)。ターゲットマシンは Mac mini と iMac だ。

どちらの Mac でも ports を使ったインストールには問題なかった。ちょっと試したいことがあったため、mini の方から一度アンインストールすることにした。ところが、ここでつまづいた。アンインストールが失敗したのだ(↓)。

[mini] mnbiwa% sudo port uninstall ruby19                           [~]
--->  Deactivating ruby19 @1.9.2-p0_1+mactk
--->  Uninstalling ruby19 @1.9.2-p0_1+mactk
Error: port uninstall failed: list element in braces followed by \
"/cdesc-dig" instead of space

同じことを iMac でやってみると、不思議なことにこちらは成功する。Mac mini と iMac になんの違いがあるのか? どちらも、Snow Leopard だし、ports のバージョンも同じ 1.9.1 だ。違いと言えば、iMac は最近使い始めたマシンだということぐらい。

実は、そこに答えが隠れていた。

原因は MacPorts のアップグレードが完全じゃなかったため

あれこれと試すうち、/opt/local/var/macports/receipts に違いがありそうだとわかってきた。というのも、mini ではこのディレクトリにはインストールずみの port の情報が記録されているのだが、iMac ではディレクトリが空なのだ。

このディレクトリを頼りにググってみたところ、答え(↓)を見つけた。

(談話室 - MacPorts-JP にある「1.9.0 リリース時のChangeLog の抄訳」より)
sqlite ベースの registry2.0 コードが統合されました。macports.conf 中の portdbformat 変数を 'sqlite' に設定することで有効になります。既存のフラットな レシートは、充分な権限下にて初回 port(1) が実行された際に変換されます。 オリジナルのコードは sfiera によるもので、r63398 以降 jmr によって修正・統合 されました。#13054 (dependencies from old port versions stick around across upgrades) や #14123 (files whose paths differ only in case are left behind when uninstalling) といった、古いフォーマットで悩まされていた問題の多くは、 新しいフォーマットでは発生しません。

同じ場所に、この抄訳の訳者による注意書きもあった。曰く、selfupdate しただけでは registry 2.0 の恩恵を受けられないため手動で macports.conf を更新すると良い、と。まったく、その通りだった。「たちゃな」さん(ChangeLog の訳者の人)、感謝します。

mini では 1.8.1 の頃から ports を使ってきた。それを何も気にせず、1.9.x に selfupdate しただけで放っておいたのだ。iMac は 最初から 1.9.x だったため、新しい DB を使うようになっていた。そこが差だったのだ。

レシート DB の変換作業の様子を以下に示す。説明しやすくするため行番号を付けてある。

 1: [mini] mnbiwa% cd /opt/local/etc/macports                        [~]
 2: [mini] mnbiwa% ls                          [/opt/local/etc/macports]
 3: macports.conf  sources.conf  variants.conf
 4: macports.conf.default sources.conf.default variants.conf.default
 5: [mini] mnbiwa% sudo cp macports.conf macports.conf_1.8  
 6: [mini] mnbiwa% sudo cp macports.conf.default macports.conf
 7: [mini] mnbiwa% port installed              [/opt/local/etc/macports]
 8: port registry doesn't exist at \
        "/opt/local/var/macports/registry/registry.db" \
        and couldn't write to this location
 9:     while executing
10: "registry::open $db_path"
11:     (procedure "mportinit" line 536)
12:     invoked from within
13: "mportinit ui_options global_options global_variations"
14: Error: /opt/local/bin/port: Failed to initialize MacPorts, \
    port registry doesn't exist at \
    "/opt/local/var/macports/registry/registry.db" \
    and couldn't write to this location
15: [mini] mnbiwa% sudo port sync             [/opt/local/etc/macports]
16: Warning: Converting your registry to sqlite format, \
    this might take a while...
17: Warning: Successfully converted your registry to sqlite!
18: [mini] mnbiwa% ls -l /opt/local/var/macports/registry
19: total 10848
20: -rw-r--r--  1 root  admin  5554176 Aug 27 18:27 registry.db

1 〜 6 行目が設定ファイルの置き換えだ。それだけだと肝心の DB が更新されていないため、7 行目の port コマンド実行でエラーが出ている。これは、port コマンドが DB を変換しようしたが、DB を置く場所が一般ユーザでは書き込めないためだ。port コマンドに権限を与えるため、15 行目では sudo 付きで実行している。権限さえ与えたやれば、port に指定するサブコマンドは sync でなくとも良いはず。18 〜 20 行目で新しいフォーマットの DB ができていることを確認している。

DB を sqlite に変換した後は、mini でも Ruby のアンインストールができた。ちなみに、MacBook でも 1.8.x から 1.9.x へアップグレードしているので、mini と同じ状態になっていた。こちらでも、↑と同様に DB の変換をしておいた。

ソフトのアップグレード(それもメジャーなもの)のときにはアナウンスメントを読まないとダメだってことだね。

MacPorts だけが原因だったのか?

問題は一応の解決を見たが、実はまだ疑問が残っている。なぜ、古い方式 DB だとアンインストールに失敗してしまったのか。ports だけの問題だったのか?

そもそも port コマンドが Ruby 1.9.2p0 のアンインストールに失敗していたのは、ri コマンドが参照するディレクトリに奇妙な名前のディレクトリができていたためだ。それは /opt/local/share/ri/1.9.1/system/Set にある dig = {} だ。これは正しく作られた結果なのかな? /opt/local/lib/ruby1.9/1.9.1/set.rb の 427 行目が、これの元になっているようなんだが……。

関連リンク

関連記事

0 件のコメント:

コメントを投稿