301 lines
8.8 KiB
Ruby
301 lines
8.8 KiB
Ruby
# Copyright 2013 Mirantis, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
require 'astute/server/reporter'
|
|
|
|
module Astute
|
|
module Server
|
|
|
|
class Dispatcher
|
|
def initialize(producer)
|
|
@orchestrator = Astute::Orchestrator.new(log_parsing=true)
|
|
@producer = producer
|
|
@provisionLogParser = Astute::LogParser::ParseProvisionLogs.new
|
|
end
|
|
|
|
def echo(args)
|
|
Astute.logger.info('Running echo command')
|
|
args
|
|
end
|
|
|
|
#
|
|
# Main worker actions
|
|
#
|
|
|
|
def image_provision(data)
|
|
provision(data, 'image')
|
|
end
|
|
|
|
def native_provision(data)
|
|
provision(data, 'native')
|
|
end
|
|
|
|
def provision(data, provision_method)
|
|
|
|
Astute.logger.info("'provision' method called with data:\n"\
|
|
"#{data.pretty_inspect}")
|
|
|
|
reporter = create_reporter(data)
|
|
begin
|
|
result = @orchestrator.provision(
|
|
reporter,
|
|
data['args']['task_uuid'],
|
|
data['args']['provisioning_info'],
|
|
provision_method
|
|
)
|
|
rescue => e
|
|
Astute.logger.error("Error running provisioning: #{e.message}, "\
|
|
"trace: #{e.format_backtrace}")
|
|
raise StopIteration
|
|
end
|
|
raise StopIteration if result && result['status'] == 'error'
|
|
end
|
|
|
|
def deploy(data)
|
|
Astute.logger.info("'deploy' method called with data:\n"\
|
|
"#{data.pretty_inspect}")
|
|
|
|
reporter = create_reporter(data)
|
|
begin
|
|
@orchestrator.deploy(
|
|
reporter,
|
|
data['args']['task_uuid'],
|
|
data['args']['deployment_info'],
|
|
data['args']['pre_deployment'] || [],
|
|
data['args']['post_deployment'] || []
|
|
)
|
|
reporter.report('status' => 'ready', 'progress' => 100)
|
|
rescue Timeout::Error
|
|
msg = "Timeout of deployment is exceeded."
|
|
Astute.logger.error(msg)
|
|
reporter.report('status' => 'error', 'error' => msg)
|
|
end
|
|
end
|
|
|
|
def granular_deploy(data)
|
|
Astute.logger.info("'granular_deploy' method called with data:\n"\
|
|
"#{data.pretty_inspect}")
|
|
|
|
reporter = create_reporter(data)
|
|
begin
|
|
@orchestrator.granular_deploy(
|
|
reporter,
|
|
data['args']['task_uuid'],
|
|
data['args']['deployment_info'],
|
|
data['args']['pre_deployment'] || [],
|
|
data['args']['post_deployment'] || []
|
|
)
|
|
reporter.report('status' => 'ready', 'progress' => 100)
|
|
rescue Timeout::Error
|
|
msg = "Timeout of deployment is exceeded."
|
|
Astute.logger.error(msg)
|
|
reporter.report('status' => 'error', 'error' => msg)
|
|
end
|
|
end
|
|
|
|
def verify_networks(data)
|
|
data.fetch('subtasks', []).each do |subtask|
|
|
if self.respond_to?(subtask['method'])
|
|
self.send(subtask['method'], subtask)
|
|
else
|
|
Astute.logger.warn("No method for #{subtask}")
|
|
end
|
|
end
|
|
reporter = create_reporter(data)
|
|
result = @orchestrator.verify_networks(
|
|
reporter,
|
|
data['args']['task_uuid'],
|
|
data['args']['nodes']
|
|
)
|
|
report_result(result, reporter)
|
|
end
|
|
|
|
def check_dhcp(data)
|
|
reporter = create_reporter(data)
|
|
result = @orchestrator.check_dhcp(
|
|
reporter,
|
|
data['args']['task_uuid'],
|
|
data['args']['nodes']
|
|
)
|
|
report_result(result, reporter)
|
|
end
|
|
|
|
def multicast_verification(data)
|
|
reporter = create_reporter(data)
|
|
result = @orchestrator.multicast_verification(
|
|
reporter,
|
|
data['args']['task_uuid'],
|
|
data['args']['nodes']
|
|
)
|
|
report_result(result, reporter)
|
|
end
|
|
|
|
def check_repositories(data)
|
|
reporter = create_reporter(data)
|
|
result = @orchestrator.check_repositories(
|
|
reporter,
|
|
data['args']['task_uuid'],
|
|
data['args']['nodes'],
|
|
data['args']['urls']
|
|
)
|
|
report_result(result, reporter)
|
|
end
|
|
|
|
def check_repositories_with_setup(data)
|
|
reporter = create_reporter(data)
|
|
result = @orchestrator.check_repositories_with_setup(
|
|
reporter,
|
|
data['args']['task_uuid'],
|
|
data['args']['nodes']
|
|
)
|
|
report_result(result, reporter)
|
|
end
|
|
|
|
def dump_environment(data)
|
|
@orchestrator.dump_environment(
|
|
create_reporter(data),
|
|
data['args']['task_uuid'],
|
|
data['args']['settings']
|
|
)
|
|
end
|
|
|
|
def remove_nodes(data, reset=false)
|
|
task_uuid = data['args']['task_uuid']
|
|
reporter = create_reporter(data)
|
|
|
|
result = if data['args']['nodes'].empty?
|
|
Astute.logger.debug("#{task_uuid} Node list is empty")
|
|
nil
|
|
else
|
|
@orchestrator.remove_nodes(
|
|
reporter,
|
|
task_uuid,
|
|
data['args']['engine'],
|
|
data['args']['nodes'],
|
|
{
|
|
:reboot => true,
|
|
:check_ceph => data['args']['check_ceph'],
|
|
:reset => reset
|
|
}
|
|
)
|
|
end
|
|
|
|
report_result(result, reporter)
|
|
end
|
|
|
|
def reset_environment(data)
|
|
remove_nodes(data, reset=true)
|
|
end
|
|
|
|
def execute_tasks(data)
|
|
@orchestrator.execute_tasks(
|
|
create_reporter(data),
|
|
data['args']['task_uuid'],
|
|
data['args']['tasks']
|
|
)
|
|
end
|
|
|
|
#
|
|
# Service worker actions
|
|
#
|
|
|
|
def stop_deploy_task(data, service_data)
|
|
Astute.logger.debug("'stop_deploy_task' service method called with"\
|
|
"data:\n#{data.pretty_inspect}")
|
|
target_task_uuid = data['args']['stop_task_uuid']
|
|
task_uuid = data['args']['task_uuid']
|
|
|
|
return unless task_in_queue?(target_task_uuid,
|
|
service_data[:tasks_queue])
|
|
|
|
Astute.logger.debug("Cancel task #{target_task_uuid}. Start")
|
|
if target_task_uuid == service_data[:tasks_queue].current_task_id
|
|
reporter = create_reporter(data)
|
|
result = stop_current_task(data, service_data, reporter)
|
|
report_result(result, reporter)
|
|
else
|
|
replace_future_task(data, service_data)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def create_reporter(data)
|
|
Astute::Server::Reporter.new(
|
|
@producer,
|
|
data['respond_to'],
|
|
data['args']['task_uuid']
|
|
)
|
|
end
|
|
|
|
def task_in_queue?(task_uuid, tasks_queue)
|
|
tasks_queue.task_in_queue?(task_uuid)
|
|
end
|
|
|
|
def replace_future_task(data, service_data)
|
|
target_task_uuid = data['args']['stop_task_uuid']
|
|
task_uuid = data['args']['task_uuid']
|
|
|
|
new_task_data = data_for_rm_nodes(data)
|
|
Astute.logger.info("Replace running task #{target_task_uuid} to "\
|
|
"new #{task_uuid} with data:\n"\
|
|
"#{new_task_data.pretty_inspect}")
|
|
service_data[:tasks_queue].replace_task(
|
|
target_task_uuid,
|
|
new_task_data
|
|
)
|
|
end
|
|
|
|
def stop_current_task(data, service_data, reporter)
|
|
target_task_uuid = data['args']['stop_task_uuid']
|
|
task_uuid = data['args']['task_uuid']
|
|
nodes = data['args']['nodes']
|
|
|
|
Astute.logger.info("Try to kill running task #{target_task_uuid}")
|
|
service_data[:main_work_thread].kill
|
|
|
|
result = if ['deploy', 'task_deployment', 'granular_deploy'].include? (
|
|
service_data[:tasks_queue].current_task_method)
|
|
@orchestrator.stop_puppet_deploy(reporter, task_uuid, nodes)
|
|
@orchestrator.remove_nodes(
|
|
reporter,
|
|
task_uuid,
|
|
data['args']['engine'],
|
|
nodes
|
|
)
|
|
else
|
|
@orchestrator.stop_provision(
|
|
reporter,
|
|
task_uuid,
|
|
data['args']['engine'],
|
|
nodes
|
|
)
|
|
end
|
|
end
|
|
|
|
def data_for_rm_nodes(data)
|
|
data['method'] = 'remove_nodes'
|
|
data
|
|
end
|
|
|
|
def report_result(result, reporter)
|
|
result = {} unless result.instance_of?(Hash)
|
|
status = {'status' => 'ready', 'progress' => 100}.merge(result)
|
|
reporter.report(status)
|
|
end
|
|
end
|
|
|
|
end #Server
|
|
end #Astute
|