Fix node lock aquire to force with node operation
This patch fixes the node_operation action to properly steal the lock for the node. This is to prevent failures when a delete action is using node_stop_on_delete. Change-Id: I97fbc126bef4cd1bec65201320365cf6fa2f41e4
This commit is contained in:
parent
8bc176742c
commit
7581f527ca
|
@ -1179,7 +1179,7 @@ class ClusterAction(base.Action):
|
|||
was a success and why if it wasn't a success.
|
||||
"""
|
||||
# Try to lock cluster before do real operation
|
||||
forced = True if self.action == consts.CLUSTER_DELETE else False
|
||||
forced = (self.action == consts.CLUSTER_DELETE)
|
||||
res = senlin_lock.cluster_lock_acquire(self.context, self.target,
|
||||
self.id, self.owner,
|
||||
senlin_lock.CLUSTER_SCOPE,
|
||||
|
|
|
@ -247,6 +247,7 @@ class NodeAction(base.Action):
|
|||
"""
|
||||
# Since node.cluster_id could be reset to '' during action execution,
|
||||
# we record it here for policy check and cluster lock release.
|
||||
forced = (self.action in [consts.NODE_DELETE, consts.NODE_OPERATION])
|
||||
saved_cluster_id = self.entity.cluster_id
|
||||
if saved_cluster_id:
|
||||
if self.cause == consts.CAUSE_RPC:
|
||||
|
@ -268,11 +269,11 @@ class NodeAction(base.Action):
|
|||
return self.RES_ERROR, ('Policy check: ' +
|
||||
self.data['reason'])
|
||||
elif self.cause == consts.CAUSE_DERIVED_LCH:
|
||||
self.policy_check(self.entity.cluster_id, 'BEFORE')
|
||||
self.policy_check(saved_cluster_id, 'BEFORE')
|
||||
|
||||
try:
|
||||
res = senlin_lock.node_lock_acquire(self.context, self.entity.id,
|
||||
self.id, self.owner, False)
|
||||
self.id, self.owner, forced)
|
||||
if not res:
|
||||
res = self.RES_RETRY
|
||||
reason = 'Failed in locking node'
|
||||
|
|
|
@ -1995,6 +1995,7 @@ class EngineService(service.Service):
|
|||
|
||||
db_node = node_obj.Node.find(ctx, req.identity)
|
||||
node = node_mod.Node.load(ctx, db_node=db_node)
|
||||
|
||||
profile = node.rt['profile']
|
||||
if req.operation not in profile.OPERATIONS:
|
||||
msg = _("The requested operation '%(o)s' is not supported by the "
|
||||
|
|
|
@ -716,6 +716,52 @@ class NodeActionTest(base.SenlinTestCase):
|
|||
'ACTION_ID', None, False)
|
||||
mock_release_node.assert_called_once_with('NODE_ID', 'ACTION_ID')
|
||||
|
||||
@mock.patch.object(lock, 'cluster_lock_acquire')
|
||||
@mock.patch.object(lock, 'cluster_lock_release')
|
||||
@mock.patch.object(base_action.Action, 'policy_check')
|
||||
@mock.patch.object(lock, 'node_lock_acquire')
|
||||
@mock.patch.object(lock, 'node_lock_release')
|
||||
def test_execute_success_stealing_node_lock(self, mock_release_node,
|
||||
mock_acquire_node, mock_check,
|
||||
mock_release, mock_acquire,
|
||||
mock_load):
|
||||
node = mock.Mock()
|
||||
node.cluster_id = 'FAKE_CLUSTER'
|
||||
node.id = 'NODE_ID'
|
||||
mock_load.return_value = node
|
||||
|
||||
action = node_action.NodeAction('NODE_ID', 'NODE_OPERATION', self.ctx,
|
||||
cause='RPC Request')
|
||||
action.id = 'ACTION_ID'
|
||||
action.data = {
|
||||
'status': policy_mod.CHECK_OK,
|
||||
'reason': 'Policy checking passed'
|
||||
}
|
||||
action.inputs = {'operation': 'stop', 'params': {}}
|
||||
|
||||
mock_acquire.return_value = 'ACTION_ID'
|
||||
mock_acquire_node.return_value = True
|
||||
|
||||
res_code, res_msg = action.execute()
|
||||
|
||||
reason = "Node operation 'stop' succeeded."
|
||||
self.assertEqual(action.RES_OK, res_code)
|
||||
self.assertEqual(reason, res_msg)
|
||||
mock_load.assert_called_once_with(action.context, node_id='NODE_ID')
|
||||
mock_acquire.assert_called_once_with(self.ctx, 'FAKE_CLUSTER',
|
||||
'ACTION_ID', None,
|
||||
lock.NODE_SCOPE, False)
|
||||
policy_calls = [
|
||||
mock.call('FAKE_CLUSTER', 'BEFORE'),
|
||||
mock.call('FAKE_CLUSTER', 'AFTER')
|
||||
]
|
||||
mock_release.assert_called_once_with('FAKE_CLUSTER', 'ACTION_ID',
|
||||
lock.NODE_SCOPE)
|
||||
mock_check.assert_has_calls(policy_calls)
|
||||
mock_acquire_node.assert_called_once_with(self.ctx, 'NODE_ID',
|
||||
'ACTION_ID', None, True)
|
||||
mock_release_node.assert_called_once_with('NODE_ID', 'ACTION_ID')
|
||||
|
||||
@mock.patch.object(lock, 'cluster_lock_acquire')
|
||||
@mock.patch.object(lock, 'cluster_lock_release')
|
||||
@mock.patch.object(base_action.Action, 'policy_check')
|
||||
|
|
Loading…
Reference in New Issue