class Nucleon::Util::Shell
Public Class Methods
connection(name = :core)
click to toggle source
# File lib/core/util/shell.rb 51 def self.connection(name = :core) 52 Nucleon.manager(@@supervisors, name, self) 53 end
Public Instance Methods
exec(command, options = {}, &code)
click to toggle source
# File lib/core/util/shell.rb 63 def exec(command, options = {}, &code) 64 config = Config.ensure(options) 65 66 min = config.get(:min, 1).to_i 67 tries = config.get(:tries, min).to_i 68 tries = ( min > tries ? min : tries ) 69 70 info_prefix = config.get(:info_prefix, '') 71 info_suffix = config.get(:info_suffix, '') 72 error_prefix = config.get(:error_prefix, '') 73 error_suffix = config.get(:error_suffix, '') 74 75 ui = config.get(:ui, Nucleon.ui) 76 77 conditions = Nucleon.events(config.get(:exit, {}), true) 78 79 $stdout.sync = true 80 $stderr.sync = true 81 82 system_result = Result.new(command) 83 84 for i in tries.downto(1) 85 logger.info(">> running shell: #{command}") 86 87 begin 88 t1, output_new, output_orig, output_reader = pipe_exec_stream($stdout, conditions, { 89 :prefix => info_prefix, 90 :suffix => info_suffix, 91 :quiet => config.get(:quiet, false) 92 }, 'output') do |data| 93 system_result.append_output(data) 94 code ? code.call(:output, command, data) : true 95 end 96 97 t2, error_new, error_orig, error_reader = pipe_exec_stream($stderr, conditions, { 98 :prefix => error_prefix, 99 :suffix => error_suffix, 100 :quiet => config.get(:quiet, false) 101 }, 'error') do |data| 102 system_result.append_errors(data) 103 code ? code.call(:error, command, data) : true 104 end 105 106 system_success = system(command) 107 system_result.status = $?.exitstatus 108 109 ensure 110 output_success = close_exec_pipe(t1, $stdout, output_orig, output_new, 'output') 111 error_success = close_exec_pipe(t2, $stderr, error_orig, error_new, 'error') 112 end 113 114 unless config.get(:quiet, false) 115 logger.warn("`#{command}` messages: #{system_result.errors}") if system_result.errors.length > 0 116 end 117 logger.warn("`#{command}` status: #{system_result.status}") unless system_result.status == 0 118 119 success = ( system_success && output_success && error_success ) 120 121 min -= 1 122 break if success && min <= 0 && conditions.empty? 123 end 124 system_result 125 end
test_connection()
click to toggle source
# File lib/core/util/shell.rb 57 def test_connection 58 true 59 end
Protected Instance Methods
check_conditions(data, conditions, match_prefix = '', &code)
click to toggle source
# File lib/core/util/shell.rb 163 def check_conditions(data, conditions, match_prefix = '', &code) 164 prefix = '' 165 166 unless ! conditions || conditions.empty? 167 conditions.each do |key, event| 168 if event.check(data) 169 prefix = match_prefix 170 conditions.delete(key) 171 end 172 end 173 end 174 175 result = true 176 if code 177 result = code.call 178 179 unless prefix.empty? 180 case result 181 when Hash 182 result[:prefix] = prefix 183 else 184 result = { :success => result, :prefix => prefix } 185 end 186 end 187 end 188 return result 189 end
close_exec_pipe(thread, output, original, write, label)
click to toggle source
# File lib/core/util/shell.rb 150 def close_exec_pipe(thread, output, original, write, label) 151 output.reopen(original) 152 153 write.close 154 success = thread.value 155 156 original.close 157 return success 158 end
pipe_exec_stream(output, conditions, options, label, &code)
click to toggle source
# File lib/core/util/shell.rb 129 def pipe_exec_stream(output, conditions, options, label, &code) 130 original = output.dup 131 read, write = IO.pipe 132 133 match_prefix = ( options[:match_prefix] ? options[:match_prefix] : 'EXIT' ) 134 135 thread = process_stream(read, original, options, label) do |data| 136 check_conditions(data, conditions, match_prefix) do 137 code ? code.call(data) : true 138 end 139 end 140 141 thread.abort_on_exception = false 142 143 output.reopen(write) 144 return thread, write, original, read 145 end
process_stream(input, output, options, label, &code)
click to toggle source
# File lib/core/util/shell.rb 194 def process_stream(input, output, options, label, &code) 195 return Thread.new do 196 success = true 197 default_prefix = ( options[:prefix] ? options[:prefix] : '' ) 198 default_suffix = ( options[:suffix] ? options[:suffix] : '' ) 199 200 begin 201 while ( data = input.readpartial(1024) ) 202 message = data.strip 203 newline = ( data[-1,1].match(/\n/) ? true : false ) 204 205 unless message.empty? 206 lines = message.split(/\n/) 207 lines.each_with_index do |line, index| 208 prefix = default_prefix 209 suffix = default_suffix 210 211 unless line.empty? 212 if code 213 result = code.call(line) 214 215 if result && result.is_a?(Hash) 216 prefix = result[:prefix] 217 suffix = result[:suffix] 218 result = result[:success] 219 end 220 success = result if success 221 end 222 223 prefix = ( prefix && ! prefix.empty? ? prefix : '' ) 224 suffix = ( suffix && ! suffix.empty? ? suffix : '' ) 225 eol = ( index < lines.length - 1 || newline ? "\n" : ' ' ) 226 227 unless options[:quiet] 228 output.write(prefix.lstrip + line + suffix.rstrip + eol) 229 end 230 end 231 end 232 end 233 end 234 rescue EOFError 235 end 236 237 input.close() 238 success 239 end 240 end