summaryrefslogtreecommitdiff
path: root/ironic
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-08-27 17:21:58 +0000
committerGerrit Code Review <review@openstack.org>2018-08-27 17:21:58 +0000
commitded9e7ce871d4c6b21e1ace7aa110ddcec0bb346 (patch)
treed7bb496566eef956d8e1323bc81a1e6f6ce674c1 /ironic
parent01c6890d7008ffbe6d9204dac5eefa88de2bdb2f (diff)
parent9911293e68d55db2f9b281ca31d5e48830e4dd8f (diff)
downloadironic-ded9e7ce871d4c6b21e1ace7aa110ddcec0bb346.tar.gz
Merge "Fix provisioning failure with `ramdisk` deploy interface"
Diffstat (limited to 'ironic')
-rw-r--r--ironic/drivers/modules/pxe.py69
-rw-r--r--ironic/tests/unit/drivers/modules/test_pxe.py55
2 files changed, 93 insertions, 31 deletions
diff --git a/ironic/drivers/modules/pxe.py b/ironic/drivers/modules/pxe.py
index baa43ad09..e10c492fa 100644
--- a/ironic/drivers/modules/pxe.py
+++ b/ironic/drivers/modules/pxe.py
@@ -589,6 +589,37 @@ class PXEBoot(base.BootInterface):
else:
_clean_up_pxe_env(task, images_info)
+ def _prepare_instance_pxe_config(self, task, image_info,
+ iscsi_boot=False,
+ ramdisk_boot=False):
+ """Prepares the config file for PXE boot
+
+ :param task: a task from TaskManager.
+ :param image_info: a dict of values of instance image
+ metadata to set on the configuration file.
+ :param iscsi_boot: if boot is from an iSCSI volume or not.
+ :param ramdisk_boot: if the boot is to a ramdisk configuration.
+ :returns: None
+ """
+
+ node = task.node
+ dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
+ provider = dhcp_factory.DHCPFactory()
+ provider.update_dhcp(task, dhcp_opts)
+ pxe_config_path = pxe_utils.get_pxe_config_file_path(
+ node.uuid)
+ if not os.path.isfile(pxe_config_path):
+ pxe_options = _build_pxe_config_options(
+ task, image_info, service=ramdisk_boot)
+ pxe_config_template = (
+ deploy_utils.get_pxe_config_template(node))
+ pxe_utils.create_pxe_config(
+ task, pxe_options, pxe_config_template)
+ deploy_utils.switch_pxe_config(
+ pxe_config_path, None,
+ boot_mode_utils.get_boot_mode_for_deploy(node), False,
+ iscsi_boot=iscsi_boot, ramdisk_boot=ramdisk_boot)
+
@METRICS.timer('PXEBoot.prepare_instance')
def prepare_instance(self, task):
"""Prepares the boot of instance.
@@ -606,40 +637,18 @@ class PXEBoot(base.BootInterface):
node = task.node
boot_option = deploy_utils.get_boot_option(node)
boot_device = None
- if deploy_utils.is_iscsi_boot(task):
- dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
- provider = dhcp_factory.DHCPFactory()
- provider.update_dhcp(task, dhcp_opts)
-
- # configure iPXE for iscsi boot
- pxe_config_path = pxe_utils.get_pxe_config_file_path(
- task.node.uuid)
- if not os.path.isfile(pxe_config_path):
- pxe_options = _build_pxe_config_options(task, {})
- pxe_config_template = (
- deploy_utils.get_pxe_config_template(node))
- pxe_utils.create_pxe_config(
- task, pxe_options, pxe_config_template)
- deploy_utils.switch_pxe_config(
- pxe_config_path, None,
- boot_mode_utils.get_boot_mode_for_deploy(node), False,
- iscsi_boot=True)
- boot_device = boot_devices.PXE
-
- elif boot_option == "ramdisk":
+ instance_image_info = {}
+ if boot_option == "ramdisk":
instance_image_info = _get_instance_image_info(
task.node, task.context)
_cache_ramdisk_kernel(task.context, task.node,
instance_image_info)
- dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
- provider = dhcp_factory.DHCPFactory()
- provider.update_dhcp(task, dhcp_opts)
- pxe_config_path = pxe_utils.get_pxe_config_file_path(
- task.node.uuid)
- deploy_utils.switch_pxe_config(
- pxe_config_path, None,
- boot_mode_utils.get_boot_mode_for_deploy(node), False,
- iscsi_boot=False, ramdisk_boot=True)
+
+ if deploy_utils.is_iscsi_boot(task) or boot_option == "ramdisk":
+ self._prepare_instance_pxe_config(
+ task, instance_image_info,
+ iscsi_boot=deploy_utils.is_iscsi_boot(task),
+ ramdisk_boot=(boot_option == "ramdisk"))
boot_device = boot_devices.PXE
elif boot_option != "local":
diff --git a/ironic/tests/unit/drivers/modules/test_pxe.py b/ironic/tests/unit/drivers/modules/test_pxe.py
index d8a1b2d46..d85ac33ba 100644
--- a/ironic/tests/unit/drivers/modules/test_pxe.py
+++ b/ironic/tests/unit/drivers/modules/test_pxe.py
@@ -1400,7 +1400,7 @@ class PXEBootTestCase(db_base.DbTestCase):
task, mock.ANY, CONF.pxe.pxe_config_template)
switch_pxe_config_mock.assert_called_once_with(
pxe_config_path, None, boot_modes.LEGACY_BIOS, False,
- iscsi_boot=True)
+ iscsi_boot=True, ramdisk_boot=False)
set_boot_device_mock.assert_called_once_with(task,
boot_devices.PXE,
persistent=True)
@@ -1453,6 +1453,59 @@ class PXEBootTestCase(db_base.DbTestCase):
clean_up_pxe_config_mock.assert_called_once_with(task)
self.assertFalse(set_boot_device_mock.called)
+ @mock.patch.object(manager_utils, 'node_set_boot_device', autospec=True)
+ @mock.patch.object(deploy_utils, 'switch_pxe_config', autospec=True)
+ @mock.patch.object(pxe_utils, 'create_pxe_config', autospec=True)
+ @mock.patch.object(dhcp_factory, 'DHCPFactory', autospec=True)
+ @mock.patch.object(pxe, '_cache_ramdisk_kernel', autospec=True)
+ @mock.patch.object(pxe, '_get_instance_image_info', autospec=True)
+ def _test_prepare_instance_ramdisk(
+ self, get_image_info_mock, cache_mock,
+ dhcp_factory_mock, create_pxe_config_mock,
+ switch_pxe_config_mock,
+ set_boot_device_mock, config_file_exits=False):
+ image_info = {'kernel': ['', '/path/to/kernel'],
+ 'ramdisk': ['', '/path/to/ramdisk']}
+ get_image_info_mock.return_value = image_info
+ provider_mock = mock.MagicMock()
+ dhcp_factory_mock.return_value = provider_mock
+ self.node.provision_state = states.DEPLOYING
+ get_image_info_mock.return_value = image_info
+ with task_manager.acquire(self.context, self.node.uuid) as task:
+ instance_info = task.node.instance_info
+ instance_info['capabilities'] = {'boot_option': 'ramdisk'}
+ task.node.instance_info = instance_info
+ task.node.save()
+ dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
+ pxe_config_path = pxe_utils.get_pxe_config_file_path(
+ task.node.uuid)
+ task.driver.boot.prepare_instance(task)
+
+ get_image_info_mock.assert_called_once_with(
+ task.node, task.context)
+ cache_mock.assert_called_once_with(
+ task.context, task.node, image_info)
+ provider_mock.update_dhcp.assert_called_once_with(task, dhcp_opts)
+ if config_file_exits:
+ self.assertFalse(create_pxe_config_mock.called)
+ else:
+ create_pxe_config_mock.assert_called_once_with(
+ task, mock.ANY, CONF.pxe.pxe_config_template)
+ switch_pxe_config_mock.assert_called_once_with(
+ pxe_config_path, None,
+ 'bios', False, iscsi_boot=False, ramdisk_boot=True)
+ set_boot_device_mock.assert_called_once_with(task,
+ boot_devices.PXE,
+ persistent=True)
+
+ @mock.patch.object(os.path, 'isfile', lambda path: True)
+ def test_prepare_instance_ramdisk_pxe_conf_missing(self):
+ self._test_prepare_instance_ramdisk(config_file_exits=True)
+
+ @mock.patch.object(os.path, 'isfile', lambda path: False)
+ def test_prepare_instance_ramdisk_pxe_conf_exists(self):
+ self._test_prepare_instance_ramdisk(config_file_exits=False)
+
@mock.patch.object(pxe, '_clean_up_pxe_env', autospec=True)
@mock.patch.object(pxe, '_get_instance_image_info', autospec=True)
def test_clean_up_instance(self, get_image_info_mock,