Merge "Adds support for 'ramdisk' deploy with 'ilo-virtual-media' boot"
This commit is contained in:
commit
6b87367a0f
@ -187,6 +187,12 @@ def _get_boot_iso(task, root_uuid):
|
||||
deploy_iso_uuid = deploy_info['ilo_deploy_iso']
|
||||
boot_mode = boot_mode_utils.get_boot_mode_for_deploy(task.node)
|
||||
boot_iso_object_name = _get_boot_iso_object_name(task.node)
|
||||
kernel_params = ""
|
||||
if deploy_utils.get_boot_option(task.node) == "ramdisk":
|
||||
i_info = task.node.instance_info
|
||||
kernel_params = "root=/dev/ram0 text "
|
||||
kernel_params += i_info.get("ramdisk_kernel_arguments", "")
|
||||
else:
|
||||
kernel_params = CONF.pxe.pxe_append_params
|
||||
with tempfile.NamedTemporaryFile(dir=CONF.tempdir) as fileobj:
|
||||
boot_iso_tmp_file = fileobj.name
|
||||
@ -396,7 +402,7 @@ def disable_secure_boot_if_supported(task):
|
||||
|
||||
class IloVirtualMediaBoot(base.BootInterface):
|
||||
|
||||
capabilities = ['iscsi_volume_boot']
|
||||
capabilities = ['iscsi_volume_boot', 'ramdisk_boot']
|
||||
|
||||
def get_properties(self):
|
||||
# TODO(stendulker): COMMON_PROPERTIES should also include rescue
|
||||
@ -414,6 +420,22 @@ class IloVirtualMediaBoot(base.BootInterface):
|
||||
missing in the Glance image or 'kernel' and 'ramdisk' not provided
|
||||
in instance_info for non-Glance image.
|
||||
"""
|
||||
node = task.node
|
||||
boot_option = deploy_utils.get_boot_option(node)
|
||||
boot_iso = node.instance_info.get('ilo_boot_iso')
|
||||
if (boot_option == "ramdisk" and boot_iso):
|
||||
if not service_utils.is_glance_image(boot_iso):
|
||||
try:
|
||||
image_service.HttpImageService().validate_href(boot_iso)
|
||||
except exception.ImageRefValidationFailed:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error("Virtual media deploy with 'ramdisk' "
|
||||
"boot_option accepts only Glance images or "
|
||||
"HTTP(S) URLs as "
|
||||
"instance_info['ilo_boot_iso']. Either %s "
|
||||
"is not a valid HTTP(S) URL or is not "
|
||||
"reachable.", boot_iso)
|
||||
return
|
||||
|
||||
_validate_driver_info(task)
|
||||
|
||||
@ -501,10 +523,10 @@ class IloVirtualMediaBoot(base.BootInterface):
|
||||
:raises: InstanceDeployFailure, if its try to boot iSCSI volume in
|
||||
'BIOS' boot mode.
|
||||
"""
|
||||
|
||||
ilo_common.cleanup_vmedia_boot(task)
|
||||
|
||||
boot_mode = boot_mode_utils.get_boot_mode_for_deploy(task.node)
|
||||
boot_option = deploy_utils.get_boot_option(task.node)
|
||||
|
||||
if deploy_utils.is_iscsi_boot(task):
|
||||
# It will set iSCSI info onto iLO
|
||||
@ -520,6 +542,12 @@ class IloVirtualMediaBoot(base.BootInterface):
|
||||
else:
|
||||
msg = 'Virtual media can not boot volume in BIOS boot mode.'
|
||||
raise exception.InstanceDeployFailure(msg)
|
||||
elif boot_option == "ramdisk":
|
||||
boot_iso = _get_boot_iso(task, None)
|
||||
ilo_common.setup_vmedia_for_boot(task, boot_iso)
|
||||
manager_utils.node_set_boot_device(task,
|
||||
boot_devices.CDROM,
|
||||
persistent=True)
|
||||
else:
|
||||
# Boot from disk every time if the image deployed is
|
||||
# a whole disk image.
|
||||
|
@ -683,6 +683,88 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest):
|
||||
mock_val_instance_image_info.assert_called_once_with(task)
|
||||
mock_val_driver_info.assert_called_once_with(task)
|
||||
|
||||
@mock.patch.object(ilo_boot, '_validate_driver_info',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(image_service.HttpImageService, 'validate_href',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(service_utils, 'is_glance_image', spec_set=True,
|
||||
autospec=True)
|
||||
def test_validate_ramdisk_boot_option_glance(self, is_glance_image_mock,
|
||||
validate_href_mock,
|
||||
val_driver_info_mock):
|
||||
instance_info = self.node.instance_info
|
||||
boot_iso = '6b2f0c0c-79e8-4db6-842e-43c9764204af'
|
||||
instance_info['ilo_boot_iso'] = boot_iso
|
||||
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
|
||||
self.node.instance_info = instance_info
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
is_glance_image_mock.return_value = True
|
||||
task.driver.boot.validate(task)
|
||||
is_glance_image_mock.assert_called_once_with(boot_iso)
|
||||
self.assertFalse(validate_href_mock.called)
|
||||
self.assertFalse(val_driver_info_mock.called)
|
||||
|
||||
@mock.patch.object(ilo_boot, '_validate_driver_info',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(image_service.HttpImageService, 'validate_href',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(service_utils, 'is_glance_image', spec_set=True,
|
||||
autospec=True)
|
||||
def test_validate_ramdisk_boot_option_webserver(self, is_glance_image_mock,
|
||||
validate_href_mock,
|
||||
val_driver_info_mock):
|
||||
instance_info = self.node.instance_info
|
||||
boot_iso = 'http://myserver/boot.iso'
|
||||
instance_info['ilo_boot_iso'] = boot_iso
|
||||
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
|
||||
self.node.instance_info = instance_info
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
is_glance_image_mock.return_value = False
|
||||
task.driver.boot.validate(task)
|
||||
is_glance_image_mock.assert_called_once_with(boot_iso)
|
||||
validate_href_mock.assert_called_once_with(mock.ANY, boot_iso)
|
||||
self.assertFalse(val_driver_info_mock.called)
|
||||
|
||||
@mock.patch.object(ilo_boot.LOG, 'error', spec_set=True, autospec=True)
|
||||
@mock.patch.object(ilo_boot, '_validate_driver_info',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(image_service.HttpImageService, 'validate_href',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(service_utils, 'is_glance_image', spec_set=True,
|
||||
autospec=True)
|
||||
def test_validate_ramdisk_boot_option_webserver_exc(self,
|
||||
is_glance_image_mock,
|
||||
validate_href_mock,
|
||||
val_driver_info_mock,
|
||||
log_mock):
|
||||
instance_info = self.node.instance_info
|
||||
validate_href_mock.side_effect = exception.ImageRefValidationFailed(
|
||||
image_href='http://myserver/boot.iso', reason='fail')
|
||||
boot_iso = 'http://myserver/boot.iso'
|
||||
instance_info['ilo_boot_iso'] = boot_iso
|
||||
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
|
||||
self.node.instance_info = instance_info
|
||||
self.node.save()
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
|
||||
is_glance_image_mock.return_value = False
|
||||
self.assertRaisesRegex(exception.ImageRefValidationFailed,
|
||||
"Validation of image href "
|
||||
"http://myserver/boot.iso failed",
|
||||
task.driver.boot.validate, task)
|
||||
is_glance_image_mock.assert_called_once_with(boot_iso)
|
||||
validate_href_mock.assert_called_once_with(mock.ANY, boot_iso)
|
||||
self.assertFalse(val_driver_info_mock.called)
|
||||
self.assertIn("Virtual media deploy with 'ramdisk' boot_option "
|
||||
"accepts only Glance images or HTTP(S) URLs as "
|
||||
"instance_info['ilo_boot_iso'].",
|
||||
log_mock.call_args[0][0])
|
||||
|
||||
@mock.patch.object(noop_storage.NoopStorage, 'should_write_image',
|
||||
autospec=True)
|
||||
@mock.patch.object(ilo_boot, '_validate_driver_info',
|
||||
@ -1086,6 +1168,45 @@ class IloVirtualMediaBootTestCase(test_common.BaseIloTest):
|
||||
self.assertIsNone(task.node.driver_internal_info.get(
|
||||
'ilo_uefi_iscsi_boot'))
|
||||
|
||||
@mock.patch.object(ilo_common, 'cleanup_vmedia_boot', spec_set=True,
|
||||
autospec=True)
|
||||
@mock.patch.object(deploy_utils, 'is_iscsi_boot',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(ilo_common, 'setup_vmedia_for_boot',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(ilo_boot, '_get_boot_iso',
|
||||
spec_set=True, autospec=True)
|
||||
@mock.patch.object(manager_utils, 'node_set_boot_device', spec_set=True,
|
||||
autospec=True)
|
||||
@mock.patch.object(ilo_common, 'update_boot_mode', spec_set=True,
|
||||
autospec=True)
|
||||
@mock.patch.object(ilo_common, 'update_secure_boot_mode', spec_set=True,
|
||||
autospec=True)
|
||||
def test_prepare_instance_boot_ramdisk(self, update_secure_boot_mode_mock,
|
||||
update_boot_mode_mock,
|
||||
set_boot_device_mock,
|
||||
get_boot_iso_mock,
|
||||
setup_vmedia_mock,
|
||||
is_iscsi_boot_mock,
|
||||
cleanup_vmedia_boot_mock):
|
||||
with task_manager.acquire(self.context, self.node.uuid,
|
||||
shared=False) as task:
|
||||
instance_info = task.node.instance_info
|
||||
instance_info['capabilities'] = '{"boot_option": "ramdisk"}'
|
||||
task.node.instance_info = instance_info
|
||||
task.node.save()
|
||||
is_iscsi_boot_mock.return_value = False
|
||||
url = 'http://myserver/boot.iso'
|
||||
get_boot_iso_mock.return_value = url
|
||||
task.driver.boot.prepare_instance(task)
|
||||
cleanup_vmedia_boot_mock.assert_called_once_with(task)
|
||||
get_boot_iso_mock.assert_called_once_with(task, None)
|
||||
setup_vmedia_mock.assert_called_once_with(task, url)
|
||||
set_boot_device_mock.assert_called_once_with(
|
||||
task, boot_devices.CDROM, persistent=True)
|
||||
update_boot_mode_mock.assert_called_once_with(task)
|
||||
update_secure_boot_mode_mock.assert_called_once_with(task, True)
|
||||
|
||||
def test_validate_rescue(self):
|
||||
driver_info = self.node.driver_info
|
||||
driver_info['ilo_rescue_iso'] = 'rescue.iso'
|
||||
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds support for booting a ramdisk using virtual media to
|
||||
``ilo-virtual-media`` boot interface when an ironic node is configured
|
||||
with ``ramdisk`` deploy interface.
|
Loading…
Reference in New Issue
Block a user