We assume that there are machines organized like below. * Admin machine: 1 host * The sample code is executed on this machine * Managed machine: 3 host * sunagimo01: 192.168.2.1 * sunagimo02: 192.168.2.2 * sunagimo03: 192.168.2.3 * #all managed machines can be logined as user "bob" whose password is "bar" * #Requirements for managed machines are accessibility through SSH and file transfer with SFTP Here, we perform operations below to all managed machines. * 1.Installation of some packages * 2.Editing of configuration file * 3.Execution of experiment program * Transfer /home/taro/scenario.sh on admin machine to managed machines and executes them * echo "`hostname`: Hello svengali!!" * #each step is executed serial Code for above operations can be written like below. {{{ code ruby #! /bin/ruby require "svengali/svengali" user_name = "bob" password = "bar" #use IP addres due to access by sequence number 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| # FQDN machine name can be passed nodes[n] = Machine.new(tmp_ipaddr) nodes[n].set_auth_info(user_name,password) # establishes a transport for command execution via SSH nodes[n].establish_session() # install インストールするパッケージは適当 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") } }}} [[BR]] 実行結果 {{{ $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!! }}} [[BR]] ネットワーク回りの設定処理は,以下のように書けます。 {{{ code ruby (上のコードと一緒の部分は省略) 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") } }}}