cpanm の --test-only
言わずと知れた、perlのcpanモジュール用のCLIツール、そのオプションに、 --test-only
があります。
実際にモジュールをインストールせずに、単体テストを通して合格するかを試すことができます。
実際に使ってみる
とあるモジュールを使用したいという事で、以下のコマンドでテストを実行していきます。
cpanm --test-only [モジュール名]
...
Successfully tested [モジュール名]
テストが通ったのが確認できました。問題なく使えそうです。
本番環境でも同じく実行して、テストが通りました。これで明日のリリースは大丈夫ですね!
事件が起きた
「サーバーが立ち上がらないんだけど、誰か何かした?」という、不穏な連絡が飛んできました。
でているのはモジュールエラー。以下のようなものが大量にでています。
Can't locate 〇〇.pm in @INC (@INC contains: ~~~...)
モジュール関係。。もしや。。ですが、今回やった事はモジュールのインストールの --test-only
なので本番には影響を与えていないはずです。
しばらく調査しているとcpanmの--test-onlyのリファレンスに怪しい記述がありました。
依存のあるモジュールやディストリビューションに このオプションを指定した場合、これらの依存は、現在持っていなければ、 インストールされます。
引用元: http://perldoc.jp/docs/modules/App-cpanminus-1.7001/lib/App/cpanminus/fatscript.pod
これが原因でした。 --test-only
でテストのみ実行しているつもりですが、この仕様で依存するモジュールの更新とインストールを行っていました。
ローカルでは依存するバージョンが通っていたので依存関係のインストールが発生せずサーバーも問題なく起動して気づかなかったです。本番サーバーのみモジュールのバージョンが一部古く、そこに紐づく依存関係がすべて更新してしまった事でサーバーエラーが発生しました。
今回インストールしようとしたモジュールに依存するモジュールをインストールし、更にそれに依存するモジュールが更に存在する場合ピラミッド式にインストールを行ってしまっているようでした。
修正作業
モジュールのバージョンがおかしくなってしまったので、cpanfileを使って動いていたバージョンのモジュールをインストールして戻そう!という話になったので、本番環境のcpanfileを使ってモジュールを全て再インストール。
cpanm --installdeps [cpanfileのパス]
ここでも大量のエラー。すでに新しいバージョンがインストールされていたり、配布が停止しているモジュールがあったりで大変な事になりました。
- 一部のモジュールは今回インストールしようとしたモジュールの依存関係に紐づくバージョンに
- 一部のモジュールはcpanfileのバージョンに
- 一部のモジュールは旧本番環境のバージョンのままに
という3つの状態が混在してしまい大変な事になりました。。。
結局エラーのメッセージを一つ一つ潰して動くバージョンをインストールしていくという作業を永遠と繰り返してサーバーを復旧させました。
最後に
公式リファレンスをよく見ずに使うのは気を付けましょうという基本的な話でした。ただ、 --test-only
といういかにも安全なオプション名をしているのにこの挙動は予測できなかった。。
ちゃんとcpanfileをメンテナンスしていれば、何かあった時も簡単に戻せるはずなので反省点です。
明日の記事はtake_3さんです。