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 行目が、これの元になっているようなんだが……。
関連リンク
- 談話室 - MacPorts-JP (1.9.0 リリース時の ChangeLog の抄訳および portdbformat 変更に関する注意がある)
- [MacPorts-announce] MacPorts 1.9.0 has been released (ML に流された 1.9.0 のリリース通知; DB の変換手順についても書かれている)
関連記事
- MacPorts 1.8.1 (Macをプログラムする)
0 件のコメント:
コメントを投稿