Ruby, net-ssh, running an application on remote systems


#1

ok, I have a server with a dozen systems attached to it. there are
commands that I need to run on each system one at a time. i can
connect to each system with the admin script, i can launch basic
commands i can even launch the script i need to but when that script
tries to launch the partimage application to backup the windows
partitions (this is all being done from linux) it doesn’t, i don’t get
any good errors it just dies closes the connection an moves onto the
next system.

==admin.rb==
#!/usr/bin/ruby
require ‘net/ssh’
Username=‘root’
Password=’{plain_text_password}’
Hosts = (101…112).collect {|x| “192.168.0.#{x}”}
def classroom_pc(host, command)
Net::SSH.start( host, Username, Password) do |session|
session.open_channel do |channel|
channel.on_success do
puts “Connected to #{host}”
end
channel.on_close do
puts “Connection Closed to #{host}”
end
#channel.on_data do |ch, data|
# puts “\trecieved #{data}”
# puts “\tfrom #{host}”
#end

  channel.send_request "shell", nil, true
  channel.send_data "#{command}\n"
  channel.send_data "exit\n"
end
session.loop

end
end
if $0 == FILE
Hosts.length.times do |i|
classroom_pc(Hosts[i], “/mnt/backup/partimage.rb
save”)
end
end

==/mnt/backup/partimage.rb==
#!/usr/bin/ruby
Win_drive = “/dev/hda1”
Location = “/mnt/backup/classroom/”
File_type = “partimag.gz”
def help_message
puts “Usage:”
puts “\tsave to save the image”
puts “\tload to restore an image”
puts “\thelp prints this message”
end
def hostname
hostname.chomp
end
def save_image
system(“rm #{Location}#{hostname}*”)
system(“partimage -odb -f3 -z1 save #{Win_drive}
#{Location}#{hostname}.#{File_type}”)
end
def load_image
system(“partimage -eb -f3 restore #{Win_drive}
#{Location}#{hostname}.#{File_type}.000”)
end

if $0 == FILE
unless ARGV.length == 1
help_message
end
if ARGV.length == 1
help_message if ARGV[0].downcase == “help”
save_image if ARGV[0].downcase == “save”
load_image if ARGV[0].downcase == “load”
end
end


#2

I don’t have an answer for your specific question, but you might look
into
capistrano. It’s meant for exactly this, although it runs each request
in
parallel, not sequentially, which may or may not be a good thing for
you…

-philip


#3

sorry about that, I was implementing the shell and a responce, mozilla
crashed and google talk sent a blank message. the app i’m running
seems to be using ncurses, will that cause another problem?


#4

def classroom_pc(host, command)
Net::SSH.start( host, Username, Password) do |session|
shell = session.shell.sync
puts “Opened Connection to #{host}”

p shell.send_command( "#{command}")
shell.exit
puts "Closed Connection to #{host}"

end
end
i modified the classroom_pc function, now i’m getting an error
#<struct Net::SSH::Service::shell::SyncShell::CommandOutput stdout="",
stderr=“Failed to open terminal.TERM environment variable needs
set.\r\n”, status=0>
the application runs in a curses environment.


#5

On 3/14/07, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

Maybe you would be better off using the net/ssh shell instead of
launching a shell over the channel.
http://net-ssh.rubyforge.org/chapter-5.html

Alternatively you might use channel.exec instead of channel.request
and channel.send_data that do not seem to be the right hammer for this
nail if I recall correctly.
http://net-ssh.rubyforge.org/chapter-4.html

HTH
Robert


#6

def classroom_pc( host, command )
Net::SSH.start( host, Username, Password) do |session|
shell = session.shell.sync
puts “Opened Connection to #{host}”
shell.send_command( “export TERM=linux” )
p shell.send_command( “#{command}”)
shell.exit
puts “Closed Connection to #{host}”
end
end

that seems to have done it, it doesnt display the ncurses info but i
can live with that for now.