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.

  1. #! /bin/ruby
  2. require "rubygems"
  3. require "svengali"
  4. user_name = "bob"
  5. password = "bar"
  6. # use IP addres due to access by sequence number
  7. IPADDR_BASE = CLibIPAddr.new("192.168.2.1")
  8. MACHINE_NUM = 3
  9. nodes = Array.new(MACHINE_NUM)
  10. tmp_ipaddr = IPADDR_BASE.dup()
  11. MACHINE_NUM.times{ |n|
  12. # FQDN machine name can be also passed
  13. nodes[n] = Machine.new(tmp_ipaddr)
  14. nodes[n].set_auth_info(user_name,password)
  15. # establishes a transport for command execution via SSH
  16. nodes[n].establish_session()
  17. # install package
  18. # package system used is default one(yum)
  19. puts nodes[n].install_package("openmpi")
  20. tmp_ipaddr.inc!()
  21. }
  22. nodes.each{ |a_node|
  23. # edit configuration file( sshd_config )
  24. sshd_conf = a_node.get_config_file("/etc/ssh/sshd_config")
  25. sshd_conf.replace_col("X11Forwarding yes","X11Forwarding no")
  26. sshd_conf.save()
  27. }
  28. # start experiment
  29. nodes.each{ |a_node|
  30. # bonus
  31. puts a_node.exec!("uname -a")
  32. # executes experiment script
  33. puts a_node.exec_script_on("/home/taro/scenario.sh","","/home/taro")
  34. }


Execution result

$ruby test_svengali.rb
( --- omitted yum outputs --- )


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!!


Operation of network configuration can be written like below.

  1. ( --- codes same as former sample code are omitted --- )
  2. gateway_addr = CLibIPAddr.new("xxx.xxx.xxx.xxx")
  3. dns_addr = CLibIPAddr.new("xxx.xxx.xxx.xxx")
  4. netmask_addr = CLibIPAddr.new("xxx.xxx.xxx.xxx")
  5. CHANGED_IPADDR_BASE = CLibIPAddr.new("xxx.xxx.xxx.xxx")
  6. tmp_ipaddr = CHANGED_IPADDR_BASE.dup()
  7. nodes.each{ |a_node|
  8. # set a IP address in sequence
  9. a_node.config_nw_interface(:ipaddr => tmp_ipaddr , :interface => "eth0", :netmask => netmask_addr, :gateway => gateway_addr, :onboot => "yes")
  10. a_node.set_resolver(:primary_ip => dns_addr)
  11. # reload network configuration of each machine
  12. # returns after 10 seconds ( use timeout due to avoid implementation problem of Machine class around SSH connection)
  13. a_node.exec!("/sbin/service network restart", 10)
  14. tmp_ipaddr.inc!()
  15. }
  16. # reestablish connection with using new addresses
  17. tmp_ipaddr = CHANGED_IPADDR_BASE.dup()
  18. nodes_changed = Array.new(MACHINE_NUM)
  19. nodes_changed.each{ |a_node|
  20. a_node = Machine.new(tmp_ipaddr.to_s)
  21. a_node.set_auth_info(user_name,password)
  22. a_node.establish_session()
  23. tmp_ipaddr.inc!()
  24. puts a_node.exec!("/sbin/ifconfig eth0")
  25. }