require 'lib/helpers/job_waiter' require 'workers/bootstrap_worker' # Starts bootstrap workers for each server in group and wait for them to end (synchroniously). class Devops::Executor::StackExecutor class ServersBootstrapper include PutsAndFlush attr_reader :out class Result < Devops::Helpers::ResultObject set_result_codes( ok: 0, bootstrap_error: 2, deploy_error: 3, timeout_reached: 4 ) end def initialize(out, jid, servers) @out, @jid, @servers = out, jid, servers @server_bootstrap_jobs = {} end # returns array of Results def bootstrap_group start_workers! ::Devops::Db.connector.add_report_subreports(@jid, @server_bootstrap_jobs.values) @server_bootstrap_jobs.map do |server_id, job_id| result = wait_for_bootstrap_job(job_id) puts_and_flush Devops::Messages.t("stack_executor.servers_bootstrapper.result.#{result.reason}", server_id: server_id, job_id: job_id) result end end private # returns hash: {server_id => worker_job_id} def start_workers! @servers.each do |server| job_id = Worker.start_async(::BootstrapWorker, server_attrs: server.to_mongo_hash, bootstrap_template: 'omnibus', owner: server.created_by, skip_rollback: true ) @out.puts "Start bootstraping server '#{server.id}' job (job id: #{job_id})." @server_bootstrap_jobs[server.id] = job_id end puts_and_flush "\n\n\n" end def result(reason) Result.from_reason(reason) end def wait_for_bootstrap_job(job_id) result_code = Devops::Helpers::JobWaiter.new(job_id).wait result_from_job_code(result_code) rescue Devops::Helpers::JobWaiter::TimeoutReached result(:timeout_reached) end def result_from_job_code(result_code) job_result = Devops::Executor::ServerOperationResult.new(result_code) if job_result.ok? result(:ok) elsif job_result.one_of_bootstrap_errors? result(:bootstrap_error) else result(:deploy_error) end end end end