Browse Source

Remove clean-up of cluster/node action when cluster/node is deleted

The simultaneous delete of cluster/node actions while actual cluster/node
deletion is on-going causes DB deadlocks.  Removing the clean-up and instead
having users run the senlin-manage script periodically to purge the action
table is better way to handle this.

Change-Id: If65d8006150788fff35ecd6eddec0a761e9b4cff
Closes-Bug: 1861445
changes/95/705095/3
Duc Truong 2 weeks ago
parent
commit
d243ea253b
4 changed files with 4 additions and 46 deletions
  1. +0
    -11
      senlin/engine/actions/cluster_action.py
  2. +0
    -11
      senlin/engine/actions/node_action.py
  3. +3
    -18
      senlin/tests/unit/engine/actions/test_delete.py
  4. +1
    -6
      senlin/tests/unit/engine/actions/test_node_action.py

+ 0
- 11
senlin/engine/actions/cluster_action.py View File

@@ -540,17 +540,6 @@ class ClusterAction(base.Action):
self.entity.eval_status(self.context, consts.CLUSTER_DELETE)
return self.RES_ERROR, 'Cannot delete cluster object.'

# Remove all action records which target on deleted
# cluster except the on-going CLUSTER_DELETE action from DB
try:
ao.Action.delete_by_target(
self.context, self.target,
action_excluded=[consts.CLUSTER_DELETE],
status=[consts.ACTION_SUCCEEDED,
consts.ACTION_FAILED])
except Exception as ex:
LOG.warning('Failed to clean cluster action records: %s',
ex)
return self.RES_OK, reason

@profiler.trace('ClusterAction.do_add_nodes', hide_args=False)

+ 0
- 11
senlin/engine/actions/node_action.py View File

@@ -22,7 +22,6 @@ from senlin.engine import cluster as cm
from senlin.engine import event as EVENT
from senlin.engine import node as node_mod
from senlin.engine import senlin_lock
from senlin.objects import action as ao
from senlin.objects import node as no
from senlin.policies import base as pb

@@ -121,16 +120,6 @@ class NodeAction(base.Action):
if not res:
return self.RES_ERROR, 'Node deletion failed.'

# Remove all action records which target on deleted
# node except the on-going NODE_DELETE action from DB
try:
ao.Action.delete_by_target(
self.context, self.target,
action_excluded=[consts.NODE_DELETE],
status=[consts.ACTION_SUCCEEDED, consts.ACTION_FAILED])
except Exception as ex:
LOG.warning('Failed to clean node action records: %s',
ex)
return self.RES_OK, 'Node deleted successfully.'

@profiler.trace('NodeAction.do_update', hide_args=False)

+ 3
- 18
senlin/tests/unit/engine/actions/test_delete.py View File

@@ -535,8 +535,7 @@ class ClusterDeleteTest(base.SenlinTestCase):
mock_remove_normally.assert_called_once_with('NODE_DELETE',
['NODE_ID'])

@mock.patch.object(ao.Action, 'delete_by_target')
def test_do_delete_success(self, mock_action, mock_load):
def test_do_delete_success(self, mock_load):
node1 = mock.Mock(id='NODE_1')
node2 = mock.Mock(id='NODE_2')
cluster = mock.Mock(id='FAKE_CLUSTER', nodes=[node1, node2],
@@ -561,15 +560,10 @@ class ClusterDeleteTest(base.SenlinTestCase):
'Deletion in progress.')
mock_delete.assert_called_once_with(['NODE_1', 'NODE_2'])
cluster.do_delete.assert_called_once_with(action.context)
mock_action.assert_called_once_with(
action.context, 'FAKE_CLUSTER',
action_excluded=['CLUSTER_DELETE'],
status=['SUCCEEDED', 'FAILED'])

@mock.patch.object(ro.Receiver, 'get_all')
@mock.patch.object(cpo.ClusterPolicy, 'get_all')
@mock.patch.object(ao.Action, 'delete_by_target')
def test_do_delete_with_policies(self, mock_action, mock_policies,
def test_do_delete_with_policies(self, mock_policies,
mock_receivers, mock_load):
mock_policy1 = mock.Mock()
mock_policy1.policy_id = 'POLICY_ID1'
@@ -606,10 +600,6 @@ class ClusterDeleteTest(base.SenlinTestCase):
'Deletion in progress.')
mock_delete.assert_called_once_with(['NODE_1', 'NODE_2'])
cluster.do_delete.assert_called_once_with(action.context)
mock_action.assert_called_once_with(
action.context, 'FAKE_CLUSTER',
action_excluded=['CLUSTER_DELETE'],
status=['SUCCEEDED', 'FAILED'])
detach_calls = [mock.call(action.context, 'POLICY_ID1'),
mock.call(action.context, 'POLICY_ID2')]
cluster.detach_policy.assert_has_calls(detach_calls)
@@ -617,8 +607,7 @@ class ClusterDeleteTest(base.SenlinTestCase):
@mock.patch.object(ro.Receiver, 'delete')
@mock.patch.object(ro.Receiver, 'get_all')
@mock.patch.object(cpo.ClusterPolicy, 'get_all')
@mock.patch.object(ao.Action, 'delete_by_target')
def test_do_delete_with_receivers(self, mock_action, mock_policies,
def test_do_delete_with_receivers(self, mock_policies,
mock_receivers, mock_rec_delete,
mock_load):
mock_receiver1 = mock.Mock()
@@ -656,10 +645,6 @@ class ClusterDeleteTest(base.SenlinTestCase):
'Deletion in progress.')
mock_delete.assert_called_once_with(['NODE_1', 'NODE_2'])
cluster.do_delete.assert_called_once_with(action.context)
mock_action.assert_called_once_with(
action.context, 'FAKE_CLUSTER',
action_excluded=['CLUSTER_DELETE'],
status=['SUCCEEDED', 'FAILED'])

cluster.detach_policy.assert_not_called()
rec_delete_calls = [mock.call(action.context, 'RECEIVER_ID1'),

+ 1
- 6
senlin/tests/unit/engine/actions/test_node_action.py View File

@@ -21,7 +21,6 @@ from senlin.engine import cluster as cluster_mod
from senlin.engine import event as EVENT
from senlin.engine import node as node_mod
from senlin.engine import senlin_lock as lock
from senlin.objects import action as ao
from senlin.objects import node as node_obj
from senlin.policies import base as policy_mod
from senlin.tests.unit.common import base
@@ -150,8 +149,7 @@ class NodeActionTest(base.SenlinTestCase):
cluster.eval_status.assert_called_once_with(
action.context, consts.NODE_CREATE, desired_capacity=11)

@mock.patch.object(ao.Action, 'delete_by_target')
def test_do_delete_okay(self, mock_action, mock_load):
def test_do_delete_okay(self, mock_load):
node = mock.Mock(id='NID')
node.do_delete = mock.Mock(return_value=True)
mock_load.return_value = node
@@ -164,9 +162,6 @@ class NodeActionTest(base.SenlinTestCase):
self.assertEqual(action.RES_OK, res_code)
self.assertEqual('Node deleted successfully.', res_msg)
node.do_delete.assert_called_once_with(action.context)
mock_action.assert_called_once_with(
action.context, 'ID', action_excluded=['NODE_DELETE'],
status=['SUCCEEDED', 'FAILED'])

def test_do_delete_failed(self, mock_load):
node = mock.Mock(id='NID')

Loading…
Cancel
Save