さくらインターネットでlocal::libを使ってCPAN環境を整える

Posted at 2010-02-08T16:38:56+09:00 in Software

さくらインターネットでlocal::libを使う

だいぶ前の話になりますが、local::libを使ってCPAN moduleをインストールする環境を さくらインターネットに整えたので、そのときのことを思い出しながらまとめてみるよ!

0. 参考

1. local::libを落としてくる

local::libCPANにあるので、 CPANのlocal::libのページDownloadリンクをコピーして、 端末上で、

$ cd ~/local/src
$ wget http://search.cpan.org/CPAN/authors/id/A/AP/APEIRON/local-lib-1.004009.tar.gz

local::libを取ってくる

2. local::libを解凍する

$ tar zxvf local-lib-1.004009.tar.gz

3. BSDPANの設定をする

僕のところではこんな感じの設定をしました。

setenv  PKG_DBDIR       ~/db/pkg
setenv  PORT_DBDIR      ~/db/pkg
setenv  INSTALL_AS_USER

4. CPANの設定をする

hidekさんのところの記事によると、どうも先にCPANの設定をしないとlocal::libのインストールがうまくいかないそうなので、 とりあえずshellで

$ cpan
...
cpan> o conf commit
cpan> exit

という感じでCPANの設定を済ませます。

このときにはCPANモジュールのインストールパスなんかは設定しません。 あとUNINST=1とか--uninst=1を設定すると、どうもシステムに入ってるモジュールを消そうとして失敗する、 という動作をしだすので、これらのオプションは設定しないほうが良いと思います。

5. local::libをインストールする

ようやくlocal::libをインストールします。

僕の環境の場合、~/local/perl5がCPAN moduleをインストールするルートディレクトリなので、

$ cd ~/local/src/local-lib-local-lib-1.004009
$ perl Makefile.PL --bootstrap=/home/nyarla/local/perl5

という感じでMakefile.PLを実行。あとは

$ make
$ make test
$ make install

します。

6. 環境変数を設定

で、次に環境変数を設定します。

hidekさんの所ではechoとか使って自動的にシェルの設定ファイルに書き出しとかしてますが、 僕の環境ではどうもうまくいかなかったので、手動で、

$ perl -I$HOME/local/perl5 -Mlocal::lib=$HOME/local/perl5

を実行して、出力された環境変数の設定部分をシェルの設定ファイル(僕の環境の場合cshなので~/.cshrc) にコピペしました。

7. CPANをupdate

これでようやくCPAN moduleをインストールできる環境が整ったので、

$ cpan
...
cpan> install Bundle::CPAN

してCPANをアップデートします。

まあこれは大抵のモジュールはインストールされるはずなので、細かいところは省略。

8. CPAN moduleをインストール

んで、あとは自由にCPAN moduleをインストールできます。

僕の場合、このBlogや無貌断片で使用している plasxomが使用するモジュールなんかを入れました。

9. Perl scriptで使用するには

で、肝心のPerl scriptから各モジュールを呼び出すには、

#!/usr/bin/perl

use strict;
use warnings;

use lib '/home/nyarla/local/lib/perl5/lib';
use local::lib '~/local/perl5';

という感じで呼び出します。

ちなみにさくらインターネットではCGIはsuEXEC環境で動いてるので、 .htaccessとかの設定ファイルで設定した環境変数がCGIスクリプト内で有効になりませんが、 suEXEC環境でない場合は、.htaccess内でPERL5LIBとか設定してやれば良いと思います。

10. 以上作業は終了。感想とか

まあ作業自体をしたのがだいぶ前(いつだったか覚えてない)ので細かいところはうろ覚えですが、 大体こんな感じで作業したと思います。

本当は作業してから作業ログを書こうと思ってたんですが、 疲れたしまた後にしようと思って延び延びになって今日になった次第。

ちなみに作業してたとき、環境変数を設定するところでちょっとつまづいてました。

あと使用感ですが、CPANをダイレクトに設定して使ってたときよりも使いやすい感じです。 特にインストールされるディレクトリがバラけないのでそこら辺がスクリプトから扱いやすい感じ。 まあこれからレンタルサーバでCPAN使う人は、local::libを使うと良いんじゃないでしょうか。

以上local::libを使ってCPAN環境を整える話でした。

Plack::Loader::GatewayCGIなるものを試作してみた

Posted at 2010-01-29T17:53:17+09:00 in Project

Ruby on Railsのgateway.cgi相当のモジュールをPlack::Loaderのサブクラスとして実装してみた

前にPlack::Server::GatewayCGIなるものを試作してみたんですが、 その後Plackの開発を追っていたら、miyagawaさんがコミットメッセージで、 railsのgateway.cgiのようなものはPlack::Loaderのカテゴリがフィットするよ という趣旨のことを言ってたので、 前に書いたPlack::Server::GatewayCGIPlack::Loader::GatewayCGIとして実装しなおしてみました。

http://gist.github.com/289556

例によってコードはgithubへ見に行ってください。

今回の特徴としては、前はPlack::Server::AnyEventにベースのバックエンドサーバに依存してたのが、 今回はその依存がなくなり、Plack::Server::CoroとかPlack::Server::Standaloneとかが使えるようになりました。

今のところ、

  • Plack::Server::AnyEvent
  • Plack::Server::Coro
  • Plack::Server::POE
  • Plack::Server::ServerSimple
  • Plack::Server::Standalone

のサーバに対応しています。

一応Plack::Server::CGIでも動きますが、駐在プロセスとかできないので、 高速化は一切できません。

あとPlack::Server::FastCGIに関しては、サーバのホストとポートの取得の仕方がわからなかったので、 今のところ対応していません。誰かそのあたりのコードをプリーズ。

あ、それとPlack::Serverのネームスペースが非推奨になって、Plack::Handlerに変わったはずなので、 ここら辺これからPlackの開発がすすんでくると読み替える必要があるんで注意してください。

あとまた例によって今回書いたPlack::Loader::GatewayCGIはプロトタイプなので、 実際に実用しようと思うと、もうちょっとコードをリファクタリングする必要があると思います。

まあ実用するにはまだまだって感じなので、あんまり使い道はない感じですが、 ちょっと実験するぐらいなら使えるので、いろいろいじって見るのもいいかと思います。

以上Plack::Loader::GatewayCGIを試作してみたという話でした。

Perlスクリプトにバイナリファイル埋め込む方法

Posted at 2010-01-24T16:25:28+09:00 in Coding

Perlのスクリプトのバイナリファイルをテキストで埋め込む

しばらく前の話になりますが、この前に書いたGoogle App Engineでホスト名を効率よく取得する方法を考える という記事内の二個目の方法を実現するスクリプトをこの間の記事を書いた後に書いたとき、 画像ファイルをpsgiスクリプトに埋め込むということが必要になったので、そのとき調べたことを今日書いてみます。

まず、画像ファイルをテキスト、つまりバイナリファイルをテキストファイルとして表現するには、 uuencodeというフォーマットがあるらしいです。

で、Perlでバリナリファイルをこのuuencode文字列に変換するには、

#!perl

use strict;
use warings;

my $file = shift @ARGV;

open( my $fh, '<', $file ) or die "Cannot open file: ${file}: ${!}";
binmode $fh;
my $data = do { local $/; <$fh> };
close $fh;

my $text = pack('u*', $data);

print $text;

というスクリプトを例えばbin2text.plという感じで用意して、

$ ./bin2text.pl {binaryfile}

という感じで実行すれば、uuencodeのデータ部分が取得できます。

んで、このテキストをバイナリに戻すには、

#!perl

use strict;
use warnings;

my $source = q{uuencode形式のデータ};
my $binary = unpack('u*', $source);

という感じになります。

んで、例えばpsgiスクリプトか何かで、テキスト化された画像バイナリファイルを返すには、

#!perl

use strict;
use warnings;

# 1 x 1の透明なgifファイル
my $image   = unpack('u*', q{K1TE&.#EA`0`!`(```/_______R'Y!`$*``$`+``````!``$```("3`$`.P``});
my $length  = legnth($image);

return sub {
    return [
        200,
        [
            'Content-Type'      => 'image/gif',
            'Content-Length'    => $length,
        ],
        [ $image ]
    ]
};

という感じになります。

でこの間書いたって言ってる 任意のホストにファイルにアクセスしてきた人のIPアドレスとリモートホストを送信するスクリプトでは、 要約すれなこんな感じの方法でWebビーコンを返しています。

まあこのuuencodeっていう形式は大昔に使われてた形式らしくて、今はBase64がメジャーらしいのですが、 ちょっとしたスクリプトで使うためにMIME::Base64使うのもアレなのでuuencodeを使ってみた次第。

まあちょっと知っておくと便利かもということで今日この間調べたことをまとめてみました。

Google App Engineでホスト名を効率よく取得する方法を考える

Posted at 2010-01-18T17:27:59+09:00 in Coding

現在のGoogle App Engineで取得できないリモートホストを効率よく取得する方法

2010年1月18日現在、Google App Engineではソケットの使用とかDNSの名前解決ができないため、 リモートホストが取得できません。またGoogle App Engine上でリモートホストが必要な場合、 外部のサーバ経由で取得するとかしか方法がないのが現状です。

で、外部サーバ経由でリモートホストを取得する方法について、 今日本屋で行った帰りの電車の中で思いついたので、とりあえず書き留めてみるよ。

方法一、リモートホストを取得するWebサービスにリクエストを送ってリモホを取得する

これは僕が最初に思いついた方法なんですが、

  1. リモートホストが必要になるたびに、リモートホストを返すWebサービスにリクエストを送る
  2. Webサービスから返ってきたホスト名を使用する

という方法です。

シンプルで分かりやすいのが利点といえば利点ですが、

  1. リモートホストが必要になるたびに外部サーバにリクエストを送ることになる
  2. 貴重な外部サーバへのリクエスト要求のリソースを無駄に消費することになる

という欠点があります。

まあキャッシュしたりすればある程度はリクエストを減らすこともできると思いますが、 それでも上記の問題は完全に解決できるわけではありません。

で、今日思いついた方法が次。

方法二、外部サーバにリモートホストをGAEサーバに送らせる

これは今日思いついた方法なんですが、これは、

  1. GAEのサイト上にIPアドレスとリモートホストをGAEサーバに送信するWebアプリケーションを埋め込む
  2. リモートホスト送信サーバから送信されたリモートホストをmemcacheに保存する
  3. リモートホストが必要なときはmemcacheからリモートホストを取得する

という方法です。

一番の埋め込み方法としては、

  1. 隠しiframeとかでリクエストが飛ぶようにする
  2. Webサービスの方でWebビーコン返すようにして画像として埋め込む

という方法が考えられます。

あとIPアドレスをリモートホストを返すWebサービスで、 IPとリモートホストの対応が変更された場合にのみ、GAEサーバにリクエストを送る という風にしておけば、GAE上のリソースの消費を最小限に抑えることができます。

で、この方法の欠点としては、

  1. 結局外部サーバに依存してしまう
  2. 少なめといえGAEのリソースを消費する
  3. GAE上のサイトに初めてアクセスしたユーザーのリモートホストが取得できない(次回以降になる)

という点が挙げられます。

まあ一番二番は方法一でも一緒です。あと三番に関しては、この方法独自の問題と言えますが、 方法一と組み合わせるとなんとかなるんじゃないかと思います。

まとめ

まあ一番最初に思いついた方法も、今日思いついた方法も、 Google App Engineでリモートホストが取得できるようになればいらない子になることが確実な方法です。

つーかあとリモートホストが取れなくても、リモートアドレス取得すればいいじゃないって話なので、 上記の方法はどうしてもリモートホスト取りたいって時以外はあんまり必要無い方法だと思います。

で、なんでリモホにこだわるかっていうと、GAE上で掲示板とかコメントサービス作ろうとしたときに、 リモートホストで規制掛けられると便利じゃないかなぁと思ったからです。

まあ今日まとめた方法がどう考えてもバッドノウハウな気がしてたまらないので、 どうしてもリモートホストが必要なときに試してみてはどうでしょうか。

Plack::Server::GatewayCGIなるものを試作してみた

Posted at 2010-01-09T11:08:31+09:00 in Project

Ruby on Railsのgateway.cgiをPlackに移植してみた:試作編。

Ruby on Railsにはgateway.cgiというアプリケーションを半駐在(一定期間駐在しその後終了する)させる CGIスクリプトが付属しているらしいんですが、そのgateway.cgiと同じようなことをする、 Plack::Server::GatewayCGIなるものを試作してみました。

http://gist.github.com/271857

試作品なんでコードはgistに貼り付けてありますんで、上記リンクから見に行ってください。

で、Plack::Server::GatewayCGIの仕組みは、

  • N秒後に終了するバックエンドサーバーが起動しているか確かめる
    • 起動してなかったらバックエンドサーバを起動する
  • バックエンドサーバの存在が確認されたら、Plack::Server::GatewayCGIはバックエンドサーバと起動CGIをつなぐProxyとして振舞う。

という感じです。

ソース見てもらえれば分かると思いますが、Plack::Server::GatewayCGIのバックエンドサーバである Plack::Server::GatewayCGI::BackendPlack::Server::AnyEventを継承して作ってます。

まあPlack::Server::AnyEventにこだわりがあるわけでは無く、単にN秒後に終了するというサーバを作るのに、 コードがいじりやすそうだったからという理由でPlack::Server::AnyEventを使ってます。 事実継承してちょっといじるだけだったのでPlack::Server::GatewayCGI::Backendの行数は40行程度に収まってます。 だから、他の実装をベースにできるんであれば、他の実装をベースにしても良いと思います。

で、Plack::Server::GatewayCGIを使うと、起動に時間のかかるPSGIスクリプトをある程度高速化できると思います。 が、単純なPSGIスクリプトだと、バックエンドサーバを起動したり、バックエンドサーバとのProxy処理なんかがあるため、 逆に遅くなってしまうと思います。

で、ローカルでテストしているplasxomのスクリプトを実行してみましたが、一回目のアクセスはちょっと遅かったものの、 二回目のアクセスは比較的早く処理されました。 まあでもベンチ取ったわけではないので、本当に高速化できてるか微妙な感じです。

あと多分ですが、一回目のバックエンドサーバを起動する時、なんとなく素のPlack::Server::CGI使ってるときよりも遅い気がするので、 アクセス数があんまり無いサイトでPlack::Server::GatewayCGIを使うと体感速度が悪化すると思います。 逆に一定間隔でアクセスがあるサイトで、起動の遅いPSGIスクリプト使ってる場合なんかは早くなるんじゃないかと。

で、なんですが、何でこんな妙なもん作ろうかと思ったかというと、まあなんとなく作ってみようかなと思ったのが一つと、 CGI環境しか用意できない人でも、PSGIスクリプトを高速化できたらいいなぁと思ったのが一つです。

まあ自宅サーバとかVPS、専用サーバなんかを用意できて、FastCGI、SpeedyCGI、mod_perl、mod_perlite、mod_psgiなんかが使える環境では、 素直にそれらの環境を使っておいた方がいいです。

あと僕の公開サーバの環境だと、なんかCPU使用時間が跳ね上がりそうなので、今回作ったGatewayCGIは今のところ使うつもりはありません。 まあ作った意味があんまり無いですね><。まあ面白そうだからなんとなく作ったってだけですし。

ま、Plack::Server::GatewayCGIPlack::Server::GatewayCGI::BackendのライセンスはPerlと同等としておいたので、 誰か引きついでモジュール化したいという方がいれば、是非ともやってください。 僕は動くものを試作できたってことで満足なので、これ以上発展させるつもりは無いです。

まあこれ本当に使い道あるのかな?って気がしなくもないんですが、 良かったら試しに使ってみてください。

About Me

name
Naoki Okamura
nick
nyarla
contact
nyarla[ at ]thotep.net
Category
Log
Banners
Powered by
plasxom