groovy-1.8をRHELやらで使えるようにrpm化した。

GroovyServをパッケージ化してFedoraでの開発環境は整ったんだけど、Fedoraでサービスインするってのはあんまり無いよなぁ、と思った。
開発するにはFedoraはパッケージも多いしやりやすいんですけどねぇ。

というわけで、サービスローンチ時に使われるであろうRHEL6(と、一応5。Scientific、CentOSでも良いけど)用にGroovyをパッケージ化した。
これでさくらVPSでも自前マシンでも良いけど、思う存分Groovyを使えますねっと。

RHEL5系: groovy-1.8.0-1.el5.noarch.rpm
RHEL6系: groovy-1.8.0-1.el6.noarch.rpm


一応お約束というか何というか、無保証ですよ。
あと、依存にOpenJDKやSunJavaが入っていないので、各自好きな方を入れてください。

git nowが素晴らしすぎたので、rpm化した。

忘れないうちに自分用メモ。


というわけで


という経緯でビルドしたのを上げておく。
git-now-0.0-1.fc15.noarch.rpm
Fedora15用。

Fedora 15でgroovyservを使える環境を用意するよ。

最近は書籍も出てきてゴキゲンなGroovyですが、ひょんな事から、groovyservrpm化するためのspecファイルを頂きました。
んで、それをちょいと手直しして0.8-release版に合わせたところ、どうやら無事取り込んで貰えたようなので、これを記念して環境を整えてみようと思います。


ちなみにビルドなんてダルイ事言ってないで、rpmをとにかく寄越せと言う人向けに、バイナリは下に置いておきます。
Fedora15用

groovyserv-0.8-0.fc15.x86_64.rpm
groovyserv-ruby-0.8-0.fc15.x86_64.rpm

このバイナリを使う場合、ビルド環境を用意する・ビルドを行うの手順はすっ飛ばしてしまってOKです。

  • Fedora15にgroovyservを入れる手順
  • Fedora15(x86_64)をminimalでインストール&updateする。
    • 余計なものはいらないから、とりあえずminimalで。環境にもよるけど、minimalならインストールに10分もかからないのでとても良いです。
    • VMとかでも良いんじゃないかな
  • groovyservのビルド環境を用意する
[kazuhisya@gserv-build ~]$ uname -a
Linux gserv-build.localdomain 2.6.38.8-32.fc15.x86_64 #1 SMP Mon Jun 13 19:49:05 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux

[kazuhisya@gserv-build ~]$ sudo yum install rpm-build wget gcc make unzip java-1.6.0-openjdk maven groovy ruby -y
[kazuhisya@gserv-build ~]$ mkdir -p rpmbuild/SPECS rpmbuild/SOURCES
[kazuhisya@gserv-build ~]$ cd rpmbuild/SOURCES
[kazuhisya@gserv-build SOURCES]$ wget http://github.com/downloads/kobo/groovyserv/groovyserv-0.8_src.zip
[kazuhisya@gserv-build SOURCES]$ cd ../SPECS
[kazuhisya@gserv-build SPECS]$ wget https://raw.github.com/kobo/groovyserv/master/contrib/rpm/groovyserv.spec
    • Fedoraのminimalインストールはwgetすら入ってない超硬派な環境なので、wgetを入れるところからになる(!)
    • Rubyを入れているのは、groovyservのruby-clientをビルドするため。いらないなら入れる必要はありません。
    • Fedoraにはgroovy-1.8、maven-3.0のrpmがはじめから存在するので、自前でお膳立てする必要がなく非常に楽です。
  • groovyservのビルドを執り行う
[kazuhisya@gserv-build SPECS]$ pwd
/home/kazuhisya/rpmbuild/SPECS

[kazuhisya@gserv-build SPECS]$ rpmbuild -ba ./groovyserv.spec
  • groovyservのrpmをインストールする。
[kazuhisya@gserv-build SPECS]$ cd ../RPMS/x86_64/
[kazuhisya@gserv-build x86_64]$ sudo yum install --nogpgcheck ./groovyserv-* -y
    • これで終了。
    • Rubyクライアントが不要の場合は、groovyserv-rubyを抜かしてインストールすればよろしい。
  • おもむろにgroovyclientを叩く
[kazuhisya@gserv-build ~]$ groovyclient -v
Invoking server: 'groovyserver' -p 1961 
Groovy home directory: (none)
Groovy command path: /usr/bin/groovy (found at PATH)
GroovyServ home directory: /opt/groovyserv
GroovyServ work directory: /home/kazuhisya/.groovy/groovyserv
Original classpath: (none)
GroovyServ default classpath: /opt/groovyserv/lib/*
Starting.....
groovyserver 1569(1961) is successfully started
Groovy Version: 1.8.0 JVM: 1.6.0_22
  • 終了は
    • ※ 通常、1度立ち上げたら終了はせずに使うんだと思う。
[kazuhisya@gserv-build ~]$ groovyserver -k
Groovy home directory: (none)
Groovy command path: /usr/bin/groovy (found at PATH)
GroovyServ home directory: /opt/groovyserv
GroovyServ work directory: /home/kazuhisya/.groovy/groovyserv
Original classpath: (none)
GroovyServ default classpath: /opt/groovyserv/lib/*
Killed groovyserver of 1569(1961)

簡単すぐる。

  • トラブルシュート
Invoking server: 'groovyserver' -p 1961 
ERROR: Not found a groovy command. Required either PATH having groovy command or GROOVY_HOME

環境によっては、上記の様なエラーが出る場合がある。
その場合、 .bashrc か、/etc/profile に GROOVY_HOME を書けばよろしげ。
それでもダメなら、Java周りの環境変数を見直すといいかもしれないです。
参考:
はじめにお読みください ― GroovyServ v0.8 documentation (ここの環境変数など)

  • で、どんくらい速いの?

素のgroovyだと

[kazuhisya@gserv-build ~]$ time groovy -e  "println 'Hello ' + args[0]" World
Hello World

real    0m0.595s
user    0m0.669s
sys 0m0.072s

一瞬突っかかりを感じる。何度も打ってると結構気になる。


groovyservだと?
1回目

[kazuhisya@gserv-build ~]$ time groovyclient -e  "println 'Hello ' + args[0]" World
Invoking server: 'groovyserver' -p 1961 
Groovy home directory: (none)
Groovy command path: /usr/bin/groovy (found at PATH)
GroovyServ home directory: /opt/groovyserv
GroovyServ work directory: /home/kazuhisya/.groovy/groovyserv
Original classpath: (none)
GroovyServ default classpath: /opt/groovyserv/lib/*
Starting.....
groovyserver 1905(1961) is successfully started
Hello World

real	0m10.758s
user	0m0.017s
sys	0m0.034s

一発目は大分待つ(groovyserverデーモンを起動させるからかな、たぶん)


2回目以降

[kazuhisya@gserv-build ~]$ time groovyclient -e  "println 'Hello ' + args[0]" World
Hello World

real    0m0.017s
user    0m0.000s
sys 0m0.002s

はえー。ちょーはえー。突っかかりは全く感じないです。サックサク。


  • まとめ
    • Fedoraでgroovyserv使うのは簡単だよ!
    • ちなみにJavaで動くコードを書いたのはこれが初めてです。 Javaわかんないす。。。*1
      • 正確には2回目。1回目はEclipseでプロジェクト作って、Hello worldを出力し損なって挫折した。
    • という訳で、GroovyはおろかJavaすらロクに書いたこと無いけどgroovyservの環境が出来たので、誰か僕に『プログラミングGROOVY』を貢いでくれれば良いと思います。

プログラミングGROOVY

プログラミングGROOVY

*1:普段開発はperlbashスクリプトを。あとrubyを少々。pythonも読みますがJavaはからきし・・・

続:libvirtで管理さてるゲストマシンを高速シンプロビジョニングしてくれるツールを作った

libvirtで管理さてるゲストマシンを高速シンプロビジョニングしてくれるツールを作った - kazuhisya::備忘録的な何か
て言うのを前に書いたんだけど、体を表さない気がふつふつと湧いてきたので、強引だけど名前を変えてしまった。
シンプロて、まーそういう意味じゃないしねぇ。。。
GitHub - kazuhisya/virt-thinclone: Virtualmachine ThinProvisioning Clone Tool



あと前に書いた時より若干オプションを大分増やしたのですよ、誰となく。

[root@rhel6 virt-thinclone]# ./virt-thinclone --help
Usage: virt-thinclone [options]
    -o, --original             Original Domain Name: Necessary
    -n, --new                  New Domain Name: Necessary
    -i, --ip                     New Domain IP: Necessary
    -m, --mask              New Domain NetMask: Default 255.255.255.0
    -g, --gate              New Domain DefaultGateway: Default 192.168.0.1
    -M, --mac                   New Domain MAC Address: Default random
    -p, --partition       Dom root Partition Name: Default /dev/mapper/VolGroup-lv_root
    -s, --snap             New Domain Fast Snapshot Name: Default provisioning_default

libvirtで管理さてるゲストマシンを高速シンプロビジョニングしてくれるツールを作った

virt-clone コマンドって便利ですよね。
これ確かにスゲー便利なんですが、30回も40回も同じこと繰り返してると、スゲー疲れるわけです。
具体的に何に疲れるかって言うと、

  1. 待ち時間
  2. ネットワークの再設定


待ち時間に関しては、シェルスクリプトにしておくなりスパースでやるオプションを付けておけば"ある程度”我慢できるけど、ネットワークの再設定に関してはスゲータルい。
なんせ1回はゲストに入らなきゃいけない。


コレを回避するには、ゲストをクローンしたときのMACアドを、DHCPサーバに書いて決め打ちにすること。
そうすればある程度は管理できる。


…のはずだったけど、RHEL6系からは新しく追加されたネットワークデバイスは自動的に ONBOOT="no" な仕様にかわったので、そもそも立ち上がらないし、RHEL5系だと、すでにeth0があった場合、インクリメントされてeth1としてアタッチされたりで、コレはコレで美味しくない。


という訳で、これらの問題を一括で片付けるソリューションを思いついたので、やっつけで書いた。
https://github.com/kazuhisya/virt-thinpro
GitHub - kazuhisya/virt-thinclone: Virtualmachine ThinProvisioning Clone Tool

具体的には下記の流れになる

  1. qemu-imgでオリジナルのゲストの仮想ディスクから新しいゲストの仮想ディスクを作成する
    • ベースイメージから作成する場合、"皮”の部分だけ作られるので、一瞬で終わる(多分RHEVのpool機能はコレを使ってるんじゃないかな)
  2. virt-cloneに--preserve-dataオプションを付けてクローンする
    • --preserve-dataオプションは--fileオプションと一緒に使うんだけど 1. で作った仮想ディスクをアタッチする。これも一瞬
  3. 新しくできたクローンからMACアドをひっぱて来て、仮想ディスク内の各コンフィグに直接書きこんでしまう
    • これはlibguestfsっていうかなりミラクルなツールがあって、それを利用
    • 仮想ディスクをホスト側にマウントして、ifcfg-eth0とudevのルールを書き換えてます
    • 余談: ruby-libguestfsってライブラリもあるので、フツーに使えるはずなんだけど、オリジナル現行バージョンとRHELyumにあるバージョンがスゲー離れてる上、互換性なさそうな雰囲気がプンプンなので、後先考えてココは sysetm()で直接実行してます
  4. 最後の仕上げに新しい方の仮想ディスクのスナップショットを取る

出来上がった新しいゲストを実行してやれば、いきなりネットワークが設定された状態で立ち上がる。

[root@rhel6 virt-thinpro]# time ./virt-thinpro.rb -o el6-tmpl -n el6-01 -i 192.168.XXX.XXX
Formatting '/data/el6-01.img', fmt=qcow2 size=10485760000 backing_file='/data/el6-tmpl.img' encryption=off cluster_size=0 
Clone 'el6-01' created successfully.
Success: el6-01

real    0m10.841s
user    0m2.830s
sys     0m0.930s
[root@rhel6 virt-thinpro]# 

10秒ちょいですね!
多分ストレージがSSDとかだともちっと速いんでしょうが、一番時間掛かるのはゲストの仮想ディスクをマウントする所なので、劇的には改善されないと思います。(要確認?)

条件

  • ライセンス
    • GPLv2+
  • ホストOS
    • RHEL6(ないしそれと互換性のある物、例えばScientific Linux6とか、Fedora14もイケル?)
    • ruby-1.8.7
    • ruby-libvirt-0.3.0
    • libvirt
    • libvirt-client
    • qemu-img
    • python-virtinst(virt-clone)
    • guestfish-1.2.7
      • ruby-libvirt-0.3.0 は標準ではない。 公式gitから落としてコンパイルするなり、gemから落とすなりしてください
      • KVMで使うことを想定したけど、Xenでも他の動くはず。 qemu://〜 でコネクションしている部分を Xen用のURIに変えれば良いんじゃないですかね
  • ゲストOS
    • RHEL6(ないしそれと互換性のある物、例えばScientific Linux6とか、Fedora14もイケル?)
  • 書き換えてるのは下記
    • /etc/sysconfig/network-scripts/ifcfg-eth0
    • /etc/udev/rules.d/70-persistent-net.rules
  • どうしてもRHEL5系でやりたいなら下記を編集するロジックを入れればいいと思います
    • /etc/sysconfig/hwconf

制限

  • ゲストOSの仮想NICはeth0のみアサインされており、IP アドレスは固定IPを設定しているものとする
    • デフォゲの設定等はスクリプトの頭の方にあるコンフィグをいじるべし
  • ゲストOSの仮想ディスクは、ファイル形式かつqcow2形式の仮想ディスクが 1 個だけアサインされているものとする
      • /のマッピングは /dev/mapper/VolGroup-lv_root (LVM利用)がデフォ、違う場合はコンフィグをいじるべし
  • libvirtに元となるゲストが管理されていること
  • 元となるゲストは以後絶対に起動しないこと
    • 元ゲストのファイルシステムに変更が入ると、クローンした全てのゲストに変更が適応される
    • 検証してないけど最悪破損する? アップデートとかが一括で出来て楽ちんだーとか決して思わないこと
    • RedHatのソリューションであるところのRHEVもそういう仕様になってる(1回テンプレート化したら2度と戻せない)
    • なので、元ゲストはテンプレートマシンだと捉えるべき
  • 今のところ、ローカルのlibvirtにしかアクセスできない

使用方法

[root@rhel6 virt-thinpro]# ./virt-thinpro.rb --help
Usage: virt-thinpro [options]
    -o, --original          Original Domain Name
    -n, --new           New Domain Name
    -i, --ip              New Domain IP
  • -o: libvirtに登録されている元となるゲストの名前
  • -n: 新しくクローンして作成されるゲストの名前
  • -i: 新しくクローンして作成されるゲストのIP


コード的にあんまし美しくないから、ちょくちょく綺麗にしていきたいなぁ。
特にsystem()で直に叩いちゃってるところは、かなりイヤーンな感じ。
qemu-img createを叩いてる所はlibvirtのAPIで何とかできそうな気がしますね。

virt-clone叩いてる所はvirt-clone(python)からrubyに置き換えができそう。
あとlibguestfsの所を改善出来れば、リモートでも叩けそうですね。

motdをログイン毎に書き換えてくれるツール

GitHub始めたのは良いけど、公開されてるのがドットファイルばかりじゃあんまりだ。


…というわけで、普段良く使う motd を書き換えるだけという超絶どうでもいいようで、あるとちょっと便利(?)な毎回書き捨てな運命をたどるツールがあったので、そいつを整形して上げたという話。

my-tools/motd_update.sh at master · kazuhisya/my-tools · GitHub

使い方は簡単で、単純に chmod +x して root権限で叩けばいいです。
もしくはrootの .bashrc に毎回読ませるようにパスを通して書いてあげましょう。



使うとどうなるか:

root@192.168.XX.XX's password: 

Last login: Wed Jan 12 21:21:51 2011 from 192.168.XX.XX
                                                                                                            • -
Fedora release 14 (Laughlin)
                                                                                                            • -
Hostname: hogehoge.localdomain DNS Domain: localdomain Kernel: Linux 2.6.35.10-74.fc14.x86_64 x86_64 GNU/Linux
                                                                                                            • -
addr:192.168.XX.XX Bcast:192.168.XX.255 Mask:255.255.255.0 addr:192.168.YY.YY Bcast:192.168.YY.255 Mask:255.255.255.0 addr:192.168.ZZ.ZZ Bcast:192.168.ZZ.255 Mask:255.255.255.0 [root@hogehoge ~]#

こんな感じでログイン時にOS名と、kernel、ネットワーク関係が表示されるようになります。


ただ、 .bashrc に書くやり方だとどうしても、と言うか当然なんですが1回目の接続では表示が更新されないんですよね。
なので、気を取り直してもう一回ログインし直すか、 kernel update 後だとかは一回こいつを叩いてあげてください。


initに突っ込むとか色々解決策はもちろんあるわけですが、そこまでして使うものではないなーと思います、はい。


あ、あと、コレRHEL系(RHEL, Fedora, CentOS, Scientific等)のLinuxだけを想定して書いてあります。
/etc/redhat-release とか読みに行ってますので、他のディストリだとかOSXな人はその辺書き換えるとうまくいくんじゃないでしょうか。

追記

あーそうそう、勿論なんですが、ログイン毎に書き換えるようにするためには、 .bashrc に書きこむなりinitに追加しないとイケナイですよ。

簡単にやるにはrootの .bashrc にこんな感じで書けばいいでしょう。
/path/to の所は各自 本スクリプトを置いたところを指すようにすること。

GitHub始めました。

ものっそい今更ですが、github始めました。
自宅でも仕事でも基本的にはSubversionを使っているのですが、新年も明けたことだし、そろそろgitに移行かなーと思っていたので、まずはgithubを始めることに。
最近いろんなプロダクトを取ってくるのに svn co/update より git clone/pull してる回数の方が多くなってきたことですし。


kazuhisya (Kazuhisa Hara) · GitHub
※ まだ vimrc くらいしかおいてないですが。


始めて思ったことは、とりあえずgitのコマンド体系はマジでよくわかりませんね!
ということくらいかしら。
じきに慣れる、といいんですが。


慣れてきたら自宅のSVNサーバもgitに移行したいところです。