def test_prepare_boot_iso_user_supplied(self, mock_create_boot_iso, mock__prepare_iso_image, find_mock): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: d_info = { 'deploy_kernel': 'kernel', 'deploy_ramdisk': 'ramdisk', 'bootloader': 'bootloader' } task.node.driver_info.update(d_info) task.node.instance_info.update( {'boot_iso': 'http://boot/iso'}) find_call_list = [ mock.call('bootloader', d_info) ] find_mock.side_effect = [ 'bootloader' ] image_utils.prepare_boot_iso( task, d_info, root_uuid=task.node.uuid) mock__prepare_iso_image.assert_called_once_with( mock.ANY, None, None, 'bootloader', root_uuid=task.node.uuid, base_iso='http://boot/iso') find_mock.assert_has_calls(find_call_list)
def test_prepare_boot_iso(self, mock_create_boot_iso, mock__prepare_iso_image): with task_manager.acquire(self.context, self.node.uuid, shared=True) as task: d_info = { 'deploy_kernel': 'kernel', 'deploy_ramdisk': 'ramdisk', 'bootloader': 'bootloader' } task.node.driver_info.update(d_info) task.node.instance_info.update({ 'image_source': 'http://boot/iso', 'kernel': 'http://kernel/img', 'ramdisk': 'http://ramdisk/img' }) image_utils.prepare_boot_iso(task, d_info, root_uuid=task.node.uuid) mock__prepare_iso_image.assert_called_once_with( mock.ANY, 'http://kernel/img', 'http://ramdisk/img', 'bootloader', root_uuid=task.node.uuid, base_iso=None)
def prepare_instance(self, task): """Prepares the boot of instance. This method prepares the boot of the instance after reading relevant information from the node's instance_info. It does the following depending on boot_option for deploy: - If the boot_option requested for this deploy is 'local' or image is a whole disk image, then it sets the node to boot from disk. - Otherwise it finds/creates the boot ISO, sets the node boot option to UEFIHTTP and sets the URL as the boot ISO to boot the instance image. :param task: a task from TaskManager. :returns: None :raises: IloOperationError, if some operation on iLO failed. :raises: InstanceDeployFailure, if its try to boot iSCSI volume in 'BIOS' boot mode. """ node = task.node image_utils.cleanup_iso_image(task) boot_option = deploy_utils.get_boot_option(task.node) iwdi = node.driver_internal_info.get('is_whole_disk_image') if boot_option == "local" or iwdi: manager_utils.node_set_boot_device(task, boot_devices.DISK, persistent=True) LOG.debug("Node %(node)s is set to permanently boot from local " "%(device)s", {'node': task.node.uuid, 'device': boot_devices.DISK}) return params = {} if boot_option != 'ramdisk': root_uuid = node.driver_internal_info.get('root_uuid_or_disk_id') if not root_uuid and task.driver.storage.should_write_image(task): LOG.warning( "The UUID of the root partition could not be found for " "node %s. Booting instance from disk anyway.", node.uuid) manager_utils.node_set_boot_device(task, boot_devices.DISK, persistent=True) return params.update(root_uuid=root_uuid) d_info = self._parse_deploy_info(node) iso_ref = image_utils.prepare_boot_iso(task, d_info, **params) if boot_option != 'ramdisk': i_info = node.instance_info i_info['ilo_boot_iso'] = iso_ref node.instance_info = i_info node.save() ilo_common.setup_uefi_https(task, iso_ref, persistent=True) LOG.debug("Node %(node)s is set to boot from UEFIHTTP " "boot option", {'node': task.node.uuid})
def prepare_instance(self, task): """Prepares the boot of instance over virtual media. This method prepares the boot of the instance after reading relevant information from the node's instance_info. The internal logic is as follows: - If `boot_option` requested for this deploy is 'local', then set the node to boot from disk. - Unless `boot_option` requested for this deploy is 'ramdisk', pass root disk/partition ID to virtual media boot image - Otherwise build boot image, insert it into virtual media device and set node to boot from CD. :param task: a task from TaskManager. :returns: None :raises: InstanceDeployFailure, if its try to boot iSCSI volume in 'BIOS' boot mode. """ node = task.node boot_option = deploy_utils.get_boot_option(node) self.clean_up_instance(task) iwdi = node.driver_internal_info.get('is_whole_disk_image') if boot_option == "local" or iwdi: self._set_boot_device(task, boot_devices.DISK, persistent=True) LOG.debug( "Node %(node)s is set to permanently boot from local " "%(device)s", { 'node': task.node.uuid, 'device': boot_devices.DISK }) return params = {} if boot_option != 'ramdisk': root_uuid = node.driver_internal_info.get('root_uuid_or_disk_id') if not root_uuid and task.driver.storage.should_write_image(task): LOG.warning( "The UUID of the root partition could not be found for " "node %s. Booting instance from disk anyway.", node.uuid) self._set_boot_device(task, boot_devices.DISK, persistent=True) return params.update(root_uuid=root_uuid) deploy_info = _parse_deploy_info(node) iso_ref = image_utils.prepare_boot_iso(task, deploy_info, **params) _eject_vmedia(task, sushy.VIRTUAL_MEDIA_CD) _insert_vmedia(task, iso_ref, sushy.VIRTUAL_MEDIA_CD) boot_mode_utils.sync_boot_mode(task) self._set_boot_device(task, boot_devices.CDROM, persistent=True) LOG.debug( "Node %(node)s is set to permanently boot from " "%(device)s", { 'node': task.node.uuid, 'device': boot_devices.CDROM })
def _get_boot_iso(task, root_uuid): """This method returns a boot ISO to boot the node. It chooses one of the three options in the order as below: 1. Does nothing if 'ilo_boot_iso' is present in node's instance_info. 2. Image deployed has a meta-property 'boot_iso' in Glance. This should refer to the UUID of the boot_iso which exists in Glance. 3. Returns a boot ISO created on the fly using kernel and ramdisk mentioned in the image deployed. :param task: a TaskManager instance containing the node to act on. :param root_uuid: the uuid of the root partition. :returns: boot ISO URL. Should be either of below: * A Swift object - It should be of format 'swift:<object-name>'. It is assumed that the image object is present in CONF.ilo.swift_ilo_container; * A Glance image - It should be format 'glance://<glance-image-uuid>' or just <glance-image-uuid>; * An HTTP URL. On error finding the boot iso, it returns None. :raises: MissingParameterValue, if any of the required parameters are missing in the node's driver_info or instance_info. :raises: InvalidParameterValue, if any of the parameters have invalid value in the node's driver_info or instance_info. :raises: SwiftOperationError, if operation with Swift fails. :raises: ImageCreationFailed, if creation of boot ISO failed. :raises: exception.ImageRefValidationFailed if ilo_boot_iso is not HTTP(S) URL. """ LOG.debug("Trying to get a boot ISO to boot the baremetal node") # Option 1 - Check if user has provided ilo_boot_iso in node's # instance_info if task.node.instance_info.get('ilo_boot_iso'): LOG.debug("Using ilo_boot_iso provided in node's instance_info") boot_iso = task.node.instance_info['ilo_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 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 task.node.instance_info['ilo_boot_iso'] # Option 2 - Check if user has provided a boot_iso in Glance. If boot_iso # is a supported non-glance href execution will proceed to option 3. deploy_info = _parse_deploy_info(task.node) image_href = deploy_info['image_source'] image_properties = ( images.get_image_properties( task.context, image_href, ['boot_iso'])) boot_iso_uuid = image_properties.get('boot_iso') if boot_iso_uuid: LOG.debug("Found boot_iso %s in Glance", boot_iso_uuid) return boot_iso_uuid # NOTE(rameshg87): Functionality to share the boot ISOs created for # similar instances (instances with same deployed image) is # not implemented as of now. Creation/Deletion of such a shared boot ISO # will require synchronisation across conductor nodes for the shared boot # ISO. Such a synchronisation mechanism doesn't exist in ironic as of now. # Option 3 - Create boot_iso from kernel/ramdisk, upload to Swift # or web server and provide its name. return image_utils.prepare_boot_iso(task, deploy_info, root_uuid)
def prepare_instance(self, task): """Prepares the boot of instance over virtual media. This method prepares the boot of the instance after reading relevant information from the node's instance_info. The internal logic is as follows: - If `boot_option` requested for this deploy is 'local', then set the node to boot from disk. - Unless `boot_option` requested for this deploy is 'ramdisk', pass root disk/partition ID to virtual media boot image - Otherwise build boot image, insert it into virtual media device and set node to boot from CD. :param task: a task from TaskManager. :returns: None :raises: InstanceDeployFailure, if its try to boot iSCSI volume in 'BIOS' boot mode. """ node = task.node self._eject_all(task) boot_mode_utils.sync_boot_mode(task) boot_mode_utils.configure_secure_boot_if_needed(task) boot_option = deploy_utils.get_boot_option(node) iwdi = node.driver_internal_info.get('is_whole_disk_image') if boot_option == "local" or iwdi: self._set_boot_device(task, boot_devices.DISK, persistent=True) LOG.debug( "Node %(node)s is set to permanently boot from local " "%(device)s", { 'node': task.node.uuid, 'device': boot_devices.DISK }) return params = {} if boot_option != 'ramdisk': root_uuid = node.driver_internal_info.get('root_uuid_or_disk_id') if not root_uuid and task.driver.storage.should_write_image(task): LOG.warning( "The UUID of the root partition could not be found for " "node %s. Booting instance from disk anyway.", node.uuid) self._set_boot_device(task, boot_devices.DISK, persistent=True) return params.update(root_uuid=root_uuid) managers = redfish_utils.get_system(task.node).managers deploy_info = _parse_deploy_info(node) configdrive = node.instance_info.get('configdrive') iso_ref = image_utils.prepare_boot_iso(task, deploy_info, **params) _eject_vmedia(task, managers, sushy.VIRTUAL_MEDIA_CD) _insert_vmedia(task, managers, iso_ref, sushy.VIRTUAL_MEDIA_CD) if configdrive and boot_option == 'ramdisk': _eject_vmedia(task, managers, sushy.VIRTUAL_MEDIA_USBSTICK) cd_ref = image_utils.prepare_configdrive_image(task, configdrive) try: _insert_vmedia(task, managers, cd_ref, sushy.VIRTUAL_MEDIA_USBSTICK) except exception.InvalidParameterValue: raise exception.InstanceDeployFailure( _('Cannot attach configdrive for node %s: no suitable ' 'virtual USB slot has been found') % node.uuid) del managers self._set_boot_device(task, boot_devices.CDROM, persistent=True) LOG.debug( "Node %(node)s is set to permanently boot from " "%(device)s", { 'node': task.node.uuid, 'device': boot_devices.CDROM })