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 initialize () @log = Logger.new(Canzea::config[:logging_root] + '/plans.log') end def test (t) @test = t end def find(command, list = []) audit = Audit.new false @log.info(" FIND: " + 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(" [#{ref}] RECURSE: " + l) workingDir = "#{Pathname.new(Canzea::config[:catalog_location]).realpath}" Dir.chdir(workingDir) { newCommand = "#{Pathname.new(l.chomp).realpath}" lines = find newCommand, list } else list.push l end } return list end def run(command, start, lines, statusIndicator = false, ref = "" ) audit = Audit.new false @log.info(" [#{ref}] 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(" [#{ref}] RECURSE: " + l) workingDir = "#{Pathname.new(Canzea::config[:catalog_location]).realpath}" Dir.chdir(workingDir){ newCommand = "#{Pathname.new(l.chomp).realpath}" lines = run newCommand, start, lines } else if ( (lines + 1) < start ) @log.info(" [#{ref}] Skipping : #{lines + 1} #{l}") lines += 1 next end audit.start( "#{lines + 1 }", l.chomp) @log.info(" [#{ref}] #{(lines + 1).to_s.rjust(2, "0")} : " + l) if @test == false t1 = Time.now begin workingDir = "#{Pathname.new(Canzea::config[:catalog_location]).realpath}" 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 begin output.split(/\n/).each do | line | puts "-- #{line}" end rescue => exception puts "-- WARNING : Unable to parse output, exception: #{exception.to_s}" 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