lib/screwcap/runner.rb in screwcap-0.7.4 vs lib/screwcap/runner.rb in screwcap-0.8
- old
+ new
@@ -4,85 +4,95 @@
def self.execute! options
@@silent = options[:silent]
@@verbose = options[:verbose]
task = options[:task]
+ results = []
if (task.__servers.nil? or task.__servers == [] or task.__servers.compact == []) and task.__built_commands.any? {|c| c[:type] == :remote or c[:type] == :scp }
raise Screwcap::ConfigurationError, "The task #{task.name} includes remote commands, however no servers were defined for this task."
end
if options[:servers] and task.__servers
- begin
- servers = options[:servers].select {|s| task.__servers.include? s.__name }
- connections = servers.map {|server| server.connect! }.flatten
- rescue Net::SSH::AuthenticationFailed => e
- raise Net::SSH::AuthenticationFailed, "Authentication failed for server named #{server.name}. Please check your authentication credentials."
- end
+ servers = options[:servers].select {|s| task.__servers.include? s.__name }
+ connections = servers.map {|server| server.connect! }.flatten
end
_log "\nExecuting task #{task.name}\n", :color => :blue
task.__built_commands.each do |command|
ret = case command[:type]
when :remote
- threads = []
- if command[:parallel] == false
- connections.each { |connection| run_remote_command(command, connection, options) }
+ if command[:parallel] == false or command[:block]
+ connections.each do |connection|
+ results << run_remote_command(command, connection[:connection], options)
+ if command[:block]
+ opts = task.__options.clone.merge(:stderr => command[:stderr], :stdout => command[:stdout], :exit_code => command[:exit_code])
+ opts[:servers] = task.__servers
+ opts[:name] = "Run results"
+
+ inner_task = Task.new(opts, &command[:block])
+ inner_task.__build_commands(options[:tasks])
+ results << self.execute!(options.merge(:task => inner_task))
+ end
+ end
else
+ threads = []
connections.each do |connection|
threads << Thread.new(connection) do |conn|
- run_remote_command(command, conn, options)
+ results << run_remote_command(command, conn[:connection], options)
end
end
threads.each {|t| t.join }
end
when :local
- ret = `#{command[:command]}`
- command[:stdout] = ret
+ result = {}
+ result[:stdout] = `#{command[:command]}`
+ result[:exit_code] = $?.to_i
+ results << result
if $?.to_i == 0
if options[:verbose]
_log " O: #{ret}\n", :color => :green
else
_log(".", :color => :green)
end
else
_errorlog(" E: (local): #{command[:command]} return exit code: #{$?}\n", :color => :red) if $? != 0
end
- ret
when :scp
threads = []
servers.each do |server|
threads << Thread.new(server) { |_server| _server.upload! command[:local], command[:remote] }
end
threads.each {|t| t.join }
when :block
command[:block].call
end
end
- _log "\nComplete\n", :color => :blue
- task.__built_commands # for tests
+ _log "Complete\n", :color => :blue
+ results
end
private
def self.run_remote_command(command, ssh, options)
stdout, stderr, exit_code, exit_signal = ssh_exec! ssh, command[:command]
- command[:stdout] = stdout
- command[:stderr] = stderr
- command[:exit_code] = exit_code
+ ret = {:command => command[:command]}
+ ret[:stdout] = command[:stdout] = stdout
+ ret[:stderr] = command[:stderr] = stderr
+ ret[:exit_code] = command[:exit_code] = exit_code
if exit_code == 0
if @@verbose
_log(" I: #{command[:command]}\n", :color => :green)
_log(" O: #{command[:stdout]}\n", :color => :green)
else
_log(".", :color => :green)
- $stdout.flush
end
else
- _errorlog(" E: (#{options[:address]}): #{command[:command]} return exit code: #{exit_code}\n", :color => :red) if exit_code != 0
+ _log(" I: #{command[:command]}\n", :color => :green)
+ _errorlog(" E: (exit code: #{exit_code}) #{command[:stderr]} \n", :color => :red)
end
- exit_code
+ ret
end
# courtesy of flitzwald on stackoverflow
# http://stackoverflow.com/questions/3386233/how-to-get-exit-status-with-rubys-netssh-library
def self.ssh_exec!(ssh, command)