require 'json' require 'open3' require 'stringio' require 'logger' require 'audit' def time_diff_milli(start, finish) (finish - start) * 1000.0 end def handleIO(stillOpen, ioArray, io, log) if ioArray.include?(io) begin log.write(io.readpartial(4096)) rescue EOFError stillOpen.delete_if{|s| s == io} end end end class ManagedError < StandardError end class Worker @test = false def test (t) @test = t end def run(command, start, lines, statusIndicator = false ) audit = Audit.new log = Logger.new(Canzea::config[:logging_root] + '/plans.log') log.info("HANDLING: " + command) File.foreach(command) { |l| if ( l.start_with?('## ') ) log.info "#{lines + 1} Label: " + l elsif ( l.start_with?('#') ) elsif ( /\S/ !~ l ) elsif ( l.chomp.end_with?(".sh") && !l.chomp.end_with?(".atomic.sh") && !l.include?("cp ") && !l.include?("chmod") ) log.info("#{lines + 1} RECURSE: " + l) workingDir = "#{Pathname.new(Canzea::config[:catalog_location]).realpath}/catalog" Dir.chdir(workingDir){ newCommand = "#{Pathname.new(l.chomp).realpath}" lines = run newCommand, start, lines } else if ( (lines + 1) < start ) log.info("Skipping : #{lines + 1} #{l}") lines += 1 next end audit.start( "#{lines + 1 }", l.chomp) log.info("#{lines + 1} FOUND: " + l) if @test == false t1 = Time.now begin workingDir = "#{Pathname.new(Canzea::config[:catalog_location]).realpath}/catalog" puts "-- Executing [#{workingDir}] #{l}" Dir.chdir(workingDir){ Open3.popen3(l) {|stdin, stdout, stderr, wait_thr| pid = wait_thr.pid # pid of the started process. log_w = StringIO.new stillOpen = [stdout, stderr] while !stillOpen.empty? fhs = select(stillOpen, nil, nil, nil) handleIO(stillOpen, fhs[0], stdout, log_w) handleIO(stillOpen, fhs[0], stderr, log_w) end exit_status = wait_thr.value # wait for it to finish log_w.close_write output = log_w.string output.split(/\n/).each do | line | puts "-- #{line}" end puts "-- Exit Status = #{exit_status}" log.info("STDOUT #{output}") log.info("Exit Status = #{exit_status}") # if exit status is failure then exit right away t2 = Time.now msecs = time_diff_milli t1, t2 audit.complete("#{lines + 1}", l.chomp, exit_status.exitstatus, msecs, output) if (statusIndicator) audit.status("#{lines + 1}", l.chomp, exit_status.exitstatus, msecs, output) end if exit_status.exitstatus != 0 abort() end } } rescue => exception msecs = time_diff_milli t1, Time.now audit.complete("#{lines + 1}", l.chomp, "-1", msecs, exception.to_s) raise end else puts "-- TEST -- [#{lines + 1}] FOUND: " + l end end lines += 1 } return lines end end