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:
parent
ee9135b051
commit
6eb06140d0
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user