예제 #1
0
 def test_switch_pxe_config(self):
     fname = self._create_config()
     utils.switch_pxe_config(fname,
                            '12345678-1234-1234-1234-1234567890abcdef')
     with open(fname, 'r') as f:
         pxeconf = f.read()
     self.assertEqual(_PXECONF_BOOT, pxeconf)
예제 #2
0
파일: pxe.py 프로젝트: skw0rm/ironic
    def _continue_deploy(self, task, **kwargs):
        """Continues the deployment of baremetal node over iSCSI.

        This method continues the deployment of the baremetal node over iSCSI
        from where the deployment ramdisk has left off.

        :param task: a TaskManager instance containing the node to act on.
        :param kwargs: kwargs for performing iscsi deployment.
        :raises: InvalidState
        """
        node = task.node
        task.process_event('resume')

        _destroy_token_file(node)

        root_uuid = iscsi_deploy.continue_deploy(task, **kwargs)

        if not root_uuid:
            return

        try:
            pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
            deploy_utils.switch_pxe_config(pxe_config_path, root_uuid,
                          driver_utils.get_node_capability(node, 'boot_mode'))

            deploy_utils.notify_deploy_complete(kwargs['address'])

            LOG.info(_LI('Deployment to node %s done'), node.uuid)
            task.process_event('done')
        except Exception as e:
            LOG.error(_LE('Deploy failed for instance %(instance)s. '
                          'Error: %(error)s'),
                      {'instance': node.instance_uuid, 'error': e})
            msg = _('Failed to continue iSCSI deployment.')
            deploy_utils.set_failed_state(task, msg)
예제 #3
0
def build_service_pxe_config(task,
                             instance_image_info,
                             root_uuid_or_disk_id,
                             ramdisk_boot=False,
                             ipxe_enabled=False):
    node = task.node
    pxe_config_path = get_pxe_config_file_path(node.uuid)
    # NOTE(pas-ha) if it is takeover of ACTIVE node or node performing
    # unrescue operation, first ensure that basic PXE configs and links
    # are in place before switching pxe config
    if (node.provision_state in [states.ACTIVE, states.UNRESCUING]
            and not os.path.isfile(pxe_config_path)):
        pxe_options = build_pxe_config_options(task,
                                               instance_image_info,
                                               service=True,
                                               ipxe_enabled=ipxe_enabled)
        pxe_config_template = deploy_utils.get_pxe_config_template(node)
        create_pxe_config(task,
                          pxe_options,
                          pxe_config_template,
                          ipxe_enabled=ipxe_enabled)
    iwdi = node.driver_internal_info.get('is_whole_disk_image')
    deploy_utils.switch_pxe_config(
        pxe_config_path,
        root_uuid_or_disk_id,
        boot_mode_utils.get_boot_mode(node),
        iwdi,
        deploy_utils.is_trusted_boot_requested(node),
        deploy_utils.is_iscsi_boot(task),
        ramdisk_boot,
        ipxe_enabled=ipxe_enabled)
예제 #4
0
파일: pxe.py 프로젝트: overcastcloud/ironic
    def prepare(self, task):
        """Prepare the deployment environment for this task's node.

        Generates the TFTP configuration for PXE-booting both the deployment
        and user images, fetches the TFTP image from Glance and add it to the
        local cache.

        :param task: a TaskManager instance containing the node to act on.
        """
        node = task.node
        # TODO(deva): optimize this if rerun on existing files
        if CONF.pxe.ipxe_enabled:
            # Copy the iPXE boot script to HTTP root directory
            bootfile_path = os.path.join(
                CONF.pxe.http_root,
                os.path.basename(CONF.pxe.ipxe_boot_script))
            shutil.copyfile(CONF.pxe.ipxe_boot_script, bootfile_path)
        pxe_info = _get_image_info(node, task.context)
        pxe_options = _build_pxe_config_options(node, pxe_info, task.context)

        if deploy_utils.get_boot_mode_for_deploy(node) == 'uefi':
            pxe_config_template = CONF.pxe.uefi_pxe_config_template
        else:
            pxe_config_template = CONF.pxe.pxe_config_template

        pxe_utils.create_pxe_config(task, pxe_options, pxe_config_template)

        # FIXME(lucasagomes): If it's local boot we should not cache
        # the image kernel and ramdisk (Or even require it).
        _cache_ramdisk_kernel(task.context, node, pxe_info)

        # NOTE(deva): prepare may be called from conductor._do_takeover
        # in which case, it may need to regenerate the PXE config file for an
        # already-active deployment.
        if node.provision_state == states.ACTIVE:
            # this should have been stashed when the deploy was done
            # but let's guard, just in case it's missing
            iwdi = node.driver_internal_info.get('is_whole_disk_image')
            try:
                root_uuid_or_disk_id = (
                    node.driver_internal_info['root_uuid_or_disk_id'])
            except KeyError:
                if not iwdi:
                    LOG.warn(
                        _LW("The UUID for the root partition can't be "
                            "found, unable to switch the pxe config from "
                            "deployment mode to service (boot) mode for node "
                            "%(node)s"), {"node": node.uuid})
                else:
                    LOG.warn(
                        _LW("The disk id for the whole disk image can't "
                            "be found, unable to switch the pxe config from "
                            "deployment mode to service (boot) mode for "
                            "node %(node)s"), {"node": node.uuid})
            else:
                pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
                deploy_utils.switch_pxe_config(
                    pxe_config_path, root_uuid_or_disk_id,
                    deploy_utils.get_boot_mode_for_deploy(node), iwdi,
                    deploy_utils.is_trusted_boot_requested(node))
예제 #5
0
파일: pxe.py 프로젝트: uggla/ironic
    def prepare(self, task):
        """Prepare the deployment environment for this task's node.

        Generates the TFTP configuration for PXE-booting both the deployment
        and user images, fetches the TFTP image from Glance and add it to the
        local cache.

        :param task: a TaskManager instance containing the node to act on.
        """
        node = task.node
        # TODO(deva): optimize this if rerun on existing files
        if CONF.pxe.ipxe_enabled:
            # Copy the iPXE boot script to HTTP root directory
            bootfile_path = os.path.join(CONF.pxe.http_root,
                                   os.path.basename(CONF.pxe.ipxe_boot_script))
            shutil.copyfile(CONF.pxe.ipxe_boot_script, bootfile_path)
        pxe_info = _get_image_info(node, task.context)
        pxe_options = _build_pxe_config_options(node, pxe_info,
                                                task.context)

        if deploy_utils.get_boot_mode_for_deploy(node) == 'uefi':
            pxe_config_template = CONF.pxe.uefi_pxe_config_template
        else:
            pxe_config_template = CONF.pxe.pxe_config_template

        pxe_utils.create_pxe_config(task, pxe_options,
                                    pxe_config_template)

        # FIXME(lucasagomes): If it's local boot we should not cache
        # the image kernel and ramdisk (Or even require it).
        _cache_ramdisk_kernel(task.context, node, pxe_info)

        # NOTE(deva): prepare may be called from conductor._do_takeover
        # in which case, it may need to regenerate the PXE config file for an
        # already-active deployment.
        if node.provision_state == states.ACTIVE:
            # this should have been stashed when the deploy was done
            # but let's guard, just in case it's missing
            iwdi = node.driver_internal_info.get('is_whole_disk_image')
            try:
                root_uuid_or_disk_id = node.driver_internal_info[
                                                'root_uuid_or_disk_id']
            except KeyError:
                if not iwdi:
                    LOG.warn(_LW("The UUID for the root partition can't be "
                             "found, unable to switch the pxe config from "
                             "deployment mode to service (boot) mode for node "
                             "%(node)s"), {"node": node.uuid})
                else:
                    LOG.warn(_LW("The disk id for the whole disk image can't "
                             "be found, unable to switch the pxe config from "
                             "deployment mode to service (boot) mode for "
                             "node %(node)s"), {"node": node.uuid})
            else:
                pxe_config_path = pxe_utils.get_pxe_config_file_path(
                    node.uuid)
                deploy_utils.switch_pxe_config(
                    pxe_config_path, root_uuid_or_disk_id,
                    deploy_utils.get_boot_mode_for_deploy(node),
                    iwdi)
예제 #6
0
def build_service_pxe_config(task, instance_image_info,
                             root_uuid_or_disk_id,
                             ramdisk_boot=False,
                             ipxe_enabled=False):
    node = task.node
    pxe_config_path = get_pxe_config_file_path(node.uuid)
    # NOTE(pas-ha) if it is takeover of ACTIVE node or node performing
    # unrescue operation, first ensure that basic PXE configs and links
    # are in place before switching pxe config
    # NOTE(TheJulia): Also consider deploying a valid state to go ahead
    # and check things before continuing, as otherwise deployments can
    # fail if the agent was booted outside the direct actions of the
    # boot interface.
    if (node.provision_state in [states.ACTIVE, states.UNRESCUING,
                                 states.DEPLOYING]
            and not os.path.isfile(pxe_config_path)):
        pxe_options = build_pxe_config_options(task, instance_image_info,
                                               service=True,
                                               ipxe_enabled=ipxe_enabled)
        pxe_config_template = deploy_utils.get_pxe_config_template(node)
        create_pxe_config(task, pxe_options, pxe_config_template,
                          ipxe_enabled=ipxe_enabled)
    iwdi = node.driver_internal_info.get('is_whole_disk_image')

    deploy_utils.switch_pxe_config(
        pxe_config_path, root_uuid_or_disk_id,
        boot_mode_utils.get_boot_mode(node),
        iwdi, deploy_utils.is_trusted_boot_requested(node),
        deploy_utils.is_iscsi_boot(task), ramdisk_boot,
        ipxe_enabled=ipxe_enabled)
예제 #7
0
    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)
예제 #8
0
def build_service_pxe_config(task, instance_image_info,
                             root_uuid_or_disk_id,
                             ramdisk_boot=False,
                             ipxe_enabled=False):
    node = task.node
    pxe_config_path = get_pxe_config_file_path(node.uuid,
                                               ipxe_enabled=ipxe_enabled)
    # NOTE(pas-ha) if it is takeover of ACTIVE node or node performing
    # unrescue operation, first ensure that basic PXE configs and links
    # are in place before switching pxe config
    # NOTE(TheJulia): Also consider deploying a valid state to go ahead
    # and check things before continuing, as otherwise deployments can
    # fail if the agent was booted outside the direct actions of the
    # boot interface.
    if (node.provision_state in [states.ACTIVE, states.UNRESCUING,
                                 states.DEPLOYING]
            and not os.path.isfile(pxe_config_path)):
        pxe_options = build_pxe_config_options(task, instance_image_info,
                                               service=True,
                                               ipxe_enabled=ipxe_enabled)
        pxe_config_template = deploy_utils.get_pxe_config_template(node)
        create_pxe_config(task, pxe_options, pxe_config_template,
                          ipxe_enabled=ipxe_enabled)
    iwdi = node.driver_internal_info.get('is_whole_disk_image')

    deploy_utils.switch_pxe_config(
        pxe_config_path, root_uuid_or_disk_id,
        boot_mode_utils.get_boot_mode(node),
        iwdi, deploy_utils.is_trusted_boot_requested(node),
        deploy_utils.is_iscsi_boot(task), ramdisk_boot,
        ipxe_enabled=ipxe_enabled)
예제 #9
0
파일: pxe.py 프로젝트: CiscoUcs/Ironic
    def pass_deploy_info(self, task, **kwargs):
        """Continues the deployment of baremetal node over iSCSI.

        This method continues the deployment of the baremetal node over iSCSI
        from where the deployment ramdisk has left off.

        :param task: a TaskManager instance containing the node to act on.
        :param kwargs: kwargs for performing iscsi deployment.
        :raises: InvalidState
        """
        node = task.node
        task.process_event('resume')

        _destroy_token_file(node)
        is_whole_disk_image = node.driver_internal_info['is_whole_disk_image']
        uuid_dict = iscsi_deploy.continue_deploy(task, **kwargs)
        root_uuid_or_disk_id = uuid_dict.get(
            'root uuid', uuid_dict.get('disk identifier'))

        # save the node's root disk UUID so that another conductor could
        # rebuild the PXE config file. Due to a shortcoming in Nova objects,
        # we have to assign to node.driver_internal_info so the node knows it
        # has changed.
        driver_internal_info = node.driver_internal_info
        driver_internal_info['root_uuid_or_disk_id'] = root_uuid_or_disk_id
        node.driver_internal_info = driver_internal_info
        node.save()

        try:
            if iscsi_deploy.get_boot_option(node) == "local":
                deploy_utils.try_set_boot_device(task, boot_devices.DISK)

                # If it's going to boot from the local disk, get rid of
                # the PXE configuration files used for the deployment
                pxe_utils.clean_up_pxe_config(task)

                # Ask the ramdisk to install bootloader and
                # wait for the call-back through the vendor passthru
                # 'pass_bootloader_install_info', if it's not a
                # whole disk image.
                if not is_whole_disk_image:
                    deploy_utils.notify_ramdisk_to_proceed(kwargs['address'])
                    task.process_event('wait')
                    return
            else:
                pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
                boot_mode = deploy_utils.get_boot_mode_for_deploy(node)
                deploy_utils.switch_pxe_config(pxe_config_path,
                                               root_uuid_or_disk_id,
                                               boot_mode, is_whole_disk_image)

        except Exception as e:
            LOG.error(_LE('Deploy failed for instance %(instance)s. '
                          'Error: %(error)s'),
                      {'instance': node.instance_uuid, 'error': e})
            msg = _('Failed to continue iSCSI deployment.')
            deploy_utils.set_failed_state(task, msg)
        else:
            iscsi_deploy.finish_deploy(task, kwargs.get('address'))
예제 #10
0
 def test_switch_ipxe_config(self):
     cfg.CONF.set_override('ipxe_enabled', True, 'pxe')
     fname = self._create_config(ipxe=True)
     utils.switch_pxe_config(fname,
                            '12345678-1234-1234-1234-1234567890abcdef')
     with open(fname, 'r') as f:
         pxeconf = f.read()
     self.assertEqual(_IPXECONF_BOOT, pxeconf)
예제 #11
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. In case of netboot,
        it updates the dhcp entries and switches the PXE config. In case of
        localboot, it cleans up the PXE config.

        :param task: a task from TaskManager.
        :returns: None
        """
        node = task.node
        boot_option = deploy_utils.get_boot_option(node)

        if boot_option != "local":
            # Make sure that the instance kernel/ramdisk is cached.
            # This is for the takeover scenario for active nodes.
            instance_image_info = _get_instance_image_info(
                task.node, task.context)
            _cache_ramdisk_kernel(task.context, task.node, instance_image_info)

            # If it's going to PXE boot we need to update the DHCP server
            dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
            provider = dhcp_factory.DHCPFactory()
            provider.update_dhcp(task, dhcp_opts)

            iwdi = task.node.driver_internal_info.get('is_whole_disk_image')
            try:
                root_uuid_or_disk_id = task.node.driver_internal_info[
                    'root_uuid_or_disk_id']
            except KeyError:
                if not iwdi:
                    LOG.warn(
                        _LW("The UUID for the root partition can't be "
                            "found, unable to switch the pxe config from "
                            "deployment mode to service (boot) mode for "
                            "node %(node)s"), {"node": task.node.uuid})
                else:
                    LOG.warn(
                        _LW("The disk id for the whole disk image can't "
                            "be found, unable to switch the pxe config "
                            "from deployment mode to service (boot) mode "
                            "for node %(node)s"), {"node": task.node.uuid})
            else:
                pxe_config_path = pxe_utils.get_pxe_config_file_path(
                    task.node.uuid)
                deploy_utils.switch_pxe_config(
                    pxe_config_path, root_uuid_or_disk_id,
                    deploy_utils.get_boot_mode_for_deploy(node), iwdi,
                    deploy_utils.is_trusted_boot_requested(node))

        else:
            # If it's going to boot from the local disk, we don't need
            # PXE config files. They still need to be generated as part
            # of the prepare() because the deployment does PXE boot the
            # deploy ramdisk
            pxe_utils.clean_up_pxe_config(task)
예제 #12
0
 def test_switch_uefi_pxe_config(self):
     boot_mode = 'uefi'
     fname = self._create_config(boot_mode=boot_mode)
     utils.switch_pxe_config(fname,
                            '12345678-1234-1234-1234-1234567890abcdef',
                            boot_mode)
     with open(fname, 'r') as f:
         pxeconf = f.read()
     self.assertEqual(_UEFI_PXECONF_BOOT, pxeconf)
예제 #13
0
 def test_switch_uefi_pxe_config(self):
     boot_mode = 'uefi'
     fname = self._create_config(boot_mode=boot_mode)
     utils.switch_pxe_config(fname,
                            '12345678-1234-1234-1234-1234567890abcdef',
                            boot_mode)
     with open(fname, 'r') as f:
         pxeconf = f.read()
     self.assertEqual(_UEFI_PXECONF_BOOT, pxeconf)
예제 #14
0
파일: pxe.py 프로젝트: allen-yin/ironic
    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. In case of netboot,
        it updates the dhcp entries and switches the PXE config. In case of
        localboot, it cleans up the PXE config.

        :param task: a task from TaskManager.
        :returns: None
        """
        node = task.node
        boot_option = deploy_utils.get_boot_option(node)

        if boot_option != "local":
            # Make sure that the instance kernel/ramdisk is cached.
            # This is for the takeover scenario for active nodes.
            instance_image_info = _get_instance_image_info(
                task.node, task.context)
            _cache_ramdisk_kernel(task.context, task.node, instance_image_info)

            # If it's going to PXE boot we need to update the DHCP server
            dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
            provider = dhcp_factory.DHCPFactory()
            provider.update_dhcp(task, dhcp_opts)

            iwdi = task.node.driver_internal_info.get('is_whole_disk_image')
            try:
                root_uuid_or_disk_id = task.node.driver_internal_info[
                    'root_uuid_or_disk_id'
                ]
            except KeyError:
                if not iwdi:
                    LOG.warn(_LW("The UUID for the root partition can't be "
                                 "found, unable to switch the pxe config from "
                                 "deployment mode to service (boot) mode for "
                                 "node %(node)s"), {"node": task.node.uuid})
                else:
                    LOG.warn(_LW("The disk id for the whole disk image can't "
                                 "be found, unable to switch the pxe config "
                                 "from deployment mode to service (boot) mode "
                                 "for node %(node)s"),
                             {"node": task.node.uuid})
            else:
                pxe_config_path = pxe_utils.get_pxe_config_file_path(
                    task.node.uuid)
                deploy_utils.switch_pxe_config(
                    pxe_config_path, root_uuid_or_disk_id,
                    deploy_utils.get_boot_mode_for_deploy(node),
                    iwdi, deploy_utils.is_trusted_boot_requested(node))

        else:
            # If it's going to boot from the local disk, we don't need
            # PXE config files. They still need to be generated as part
            # of the prepare() because the deployment does PXE boot the
            # deploy ramdisk
            pxe_utils.clean_up_pxe_config(task)
예제 #15
0
 def test_switch_ipxe_config(self):
     boot_mode = 'bios'
     cfg.CONF.set_override('ipxe_enabled', True, 'pxe')
     fname = self._create_config(ipxe=True)
     utils.switch_pxe_config(fname,
                            '12345678-1234-1234-1234-1234567890abcdef',
                            boot_mode)
     with open(fname, 'r') as f:
         pxeconf = f.read()
     self.assertEqual(_IPXECONF_BOOT, pxeconf)
예제 #16
0
파일: pxe.py 프로젝트: infraredgirl/ironic
    def _continue_deploy(self, task, **kwargs):
        """Continues the deployment of baremetal node over iSCSI.

        This method continues the deployment of the baremetal node over iSCSI
        from where the deployment ramdisk has left off.

        :param task: a TaskManager instance containing the node to act on.
        :param kwargs: kwargs for performing iscsi deployment.
        :raises: InvalidState
        """
        node = task.node
        task.process_event('resume')

        _destroy_token_file(node)

        root_uuid = iscsi_deploy.continue_deploy(task, **kwargs)

        if not root_uuid:
            return

        # save the node's root disk UUID so that another conductor could
        # rebuild the PXE config file. Due to a shortcoming in Nova objects,
        # we have to assign to node.driver_internal_info so the node knows it
        # has changed.
        driver_internal_info = node.driver_internal_info
        driver_internal_info['root_uuid'] = root_uuid
        node.driver_internal_info = driver_internal_info
        node.save()

        try:
            if iscsi_deploy.get_boot_option(node) == "local":
                try_set_boot_device(task, boot_devices.DISK)
                # If it's going to boot from the local disk, get rid of
                # the PXE configuration files used for the deployment
                pxe_utils.clean_up_pxe_config(task)
            else:
                pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
                deploy_utils.switch_pxe_config(pxe_config_path, root_uuid,
                    driver_utils.get_node_capability(node, 'boot_mode'))

            deploy_utils.notify_deploy_complete(kwargs['address'])
            LOG.info(_LI('Deployment to node %s done'), node.uuid)
            task.process_event('done')
        except Exception as e:
            LOG.error(_LE('Deploy failed for instance %(instance)s. '
                          'Error: %(error)s'),
                      {'instance': node.instance_uuid, 'error': e})
            msg = _('Failed to continue iSCSI deployment.')
            deploy_utils.set_failed_state(task, msg)
예제 #17
0
파일: pxe_utils.py 프로젝트: WW-Gary/ironic
def prepare_instance_pxe_config(task,
                                image_info,
                                iscsi_boot=False,
                                ramdisk_boot=False,
                                ipxe_enabled=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.
    :param ipxe_enabled: Default false boolean to indicate if ipxe
                         is in use by the caller.
    :returns: None
    """
    node = task.node
    # Generate options for both IPv4 and IPv6, and they can be
    # filtered down later based upon the port options.
    # TODO(TheJulia): This should be re-tooled during the Victoria
    # development cycle so that we call a single method and return
    # combined options. The method we currently call is relied upon
    # by two eternal projects, to changing the behavior is not ideal.
    dhcp_opts = dhcp_options_for_instance(task, ipxe_enabled, ip_version=4)
    dhcp_opts += dhcp_options_for_instance(task, ipxe_enabled, ip_version=6)
    provider = dhcp_factory.DHCPFactory()
    provider.update_dhcp(task, dhcp_opts)
    pxe_config_path = get_pxe_config_file_path(node.uuid,
                                               ipxe_enabled=ipxe_enabled)
    if not os.path.isfile(pxe_config_path):
        pxe_options = build_pxe_config_options(task,
                                               image_info,
                                               service=ramdisk_boot,
                                               ipxe_enabled=ipxe_enabled)
        if ipxe_enabled:
            pxe_config_template = (deploy_utils.get_ipxe_config_template(node))
        else:
            pxe_config_template = (deploy_utils.get_pxe_config_template(node))
        create_pxe_config(task,
                          pxe_options,
                          pxe_config_template,
                          ipxe_enabled=ipxe_enabled)
    deploy_utils.switch_pxe_config(pxe_config_path,
                                   None,
                                   boot_mode_utils.get_boot_mode(node),
                                   False,
                                   iscsi_boot=iscsi_boot,
                                   ramdisk_boot=ramdisk_boot,
                                   ipxe_enabled=ipxe_enabled)
예제 #18
0
    def continue_deploy(self, task, **kwargs):
        """Method invoked when deployed with the IPA ramdisk.

        This method is invoked during a heartbeat from an agent when
        the node is in wait-call-back state. This deploys the image on
        the node and then configures the node to boot according to the
        desired boot option (netboot or localboot).

        :param task: a TaskManager object containing the node.
        :param kwargs: the kwargs passed from the heartbeat method.
        :raises: InstanceDeployFailure, if it encounters some error during
            the deploy.
        """
        task.process_event('resume')
        node = task.node
        LOG.debug('Continuing the deployment on node %s', node.uuid)

        # NOTE(lucasagomes): We don't use the token file with the agent,
        # but as it's created as part of deploy() we are going to remove
        # it here.
        _destroy_token_file(node)

        uuid_dict = iscsi_deploy.do_agent_iscsi_deploy(task, self._client)

        is_whole_disk_image = node.driver_internal_info['is_whole_disk_image']
        if iscsi_deploy.get_boot_option(node) == "local":
            # Install the boot loader
            root_uuid = uuid_dict.get('root uuid')
            efi_sys_uuid = uuid_dict.get('efi system partition uuid')
            self.configure_local_boot(task,
                                      root_uuid=root_uuid,
                                      efi_system_part_uuid=efi_sys_uuid)

            # If it's going to boot from the local disk, get rid of
            # the PXE configuration files used for the deployment
            pxe_utils.clean_up_pxe_config(task)
        else:
            root_uuid_or_disk_id = uuid_dict.get(
                'root uuid', uuid_dict.get('disk identifier'))
            pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
            boot_mode = deploy_utils.get_boot_mode_for_deploy(node)
            deploy_utils.switch_pxe_config(pxe_config_path,
                                           root_uuid_or_disk_id, boot_mode,
                                           is_whole_disk_image)

        self.reboot_and_finish_deploy(task)
예제 #19
0
파일: pxe.py 프로젝트: CiscoUcs/Ironic
    def continue_deploy(self, task, **kwargs):
        """Method invoked when deployed with the IPA ramdisk.

        This method is invoked during a heartbeat from an agent when
        the node is in wait-call-back state. This deploys the image on
        the node and then configures the node to boot according to the
        desired boot option (netboot or localboot).

        :param task: a TaskManager object containing the node.
        :param kwargs: the kwargs passed from the heartbeat method.
        :raises: InstanceDeployFailure, if it encounters some error during
            the deploy.
        """
        task.process_event('resume')
        node = task.node
        LOG.debug('Continuing the deployment on node %s', node.uuid)

        # NOTE(lucasagomes): We don't use the token file with the agent,
        # but as it's created as part of deploy() we are going to remove
        # it here.
        _destroy_token_file(node)

        uuid_dict = iscsi_deploy.do_agent_iscsi_deploy(task, self._client)

        is_whole_disk_image = node.driver_internal_info['is_whole_disk_image']
        if iscsi_deploy.get_boot_option(node) == "local":
            # Install the boot loader
            root_uuid = uuid_dict.get('root uuid')
            efi_sys_uuid = uuid_dict.get('efi system partition uuid')
            self.configure_local_boot(
                task, root_uuid=root_uuid,
                efi_system_part_uuid=efi_sys_uuid)

            # If it's going to boot from the local disk, get rid of
            # the PXE configuration files used for the deployment
            pxe_utils.clean_up_pxe_config(task)
        else:
            root_uuid_or_disk_id = uuid_dict.get(
                'root uuid', uuid_dict.get('disk identifier'))
            pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
            boot_mode = deploy_utils.get_boot_mode_for_deploy(node)
            deploy_utils.switch_pxe_config(pxe_config_path,
                                           root_uuid_or_disk_id,
                                           boot_mode, is_whole_disk_image)

        self.reboot_and_finish_deploy(task)
예제 #20
0
파일: pxe.py 프로젝트: stackhpc/ironic
def _build_service_pxe_config(task, instance_image_info, root_uuid_or_disk_id):
    node = task.node
    pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
    # NOTE(pas-ha) if it is takeover of ACTIVE node,
    # first ensure that basic PXE configs and links
    # are in place before switching pxe config
    if (node.provision_state == states.ACTIVE
            and not os.path.isfile(pxe_config_path)):
        pxe_options = _build_pxe_config_options(task,
                                                instance_image_info,
                                                service=True)
        pxe_config_template = deploy_utils.get_pxe_config_template(node)
        pxe_utils.create_pxe_config(task, pxe_options, pxe_config_template)
    iwdi = node.driver_internal_info.get('is_whole_disk_image')
    deploy_utils.switch_pxe_config(
        pxe_config_path, root_uuid_or_disk_id,
        deploy_utils.get_boot_mode_for_deploy(node), iwdi,
        deploy_utils.is_trusted_boot_requested(node))
예제 #21
0
    def _continue_deploy(self, task, **kwargs):
        """Continues the deployment of baremetal node over iSCSI.

        This method continues the deployment of the baremetal node over iSCSI
        from where the deployment ramdisk has left off.

        :param task: a TaskManager instance containing the node to act on.
        :param kwargs: kwargs for performing iscsi deployment.
        """
        node = task.node

        if node.provision_state != states.DEPLOYWAIT:
            LOG.error(_LE('Node %s is not waiting to be deployed.'), node.uuid)
            return

        _destroy_token_file(node)

        root_uuid = iscsi_deploy.continue_deploy(task, **kwargs)

        if not root_uuid:
            return

        try:
            pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
            deploy_utils.switch_pxe_config(
                pxe_config_path, root_uuid,
                driver_utils.get_node_capability(node, 'boot_mode'))

            deploy_utils.notify_deploy_complete(kwargs['address'])

            LOG.info(_LI('Deployment to node %s done'), node.uuid)
            node.provision_state = states.ACTIVE
            node.target_provision_state = states.NOSTATE
            node.save()
        except Exception as e:

            LOG.error(
                _LE('Deploy failed for instance %(instance)s. '
                    'Error: %(error)s'), {
                        'instance': node.instance_uuid,
                        'error': e
                    })
            msg = _('Failed to continue iSCSI deployment.')
            iscsi_deploy.set_failed_state(task, msg)
예제 #22
0
파일: pxe.py 프로젝트: Tehsmash/ironic
def _build_service_pxe_config(task, instance_image_info,
                              root_uuid_or_disk_id):
    node = task.node
    pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
    # NOTE(pas-ha) if it is takeover of ACTIVE node,
    # first ensure that basic PXE configs and links
    # are in place before switching pxe config
    if (node.provision_state == states.ACTIVE and
            not os.path.isfile(pxe_config_path)):
        pxe_options = _build_pxe_config_options(task, instance_image_info,
                                                service=True)
        pxe_config_template = deploy_utils.get_pxe_config_template(node)
        pxe_utils.create_pxe_config(task, pxe_options, pxe_config_template)
    iwdi = node.driver_internal_info.get('is_whole_disk_image')
    deploy_utils.switch_pxe_config(
        pxe_config_path, root_uuid_or_disk_id,
        deploy_utils.get_boot_mode_for_deploy(node),
        iwdi, deploy_utils.is_trusted_boot_requested(node),
        deploy_utils.is_iscsi_boot(task))
예제 #23
0
파일: pxe.py 프로젝트: Codixis/ironic
    def continue_deploy(self, task, **kwargs):
        """Method invoked when deployed with the IPA ramdisk.

        This method is invoked during a heartbeat from an agent when
        the node is in wait-call-back state. This deploys the image on
        the node and then configures the node to boot according to the
        desired boot option (netboot or localboot).

        :param task: a TaskManager object containing the node.
        :param kwargs: the kwargs passed from the heartbeat method.
        :raises: InstanceDeployFailure, if it encounters some error during
            the deploy.
        """
        task.process_event("resume")
        node = task.node
        LOG.debug("Continuing the deployment on node %s", node.uuid)

        uuid_dict = iscsi_deploy.do_agent_iscsi_deploy(task, self._client)

        is_whole_disk_image = node.driver_internal_info["is_whole_disk_image"]
        if iscsi_deploy.get_boot_option(node) == "local":
            # Install the boot loader
            root_uuid = uuid_dict.get("root uuid")
            efi_sys_uuid = uuid_dict.get("efi system partition uuid")
            self.configure_local_boot(task, root_uuid=root_uuid, efi_system_part_uuid=efi_sys_uuid)

            # If it's going to boot from the local disk, get rid of
            # the PXE configuration files used for the deployment
            pxe_utils.clean_up_pxe_config(task)
        else:
            root_uuid_or_disk_id = uuid_dict.get("root uuid", uuid_dict.get("disk identifier"))
            pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
            boot_mode = deploy_utils.get_boot_mode_for_deploy(node)
            deploy_utils.switch_pxe_config(
                pxe_config_path,
                root_uuid_or_disk_id,
                boot_mode,
                is_whole_disk_image,
                deploy_utils.is_trusted_boot_requested(node),
            )

        self.reboot_and_finish_deploy(task)
예제 #24
0
def prepare_instance_pxe_config(task,
                                image_info,
                                iscsi_boot=False,
                                ramdisk_boot=False,
                                ipxe_enabled=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.
    :param ipxe_enabled: Default false boolean to indicate if ipxe
                         is in use by the caller.
    :returns: None
    """

    node = task.node
    dhcp_opts = dhcp_options_for_instance(task, ipxe_enabled)
    provider = dhcp_factory.DHCPFactory()
    provider.update_dhcp(task, dhcp_opts)
    pxe_config_path = get_pxe_config_file_path(node.uuid,
                                               ipxe_enabled=ipxe_enabled)
    if not os.path.isfile(pxe_config_path):
        pxe_options = build_pxe_config_options(task,
                                               image_info,
                                               service=ramdisk_boot,
                                               ipxe_enabled=ipxe_enabled)
        pxe_config_template = (deploy_utils.get_pxe_config_template(node))
        create_pxe_config(task,
                          pxe_options,
                          pxe_config_template,
                          ipxe_enabled=ipxe_enabled)
    deploy_utils.switch_pxe_config(pxe_config_path,
                                   None,
                                   boot_mode_utils.get_boot_mode(node),
                                   False,
                                   iscsi_boot=iscsi_boot,
                                   ramdisk_boot=ramdisk_boot,
                                   ipxe_enabled=ipxe_enabled)
예제 #25
0
파일: pxe.py 프로젝트: ader1990/ironic
    def _continue_deploy(self, task, **kwargs):
        """Continues the deployment of baremetal node over iSCSI.

        This method continues the deployment of the baremetal node over iSCSI
        from where the deployment ramdisk has left off.

        :param task: a TaskManager instance containing the node to act on.
        :param kwargs: kwargs for performing iscsi deployment.
        """
        node = task.node

        if node.provision_state != states.DEPLOYWAIT:
            LOG.error(_LE('Node %s is not waiting to be deployed.'), node.uuid)
            return

        _destroy_token_file(node)

        root_uuid = iscsi_deploy.continue_deploy(task, **kwargs)

        if not root_uuid:
            return

        try:
            pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
            deploy_utils.switch_pxe_config(pxe_config_path, root_uuid,
                          driver_utils.get_node_capability(node, 'boot_mode'))

            deploy_utils.notify_deploy_complete(kwargs['address'])

            LOG.info(_LI('Deployment to node %s done'), node.uuid)
            node.provision_state = states.ACTIVE
            node.target_provision_state = states.NOSTATE
            node.save()
        except Exception as e:

            LOG.error(_LE('Deploy failed for instance %(instance)s. '
                          'Error: %(error)s'),
                      {'instance': node.instance_uuid, 'error': e})
            msg = _('Failed to continue iSCSI deployment.')
            iscsi_deploy.set_failed_state(task, msg)
예제 #26
0
파일: pxe.py 프로젝트: ramineni/myironic
    def _continue_deploy(self, task, **kwargs):
        """Continues the deployment of baremetal node over iSCSI.

        This method continues the deployment of the baremetal node over iSCSI
        from where the deployment ramdisk has left off.

        :param task: a TaskManager instance containing the node to act on.
        :param kwargs: kwargs for performing iscsi deployment.
        :raises: InvalidState
        """
        node = task.node
        task.process_event('resume')

        _destroy_token_file(node)

        root_uuid = iscsi_deploy.continue_deploy(task, **kwargs)

        if not root_uuid:
            return

        try:
            if iscsi_deploy.get_boot_option(node) == "local":
                try_set_boot_device(task, boot_devices.DISK)
                # If it's going to boot from the local disk, get rid of
                # the PXE configuration files used for the deployment
                pxe_utils.clean_up_pxe_config(task)
            else:
                pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
                deploy_utils.switch_pxe_config(pxe_config_path, root_uuid,
                    driver_utils.get_node_capability(node, 'boot_mode'))

            deploy_utils.notify_deploy_complete(kwargs['address'])
            LOG.info(_LI('Deployment to node %s done'), node.uuid)
            task.process_event('done')
        except Exception as e:
            LOG.error(_LE('Deploy failed for instance %(instance)s. '
                          'Error: %(error)s'),
                      {'instance': node.instance_uuid, 'error': e})
            msg = _('Failed to continue iSCSI deployment.')
            deploy_utils.set_failed_state(task, msg)
예제 #27
0
def prepare_instance_pxe_config(task, image_info,
                                iscsi_boot=False,
                                ramdisk_boot=False,
                                ipxe_enabled=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.
    :param ipxe_enabled: Default false boolean to indicate if ipxe
                         is in use by the caller.
    :returns: None
    """

    node = task.node
    dhcp_opts = dhcp_options_for_instance(task, ipxe_enabled)
    provider = dhcp_factory.DHCPFactory()
    provider.update_dhcp(task, dhcp_opts)
    pxe_config_path = 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,
            ipxe_enabled=ipxe_enabled)
        pxe_config_template = (
            deploy_utils.get_pxe_config_template(node))
        create_pxe_config(
            task, pxe_options, pxe_config_template,
            ipxe_enabled=ipxe_enabled)
    deploy_utils.switch_pxe_config(
        pxe_config_path, None,
        boot_mode_utils.get_boot_mode(node), False,
        iscsi_boot=iscsi_boot, ramdisk_boot=ramdisk_boot,
        ipxe_enabled=ipxe_enabled)
예제 #28
0
 def test_switch_pxe_config(self):
     utils.switch_pxe_config(self.fname,
                             '12345678-1234-1234-1234-1234567890abcdef')
     with open(self.fname, 'r') as f:
         pxeconf = f.read()
     self.assertEqual(pxeconf, _PXECONF_BOOT)
예제 #29
0
파일: pxe.py 프로젝트: olliewalsh/ironic
    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. In case of netboot,
        it updates the dhcp entries and switches the PXE config. In case of
        localboot, it cleans up the PXE config.

        :param task: a task from TaskManager.
        :returns: None
        """
        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,
                deploy_utils.get_boot_mode_for_deploy(node), False,
                iscsi_boot=True)
            boot_device = boot_devices.PXE

        elif boot_option != "local":
            if task.driver.storage.should_write_image(task):
                # Make sure that the instance kernel/ramdisk is cached.
                # This is for the takeover scenario for active nodes.
                instance_image_info = _get_instance_image_info(
                    task.node, task.context)
                _cache_ramdisk_kernel(task.context, task.node,
                                      instance_image_info)

            # If it's going to PXE boot we need to update the DHCP server
            dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
            provider = dhcp_factory.DHCPFactory()
            provider.update_dhcp(task, dhcp_opts)

            iwdi = task.node.driver_internal_info.get('is_whole_disk_image')
            try:
                root_uuid_or_disk_id = task.node.driver_internal_info[
                    'root_uuid_or_disk_id'
                ]
            except KeyError:
                if not task.driver.storage.should_write_image(task):
                    pass
                elif not iwdi:
                    LOG.warning("The UUID for the root partition can't be "
                                "found, unable to switch the pxe config from "
                                "deployment mode to service (boot) mode for "
                                "node %(node)s", {"node": task.node.uuid})
                else:
                    LOG.warning("The disk id for the whole disk image can't "
                                "be found, unable to switch the pxe config "
                                "from deployment mode to service (boot) mode "
                                "for node %(node)s. Booting the instance "
                                "from disk.", {"node": task.node.uuid})
                    pxe_utils.clean_up_pxe_config(task)
                    boot_device = boot_devices.DISK
            else:
                _build_service_pxe_config(task, instance_image_info,
                                          root_uuid_or_disk_id)
                boot_device = boot_devices.PXE
        else:
            # If it's going to boot from the local disk, we don't need
            # PXE config files. They still need to be generated as part
            # of the prepare() because the deployment does PXE boot the
            # deploy ramdisk
            pxe_utils.clean_up_pxe_config(task)
            boot_device = boot_devices.DISK

        # NOTE(pas-ha) do not re-set boot device on ACTIVE nodes
        # during takeover
        if boot_device and task.node.provision_state != states.ACTIVE:
            manager_utils.node_set_boot_device(task, boot_device,
                                               persistent=True)
예제 #30
0
 def test_switch_pxe_config(self):
     utils.switch_pxe_config(self.fname,
                            '12345678-1234-1234-1234-1234567890abcdef')
     with open(self.fname, 'r') as f:
         pxeconf = f.read()
     self.assertEqual(pxeconf, _PXECONF_BOOT)
예제 #31
0
파일: pxe.py 프로젝트: Tehsmash/ironic
    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. In case of netboot,
        it updates the dhcp entries and switches the PXE config. In case of
        localboot, it cleans up the PXE config.

        :param task: a task from TaskManager.
        :returns: None
        """
        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,
                deploy_utils.get_boot_mode_for_deploy(node), False,
                iscsi_boot=True)
            boot_device = boot_devices.PXE

        elif boot_option != "local":
            if task.driver.storage.should_write_image(task):
                # Make sure that the instance kernel/ramdisk is cached.
                # This is for the takeover scenario for active nodes.
                instance_image_info = _get_instance_image_info(
                    task.node, task.context)
                _cache_ramdisk_kernel(task.context, task.node,
                                      instance_image_info)

            # If it's going to PXE boot we need to update the DHCP server
            dhcp_opts = pxe_utils.dhcp_options_for_instance(task)
            provider = dhcp_factory.DHCPFactory()
            provider.update_dhcp(task, dhcp_opts)

            iwdi = task.node.driver_internal_info.get('is_whole_disk_image')
            try:
                root_uuid_or_disk_id = task.node.driver_internal_info[
                    'root_uuid_or_disk_id'
                ]
            except KeyError:
                if not task.driver.storage.should_write_image(task):
                    pass
                elif not iwdi:
                    LOG.warning("The UUID for the root partition can't be "
                                "found, unable to switch the pxe config from "
                                "deployment mode to service (boot) mode for "
                                "node %(node)s", {"node": task.node.uuid})
                else:
                    LOG.warning("The disk id for the whole disk image can't "
                                "be found, unable to switch the pxe config "
                                "from deployment mode to service (boot) mode "
                                "for node %(node)s", {"node": task.node.uuid})
            else:
                _build_service_pxe_config(task, instance_image_info,
                                          root_uuid_or_disk_id)
                boot_device = boot_devices.PXE
        else:
            # If it's going to boot from the local disk, we don't need
            # PXE config files. They still need to be generated as part
            # of the prepare() because the deployment does PXE boot the
            # deploy ramdisk
            pxe_utils.clean_up_pxe_config(task)
            boot_device = boot_devices.DISK

        # NOTE(pas-ha) do not re-set boot device on ACTIVE nodes
        # during takeover
        if boot_device and task.node.provision_state != states.ACTIVE:
            manager_utils.node_set_boot_device(task, boot_device,
                                               persistent=True)
예제 #32
0
    def pass_deploy_info(self, task, **kwargs):
        """Continues the deployment of baremetal node over iSCSI.

        This method continues the deployment of the baremetal node over iSCSI
        from where the deployment ramdisk has left off.

        :param task: a TaskManager instance containing the node to act on.
        :param kwargs: kwargs for performing iscsi deployment.
        :raises: InvalidState
        """
        node = task.node
        task.process_event('resume')
        LOG.debug('Continuing the deployment on node %s', node.uuid)

        _destroy_token_file(node)
        is_whole_disk_image = node.driver_internal_info['is_whole_disk_image']
        uuid_dict = iscsi_deploy.continue_deploy(task, **kwargs)
        root_uuid_or_disk_id = uuid_dict.get('root uuid',
                                             uuid_dict.get('disk identifier'))

        # save the node's root disk UUID so that another conductor could
        # rebuild the PXE config file. Due to a shortcoming in Nova objects,
        # we have to assign to node.driver_internal_info so the node knows it
        # has changed.
        driver_internal_info = node.driver_internal_info
        driver_internal_info['root_uuid_or_disk_id'] = root_uuid_or_disk_id
        node.driver_internal_info = driver_internal_info
        node.save()

        try:
            if iscsi_deploy.get_boot_option(node) == "local":
                deploy_utils.try_set_boot_device(task, boot_devices.DISK)

                # If it's going to boot from the local disk, get rid of
                # the PXE configuration files used for the deployment
                pxe_utils.clean_up_pxe_config(task)

                # Ask the ramdisk to install bootloader and
                # wait for the call-back through the vendor passthru
                # 'pass_bootloader_install_info', if it's not a
                # whole disk image.
                if not is_whole_disk_image:
                    LOG.debug('Installing the bootloader on node %s',
                              node.uuid)
                    deploy_utils.notify_ramdisk_to_proceed(kwargs['address'])
                    task.process_event('wait')
                    return
            else:
                pxe_config_path = pxe_utils.get_pxe_config_file_path(node.uuid)
                boot_mode = deploy_utils.get_boot_mode_for_deploy(node)
                deploy_utils.switch_pxe_config(pxe_config_path,
                                               root_uuid_or_disk_id, boot_mode,
                                               is_whole_disk_image)

        except Exception as e:
            LOG.error(
                _LE('Deploy failed for instance %(instance)s. '
                    'Error: %(error)s'), {
                        'instance': node.instance_uuid,
                        'error': e
                    })
            msg = _('Failed to continue iSCSI deployment.')
            deploy_utils.set_failed_state(task, msg)
        else:
            iscsi_deploy.finish_deploy(task, kwargs.get('address'))