1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-27 14:03:40 +03:00

Added support to specify stdin for commands

git-svn-id: http://svn.opennebula.org/one/trunk@371 3034c82b-c49b-4eb3-8279-a7acafdc01c0
This commit is contained in:
Rubén S. Montero 2009-02-21 01:45:42 +00:00
parent ee9135b051
commit 6eb06140d0

View File

@ -32,59 +32,64 @@ require 'open3'
class GenericCommand
attr_reader :code, :stdout, :stderr, :command
attr_accessor :callback
# Creates a command and runs it
def self.run(command, logger=nil)
cmd=self.new(command, logger)
def self.run(command, logger=nil, stdin=nil)
cmd = self.new(command, logger, stdin)
cmd.run
cmd
end
# Creates the new command:
# +command+: string with the command to be executed
# +logger+: proc that takes a message parameter and logs it
def initialize(command, logger=nil)
@command=command
@logger=logger
@callback=nil
def initialize(command, logger=nil, stdin=nil)
@command = command
@logger = logger
@stdin = stdin
@callback= nil
end
# Sends a log message to the logger proc
def log(message)
@logger.call(message) if @logger
end
# Runs the command and calls the callback if it is defined
# +data+: variable to pass to the callaback to provide data
# or to share with other callbacks
def run(data=nil)
log("About to execute #{command}")
std=execute
std = execute
# Close standard IO descriptors
if @stdin
std[0] << @stdin
std[0].flush
end
std[0].close if !std[0].closed?
@stdout=std[1].read
std[1].close if !std[1].closed?
@stderr=std[2].read
std[2].close if !std[2].closed?
@code=get_exit_code(@stderr)
log("Command executed, exit code: #{@code}")
@callback.call(self, data) if @callback
if @code!=0
log("Command execution fail. STDERR follows.")
log(@stderr)
end
return @code
end
private
# Gets exit code from STDERR
@ -93,7 +98,7 @@ private
return nil if !tmp[0]
tmp[0][0].to_i
end
# Low level command execution. This method has to be redefined
# for each kind of command execution. Returns an array with
# +stdin+, +stdout+ and +stderr+ handlers of the command execution.
@ -101,7 +106,7 @@ private
puts "About to execute \"#{@command}\""
[StringIO.new, StringIO.new, StringIO.new]
end
end
# Executes commands in the machine where it is called. See documentation
@ -120,40 +125,44 @@ class SSHCommand < GenericCommand
attr_accessor :host
# Creates a command and runs it
def self.run(command, host, logger=nil)
cmd=self.new(command, host, logger)
def self.run(command, host, logger=nil, stdin=nil)
cmd=self.new(command, host, logger, stdin)
cmd.run
cmd
end
# This one takes another parameter. +host+ is the machine
# where the command is going to be executed
def initialize(command, host, logger=nil)
def initialize(command, host, logger=nil, stdin=nil)
@host=host
super(command, logger)
super(command, logger, stdin)
end
private
def execute
Open3.popen3("ssh -n #{@host} #{@command} ; echo ExitCode: $? 1>&2")
if @stdin
Open3.popen3("ssh #{@host} #{@command} ; echo ExitCode: $? 1>&2")
else
Open3.popen3("ssh -n #{@host} #{@command} ; echo ExitCode: $? 1>&2")
end
end
end
if $0 == __FILE__
data={}
command=GenericCommand.new("uname -a")
command.callback=lambda {|obj,data|
puts obj.stderr
data[1]=[obj.command, obj.code]
}
command.run(data)
# command.run(data)
local_command=LocalCommand.new("uname -a")
local_command.callback=lambda {|obj,data|
puts "STDOUT:"
@ -161,12 +170,12 @@ if $0 == __FILE__
puts
puts "STDERR:"
puts obj.stderr
data[2]=[obj.command, obj.code]
}
local_command.run(data)
ssh_command=SSHCommand.new("uname -a", "localhost")
ssh_command.callback=lambda {|obj,data|
puts "STDOUT:"
@ -174,11 +183,17 @@ if $0 == __FILE__
puts
puts "STDERR:"
puts obj.stderr
data[3]=[obj.command, obj.host, obj.code]
}
ssh_command.run(data)
pp data
fd = File.new("/etc/passwd")
str = String.new
fd.each {|line| str << line}
fd.close
ssh_in = SSHCommand.new("cat > /tmp/test","localhost",nil,str)
ssh_in.run
end