require "db/mongo/models/stack/stack_factory" require "db/mongo/models/project" require "db/mongo/models/report" require "workers/stack_bootstrap/stack_synchronizer" require "workers/stack_bootstrap/stack_servers_bootstrapper" require "workers/stack_bootstrap/stack_servers_persister" require "workers/stack_bootstrap/errors" class StackBootstrapWorker < Worker # options must contain 'stack_attributes' def perform(options) call do stack_attrs = options.fetch('stack_attributes') without_bootstrap = stack_attrs.delete('without_bootstrap') @out.puts "Received 'without_bootstrap' option" if without_bootstrap save_report(stack_attrs) @stack = create_stack(stack_attrs) if !sync_stack puts_and_flush "Stack creating error" return 1 end begin @servers_with_priority = stack_servers_persister.persist bootstrap_in_priority_order unless without_bootstrap 0 rescue StackServerBootstrapError puts_and_flush "\nAn error occured during bootstraping stack servers." rollback_stack!(@stack) 2 rescue StackServerDeployError out.puts "\nStack was launched, but an error occured during deploying stack servers." puts_and_flush "You can redeploy stack after fixing the error." 3 rescue StackServerBootstrapDeployTimeout puts_and_flush "\nBootstrap or deploy wasn't completed due to timeout." 4 rescue StandardError => e puts_and_flush "\nAn error occured." rollback_stack!(@stack) raise e end end end private def stack_synchronizer @stack_synchronizer ||= StackSynchronizer.new(@stack, out) end def stack_servers_persister @stack_servers_persister ||= StackServersPersister.new(@stack, out) end def stack_servers_bootstrapper @stack_servers_bootstrapper ||= StackServersBootstrapper.new(out, jid) end # builds and persist stack model, initiate stack creating in cloud def create_stack(stack_attrs) stack = Devops::Model::StackFactory.create(stack_attrs["provider"], stack_attrs, @out) mongo.stack_insert(stack) end def sync_stack sync_result = stack_synchronizer.sync if sync_result.ok? puts_and_flush "\nStack '#{@stack.name}' has been created" true else puts_and_flush "An error ocurred during stack synchronization: #{sync_result.reason}" false end end # Bootstrap servers with high priorities first def bootstrap_in_priority_order sorted_priorities = @servers_with_priority.keys.sort.reverse sorted_priorities.each do |priority| @out.puts "Servers with priority '#{priority}':" stack_servers_bootstrapper.bootstrap(@servers_with_priority[priority]) end puts_and_flush "Done." end def rollback_stack!(stack) puts_and_flush "\nStart rollback of a stack" stack.delete_stack_in_cloud! Devops::Db.connector.stack_servers_delete(stack.name) Devops::Db.connector.stack_delete(stack.id) puts_and_flush "Rollback has been completed" end def save_report(stack_attrs) update_report( "created_by" => stack_attrs['owner'], "project" => stack_attrs["project"], "deploy_env" => stack_attrs["deploy_env"], "type" => ::Devops::Model::Report::STACK_TYPE, "subreports" => [], "stack" => stack_attrs['name'] ) end end