2010-07-17

rvmを使ってREEへの移行を考える

Ruby Enterprise Edition が海外では人気らしいというのは知っていたけど、別に今のところ Rails 仕事なんてないしなとか悠長なことを考えていました。

Welcome — Ruby Enterprise Edition

RHEL クローンでは RubyEE は yum ですぐ使える

そんな中、RHEL 5 クローンな OS では yum で入る Ruby が 1.8.5 で、いやだなぁ、せめて 1.8.6 なら良かったのにと考えていたら以下の記事で

Ruby 1.8.6 Policy

いよいよ RubyGems も RDoc も Ruby 1.8.7 に絞りたいよんと言い始めました。さすがにこれはちょっと困ったなー、どうすっかなーと思っていたところ、先日 Ruby EE ( Enterprise Edition ) が 1.8.7 ベースになっていたことを偶然知り1、また

End Point Package Repository

で RHEL 5 用に Ruby EE を含むパッケージ群の yum レポジトリが用意されていることも知っていたし、

Twitter / poppen: centosにRubyEEとnginx + pass …

centosにRubyEEとnginx + passengerをインストールしたでござる

と、普段CentOSを使わない人の動向も知っていたので、間違いなくイケるぞと判断し、

こりゃあ Ruby EE に移行するしかない

と、ようやく思い立ったわけです。うーん前振りが長いな。

yum で RubyEE を入れる作業は省略

End Point のサイトに書いてある通りなので。自分の platform に合う repository データの rpm を入れるだけ。

2010-07-17 現在、i386 向けのものは

ruby-enterprise.i386 : Ruby Enterprise Edition (Release 20090520)

です。

RubyEE 移行への検証環境を rvm で作る

RVM: Ruby Version Manager - RVM Ruby Version Manager - Documentation

問題は RubyEE へすぐ移行できるかどうかです。少ないながらも Ruby のコード資産はあります。一応常用環境が 1.8.[67] なので新たに書いたコードは問題ないと思いますが、1.6 時代から使っているものはさすがに一通り検証してからでないとちょっと怖い。特に 1.8.7 は非互換の部分がちょいちょいあるので、意図せず踏んでいるケースが考えられます。

そうなると一気に yum で Ruby を抜いて Ruby EE を入れて gem を入れ直しておしまい、とはいきません。

どっかに検証環境を作らなきゃ。でも Ruby EE を手軽に入れられる環境は他にないな。

普段使っているプラットフォームは

  • OSX 10.5 + Fink Ruby 1.8.6
  • Debian 5.0.x + Ruby 1.8.7
  • CentOS 5.x + Ruby 1.8.5

で、問題はこの CentOS なわけですが、これを入れ替える前に RubyEE の検証を行いたいわけです。

やりやすいのは Debian に rvm 環境を作って rvm で RubyEE を入れる方法かなー、読んだことあるし。2

ということで今度は rvm のインストール。

rvm は bash スクリプトで install して動かす

※ Windows ? 知らないっす :-) 適当に VM で Linux 動かせばいいと思います。

入れ方は何通りかあるように見えますが、結局

bash スクリプト群を download して動かす

という方法には変わりありません。shebang に

#! /usr/bin/env bash

と書かれているので *BSD など bash の入ってない環境では先にインストールしてください。

自分が試したのは github から直接 download して動かす方法でしたが、rubygems からインストールしてる人もいるようですし、たぶんどっちでもうまくいきます。というのも、普通にユーザー権限でインストールしていく場合には rvm は

~/.rvm

で完結し、システムに用意されている Ruby と rvm でインストールした Ruby を明確に区別できるからです。そのために login shell の rc ファイルに

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"

を追加しろ、と書かれています。

つまり、そういうことです。基本的には rvm で入れる Ruby は他のユーザーには影響しませんし、何もケアしていない場合は shell を変えるだけで使えなくなります。

ビルドに必要なものをパッケージで用意

さて、rvm 自体は bash スクリプト群なので扱いも楽ですが、rvm で Ruby をインストールする作業は結局自分でコンパイルすることに他なりません。少なくとも RubyEE を rvm でインストールする際には以下のものを要求されるようです。

  • C Compiler
  • C++ Compiler
  • make
  • patch
  • zlib headers
  • openssl headers
  • readline headers

環境や入れる Ruby のバージョンによって要求されるものは当然違うと思いますが、これらをシステム標準のパッケージでインストールしてしまえば ok です。インストールがうまくいかない場合はカラフルな log を見ればたぶん分かります。実際この記事は log を開いて書いてます。–trace を使えばリアルタイムにも確認できるかもしれません。やってみてないですけど。

rvm でインストールした ruby の使い方

同じです。irb の prompt などは違いますし、インストール済みの gem も違いますが、動かし方は同じです。というか、何を起動しようとしているかによって違います。MRI にない JRuby 独自の動かし方などがあればそれに従います。

基本的な rvm サブコマンド

rvm use利用する Ruby を切り替える
rvm use –default指定のバージョンをデフォルトの Ruby とする

use –default を使えばシステム標準の Ruby がなくてもとりあえず開発はできるかもしれませんね。

ちなみに default は

~/.rvm/environment/

以下を見れば分かります。

default -> ~/.rvm/environments/ree-1.8.7-2010.02
ree-1.8.7-2010.02
ree-1.8.7-2010.02@global
ruby-1.9.2-rc2
ruby-1.9.2-rc2@global
system

こんな風になっています。system が何ともリンクしていないのはたぶん system の Ruby がないからです。

rvm listインストール済み Ruby の一覧
rvm list knownインストール可能な Ruby の一覧

2010-07-17 時点で Ruby 1.8.6 からしかインストールできないっぽいんですが、もう今のバージョンはそうなんですかね。昔のバージョンはもっと古いものも入れられたみたいですが。

rvm ruby SCRIPT指定の SCRIPT をインストール済みの全 ruby で実行
rvm VERSION,VERSION[, …] SCRIPT指定の SCRIPT を指定の VERSION の ruby で実行
rvm rubydefault の ruby で irb を立ち上げる

検証対象のコードをインストール済みの ruby で一気に実行することができます。いちいち rvm use で切り替える必要なし。 全 ruby じゃなくてコレとコレで実行したい、という指定もできますが、特定のバージョンでだけ実行することはできないようです3

その場合は rvm use して切り替えてから普通に

ruby SCRIPT

で実行すれば済む、ということでしょうね。

sudoして使いたい

Ruby スクリプトを純粋に Web アプリだけに使っているのならあまり関係しないかもしれませんが、システム管理に使っている場合は sudo で権限を変えて実行したい場合がよくあります。しかし、先に書いたように rvm でインストールした Ruby は基本的に自分の常用環境でしか動きません。

そこで rvmsudo というツールが用意されています。

~/.rvm/bin/rvmsudo

これで rvm でインストールした Ruby を sudo で使えます。

特定のディレクトリだけ違うバージョンを使いたい

これ! これめっちゃ便利そう。使い方は簡単、目的のディレクトリに

.rvmrc

というファイルを置き、中に Ruby のバージョンを指定するコマンドを書くだけ。例えば

rvm use 1.9.2

としておくと、この .rvmrc の置いてあるディレクトリ以下だけで Ruby 1.9.2 がデフォルトの Ruby になります。外からこのディレクトリに cd したときに Ruby が切り替わった旨のメッセージも出ます。

info: Using ruby 1.9.2 rc2

これはすごいなぁ。例えば特定の branch は特定のバージョンの Ruby 用です、ということをこのたった一つのファイルだけで明示できる。なんてこった!

※ 脱線しますが、こういうものこそ PHP に欲しいんですよねぇ。いい悪いでなく PHP では中小規模のものを扱うことが多いので、より多くの環境に対応できた方が嬉しいんです。でも基本的に mod_php だと OS ごと仮想化する形の方が結果的に面倒が少ないんです。とは言えやはり大げさなんですよねぇ。別に Apache のバージョンや OS のバージョンに依存してないのに全環境を仮想化しなきゃいけないのは。

まとめ

Ruby 1.9 移行期であり、また複数の Ruby 実装の完成度が急速に上がってきていますし、Ruby で開発を行う人には rvm はとても便利ですね。面倒そうで渋っていたけど、自分のスクリプトの portability も上げていかないといけないので Mac にも入れないとダメだなと思いました。(これ書いている時点ではまだ仮想環境でしか入れてないですけど。)

RubyEE はあえて歩みを遅くしたい場合に有効な選択肢で、RHEL クローンでは簡単にインストールできるのがとてもありがたいです。恐らく RHEL 系は想定以上の歩みの遅さに悩まされると思いますので、RubyEE を基本と考えるくらいでいいのかもしれません。

残った課題は

  • rvm で入れた Ruby 自体をシステム標準とする方法
    • そもそもこれにメリットがないといけないので、しばらくは放置かな?
  • bundler との組み合わせでも大丈夫になったらしい情報が rvm のサイトに書いてあるが、bundler 自体が分かっていない

なんとなく bundler こそ PHP に欲しい機能のはずだと思っているので、時間を見つけて try したいです。

参考

  1. チェックしていなかった 

  2. 幸いこの Debian は比較的速いマシンで動いているし。 

  3. 0.1.43で確認 

About

例によって個人のなんちゃらです