( クラウド時代の分散マシン操作ライブラリ Svengali )
以下のような構成のマシン群があったとします。
- ・管理用マシン: 1台
- ・ここで下のプログラムを実行
- ・被管理(操作?)マシン: 3台
- ・sunagimo01: 192.168.2.1
- ・sunagimo02: 192.168.2.2
- ・sunagimo03: 192.168.2.3
- < 全てのマシンに,ユーザ:taro,パスワード:bar でログインできる >
- < 被管理マシンではsshとsftpさえ通れば良い >
ここで,全てのマシンに対して
- 1.全てのマシンに対してパッケージをインストール
- 2.設定ファイルの編集
- 3.実験プログラムの実行
- ・管理用マシンの/home/taro/scenario.shを転送し実行
- ・echo "`hostname`: Hello svengali!!"
- ・管理用マシンの/home/taro/scenario.shを転送し実行
- #各ステップは各マシンについて逐次で実行
を行うプログラムは以下のように書けます。
#! /bin/ruby require "rubygems" require "svengali" user_name = "taro" password = "bar" #連番でアクセスするためにあえてIPアドレスで指定 IPADDR_BASE = CLibIPAddr.new("192.168.2.1") MACHINE_NUM = 3 nodes = Array.new(MACHINE_NUM) tmp_ipaddr = IPADDR_BASE.dup() MACHINE_NUM.times{ |n| #ホストネームでの指定も可 nodes[n] = Machine.new(tmp_ipaddr) nodes[n].set_auth_info(user_name,password) #コマンドの発行が可能な通信路を確保する nodes[n].establish_session() #インストールするパッケージは適当 puts nodes[n].install_package("openmpi") tmp_ipaddr.inc!() } nodes.each{ |a_node| #設定ファイル(sshd_config)を編集 sshd_conf = a_node.get_config_file("/etc/ssh/sshd_config") #行う設定も適当 sshd_conf.replace_col("X11Forwarding yes","X11Forwarding no") sshd_conf.save() } #実験開始 nodes.each{ |a_node| #おまけ puts a_node.exec!("uname -a") #実験用のスクリプトを実行 puts a_node.exec_script_on("/home/taro/scenario.sh","","/home/taro") }
実行結果
$ruby test_svengali.rb
(yumの出力が延々と続くので省略)
Linux sunagimo01 2.6.32-22-generic #33-Ubuntu SMP Wed Jan 21 10:44:23 EST 2009
sunagimo01: Hello svengali!!
Linux sunagimo02 2.6.32-22-generic #33-Ubuntu SMP Wed Jan 21 10:44:35 EST 2009
sunagimo02: Hello svengali!!
Linux sunagimo03 2.6.32-22-generic #33-Ubuntu SMP Wed Jan 21 10:44:47 EST 2009
sunagimo03: Hello svengali!!
ネットワーク回りの設定処理は,以下のように書けます。
(上のコードと一緒の部分は省略) gateway_addr = CLibIPAddr.new("xxx.xxx.xxx.xxx") dns_addr = CLibIPAddr.new("xxx.xxx.xxx.xxx") netmask_addr = CLibIPAddr.new("xxx.xxx.xxx.xxx") CHANGED_IPADDR_BASE = CLibIPAddr.new("xxx.xxx.xxx.xxx") tmp_ipaddr = CHANGED_IPADDR_BASE.dup() nodes.each{ |a_node| #連番でIPアドレスを(静的に)設定 a_node.config_nw_interface(:ipaddr => tmp_ipaddr , :interface => "eth0", :netmask => netmask_addr, :gateway => gateway_addr, :onboot => "yes") a_node.set_resolver(:primary_ip => dns_addr) #各ノード上のネットワーク設定をリロードさせる #10秒後にnilを返して抜ける(タイムアウトは実装上の問題を回避するため) puts a_node.exec!("/sbin/service network restart", 10) tmp_ipaddr.inc!() } #新しいアドレスを用いて再接続 tmp_ipaddr = CHANGED_IPADDR_BASE.dup() nodes_changed = Array.new(MACHINE_NUM) nodes_changed.each{ |a_node| a_node = Machine.new(tmp_ipaddr.to_s) a_node.set_auth_info(user_name,password) a_node.establish_session() tmp_ipaddr.inc!() puts a_node.exec!("/sbin/ifconfig eth0") }