Set cluster to correct status when scaling failed
Currently, cluster status will not be set to correct value when resizing/scaling action failed for size limitation check failure. This patch fixes this issue. Change-Id: I9de9a8684c8aa6ffeae9b5f7df9331e51eb168b3 Closes-Bug: #1530746
This commit is contained in:
parent
ec193177a2
commit
84b39d1eb7
|
@ -450,7 +450,7 @@ class ClusterAction(base.Action):
|
|||
:returns: A tuple containing the result and the corresponding reason.
|
||||
"""
|
||||
self.cluster.set_status(self.context, self.cluster.RESIZING,
|
||||
reason='Cluster resize started.')
|
||||
'Cluster resize started.')
|
||||
node_list = self.cluster.nodes
|
||||
current_size = len(node_list)
|
||||
count, desired, candidates = self._get_action_data(current_size)
|
||||
|
@ -460,6 +460,9 @@ class ClusterAction(base.Action):
|
|||
if count == 0:
|
||||
result, reason = scaleutils.parse_resize_params(self, self.cluster)
|
||||
if result != self.RES_OK:
|
||||
status_reason = _('Cluster resizing failed: %s') % reason
|
||||
self.cluster.set_status(self.context, self.cluster.ACTIVE,
|
||||
status_reason)
|
||||
return result, reason
|
||||
count, desired, candidates = self._get_action_data(current_size)
|
||||
elif 'deletion' in self.data:
|
||||
|
@ -478,13 +481,13 @@ class ClusterAction(base.Action):
|
|||
if grace_period is not None:
|
||||
self._wait_before_deletion(grace_period)
|
||||
result, reason = self._delete_nodes(candidates)
|
||||
if result != self.RES_OK:
|
||||
return result, reason
|
||||
# Create new nodes if desired_capacity increased
|
||||
else:
|
||||
result, reason = self._create_nodes(count)
|
||||
if result != self.RES_OK:
|
||||
return result, reason
|
||||
|
||||
if result != self.RES_OK:
|
||||
self.cluster.set_status(self.context, self.cluster.WARNING, reason)
|
||||
return result, reason
|
||||
|
||||
reason = _('Cluster resize succeeded.')
|
||||
kwargs = {'desired_capacity': desired}
|
||||
|
@ -504,7 +507,7 @@ class ClusterAction(base.Action):
|
|||
:returns: A tuple containing the result and the corresponding reason.
|
||||
"""
|
||||
self.cluster.set_status(self.context, self.cluster.RESIZING,
|
||||
reason='Cluster scale out started.')
|
||||
'Cluster scale out started.')
|
||||
# We use policy output if any, or else the count is
|
||||
# set to 1 as default.
|
||||
pd = self.data.get('creation', None)
|
||||
|
@ -517,6 +520,9 @@ class ClusterAction(base.Action):
|
|||
|
||||
if count <= 0:
|
||||
reason = _('Invalid count (%s) for scaling out.') % count
|
||||
status_reason = _('Cluster scaling failed: %s') % reason
|
||||
self.cluster.set_status(self.context, self.cluster.ACTIVE,
|
||||
status_reason)
|
||||
return self.RES_ERROR, reason
|
||||
|
||||
# check provided params against current properties
|
||||
|
@ -527,6 +533,9 @@ class ClusterAction(base.Action):
|
|||
result = scaleutils.check_size_params(self.cluster, new_size,
|
||||
None, None, True)
|
||||
if result != '':
|
||||
status_reason = _('Cluster scaling failed: %s') % result
|
||||
self.cluster.set_status(self.context, self.cluster.ACTIVE,
|
||||
status_reason)
|
||||
return self.RES_ERROR, result
|
||||
|
||||
result, reason = self._create_nodes(count)
|
||||
|
@ -548,7 +557,7 @@ class ClusterAction(base.Action):
|
|||
:returns: A tuple containing the result and the corresponding reason.
|
||||
"""
|
||||
self.cluster.set_status(self.context, self.cluster.RESIZING,
|
||||
reason='Cluster scale in started.')
|
||||
'Cluster scale in started.')
|
||||
# We use policy data if any, deletion policy and scaling policy might
|
||||
# be attached.
|
||||
pd = self.data.get('deletion', None)
|
||||
|
@ -565,6 +574,9 @@ class ClusterAction(base.Action):
|
|||
|
||||
if count <= 0:
|
||||
reason = _('Invalid count (%s) for scaling in.') % count
|
||||
status_reason = _('Cluster scaling failed: %s') % reason
|
||||
self.cluster.set_status(self.context, self.cluster.ACTIVE,
|
||||
status_reason)
|
||||
return self.RES_ERROR, reason
|
||||
|
||||
# check provided params against current properties
|
||||
|
@ -580,6 +592,9 @@ class ClusterAction(base.Action):
|
|||
result = scaleutils.check_size_params(self.cluster, new_size,
|
||||
None, None, False)
|
||||
if result != '':
|
||||
status_reason = _('Cluster scaling failed: %s') % result
|
||||
self.cluster.set_status(self.context, self.cluster.ACTIVE,
|
||||
status_reason)
|
||||
return self.RES_ERROR, result
|
||||
|
||||
# Choose victims randomly
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
import mock
|
||||
|
||||
from senlin.common import exception
|
||||
from senlin.common.i18n import _
|
||||
from senlin.common import scaleutils
|
||||
from senlin.db.sqlalchemy import api as db_api
|
||||
from senlin.engine.actions import base as base_action
|
||||
|
@ -1162,8 +1163,7 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
mock_create.assert_called_once_with(2)
|
||||
self.assertEqual({'creation': {'count': 2}}, action.data)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, 'RESIZING',
|
||||
reason='Cluster resize started.'),
|
||||
mock.call(action.context, 'RESIZING', 'Cluster resize started.'),
|
||||
mock.call(action.context, 'ACTIVE', 'Cluster resize succeeded.',
|
||||
desired_capacity=12)])
|
||||
|
||||
|
@ -1212,8 +1212,7 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
mock_create.assert_called_once_with(2)
|
||||
self.assertEqual({'creation': {'count': 2}}, action.data)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, 'RESIZING',
|
||||
reason='Cluster resize started.'),
|
||||
mock.call(action.context, 'RESIZING', 'Cluster resize started.'),
|
||||
mock.call(action.context, 'ACTIVE', 'Cluster resize succeeded.',
|
||||
desired_capacity=12, min_size=5, max_size=20)])
|
||||
|
||||
|
@ -1223,7 +1222,8 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
cluster.id = 'FAKE_ID'
|
||||
cluster.desired_capacity = 3
|
||||
cluster.nodes = []
|
||||
cluster.ACTIVE = 'ACTIVE'
|
||||
cluster.RESIZING = 'RESIZING'
|
||||
cluster.WARNING = 'WARNING'
|
||||
mock_load.return_value = cluster
|
||||
action = ca.ClusterAction(cluster.id, 'CLUSTER_ACTION', self.ctx)
|
||||
action.data = {
|
||||
|
@ -1238,9 +1238,11 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
# assertions
|
||||
self.assertEqual(action.RES_ERROR, res_code)
|
||||
self.assertEqual('Things out of control.', res_msg)
|
||||
|
||||
mock_create.assert_called_once_with(5)
|
||||
self.assertEqual({'creation': {'count': 5}}, action.data)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, 'RESIZING', 'Cluster resize started.'),
|
||||
mock.call(action.context, 'WARNING', 'Things out of control.')])
|
||||
|
||||
@mock.patch.object(ca.ClusterAction, '_wait_before_deletion')
|
||||
@mock.patch.object(ca.ClusterAction, '_get_action_data')
|
||||
|
@ -1290,8 +1292,7 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
self.assertEqual(2, len(mock_delete.call_args[0][0]))
|
||||
self.assertEqual({'deletion': {'count': 2}}, action.data)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, 'RESIZING',
|
||||
reason='Cluster resize started.'),
|
||||
mock.call(action.context, 'RESIZING', 'Cluster resize started.'),
|
||||
mock.call(action.context, 'ACTIVE', 'Cluster resize succeeded.',
|
||||
desired_capacity=8)])
|
||||
|
||||
|
@ -1317,6 +1318,8 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
|
||||
def test_do_resize_failed_checking(self, mock_load):
|
||||
cluster = mock.Mock()
|
||||
cluster.ACTIVE = 'ACTIVE'
|
||||
cluster.RESIZING = 'RESIZING'
|
||||
cluster.desired_capacity = 8
|
||||
cluster.nodes = []
|
||||
mock_load.return_value = cluster
|
||||
|
@ -1331,8 +1334,13 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
|
||||
# assertions
|
||||
self.assertEqual(action.RES_ERROR, res_code)
|
||||
self.assertEqual('The target capacity (8) is less than the specified '
|
||||
'min_size (10).', res_msg)
|
||||
reason = _('The target capacity (8) is less than the specified '
|
||||
'min_size (10).')
|
||||
self.assertEqual(reason, res_msg)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, 'RESIZING', 'Cluster resize started.'),
|
||||
mock.call(action.context, 'ACTIVE',
|
||||
'Cluster resizing failed: %s' % reason)])
|
||||
|
||||
@mock.patch.object(ca.ClusterAction, '_delete_nodes')
|
||||
def test_do_resize_shrink_failed_delete(self, mock_delete, mock_load):
|
||||
|
@ -1372,7 +1380,7 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
self.assertEqual(2, len(mock_delete.call_args[0][0]))
|
||||
self.assertEqual({'deletion': {'count': 2, 'grace_period': 2}},
|
||||
action.data)
|
||||
self.assertEqual(1, cluster.set_status.call_count)
|
||||
self.assertEqual(2, cluster.set_status.call_count)
|
||||
|
||||
@mock.patch.object(ca.ClusterAction, '_create_nodes')
|
||||
def test_do_scale_out_no_pd_no_inputs(self, mock_create, mock_load):
|
||||
|
@ -1398,7 +1406,7 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
mock_create.assert_called_once_with(1)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, cluster.RESIZING,
|
||||
reason='Cluster scale out started.'),
|
||||
'Cluster scale out started.'),
|
||||
mock.call(action.context, cluster.ACTIVE,
|
||||
'Cluster scaling succeeded.', desired_capacity=1)])
|
||||
|
||||
|
@ -1426,7 +1434,7 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
mock_create.assert_called_once_with(3)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, cluster.RESIZING,
|
||||
reason='Cluster scale out started.'),
|
||||
'Cluster scale out started.'),
|
||||
mock.call(action.context, cluster.ACTIVE,
|
||||
'Cluster scaling succeeded.', desired_capacity=3)])
|
||||
|
||||
|
@ -1455,12 +1463,14 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
mock_create.assert_called_once_with(2)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, cluster.RESIZING,
|
||||
reason='Cluster scale out started.'),
|
||||
'Cluster scale out started.'),
|
||||
mock.call(action.context, cluster.ACTIVE,
|
||||
'Cluster scaling succeeded.', desired_capacity=2)])
|
||||
|
||||
def test_do_scale_out_count_negative(self, mock_load):
|
||||
cluster = mock.Mock()
|
||||
cluster.ACTIVE = 'ACTIVE'
|
||||
cluster.RESIZING = 'RESIZING'
|
||||
cluster.id = 'CID'
|
||||
mock_load.return_value = cluster
|
||||
action = ca.ClusterAction(cluster.id, 'CLUSTER_ACTION', self.ctx)
|
||||
|
@ -1472,10 +1482,18 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
|
||||
# assertions
|
||||
self.assertEqual(action.RES_ERROR, res_code)
|
||||
self.assertEqual('Invalid count (-2) for scaling out.', res_msg)
|
||||
reason = 'Invalid count (-2) for scaling out.'
|
||||
self.assertEqual(reason, res_msg)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, 'RESIZING',
|
||||
'Cluster scale out started.'),
|
||||
mock.call(action.context, 'ACTIVE',
|
||||
'Cluster scaling failed: %s' % reason)])
|
||||
|
||||
def test_do_scale_out_failed_checking(self, mock_load):
|
||||
cluster = mock.Mock()
|
||||
cluster.ACTIVE = 'ACTIVE'
|
||||
cluster.RESIZING = 'RESIZING'
|
||||
cluster.id = 'CID'
|
||||
cluster.desired_capacity = 3
|
||||
cluster.min_size = 1
|
||||
|
@ -1491,8 +1509,14 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
|
||||
# assertions
|
||||
self.assertEqual(action.RES_ERROR, res_code)
|
||||
self.assertEqual('The target capacity (5) is greater than the '
|
||||
'cluster\'s max_size (4).', res_msg)
|
||||
reason = _('The target capacity (5) is greater than the '
|
||||
'cluster\'s max_size (4).')
|
||||
self.assertEqual(reason, res_msg)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, 'RESIZING',
|
||||
'Cluster scale out started.'),
|
||||
mock.call(action.context, 'ACTIVE',
|
||||
'Cluster scaling failed: %s' % reason)])
|
||||
|
||||
@mock.patch.object(ca.ClusterAction, '_create_nodes')
|
||||
def test_do_scale_out_failed_create_nodes(self, mock_create, mock_load):
|
||||
|
@ -1518,7 +1542,7 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
self.assertEqual('Too hot to work!', res_msg)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, cluster.RESIZING,
|
||||
reason='Cluster scale out started.'),
|
||||
'Cluster scale out started.'),
|
||||
mock.call(action.context, cluster.ERROR, 'Too hot to work!')])
|
||||
cluster.set_status.reset_mock()
|
||||
mock_create.assert_called_once_with(2)
|
||||
|
@ -1563,7 +1587,7 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
self.assertEqual(1, len(mock_delete.call_args[0][0]))
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, cluster.RESIZING,
|
||||
reason='Cluster scale in started.'),
|
||||
'Cluster scale in started.'),
|
||||
mock.call(action.context, cluster.ACTIVE,
|
||||
'Cluster scaling succeeded.', desired_capacity=9)])
|
||||
|
||||
|
@ -1606,7 +1630,7 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
self.assertIn('NODE_ID_4', mock_delete.call_args[0][0])
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, cluster.RESIZING,
|
||||
reason='Cluster scale in started.'),
|
||||
'Cluster scale in started.'),
|
||||
mock.call(action.context, cluster.ACTIVE,
|
||||
'Cluster scaling succeeded.', desired_capacity=3)])
|
||||
mock_wait.assert_called_once_with(2)
|
||||
|
@ -1640,12 +1664,14 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
self.assertEqual(3, len(mock_delete.call_args[0][0]))
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, cluster.RESIZING,
|
||||
reason='Cluster scale in started.'),
|
||||
'Cluster scale in started.'),
|
||||
mock.call(action.context, cluster.ACTIVE,
|
||||
'Cluster scaling succeeded.', desired_capacity=2)])
|
||||
|
||||
def test_do_scale_in_invalid_count(self, mock_load):
|
||||
cluster = mock.Mock()
|
||||
cluster.ACTIVE = 'ACTIVE'
|
||||
cluster.RESIZING = 'RESIZING'
|
||||
cluster.id = 'CID'
|
||||
cluster.min_size = 1
|
||||
cluster.max_size = -1
|
||||
|
@ -1663,8 +1689,14 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
res_code, res_msg = action.do_scale_in()
|
||||
|
||||
# assertions
|
||||
self.assertEqual('Invalid count (-3) for scaling in.', res_msg)
|
||||
reason = 'Invalid count (-3) for scaling in.'
|
||||
self.assertEqual(reason, res_msg)
|
||||
self.assertEqual(action.RES_ERROR, res_code)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, 'RESIZING',
|
||||
'Cluster scale in started.'),
|
||||
mock.call(action.context, 'ACTIVE',
|
||||
'Cluster scaling failed: %s' % reason)])
|
||||
|
||||
@mock.patch.object(ca.ClusterAction, '_delete_nodes')
|
||||
def test_do_scale_in_best_effort(self, mock_delete, mock_load):
|
||||
|
@ -1693,12 +1725,14 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
self.assertEqual(2, len(mock_delete.call_args[0][0]))
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, cluster.RESIZING,
|
||||
reason='Cluster scale in started.'),
|
||||
'Cluster scale in started.'),
|
||||
mock.call(action.context, cluster.ACTIVE,
|
||||
'Cluster scaling succeeded.', desired_capacity=0)])
|
||||
|
||||
def test_do_scale_in_failed_check(self, mock_load):
|
||||
cluster = mock.Mock()
|
||||
cluster.ACTIVE = 'ACTIVE'
|
||||
cluster.RESIZING = 'RESIZING'
|
||||
cluster.id = 'CID'
|
||||
cluster.min_size = 1
|
||||
cluster.max_size = -1
|
||||
|
@ -1717,8 +1751,14 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
|
||||
# assertions
|
||||
self.assertEqual(action.RES_ERROR, res_code)
|
||||
self.assertEqual('The target capacity (0) is less than the '
|
||||
'cluster\'s min_size (1).', res_msg)
|
||||
reason = _('The target capacity (0) is less than the '
|
||||
'cluster\'s min_size (1).')
|
||||
self.assertEqual(reason, res_msg)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, 'RESIZING',
|
||||
'Cluster scale in started.'),
|
||||
mock.call(action.context, 'ACTIVE',
|
||||
'Cluster scaling failed: %s' % reason)])
|
||||
|
||||
@mock.patch.object(ca.ClusterAction, '_delete_nodes')
|
||||
def test_do_scale_in_failed_delete_nodes(self, mock_delete, mock_load):
|
||||
|
@ -1748,7 +1788,7 @@ class ClusterActionTest(base.SenlinTestCase):
|
|||
self.assertEqual('Too cold to work!', res_msg)
|
||||
cluster.set_status.assert_has_calls([
|
||||
mock.call(action.context, cluster.RESIZING,
|
||||
reason='Cluster scale in started.'),
|
||||
'Cluster scale in started.'),
|
||||
mock.call(action.context, cluster.ERROR, 'Too cold to work!')])
|
||||
cluster.set_status.reset_mock()
|
||||
mock_delete.assert_called_once_with(mock.ANY)
|
||||
|
|
Loading…
Reference in New Issue