Add decorator that requires a lock for Drac management driver
Add decorator that requires a exclusive lock for set_boot_device in Drac management driver. Default lock is shared, which is useful for non-interfering operation, like get_boot_device. Have exclusive lock with an action, can avoid multiple threads to modify the node at same time. This is necessary for changing the boot device for a node. Change-Id: I8482da70cbb859a8da05025f2ee12a1e614f7928
This commit is contained in:
@@ -26,6 +26,7 @@ from ironic.common import boot_devices
|
||||
from ironic.common import exception
|
||||
from ironic.common.i18n import _
|
||||
from ironic.common.i18n import _LE
|
||||
from ironic.conductor import task_manager
|
||||
from ironic.drivers import base
|
||||
from ironic.drivers.modules.drac import common as drac_common
|
||||
from ironic.drivers.modules.drac import resource_uris
|
||||
@@ -204,6 +205,7 @@ class DracManagement(base.ManagementInterface):
|
||||
"""
|
||||
return list(_BOOT_DEVICES_MAP.keys())
|
||||
|
||||
@task_manager.require_exclusive_lock
|
||||
def set_boot_device(self, task, device, persistent=False):
|
||||
"""Set the boot device for a node.
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import mock
|
||||
|
||||
from ironic.common import boot_devices
|
||||
from ironic.common import exception
|
||||
from ironic.conductor import task_manager
|
||||
from ironic.drivers.modules.drac import client as drac_client
|
||||
from ironic.drivers.modules.drac import common as drac_common
|
||||
from ironic.drivers.modules.drac import management as drac_mgmt
|
||||
@@ -237,7 +238,10 @@ class DracManagementTestCase(db_base.DbTestCase):
|
||||
mock_pywsman.enumerate.return_value = mock_xml_enum
|
||||
mock_pywsman.invoke.return_value = mock_xml_invk
|
||||
|
||||
result = self.driver.set_boot_device(self.task, boot_devices.PXE)
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
task.node = self.node
|
||||
result = self.driver.set_boot_device(task, boot_devices.PXE)
|
||||
|
||||
self.assertIsNone(result)
|
||||
mock_pywsman.enumerate.assert_called_once_with(mock.ANY, mock.ANY,
|
||||
@@ -264,10 +268,12 @@ class DracManagementTestCase(db_base.DbTestCase):
|
||||
mock_pywsman = mock_client_pywsman.Client.return_value
|
||||
mock_pywsman.enumerate.return_value = mock_xml_enum
|
||||
mock_pywsman.invoke.return_value = mock_xml_invk
|
||||
|
||||
self.assertRaises(exception.DracOperationError,
|
||||
self.driver.set_boot_device, self.task,
|
||||
boot_devices.PXE)
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
task.node = self.node
|
||||
self.assertRaises(exception.DracOperationError,
|
||||
self.driver.set_boot_device, task,
|
||||
boot_devices.PXE)
|
||||
|
||||
mock_pywsman.enumerate.assert_called_once_with(mock.ANY, mock.ANY,
|
||||
resource_uris.DCIM_BootSourceSetting)
|
||||
@@ -282,10 +288,12 @@ class DracManagementTestCase(db_base.DbTestCase):
|
||||
def test_set_boot_device_client_error(self, mock_cfcj, mock_we,
|
||||
mock_client_pywsman):
|
||||
mock_we.side_effect = exception.DracClientError('E_FAKE')
|
||||
|
||||
self.assertRaises(exception.DracClientError,
|
||||
self.driver.set_boot_device, self.task,
|
||||
boot_devices.PXE)
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
task.node = self.node
|
||||
self.assertRaises(exception.DracClientError,
|
||||
self.driver.set_boot_device, task,
|
||||
boot_devices.PXE)
|
||||
mock_we.assert_called_once_with(resource_uris.DCIM_BootSourceSetting,
|
||||
mock.ANY, filter_query=mock.ANY)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user