78 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
		
		
			
		
	
	
			78 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
|   | require 'workers/bootstrap_worker' | ||
|  | require "workers/stack_bootstrap/errors" | ||
|  | 
 | ||
|  | class StackServersBootstrapper | ||
|  |   include PutsAndFlush | ||
|  |   attr_reader :out | ||
|  | 
 | ||
|  |   def initialize(out, jid) | ||
|  |     @out, @jid = out, jid | ||
|  |   end | ||
|  | 
 | ||
|  |   def bootstrap(servers) | ||
|  |     @servers = servers | ||
|  |     puts_and_flush "\nStart bootstraping stack servers" | ||
|  | 
 | ||
|  |     servers_jobs_ids = start_workers | ||
|  |     ::Devops::Db.connector.add_report_subreports(@jid, servers_jobs_ids.values) | ||
|  | 
 | ||
|  |     out.puts | ||
|  |     servers_jobs_ids.each do |server_id, subreport_id| | ||
|  |       job_result_code = wait_for_job(server_id, subreport_id) | ||
|  |       check_job_result!(server_id, job_result_code) | ||
|  |     end | ||
|  |     puts_and_flush "Stack servers have been bootstraped" | ||
|  |   end | ||
|  | 
 | ||
|  |   private | ||
|  | 
 | ||
|  |   def check_job_result!(server_id, job_result_code) | ||
|  |     return if job_result_code == 0
 | ||
|  | 
 | ||
|  |     reason = Devops::Executor::ServerExecutor.reason_from_error_code(job_result_code) | ||
|  |     puts_and_flush "Operation result for #{server_id}: #{reason}" | ||
|  | 
 | ||
|  |     if error_occured_during_bootstrap?(reason) | ||
|  |       raise StackServerBootstrapError # will cause rollback of a stack | ||
|  |     else | ||
|  |       raise StackServerDeployError #will not cause rollback of a stack | ||
|  |     end | ||
|  |   end | ||
|  | 
 | ||
|  |   def error_occured_during_bootstrap?(reason) | ||
|  |     Devops::Executor::ServerExecutor.bootstrap_errors_reasons.include?(reason) | ||
|  |   end | ||
|  | 
 | ||
|  |   def wait_for_job(server_id, subreport_id) | ||
|  |     1000.times do | ||
|  |       sleep(5) | ||
|  |       subreport = ::Devops::Db.connector.report(subreport_id) | ||
|  |       case subreport.status | ||
|  |       when Worker::STATUS::COMPLETED | ||
|  |         puts_and_flush "Server '#{server_id}' has been bootstraped with job #{subreport_id}" | ||
|  |         return 0
 | ||
|  |       when Worker::STATUS::FAILED | ||
|  |         puts_and_flush "Server '#{server_id}' hasn't been bootstraped with job #{subreport_id}. Job result code is '#{subreport.job_result_code}'" | ||
|  |         return subreport.job_result_code | ||
|  |       end | ||
|  |     end | ||
|  |     puts_and_flush "Waiting for job #{subreport_id} halted: timeout reached." | ||
|  |     raise StackServerBootstrapDeployTimeout | ||
|  |   end | ||
|  | 
 | ||
|  |   # returns hash: {server_id => worker_job_id} | ||
|  |   def start_workers | ||
|  |     servers_jobs_ids = {} | ||
|  |     @servers.each do |server| | ||
|  |       job_id = Worker.start_async(::BootstrapWorker, | ||
|  |         server_attrs: server.to_mongo_hash, | ||
|  |         bootstrap_template: 'omnibus', | ||
|  |         owner: server.created_by | ||
|  |       ) | ||
|  |       @out.puts "Bootstraping server '#{server.id}'... job id: #{job_id}" | ||
|  |       servers_jobs_ids[server.id] = job_id | ||
|  |     end | ||
|  |     puts_and_flush "\n" | ||
|  |     servers_jobs_ids | ||
|  |   end | ||
|  | end |