Allow reading root_device from instance_info
For the future deployment API we need to be able to set root_device per deployment in addition to per node. This change adds it. Change-Id: I1dd046c2e5fca211a84290bac8daa7550b21614f Depends-On: https://review.opendev.org/701043 Story: #2006910 Task: #37556
This commit is contained in:
parent
2a43e371f1
commit
42dc9787e5
@ -432,7 +432,7 @@ class AgentDeploy(AgentDeployMixin, base.DeployInterface):
|
|||||||
check_image_size(task, image_source)
|
check_image_size(task, image_source)
|
||||||
# Validate the root device hints
|
# Validate the root device hints
|
||||||
try:
|
try:
|
||||||
root_device = node.properties.get('root_device')
|
root_device = deploy_utils.get_root_device_for_deploy(node)
|
||||||
il_utils.parse_root_device_hints(root_device)
|
il_utils.parse_root_device_hints(root_device)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise exception.InvalidParameterValue(
|
raise exception.InvalidParameterValue(
|
||||||
|
@ -229,7 +229,7 @@ def _parse_partitioning_info(node):
|
|||||||
|
|
||||||
def _parse_root_device_hints(node):
|
def _parse_root_device_hints(node):
|
||||||
"""Convert string with hints to dict. """
|
"""Convert string with hints to dict. """
|
||||||
root_device = node.properties.get('root_device')
|
root_device = deploy_utils.get_root_device_for_deploy(node)
|
||||||
if not root_device:
|
if not root_device:
|
||||||
return {}
|
return {}
|
||||||
try:
|
try:
|
||||||
|
@ -1509,3 +1509,9 @@ def set_async_step_flags(node, reboot=None, skip_current_step=None,
|
|||||||
info[fields['polling']] = polling
|
info[fields['polling']] = polling
|
||||||
node.driver_internal_info = info
|
node.driver_internal_info = info
|
||||||
node.save()
|
node.save()
|
||||||
|
|
||||||
|
|
||||||
|
def get_root_device_for_deploy(node):
|
||||||
|
"""Get a root device requested for deployment or None."""
|
||||||
|
return (node.instance_info.get('root_device')
|
||||||
|
or node.properties.get('root_device'))
|
||||||
|
@ -321,7 +321,7 @@ def validate(task):
|
|||||||
deploy_utils.get_ironic_api_url()
|
deploy_utils.get_ironic_api_url()
|
||||||
# Validate the root device hints
|
# Validate the root device hints
|
||||||
try:
|
try:
|
||||||
root_device = task.node.properties.get('root_device')
|
root_device = deploy_utils.get_root_device_for_deploy(task.node)
|
||||||
il_utils.parse_root_device_hints(root_device)
|
il_utils.parse_root_device_hints(root_device)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise exception.InvalidParameterValue(
|
raise exception.InvalidParameterValue(
|
||||||
|
@ -356,6 +356,19 @@ class TestAnsibleMethods(AnsibleDeployTestCaseBase):
|
|||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
expected, ansible_deploy._parse_root_device_hints(task.node))
|
expected, ansible_deploy._parse_root_device_hints(task.node))
|
||||||
|
|
||||||
|
def test__parse_root_device_hints_iinfo(self):
|
||||||
|
hints = {"wwn": "fake wwn", "size": "12345", "rotational": True,
|
||||||
|
"serial": "HELLO"}
|
||||||
|
expected = {"wwn": "fake wwn", "size": 12345, "rotational": True,
|
||||||
|
"serial": "hello"}
|
||||||
|
iinfo = self.node.instance_info
|
||||||
|
iinfo['root_device'] = hints
|
||||||
|
self.node.instance_info = iinfo
|
||||||
|
self.node.save()
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||||
|
self.assertEqual(
|
||||||
|
expected, ansible_deploy._parse_root_device_hints(task.node))
|
||||||
|
|
||||||
def test__parse_root_device_hints_fail_advanced(self):
|
def test__parse_root_device_hints_fail_advanced(self):
|
||||||
hints = {"wwn": "s!= fake wwn",
|
hints = {"wwn": "s!= fake wwn",
|
||||||
"size": ">= 12345",
|
"size": ">= 12345",
|
||||||
|
@ -273,6 +273,22 @@ class TestAgentDeploy(db_base.DbTestCase):
|
|||||||
show_mock.assert_called_once_with(self.context, 'fake-image')
|
show_mock.assert_called_once_with(self.context, 'fake-image')
|
||||||
validate_http_mock.assert_called_once_with(task.node)
|
validate_http_mock.assert_called_once_with(task.node)
|
||||||
|
|
||||||
|
@mock.patch.object(agent, 'validate_http_provisioning_configuration',
|
||||||
|
autospec=True)
|
||||||
|
@mock.patch.object(images, 'image_show', autospec=True)
|
||||||
|
@mock.patch.object(pxe.PXEBoot, 'validate', autospec=True)
|
||||||
|
def test_validate_invalid_root_device_hints_iinfo(
|
||||||
|
self, pxe_boot_validate_mock, show_mock, validate_http_mock):
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
task.node.instance_info['root_device'] = {'size': 'not-int'}
|
||||||
|
self.assertRaises(exception.InvalidParameterValue,
|
||||||
|
task.driver.deploy.validate, task)
|
||||||
|
pxe_boot_validate_mock.assert_called_once_with(
|
||||||
|
task.driver.boot, task)
|
||||||
|
show_mock.assert_called_once_with(self.context, 'fake-image')
|
||||||
|
validate_http_mock.assert_called_once_with(task.node)
|
||||||
|
|
||||||
@mock.patch.object(agent, 'validate_http_provisioning_configuration',
|
@mock.patch.object(agent, 'validate_http_provisioning_configuration',
|
||||||
autospec=True)
|
autospec=True)
|
||||||
@mock.patch.object(images, 'image_show', autospec=True)
|
@mock.patch.object(images, 'image_show', autospec=True)
|
||||||
|
@ -574,6 +574,15 @@ class IscsiDeployMethodsTestCase(db_base.DbTestCase):
|
|||||||
self.assertRaises(exception.InvalidParameterValue,
|
self.assertRaises(exception.InvalidParameterValue,
|
||||||
iscsi_deploy.validate, task)
|
iscsi_deploy.validate, task)
|
||||||
|
|
||||||
|
@mock.patch('ironic.drivers.modules.deploy_utils.get_ironic_api_url')
|
||||||
|
def test_validate_invalid_root_device_hints_iinfo(self, mock_get_url):
|
||||||
|
mock_get_url.return_value = 'http://spam.ham/baremetal'
|
||||||
|
with task_manager.acquire(self.context, self.node.uuid,
|
||||||
|
shared=True) as task:
|
||||||
|
task.node.instance_info['root_device'] = {'size': 'not-int'}
|
||||||
|
self.assertRaises(exception.InvalidParameterValue,
|
||||||
|
iscsi_deploy.validate, task)
|
||||||
|
|
||||||
|
|
||||||
class ISCSIDeployTestCase(db_base.DbTestCase):
|
class ISCSIDeployTestCase(db_base.DbTestCase):
|
||||||
|
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Allows reading the ``root_device`` from ``instance_info``, overriding
|
||||||
|
the value in ``properties``. This enables per-instance root device
|
||||||
|
settings and requires the Ussuri release of ironic-python-agent.
|
Loading…
Reference in New Issue
Block a user