# File lib/core/util/shell.rb, line 51 def self.connection(name = :core) Nucleon.manager(@@supervisors, name, self) end
# File lib/core/util/shell.rb, line 63 def exec(command, options = {}, &code) config = Config.ensure(options) min = config.get(:min, 1).to_i tries = config.get(:tries, min).to_i tries = ( min > tries ? min : tries ) info_prefix = config.get(:info_prefix, '') info_suffix = config.get(:info_suffix, '') error_prefix = config.get(:error_prefix, '') error_suffix = config.get(:error_suffix, '') ui = config.get(:ui, Nucleon.ui) conditions = Nucleon.events(config.get(:exit, {}), true) $stdout.sync = true $stderr.sync = true system_result = Result.new(command) for i in tries.downto(1) logger.info(">> running shell: #{command}") begin t1, output_new, output_orig, output_reader = pipe_exec_stream($stdout, conditions, { :prefix => info_prefix, :suffix => info_suffix, :quiet => config.get(:quiet, false) }, 'output') do |data| system_result.append_output(data) code ? code.call(:output, command, data) : true end t2, error_new, error_orig, error_reader = pipe_exec_stream($stderr, conditions, { :prefix => error_prefix, :suffix => error_suffix, :quiet => config.get(:quiet, false) }, 'error') do |data| system_result.append_errors(data) code ? code.call(:error, command, data) : true end system_success = system(command) system_result.status = $?.exitstatus ensure output_success = close_exec_pipe(t1, $stdout, output_orig, output_new, 'output') error_success = close_exec_pipe(t2, $stderr, error_orig, error_new, 'error') end logger.warn("`#{command}` messages: #{system_result.errors}") if system_result.errors.length > 0 logger.warn("`#{command}` status: #{system_result.status}") unless system_result.status == 0 success = ( system_success && output_success && error_success ) min -= 1 break if success && min <= 0 && conditions.empty? end system_result end
# File lib/core/util/shell.rb, line 57 def test_connection true end
# File lib/core/util/shell.rb, line 161 def check_conditions(data, conditions, match_prefix = '', &code) prefix = '' unless ! conditions || conditions.empty? conditions.each do |key, event| if event.check(data) prefix = match_prefix conditions.delete(key) end end end result = true if code result = code.call unless prefix.empty? case result when Hash result[:prefix] = prefix else result = { :success => result, :prefix => prefix } end end end return result end
# File lib/core/util/shell.rb, line 148 def close_exec_pipe(thread, output, original, write, label) output.reopen(original) write.close success = thread.value original.close return success end
# File lib/core/util/shell.rb, line 127 def pipe_exec_stream(output, conditions, options, label, &code) original = output.dup read, write = IO.pipe match_prefix = ( options[:match_prefix] ? options[:match_prefix] : 'EXIT' ) thread = process_stream(read, original, options, label) do |data| check_conditions(data, conditions, match_prefix) do code ? code.call(data) : true end end thread.abort_on_exception = false output.reopen(write) return thread, write, original, read end
# File lib/core/util/shell.rb, line 192 def process_stream(input, output, options, label, &code) return Thread.new do success = true default_prefix = ( options[:prefix] ? options[:prefix] : '' ) default_suffix = ( options[:suffix] ? options[:suffix] : '' ) begin while ( data = input.readpartial(1024) ) message = data.strip newline = ( data[-1,1].match(/\n/) ? true : false ) unless message.empty? lines = message.split(/\n/) lines.each_with_index do |line, index| prefix = default_prefix suffix = default_suffix unless line.empty? if code result = code.call(line) if result && result.is_a?(Hash) prefix = result[:prefix] suffix = result[:suffix] result = result[:success] end success = result if success end prefix = ( prefix && ! prefix.empty? ? prefix : '' ) suffix = ( suffix && ! suffix.empty? ? suffix : '' ) eol = ( index < lines.length - 1 || newline ? "\n" : ' ' ) unless options[:quiet] output.write(prefix.lstrip + line + suffix.rstrip + eol) end end end end end rescue EOFError end input.close() success end end