예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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})
예제 #4
0
파일: boot.py 프로젝트: manosbagakis/ironic
    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
            })
예제 #5
0
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)
예제 #6
0
파일: boot.py 프로젝트: andornotlee/ironic
    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
            })