root = File.join(File.dirname(__FILE__), "..") $LOAD_PATH.push root unless $LOAD_PATH.include? root require "sidekiq" require "sidekiq/api" require "fileutils" require "core/devops-service" require "core/devops-config" require "core/devops-logger" require "core/devops-db" require "providers/provider_factory" require "lib/knife/knife_factory" # All options keys MUST be a symbol!!! class Worker include Sidekiq::Worker attr_accessor :out module STATUS INIT = "init" RUNNING = "running" COMPLETED = "completed" FAILED = "failed" IN_QUEUE = "queued" end def self.start_async(worker_class, request, job_options) jid = worker_class.perform_async(job_options) Worker.set_status jid, Worker::STATUS::IN_QUEUE DevopsLogger.logger.info "Job '#{jid}' has been queued" uri = URI.parse(request.url) uri.path = "#{DevopsConfig[:url_prefix]}/v2.0/report/#{jid}" uri.to_s end def self.start_sync(worker_class, request, job_options, out) stringified_options = job_options =begin job_options.each do |key, value| stringified_options[key.to_s] = value end =end w = worker_class.new w.out = out w.perform(stringified_options) end def self.set_status id, status Sidekiq.redis {|con| con.hset "devops", id, status} end def call provider_name, &block begin initialize_devops(provider_name) provider = ::Provider::ProviderFactory.get(provider_name) if provider_name if jid call_async(provider, &block) else call_sync(provider, &block) end rescue StandardError => e puts e.message puts e.backtrace.join("\n") DevopsLogger.logger.error e.message end end private def initialize_devops(provider_name) DevopsLogger.logger = logger DevopsConfig.read DevopsService.init ::Provider::ProviderFactory.init(DevopsConfig.config) end # outputs to file def call_async(provider) dir = DevopsConfig[:report_dir_v2] # directory is created on server start in config.ru file = File.join(dir, jid) update_job_status(STATUS::INIT) File.open(file, "w") do |out| begin update_job_status(STATUS::RUNNING) self.out = out job_result = yield(provider, out, file) canonical_status = (job_result == 0 ? STATUS::COMPLETED : STATUS::FAILED) update_job_status(canonical_status) rescue StandardError, RecordNotFound => e out << "\n #{e.class}\n #{e.message}\n" out << e.backtrace.join("\n") update_job_status(STATUS::FAILED) end end end # outputs to STDOUT def call_sync(provider) out = STDOUT begin yield(provider, out, '') rescue StandardError, RecordNotFound => e out << "\n" out << e.message out << "\n" out << e.backtrace.join("\n") end end def mongo ::Devops::Db.connector end def update_job_status(status) set_status(jid, status) mongo.set_report_status(jid, status) status end def init_provider(provider_name) ::Provider::ProviderFactory.init(DevopsConfig.config) ::Provider::ProviderFactory.get(provider_name) if provider_name end def convert_config conf config = {} conf.each {|k,v| config[k.is_a?(String) ? k.to_sym : k] = v} DevopsLogger.logger.info "Converted options: #{config.inspect}" config end def set_status id, status self.class.set_status(id, status) end end