Adds raid validation for in-band AgentRAID deploy step
This commit adds support for validation of raid configuration of in-band AgentRAID deploy step 'apply_configuration' and adds a post deploy hook to update root device hint. Change-Id: I52c1ad3e10d9fab3c2366d40af39667a299eb774
This commit is contained in:
parent
d867488e90
commit
a5ce4dd8d0
@ -59,6 +59,21 @@ OPTIONAL_PROPERTIES = {
|
|||||||
'``image_https_proxy`` are not specified. Optional.'),
|
'``image_https_proxy`` are not specified. Optional.'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_RAID_APPLY_CONFIGURATION_ARGSINFO = {
|
||||||
|
"raid_config": {
|
||||||
|
"description": "The RAID configuration to apply.",
|
||||||
|
"required": True,
|
||||||
|
},
|
||||||
|
"delete_existing": {
|
||||||
|
"description": (
|
||||||
|
"Setting this to 'True' indicates to delete existing RAID "
|
||||||
|
"configuration prior to creating the new configuration. "
|
||||||
|
"Default value is 'True'."
|
||||||
|
),
|
||||||
|
"required": False,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy()
|
COMMON_PROPERTIES = REQUIRED_PROPERTIES.copy()
|
||||||
COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES)
|
COMMON_PROPERTIES.update(OPTIONAL_PROPERTIES)
|
||||||
COMMON_PROPERTIES.update(agent_base.VENDOR_PROPERTIES)
|
COMMON_PROPERTIES.update(agent_base.VENDOR_PROPERTIES)
|
||||||
@ -634,6 +649,25 @@ class AgentRAID(base.RAIDInterface):
|
|||||||
"""
|
"""
|
||||||
return agent_base.get_steps(task, 'deploy', interface='raid')
|
return agent_base.get_steps(task, 'deploy', interface='raid')
|
||||||
|
|
||||||
|
@METRICS.timer('AgentRAID.apply_configuration')
|
||||||
|
@base.deploy_step(priority=0,
|
||||||
|
argsinfo=_RAID_APPLY_CONFIGURATION_ARGSINFO)
|
||||||
|
def apply_configuration(self, task, raid_config,
|
||||||
|
delete_existing=True):
|
||||||
|
"""Applies RAID configuration on the given node.
|
||||||
|
|
||||||
|
:param task: A TaskManager instance.
|
||||||
|
:param raid_config: The RAID configuration to apply.
|
||||||
|
:param delete_existing: Setting this to True indicates to delete RAID
|
||||||
|
configuration prior to creating the new configuration.
|
||||||
|
:raises: InvalidParameterValue, if the RAID configuration is invalid.
|
||||||
|
:returns: states.DEPLOYWAIT if RAID configuration is in progress
|
||||||
|
asynchronously or None if it is complete.
|
||||||
|
"""
|
||||||
|
self.validate_raid_config(task, raid_config)
|
||||||
|
step = task.node.deploy_step
|
||||||
|
return agent_base.execute_step(task, step, 'deploy')
|
||||||
|
|
||||||
@METRICS.timer('AgentRAID.create_configuration')
|
@METRICS.timer('AgentRAID.create_configuration')
|
||||||
@base.clean_step(priority=0)
|
@base.clean_step(priority=0)
|
||||||
def create_configuration(self, task,
|
def create_configuration(self, task,
|
||||||
@ -682,6 +716,8 @@ class AgentRAID(base.RAIDInterface):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
@agent_base.post_clean_step_hook(
|
@agent_base.post_clean_step_hook(
|
||||||
interface='raid', step='create_configuration')
|
interface='raid', step='create_configuration')
|
||||||
|
@agent_base.post_deploy_step_hook(
|
||||||
|
interface='raid', step='apply_configuration')
|
||||||
def _create_configuration_final(task, command):
|
def _create_configuration_final(task, command):
|
||||||
"""Clean step hook after a RAID configuration was created.
|
"""Clean step hook after a RAID configuration was created.
|
||||||
|
|
||||||
@ -699,15 +735,21 @@ class AgentRAID(base.RAIDInterface):
|
|||||||
the 'command' argument passed.
|
the 'command' argument passed.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
clean_result = command['command_result']['clean_result']
|
if task.node.provision_state == states.DEPLOYWAIT:
|
||||||
|
operation = "deploying"
|
||||||
|
result = command['command_result']['deploy_result']
|
||||||
|
else:
|
||||||
|
operation = "cleaning"
|
||||||
|
result = command['command_result']['clean_result']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise exception.IronicException(
|
raise exception.IronicException(
|
||||||
_("Agent ramdisk didn't return a proper command result while "
|
_("Agent ramdisk didn't return a proper command result while "
|
||||||
"cleaning %(node)s. It returned '%(result)s' after command "
|
"%(operation)s %(node)s. It returned '%(result)s' after "
|
||||||
"execution.") % {'node': task.node.uuid,
|
"command execution.") % {'operation': operation,
|
||||||
|
'node': task.node.uuid,
|
||||||
'result': command})
|
'result': command})
|
||||||
|
|
||||||
raid.update_raid_info(task.node, clean_result)
|
raid.update_raid_info(task.node, result)
|
||||||
|
|
||||||
@METRICS.timer('AgentRAID.delete_configuration')
|
@METRICS.timer('AgentRAID.delete_configuration')
|
||||||
@base.clean_step(priority=0)
|
@base.clean_step(priority=0)
|
||||||
|
@ -1618,8 +1618,8 @@ class AgentRAIDTestCase(db_base.DbTestCase):
|
|||||||
self.config(enabled_raid_interfaces=['fake', 'agent', 'no-raid'])
|
self.config(enabled_raid_interfaces=['fake', 'agent', 'no-raid'])
|
||||||
self.target_raid_config = {
|
self.target_raid_config = {
|
||||||
"logical_disks": [
|
"logical_disks": [
|
||||||
{'size_gb': 200, 'raid_level': 0, 'is_root_volume': True},
|
{'size_gb': 200, 'raid_level': "0", 'is_root_volume': True},
|
||||||
{'size_gb': 200, 'raid_level': 5}
|
{'size_gb': 200, 'raid_level': "5"}
|
||||||
]}
|
]}
|
||||||
self.clean_step = {'step': 'create_configuration',
|
self.clean_step = {'step': 'create_configuration',
|
||||||
'interface': 'raid'}
|
'interface': 'raid'}
|
||||||
@ -1661,6 +1661,25 @@ class AgentRAIDTestCase(db_base.DbTestCase):
|
|||||||
|
|
||||||
self.assertEqual('apply_configuration', ret[0]['step'])
|
self.assertEqual('apply_configuration', ret[0]['step'])
|
||||||
|
|
||||||
|
@mock.patch.object(agent_base, 'execute_step', autospec=True)
|
||||||
|
def test_apply_configuration(self, execute_mock):
|
||||||
|
deploy_step = {
|
||||||
|
'interface': 'raid',
|
||||||
|
'step': 'apply_configuration',
|
||||||
|
'args': {
|
||||||
|
'raid_config': self.target_raid_config,
|
||||||
|
'delete_existing': True
|
||||||
|
},
|
||||||
|
'priority': 82
|
||||||
|
}
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||||
|
execute_mock.return_value = states.DEPLOYWAIT
|
||||||
|
task.node.deploy_step = deploy_step
|
||||||
|
return_value = task.driver.raid.apply_configuration(
|
||||||
|
task, self.target_raid_config, delete_existing=True)
|
||||||
|
self.assertEqual(states.DEPLOYWAIT, return_value)
|
||||||
|
execute_mock.assert_called_once_with(task, deploy_step, 'deploy')
|
||||||
|
|
||||||
@mock.patch.object(raid, 'filter_target_raid_config', autospec=True)
|
@mock.patch.object(raid, 'filter_target_raid_config', autospec=True)
|
||||||
@mock.patch.object(agent_base, 'execute_step', autospec=True)
|
@mock.patch.object(agent_base, 'execute_step', autospec=True)
|
||||||
def test_create_configuration(self, execute_mock,
|
def test_create_configuration(self, execute_mock,
|
||||||
@ -1761,16 +1780,33 @@ class AgentRAIDTestCase(db_base.DbTestCase):
|
|||||||
update_raid_info_mock.assert_called_once_with(task.node, 'foo')
|
update_raid_info_mock.assert_called_once_with(task.node, 'foo')
|
||||||
|
|
||||||
@mock.patch.object(raid, 'update_raid_info', autospec=True)
|
@mock.patch.object(raid, 'update_raid_info', autospec=True)
|
||||||
def test__create_configuration_final_registered(
|
def _test__create_configuration_final_registered(
|
||||||
self, update_raid_info_mock):
|
self, update_raid_info_mock, step_type='clean'):
|
||||||
self.node.clean_step = {'interface': 'raid',
|
step = {'interface': 'raid'}
|
||||||
'step': 'create_configuration'}
|
if step_type == 'clean':
|
||||||
|
step['step'] = 'create_configuration'
|
||||||
|
self.node.clean_step = step
|
||||||
|
state = states.CLEANWAIT
|
||||||
command = {'command_result': {'clean_result': 'foo'}}
|
command = {'command_result': {'clean_result': 'foo'}}
|
||||||
create_hook = agent_base._get_post_step_hook(self.node, 'clean')
|
create_hook = agent_base._get_post_step_hook(self.node, 'clean')
|
||||||
|
else:
|
||||||
|
step['step'] = 'apply_configuration'
|
||||||
|
self.node.deploy_step = step
|
||||||
|
command = {'command_result': {'deploy_result': 'foo'}}
|
||||||
|
state = states.DEPLOYWAIT
|
||||||
|
create_hook = agent_base._get_post_step_hook(self.node, 'deploy')
|
||||||
|
|
||||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||||
|
task.node.provision_state = state
|
||||||
create_hook(task, command)
|
create_hook(task, command)
|
||||||
update_raid_info_mock.assert_called_once_with(task.node, 'foo')
|
update_raid_info_mock.assert_called_once_with(task.node, 'foo')
|
||||||
|
|
||||||
|
def test__create_configuration_final_registered_clean(self):
|
||||||
|
self._test__create_configuration_final_registered(step_type='clean')
|
||||||
|
|
||||||
|
def test__create_configuration_final_registered_deploy(self):
|
||||||
|
self._test__create_configuration_final_registered(step_type='deploy')
|
||||||
|
|
||||||
@mock.patch.object(raid, 'update_raid_info', autospec=True)
|
@mock.patch.object(raid, 'update_raid_info', autospec=True)
|
||||||
def test__create_configuration_final_bad_command_result(
|
def test__create_configuration_final_bad_command_result(
|
||||||
self, update_raid_info_mock):
|
self, update_raid_info_mock):
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds raid configuration validation to deploy step ``apply_configuration``
|
||||||
|
of ``agent`` RAID interface. Also, a post deploy hook has been added to
|
||||||
|
this deploy step to update root device hint.
|
Loading…
Reference in New Issue
Block a user