さて、開発に当たってフレームワーク選定に入ること早数ヶ月。未だに各候補の学習すら終わらない。何となくLightweight Languageに絞りつつあるし、その用途からもほぼこれにしよう、というのはあるんだけどね。こういう機会でもなければ一通り学ぶ事もないし、少し前までは割りとJAVA一辺倒だったから、きちんと向き合う事もなかった。まずは最も身近な言語であるPerl辺りからちょこちょこ使い始めている。まともなロジックは組んだ事ないけど、簡単な監視とかバッチとかでは普通に使っていた。
そういう訳で、今回は複数台のサーバにログインしてコマンドを発行する処理を作ってみる。用途から考えて当然、SSHによる自動処理を考える。パスワード認証を如何に通すが肝となる。普段なら、シェルでふにゃっと作って終わりにするところだが、発行するコマンドのパターンから、どうしてもハッシュやら連想配列やらを使いたい。もしかしたら、シェルでも可能なのかもしれないが、それほど頑張るところでもないのでPerlで組んでみる。こういう処理を組むときは、やっぱりPerlの手軽さが光る。
早速、ググってみるとNet::SSH::Perlというモジュールが存在するようだ。これを使えばパスワード認証に関しても、コード内で指定する形で自動化できる。インストールそのものはさくっと完了。更にググってて簡単なサンプルを探す。自分の環境に合わせてコードを準備して動作確認する。案の定、あれやこれやと不足しているモジュールを指摘される。言われるがままに必要なモジュールをインストールし続け、やっと動くところまでこぎつける。最終的にインストールしたモジュールは以下。
- Crypt-DES
- Crypt-DH
- Crypt-DSA
- Digest-HMAC
- Digest-SHA1
- Math-BigInt-GMP
- Math-GMP
- Math-Pari
- String-CRC32
各サーバへのログインはlogin()メソッドでユーザー名とパスワードを渡す形にしていたが、このままだとコード内にパスワード丸見えになってしまう。なんだかんだ言って、それはやっぱりイマイチなので公開鍵認証に切り替える。ローカル(プログラム起動側)に秘密鍵(id_dsa)を準備し、リモートサーバ(接続先)のauthorized_keysに公開鍵を登録する。コードの書き方に少し迷ったが、以下の方法でノーパス接続できた。
my %sshparams=(
protocol=>1,
interactive=>0,
identity_files=>["$ENV{HOME}/.ssh/id_dsa"],
UserKnownHostsFile=>["$ENV{HOME}/.ssh/known_hosts2",$ENV{HOME}/.ssh/known_hosts" ],
User=>"root",
);
my $ssh = Net::SSH::Perl->new($host,%sshparams);
$ssh->login();
my( $stdout, $stderr, $exit) = $ssh->cmd("ls")
これはすごい便利。今まで微妙に自動化しづらいためにハンドで実行していたルーチンワークや、SSHを使いたいがためにシェルで汚く書かれたバッチなんかも全て置き換えられそう。DBとの連携部分もスマートに書けるしね。うーん、やっぱりPerlは便利だなあ。以下、参考までに。
* Net-SSH-Perlのインストール