Add node_operation to lock and conflict bypass

This patch adds node_operation to lock & conflict bypass. This
allows the node operation to be accepted even when a cluster is
locked.

This fixes an issue when a cluster stop_on_delete flag is set.

Change-Id: Ic92eda3964c0a90aac165b412243f62c2933e459
This commit is contained in:
Jude Cross 2019-01-24 18:23:02 -08:00
parent baa94635f6
commit 9f3e49412d
3 changed files with 31 additions and 4 deletions

View File

@ -336,3 +336,11 @@ HEALTH_CHECK_MESSAGE = (
'Poll URL health check passed',
'Poll URL health check failed',
)
CONFLICT_BYPASS_ACTIONS = [
CLUSTER_DELETE, NODE_DELETE, NODE_OPERATION,
]
LOCK_BYPASS_ACTIONS = [
CLUSTER_DELETE, NODE_DELETE, NODE_OPERATION,
]

View File

@ -271,8 +271,7 @@ class Action(object):
@staticmethod
def _check_action_lock(target, action):
if action == consts.CLUSTER_DELETE or action == consts.NODE_DELETE:
# DELETE actions do not care about locks
if action in consts.LOCK_BYPASS_ACTIONS:
return
elif (action in list(consts.CLUSTER_ACTION_NAMES) and
cl.ClusterLock.is_locked(target)):
@ -287,8 +286,7 @@ class Action(object):
def _check_conflicting_actions(ctx, target, action):
conflict_actions = ao.Action.get_all_active_by_target(ctx, target)
# Ignore conflicting actions on deletes.
if not conflict_actions or action in (consts.CLUSTER_DELETE,
consts.NODE_DELETE):
if not conflict_actions or action in consts.CONFLICT_BYPASS_ACTIONS:
return
else:
action_ids = [a['id'] for a in conflict_actions]

View File

@ -381,6 +381,27 @@ class ActionBaseTest(base.SenlinTestCase):
mock_store.assert_called_once_with(self.ctx)
mock_active.assert_called_once_with(mock.ANY, OBJID)
@mock.patch.object(ab.Action, 'store')
@mock.patch.object(ao.Action, 'get_all_active_by_target')
@mock.patch.object(cl.ClusterLock, 'is_locked')
def test_action_create_node_operation_no_conflict(self, mock_lock,
mock_active, mock_store):
mock_store.return_value = 'FAKE_ID'
uuid1 = 'ce982cd5-26da-4e2c-84e5-be8f720b7478'
uuid2 = 'ce982cd5-26da-4e2c-84e5-be8f720b7479'
mock_active.return_value = [
ao.Action(id=uuid1, action='NODE_DELETE'),
ao.Action(id=uuid2, action='NODE_DELETE')
]
mock_lock.return_value = True
result = ab.Action.create(self.ctx, OBJID, 'NODE_OPERATION',
name='test')
self.assertEqual('FAKE_ID', result)
mock_store.assert_called_once_with(self.ctx)
mock_active.assert_called_once_with(mock.ANY, OBJID)
@mock.patch.object(timeutils, 'is_older_than')
@mock.patch.object(cpo.ClusterPolicy, 'get_all')
@mock.patch.object(policy_mod.Policy, 'load')