FreeBSD 8.3 を使用していますが、ports コレクションから perl 5.12が消えてしまいました。
今までもメンテナンスバージョン扱いだった perl 5.12が完全に消滅し、perl 5.16がデフォルトとして設定されたことによります。
私のシステムは、OSをインストールした時の perl 5.12のまま運用してきたため、今回の出来事はかなり痛い!perl が文字処理に向いた言語というだけなら、プログラムをバージョンアップしておしまいなのですが、OS上のパッケージ管理にC言語と同じくらい密着した言語になっていますので、perl のバージョンを更新するということは、portsコレクションからインストールしたアプリケーションの半分くらいはビルドし直しということになってしまいます。Webサーバーなどのサービスを全て停止させれば12時間程度で再構築できるかもしれませんが、Webサーバーの停止はちょっと無理そう。
それでも perl 5.12系は既に ports からソースが消えてしまっているので、いずれは 5.16系に移行せざるを得ないことはわかっています。5.16系に上げることはやむを得ないのですが、恐らく動かなくなるアプリケーションが出て来るはず。これが一番困ります。恐れているのは以下の二つ。
これらアプリケーションには一切問題ないのに、perl の仕様が変更になる度に動かなくなり、解決に時間を取られます。まるで perl がマイクロソフトのアプリケーションみたい!
perl 5.12 系を残すためにがんばったとしても、いずれ perl 5.12ではビルドできないツールが出てきますから、トラブルが発生することがわかっていても今のうちに上げておく方が得策と判断しました。FreeBSD 8.3 の既にサポート切れの状態ですからね。(FreeBSD 8系は 8.4が最新。8.4は飛ばして、9系に上げることになるでしょう。)
/usr/ports/UPDATING を読んで、perl 更新手順を確認。
Portupgrade users: 0) Fix pkgdb.db (for safety): pkgdb -Ff 1) Reinstall new version of Perl (5.16): portupgrade -o lang/perl5.16 -f lang/perl5.12 2) Reinstall everything that depends on Perl: portupgrade -fr lang/perl5.16
作業自体はとっても簡単。コマンドを3つ発行するだけ。
perl の更新自体は、4時間程度で終わりましたが、perl を使ってビルドされていた依存関係があるパッケージのビルドは12時間では終わる気配無し。24時間経っても半分程度。結局48時間以上掛かりました。
dropbox-api
さて、ビルドが終了したので、 dropbox-api コマンドを試したところ、早速エラーが発生して動きません。
> dropbox-api Can't locate LWP/UserAgent.pm in @INC (@INC contains: /usr/local/lib/perl5/5.16/BSDPAN /usr/local/lib/perl5/site_perl/5.16/mach /usr/local/lib/perl5/site_perl/5.16 /usr/local/lib/perl5/5.16/mach /usr/local/lib/perl5/5.16 .) at /usr/local/lib/perl5/site_perl/5.16/WebService/Dropbox.pm line 46. BEGIN failed--compilation aborted at /usr/local/bin/dropbox-api line 19.
dropbox-api コマンドが WebService/Dropbox.pm を呼んで、それがさらにLWP/UserAgent.pm を呼ぼうとしたところ、/usr/local/lib/perl5/5.16/BSDPAN /usr/local/lib/perl5/site_perl/5.16/mach /usr/local/lib/perl5/site_perl/5.16 /usr/local/lib/perl5/5.16/mach /usr/local/lib/perl5/5.16 . のいずれにもそれがないことが原因のようです。示されたパスをチェックしたところ、確かに存在しません。perl 5.12では動いていたのに、依存関係にあるプログラム全部が再構築された訳じゃないの? 過去に存在したライブラリが消えてしまったのか、元から入っていなくてperl 5.16 を使用するようになったためのエラーなのかは不明ですが、 LWP/UserAgent.pm をインストールすればエラーは消えるだろうということは推測できます。
問題は、UserAgent.pm は何のパッケージをインストールすれば入ってくれるのかがわからないこと。ここら辺がFreeBSD ports システムの不便なところ。幸い別のFreeBSDマシンに perl 5.12から更新していないマシンがあるので、それを使って確認してみました。
> grep "site_perl/5.12/LWP/UserAgent.pm" /var/db/pkg/*/+CONTENTS /var/db/pkg/p5-libwww-6.05/+CONTENTS:lib/perl5/site_perl/5.12/LWP/UserAgent.pm
p5-libwww だと判明しました。確か入っていたはずなんですが、確認してみるとありません。今度は、p5-libwww はどこにあるか探します。コマンドはあるものの、不便!
/usr/ports> make search key="libwww" | grep "Path:"|grep libwww Path: /usr/ports/www/libwww Path: /usr/ports/www/p5-libwww
ports/www に存在していることが判明したので、ここで make して install。
そして dropbox-api コマンドを発行してみると、、、、、
/usr/ports> dropbox-api find LWP will support https URLs if the LWP::Protocol::https module is installed.
まだ、動かないじゃないか!今度は LWP::Protocol::https を探す羽目に。
/usr/ports> make search key="LWP-Protocol-https" | grep "Path:" | grep LWP Path: /usr/ports/www/p5-LWP-Protocol-https Path: /usr/ports/www/p5-LWPx-ParanoidAgent
/usr/ports/www/p5-LWP-Protocol-https の下でビルドして、LWP::Protocol::https を入れました。さすがにこれで動くだろうと思ったものの、症状に変化無し!
試行錯誤した結果、p5-LWP-Protocol-https の依存関係を調べてみることにしました。
pkg_info -r p5-LWP-Protocol-https-6.04 Information for p5-LWP-Protocol-https-6.04: Depends on: Dependency: openssl-1.0.1_9 Dependency: p5-Net-SSLeay-1.58 Dependency: perl5-5.16.3_7 Dependency: p5-Mozilla-CA-20130114 Dependency: p5-IO-Socket-SSL-1.967 Dependency: p5-Net-HTTP-6.06
そういえば、perl 5.12と依存関係があったp5モジュールの中に再構築されていないものがあったことを思い出しました。
/usr/local/lib/perl5/site_perl> ls -lR 5.12|more total 10 drwxr-xr-x 2 root wheel 512 8月 13 2013 App drwxr-xr-x 2 root wheel 512 2月 17 00:18 auto drwxr-xr-x 4 root wheel 5632 2月 18 15:32 mach 5.12/App: total 0 5.12/auto: total 0 5.12/mach: total 4 drwxr-xr-x 3 root wheel 512 2月 17 01:40 Net drwxr-xr-x 4 root wheel 1024 2月 18 15:40 auto 5.12/mach/Net: total 372 drwxr-xr-x 2 root wheel 512 2月 16 01:55 SSLeay -r--r--r-- 1 root wheel 50791 1月 15 08:27 SSLeay.pm -r--r--r-- 1 root wheel 298373 1月 9 11:27 SSLeay.pod
p5-Net-SSLeay が 5.16用にビルドされていないことが原因かも。
/usr/ports/security/p5-Net-SSLeay に移動して、「make deinstall install clean」と手動で再インストール。
これでようやくdropbox-api コマンドが復活しました。
jdresolve / p5-Net-DNS
次に、jdresolve コマンドをテストしてみたところ、予想通り p5-Net-DNS が 0.68から0.74に更新されてしまい、動かなくなりました。
<テストファイル>
116.58.172.107 - - [01/Nov/2012:00:00:04 +0900] 116.58.172.107 - - [01/Nov/2012:00:00:09 +0900] 66.249.73.3 - - [01/Nov/2012:00:00:10 +0900] 173.199.115.171 - - [01/Nov/2012:00:00:17 +0900] 173.199.116.179 - - [01/Nov/2012:00:10:47 +0900]
<変換結果>
> jdresolve /tmp/ip.txt Net::DNS::DomainName1035=HASH(0x28496028) - - [01/Nov/2012:00:00:04 +0900] Net::DNS::DomainName1035=HASH(0x28496028) - - [01/Nov/2012:00:00:09 +0900] Net::DNS::DomainName1035=HASH(0x28496e24) - - [01/Nov/2012:00:00:10 +0900] Net::DNS::DomainName1035=HASH(0x289c2f8c) - - [01/Nov/2012:00:00:17 +0900] Net::DNS::DomainName1035=HASH(0x2849799c) - - [01/Nov/2012:00:10:47 +0900]
こっちの方も重傷。
dns/p5-Net-DNS は更新しないようにしているのですが、今回のようなケースでは避けようがありません。そのために、0.68 のソースを保持していて、今回もバージョン0.68のものからリカバーする予定でした。/usr/ports/dns/p5-Net-DNS を0.68 のものに戻して、再構築しようとしたところ、エラーが発生。
# pwd /usr/ports/dns/p5-Net-DNS # make "Makefile", line 56: Malformed conditional (${PERL_LEVEL} < 501000) "Makefile", line 58: if-less endif make: fatal errors encountered -- cannot continue
Makefile 自体がエラーとなってしまい、ビルドすることが出来ません。
.if ${PERL_LEVEL} < 501000 RUN_DEPENDS+= p5-Digest-SHA>=5.47:${PORTSDIR}/security/p5-Digest-SHA .endif
なぜこんな if 文がエラーになるのか? if 文は PERL_LEVEL とあるので perl のバージョン確認でしょう。501000 は、5.01 か 5.10 を表している気がします。今回は5.16なので、このif文の中は通らないはず・・・・ということで、Makefile の中をコメントアウトしてみました。
#.if ${PERL_LEVEL} < 501000 #RUN_DEPENDS+= p5-Digest-SHA>=5.47:${PORTSDIR}/security/p5-Digest-SHA #.endif
これで、makeをかけたところ、おっ、ビルドが進む!
しかし、今度はMakefileを開けないというエラーに。
===> Found saved configuration for p5-Net-DNS-0.68 ===> Fetching all distfiles required by p5-Net-DNS-0.68 for building ===> Extracting for p5-Net-DNS-0.68 => SHA256 Checksum OK for Net-DNS-0.68.tar.gz. ===> Patching for p5-Net-DNS-0.68 ===> Configuring for p5-Net-DNS-0.68 ===> Building for p5-Net-DNS-0.68 make: cannot open Makefile. ===> Compilation failed unexpectedly.
Makefile は今編集したので存在しています。
が、どうもworkディレクトリの下のものを指しているようです。確かに存在しません。
まったく、次から次へと・・・・
# ls -l work/Net-DNS-0.68/ total 110 -rw-r--r-- 1 root wheel 60002 1月 30 2012 Changes -rw-r--r-- 1 root wheel 1768 1月 28 2012 DNS.xs -rw-r--r-- 1 root wheel 2279 1月 27 2012 MANIFEST -rw-r--r-- 1 root wheel 677 1月 30 2012 META.yml -rw-r--r-- 1 root wheel 8703 1月 28 2012 Makefile.PL -rw-r--r-- 1 root wheel 11345 1月 28 2012 README -rw-r--r-- 1 root wheel 3302 1月 28 2012 TODO drwxr-xr-x 2 root wheel 512 1月 30 2012 contrib drwxr-xr-x 2 root wheel 512 1月 30 2012 demo drwxr-xr-x 3 root wheel 512 1月 30 2012 lib -rw-r--r-- 1 root wheel 5776 1月 28 2012 netdns.c -rw-r--r-- 1 root wheel 688 1月 28 2012 netdns.h drwxr-xr-x 2 root wheel 1024 1月 30 2012 t
ヒントがないかと、/usr/ports/Mk/bsd.port.mk を開いてMakefileに関する記述をチェックしてみたところ見つかりました。Makefile と Makefile.PL の優先順位に関する記述です。このディレクトリにはMakefile.PLはあるもののMakefileがありません。
# CONFIGURE_SCRIPT # - Name of configure script, relative to ${CONFIGURE_WRKSRC}. # Default: "Makefile.PL" if USES=perl5 and USE_PERL5=configure # are set, "configure" otherwise.
Makefile.PLを使うようにするには、環境変数を設定する必要があるようです。
USES=perl5 USE_PERL5=configure
これを設定してmake を掛けてみたところ、なんとビルドに成功。「make deinstall reinstall clean」でp5-Net-DNS 0.68が復活しました!!!
テストファイルをリゾルブしてみたところ、以下のように復活。
> jdresolve /tmp/ip.txt tokyo.lifewithunix.jp - - [01/Nov/2012:00:00:04 +0900] tokyo.lifewithunix.jp - - [01/Nov/2012:00:00:09 +0900] crawl-66-249-73-3.googlebot.com - - [01/Nov/2012:00:00:10 +0900] vpn11.radyocetin.com - - [01/Nov/2012:00:00:17 +0900] 173.199.116.179.choopa.com - - [01/Nov/2012:00:10:47 +0900] Total Lines: 5 Total Time : 00:00:01 (5.00 lines/s) Total Hosts: 4 Resolved Hosts: 4 (100.00%) Unresolved Hosts: 0 (0.00%) Average DNS time: 0.2500s per request Max DNS time: 1s (consider this value for your timeout)
毎度のことですが、perl のバージョンアップとディレクトリ構成、jdresolve と p5-Net-DNS の関係には悩まされます。ちなみに計画を立てて作業を開始したのが、土曜日深夜。ここまでたどり着いたのが火曜日深夜。丸々3日(ビルドが2日半、dropbox-apiとjdresolve の復活に12時間くらい)かかりました。
もう、やりたくない。
<2014/02/21 追記>
このサーバーでの perl 5.12→5.16への更新が終了したため、リモートにある別の FreeBSD 8.3 サーバーの perl も 5.16 に更新することにしました。
- CPU: Celeron 466
- Memory: 256MB
この「システム管理メモ」サーバー(Celeron 600MHz/256MB)よりも CPU速度が約75%でメモリ容量が半分。ただしCPU稼働率は非常に低いものです。どのくらいビルド時間が掛かるのかと思っていましたが、perlとその依存関係があるパッケージ全てを再構築したのに10時間程度であっけなく終了。しかも、dropbox-api コマンドの動作に問題なく、手動でperlモジュールをインストールし直す必要もありませんでした。インストールされているパッケージ数が多少少ないという面はあったのですが、それでも40時間近く差を付けられてしまいました。メモサーバーで動いている、radiko のエンコーダーとか、WordPress が相当重いのでしょうが、更新時間だけを評価するなら、別マシンを再構築してコンテンツだけ移行した方が早い気がします。でもまあ、サーバー停止時間を殆どゼロで更新作業するにはやむを得ないのかもしれません。
結果がわかっていたなら、クローニングした別マシンでビルドして、パッケージ化したバイナリーをインストールするという手もあったかも。