1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

added ssh_stream

This commit is contained in:
Javi Fontan 2011-11-18 17:31:18 +01:00
parent 84f912866b
commit 8a68b8eef2

175
src/mad/ruby/ssh_stream.rb Normal file
View File

@ -0,0 +1,175 @@
require 'CommandManager'
require 'open3'
class SshStream
attr_reader :stream_out, :stream_err, :stdin
attr_reader :out, :err
#
#
EOF_ERR = "EOF_ERR"
EOF_OUT = "EOF_OUT"
RC_STR = "ExitCode: "
EOF_CMD = "echo \"#{RC_STR}$?#{EOF_ERR}\" 1>&2; echo \"#{EOF_OUT}\""
SSH_CMD = "ssh"
#
#
#
def initialize(host)
@host = host
end
def opened?
defined?(@stdin)
end
def open
@stdin, @stdout, @stderr=Open3::popen3("#{SSH_CMD} #{@host} bash -s")
@stream_out = ""
@stream_err = ""
@out = ""
@err = ""
end
def close
@stdin.puts "\nexit"
@stdin.close if not @stdin.closed?
@stdout.close if not @stdout.closed?
@stderr.close if not @stderr.closed?
end
def exec(command)
@out = ""
@err = ""
begin
@stdin.write "(#{command}); #{EOF_CMD}\n"
@stdin.flush
rescue
end
end
def wait_for_command
done_out = false
done_err = false
code = -1
while not (done_out and done_err)
rc, rw, = IO.select([@stdout, @stderr],[],[])
rc.each { |fd|
c = fd.read_nonblock(1)
if !c
done = true
break
end
if fd == @stdout
@out << c
done_out = true if @out.slice!("#{EOF_OUT}\n")
else
@err << c
tmp = @err.scan(/^#{RC_STR}(\d*)#{EOF_ERR}\n/)
if tmp[0]
code = tmp[0][0].to_i
done_err = true
@err.slice!("#{EOF_ERR}\n")
end
end
}
end
@stream_out << @out
@stream_err << @err
return code
end
def exec_and_wait(command)
exec(command)
wait_for_command
end
end
class SshStreamCommand < GenericCommand
def initialize(host, logger=nil, stdin=nil)
@host=host
super('true', logger, stdin)
@stream=SshStream.new(host)
@stream.open
end
def run(command, stdin=nil)
@stream.open unless @stream.opened?
@stream.exec(command)
@stream.stdin.write(stdin) if stdin
code=@stream.wait_for_command
@stdout=@stream.out
@stderr=@stream.err
if code!=0
log("Command execution fail: #{command}")
end
log(@stderr)
return code
end
end
if $0 == __FILE__
ssh=SshStream.new('localhost')
ssh.open
ssh.exec("date | tee /tmp/test.javi")
code=ssh.wait_for_command
puts "Code: #{code}"
puts "output: #{ssh.out}"
ssh.exec "cat << EOT | cat"
ssh.stdin.puts "blah blah\nmas blah\nrequeteblah"
ssh.stdin.puts "EOT"
code=ssh.wait_for_command
puts "Code: #{code}"
puts "output: #{ssh.out}"
code=ssh.exec_and_wait("whoami")
puts "Code: #{code}"
puts "output: #{ssh.out}"
code=ssh.exec_and_wait("touch /etc/pepe.txt")
puts "Code: #{code}"
puts "output: #{ssh.out}"
puts "output err: #{ssh.err}"
ssh.close
end