fuel-astute/lib/astute/task_node.rb
Vladimir Sharshov (warpc) 496212798e Fix wrong ready status instead of stopped for stop deployment
Report ready status for node means successful node status
which can be get if all tasks was passed with ready and skipped
statuses.

Same effect can be get if Astute mark node as skipped. In this
case we also get equal status 'successful'.

So we need ask node about skipped statuses before ask it about
successful status to prevent losing context about stop
deployment operation.

Change-Id: I3c042425cab800de0bfc4e03f29414b145f44983
Closes-Bug: #1672964
2017-03-17 20:48:52 +03:00

142 lines
4.0 KiB
Ruby

# Copyright 2015 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 'fuel_deployment'
module Astute
class TaskNode < Deployment::Node
def context=(context)
@ctx = context
end
def run(inbox_task)
self.task = inbox_task
@task_engine = select_task_engine(task.data)
@task_engine.run
task.set_status_running
set_status_busy
report_node_status if report_running?(task.data)
end
def poll
return unless busy?
debug("Node #{uid}: task #{task.name}, task status #{task.status}")
# Please be informed that this code define special method
# of Deployment::Node class. We use special method `task`
# to manage task status, graph of tasks and nodes.
task.status = setup_task_status
if @task.running?
@ctx.report({
'nodes' => [{
'uid' => uid,
'deployment_graph_task_name' => task.name,
'task_status' => task.status.to_s,
}]
})
else
info "Finished task #{task} #{"with status: #{task.status}" if task}"
setup_node_status
report_node_status
end
end
def report_node_status
node_status = {
'uid' => uid,
'progress' => current_progress_bar,
}
node_status.merge!(node_report_status)
if task
node_status.merge!(
'deployment_graph_task_name' => task.name,
'task_status' => task.status.to_s,
'summary' => @task_engine.summary
)
node_status.merge!(
'error_msg' => "Task #{task.name} failed on node #{name}"
) if task.failed?
end
@ctx.report('nodes' => [node_status])
end
private
# This method support special task behavior. If task failed
# and we do not think that deployment should be stopped, Astute
# will mark such task as skipped and do not report error
def setup_task_status
if !task.data.fetch('fail_on_error', true) && @task_engine.failed?
Astute.logger.warn "Task #{task.name} failed, but marked as skipped "\
"because of 'fail on error' behavior"
return :skipped
end
@task_engine.status
end
def setup_node_status
if task
set_status_failed && return if task.failed?
set_status_skipped && return if task.dep_failed?
end
set_status_online
end
def current_progress_bar
if tasks_total_count != 0
100 * tasks_finished_count / tasks_total_count
else
100
end
end
def select_task_engine(data)
noop_prefix = noop_run? && not_noop_type?(data) ? "Noop" : ""
task_class_name = noop_prefix + data['type'].split('_').collect(&:capitalize).join
Object.const_get('Astute::' + task_class_name).new(data, @ctx)
rescue => e
raise TaskValidationError, "Unknown task type '#{data['type']}'. Detailed: #{e.message}"
end
def report_running?(data)
!['noop', 'stage', 'skipped'].include?(data['type'])
end
def noop_run?
cluster.noop_run
end
def node_report_status
if !finished?
{}
elsif skipped?
cluster.node_statuses_transitions.fetch('stopped', {})
elsif successful?
cluster.node_statuses_transitions.fetch('successful', {})
else
cluster.node_statuses_transitions.fetch('failed', {})
end
end
def not_noop_type?(data)
!['noop', 'stage', 'skipped'].include?(data['type'])
end
end
end