Пример #1
0
    def deploy(self, task):
        """Start deployment of the task's node.

        Fetches the instance image, prepares the options for the deployment
        ramdisk, sets the node to boot from virtual media cdrom, and reboots
        the given node.

        :param task: a TaskManager instance containing the node to act on.
        :returns: deploy state DEPLOYWAIT.
        :raises: InstanceDeployFailure, if image size if greater than root
            partition.
        :raises: ImageCreationFailed, if it failed while creating the floppy
            image.
        :raises: IRMCOperationError, if some operation on iRMC fails.
        """
        node = task.node
        manager_utils.node_power_action(task, states.POWER_OFF)

        iscsi_deploy.cache_instance_image(task.context, node)
        iscsi_deploy.check_image_size(task)

        deploy_ramdisk_opts = iscsi_deploy.build_deploy_ramdisk_options(node)
        agent_opts = deploy_utils.build_agent_options(node)
        deploy_ramdisk_opts.update(agent_opts)
        deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task)
        deploy_ramdisk_opts['BOOTIF'] = deploy_nic_mac

        _reboot_into_deploy_iso(task, deploy_ramdisk_opts)

        return states.DEPLOYWAIT
Пример #2
0
def _cleaning_reboot(task):
    """Reboots a node out of band after a clean step that requires it.

    If an agent clean step has 'reboot_requested': True, reboots the
    node when the step is completed. Will put the node in CLEANFAIL
    if the node cannot be rebooted.

    :param task: a TaskManager instance
    """
    try:
        # NOTE(fellypefca): Call prepare_ramdisk on ensure that the
        # baremetal node boots back into the ramdisk after reboot.
        deploy_opts = deploy_utils.build_agent_options(task.node)
        task.driver.boot.prepare_ramdisk(task, deploy_opts)
        manager_utils.node_power_action(task, states.REBOOT)
    except Exception as e:
        msg = (_('Reboot requested by clean step %(step)s failed for '
                 'node %(node)s: %(err)s') %
               {'step': task.node.clean_step,
                'node': task.node.uuid,
                'err': e})
        LOG.error(msg, exc_info=not isinstance(e, exception.IronicException))
        # do not set cleaning_reboot if we didn't reboot
        manager_utils.cleaning_error_handler(task, msg)
        return

    # Signify that we've rebooted
    driver_internal_info = task.node.driver_internal_info
    driver_internal_info['cleaning_reboot'] = True
    task.node.driver_internal_info = driver_internal_info
    task.node.save()
Пример #3
0
    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.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
            or the wrong driver info is specified for power management.
        :raises: StorageError If the storage driver is unable to attach the
            configured volumes.
        :raises: other exceptions by the node's power driver if something
            wrong occurred during the power action.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        node = task.node
        deploy_utils.populate_storage_driver_internal_info(task)
        if node.provision_state in [states.ACTIVE, states.ADOPTING]:
            task.driver.boot.prepare_instance(task)
        else:
            if node.provision_state == states.DEPLOYING:
                fast_track_deploy = manager_utils.is_fast_track(task)
                if fast_track_deploy:
                    # The agent has already recently checked in and we are
                    # configured to take that as an indicator that we can
                    # skip ahead.
                    LOG.debug(
                        'The agent for node %(node)s has recently '
                        'checked in, and the node power will remain '
                        'unmodified.', {'node': task.node.uuid})
                else:
                    # Adding the node to provisioning network so that the dhcp
                    # options get added for the provisioning port.
                    manager_utils.node_power_action(task, states.POWER_OFF)
                # NOTE(vdrok): in case of rebuild, we have tenant network
                # already configured, unbind tenant ports if present
                if task.driver.storage.should_write_image(task):
                    if not fast_track_deploy:
                        power_state_to_restore = (
                            manager_utils.power_on_node_if_needed(task))
                    task.driver.network.unconfigure_tenant_networks(task)
                    task.driver.network.add_provisioning_network(task)
                    if not fast_track_deploy:
                        manager_utils.restore_power_state_if_needed(
                            task, power_state_to_restore)
                task.driver.storage.attach_volumes(task)
                if (not task.driver.storage.should_write_image(task)
                        or fast_track_deploy):
                    # We have nothing else to do as this is handled in the
                    # backend storage system, and we can return to the caller
                    # as we do not need to boot the agent to deploy.
                    # Alternatively, we are in a fast track deployment
                    # and have nothing else to do.
                    return

            deploy_opts = deploy_utils.build_agent_options(node)
            task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #4
0
    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.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
             or the wrong driver info is specified for power management.
        :raises: other exceptions by the node's power driver if something
             wrong occurred during the power action.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        node = task.node
        if node.provision_state in [states.ACTIVE, states.ADOPTING]:
            task.driver.boot.prepare_instance(task)
        else:
            if node.provision_state == states.DEPLOYING:
                # Adding the node to provisioning network so that the dhcp
                # options get added for the provisioning port.
                manager_utils.node_power_action(task, states.POWER_OFF)
                task.driver.network.add_provisioning_network(task)

            deploy_opts = deploy_utils.build_agent_options(node)
            task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #5
0
    def deploy(self, task):
        """Start deployment of the task's node.

        Fetches the instance image, prepares the options for the deployment
        ramdisk, sets the node to boot from virtual media cdrom, and reboots
        the given node.

        :param task: a TaskManager instance containing the node to act on.
        :returns: deploy state DEPLOYWAIT.
        :raises: InstanceDeployFailure, if image size if greater than root
            partition.
        :raises: ImageCreationFailed, if it failed while creating the floppy
            image.
        :raises: IRMCOperationError, if some operation on iRMC fails.
        """
        node = task.node
        manager_utils.node_power_action(task, states.POWER_OFF)

        iscsi_deploy.cache_instance_image(task.context, node)
        iscsi_deploy.check_image_size(task)

        deploy_ramdisk_opts = iscsi_deploy.build_deploy_ramdisk_options(node)
        agent_opts = deploy_utils.build_agent_options(node)
        deploy_ramdisk_opts.update(agent_opts)
        deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task)
        deploy_ramdisk_opts['BOOTIF'] = deploy_nic_mac

        _reboot_into_deploy_iso(task, deploy_ramdisk_opts)

        return states.DEPLOYWAIT
Пример #6
0
    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.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
            or the wrong driver info is specified for power management.
        :raises: StorageError If the storage driver is unable to attach the
            configured volumes.
        :raises: other exceptions by the node's power driver if something
            wrong occurred during the power action.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        node = task.node
        deploy_utils.populate_storage_driver_internal_info(task)
        if node.provision_state in [states.ACTIVE, states.ADOPTING]:
            task.driver.boot.prepare_instance(task)
        else:
            if node.provision_state == states.DEPLOYING:
                fast_track_deploy = manager_utils.is_fast_track(task)
                if fast_track_deploy:
                    # The agent has already recently checked in and we are
                    # configured to take that as an indicator that we can
                    # skip ahead.
                    LOG.debug('The agent for node %(node)s has recently '
                              'checked in, and the node power will remain '
                              'unmodified.',
                              {'node': task.node.uuid})
                else:
                    # Adding the node to provisioning network so that the dhcp
                    # options get added for the provisioning port.
                    manager_utils.node_power_action(task, states.POWER_OFF)
                # NOTE(vdrok): in case of rebuild, we have tenant network
                # already configured, unbind tenant ports if present
                if task.driver.storage.should_write_image(task):
                    if not fast_track_deploy:
                        power_state_to_restore = (
                            manager_utils.power_on_node_if_needed(task))
                    task.driver.network.unconfigure_tenant_networks(task)
                    task.driver.network.add_provisioning_network(task)
                    if not fast_track_deploy:
                        manager_utils.restore_power_state_if_needed(
                            task, power_state_to_restore)
                task.driver.storage.attach_volumes(task)
                if (not task.driver.storage.should_write_image(task)
                    or fast_track_deploy):
                    # We have nothing else to do as this is handled in the
                    # backend storage system, and we can return to the caller
                    # as we do not need to boot the agent to deploy.
                    # Alternatively, we are in a fast track deployment
                    # and have nothing else to do.
                    return

            deploy_opts = deploy_utils.build_agent_options(node)
            task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #7
0
def _cleaning_reboot(task):
    """Reboots a node out of band after a clean step that requires it.

    If an agent clean step has 'reboot_requested': True, reboots the
    node when the step is completed. Will put the node in CLEANFAIL
    if the node cannot be rebooted.

    :param task: a TaskManager instance
    """
    try:
        # NOTE(fellypefca): Call prepare_ramdisk on ensure that the
        # baremetal node boots back into the ramdisk after reboot.
        deploy_opts = deploy_utils.build_agent_options(task.node)
        task.driver.boot.prepare_ramdisk(task, deploy_opts)
        manager_utils.node_power_action(task, states.REBOOT)
    except Exception as e:
        msg = (_('Reboot requested by clean step %(step)s failed for '
                 'node %(node)s: %(err)s') %
               {'step': task.node.clean_step,
                'node': task.node.uuid,
                'err': e})
        LOG.error(msg, exc_info=not isinstance(e, exception.IronicException))
        # do not set cleaning_reboot if we didn't reboot
        manager_utils.cleaning_error_handler(task, msg)
        return

    # Signify that we've rebooted
    driver_internal_info = task.node.driver_internal_info
    driver_internal_info['cleaning_reboot'] = True
    task.node.driver_internal_info = driver_internal_info
    task.node.save()
Пример #8
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
             or the wrong driver info is specified for power management.
        :raises: other exceptions by the node's power driver if something
             wrong occurred during the power action.
        :raises: exception.ImageRefValidationFailed if image_source is not
            Glance href and is not HTTP(S) URL.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        # Nodes deployed by AgentDeploy always boot from disk now. So there
        # is nothing to be done in prepare() when it's called during
        # take over.
        node = task.node
        if node.provision_state == states.DEPLOYING:
            # Adding the node to provisioning network so that the dhcp
            # options get added for the provisioning port.
            manager_utils.node_power_action(task, states.POWER_OFF)
            task.driver.network.add_provisioning_network(task)
        if node.provision_state not in [states.ACTIVE, states.ADOPTING]:
            node.instance_info = build_instance_info_for_deploy(task)
            node.save()
            if CONF.agent.manage_agent_boot:
                deploy_opts = deploy_utils.build_agent_options(node)
                task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #9
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
             or the wrong driver info is specified for power management.
        :raises: other exceptions by the node's power driver if something
             wrong occurred during the power action.
        :raises: exception.ImageRefValidationFailed if image_source is not
            Glance href and is not HTTP(S) URL.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        node = task.node
        if node.provision_state == states.DEPLOYING:
            # Adding the node to provisioning network so that the dhcp
            # options get added for the provisioning port.
            manager_utils.node_power_action(task, states.POWER_OFF)
            # NOTE(vdrok): in case of rebuild, we have tenant network already
            # configured, unbind tenant ports if present
            task.driver.network.unconfigure_tenant_networks(task)
            task.driver.network.add_provisioning_network(task)
        if node.provision_state == states.ACTIVE:
            task.driver.boot.prepare_instance(task)
        elif node.provision_state != states.ADOPTING:
            node.instance_info = deploy_utils.build_instance_info_for_deploy(
                task)
            node.save()
            if CONF.agent.manage_agent_boot:
                deploy_opts = deploy_utils.build_agent_options(node)
                task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #10
0
    def update_firmware(self, task, firmware_images):
        """Updates the firmware on the node.

        :param task: a TaskManager instance containing the node to act on.
        :param firmware_images: A list of firmware images are to apply.
        :returns: None if it is completed.
        :raises: RedfishError on an error from the Sushy library.
        """
        node = task.node

        LOG.debug(
            'Updating firmware on node %(node_uuid)s with firmware '
            '%(firmware_images)s', {
                'node_uuid': node.uuid,
                'firmware_images': firmware_images
            })

        update_service = redfish_utils.get_update_service(task.node)

        # The cleaning infrastructure has an exclusive lock on the node, so
        # there is no need to get one here.
        self._apply_firmware_update(node, update_service, firmware_images)

        # set_async_step_flags calls node.save()
        deploy_utils.set_async_step_flags(node,
                                          reboot=True,
                                          skip_current_step=True,
                                          polling=True)

        deploy_opts = deploy_utils.build_agent_options(task.node)
        task.driver.boot.prepare_ramdisk(task, deploy_opts)
        manager_utils.node_power_action(task, states.REBOOT)

        return deploy_utils.get_async_step_return_state(task.node)
Пример #11
0
    def rescue(self, task):
        """Boot a rescue ramdisk on the node.

        :param task: a TaskManager instance.
        :raises: NetworkError if the tenant ports cannot be removed.
        :raises: InvalidParameterValue when the wrong power state is specified
             or the wrong driver info is specified for power management.
        :raises: other exceptions by the node's power driver if something
             wrong occurred during the power action.
        :raises: any boot interface's prepare_ramdisk exceptions.
        :returns: Returns states.RESCUEWAIT
        """
        manager_utils.node_power_action(task, states.POWER_OFF)
        # NOTE(TheJulia): Revealing that the power is off at any time can
        # cause external power sync to decide that the node must be off.
        # This may result in a post-rescued instance being turned off
        # unexpectedly after rescue has started.
        # TODO(TheJulia): Once we have power/state callbacks to nova,
        # the reset of the power_state can be removed.
        task.node.power_state = states.POWER_ON
        task.node.save()

        task.driver.boot.clean_up_instance(task)
        with manager_utils.power_state_for_network_configuration(task):
            task.driver.network.unconfigure_tenant_networks(task)
            task.driver.network.add_rescuing_network(task)
        if CONF.agent.manage_agent_boot:
            ramdisk_opts = deploy_utils.build_agent_options(task.node)
            # prepare_ramdisk will set the boot device
            task.driver.boot.prepare_ramdisk(task, ramdisk_opts)
        manager_utils.node_power_action(task, states.POWER_ON)

        return states.RESCUEWAIT
Пример #12
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
             or the wrong driver info is specified for power management.
        :raises: other exceptions by the node's power driver if something
             wrong occurred during the power action.
        :raises: exception.ImageRefValidationFailed if image_source is not
            Glance href and is not HTTP(S) URL.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        # Nodes deployed by AgentDeploy always boot from disk now. So there
        # is nothing to be done in prepare() when it's called during
        # take over.
        node = task.node
        if node.provision_state == states.DEPLOYING:
            # Adding the node to provisioning network so that the dhcp
            # options get added for the provisioning port.
            manager_utils.node_power_action(task, states.POWER_OFF)
            task.driver.network.add_provisioning_network(task)
        if node.provision_state != states.ACTIVE:
            node.instance_info = build_instance_info_for_deploy(task)
            node.save()
            if CONF.agent.manage_agent_boot:
                deploy_opts = deploy_utils.build_agent_options(node)
                task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #13
0
    def prepare_cleaning(self, task):
        """Boot into the ramdisk to prepare for cleaning.

        :param task: a TaskManager object containing the node
        :raises NodeCleaningFailure: if the previous cleaning ports cannot
                be removed or if new cleaning ports cannot be created
        :returns: None or states.CLEANWAIT for async prepare.
        """
        node = task.node
        conductor_steps.set_node_cleaning_steps(task)
        if not node.driver_internal_info['clean_steps']:
            # no clean steps configured, nothing to do.
            return
        fast_track = manager_utils.is_fast_track(task)
        power_state_to_restore = None
        if not fast_track:
            power_state_to_restore = manager_utils.power_on_node_if_needed(
                task)
        task.driver.network.add_cleaning_network(task)
        manager_utils.restore_power_state_if_needed(task,
                                                    power_state_to_restore)
        boot_opt = deploy_utils.build_agent_options(node)
        task.driver.boot.prepare_ramdisk(task, boot_opt)
        if not fast_track:
            manager_utils.node_power_action(task, states.REBOOT)
        return states.CLEANWAIT
Пример #14
0
    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.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
             or the wrong driver info is specified for power management.
        :raises: other exceptions by the node's power driver if something
             wrong occurred during the power action.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        node = task.node
        if node.provision_state in [states.ACTIVE, states.ADOPTING]:
            task.driver.boot.prepare_instance(task)
        else:
            if node.provision_state == states.DEPLOYING:
                # Adding the node to provisioning network so that the dhcp
                # options get added for the provisioning port.
                manager_utils.node_power_action(task, states.POWER_OFF)
                task.driver.network.add_provisioning_network(task)

            deploy_opts = deploy_utils.build_agent_options(node)
            task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #15
0
 def prepare_cleaning(self, task):
     deploy_utils.agent_add_clean_params(task)
     ramdisk_opts = deploy_utils.build_agent_options(task.node)
     ramdisk_opts.update(
         iscsi_deploy.build_deploy_ramdisk_options(task.node))
     task.driver.boot.prepare_ramdisk(task, ramdisk_opts)
     manager_utils.node_power_action(task, states.REBOOT)
     return states.CLEANWAIT
Пример #16
0
    def _execute_pre_boot_bios_step(self, task, step, data=None):
        """Perform operations required prior to the reboot.

        Depending on the step, it executes the operations required
        and moves the node to CLEANWAIT or DEPLOYWAIT state prior to reboot
        based on the operation being performed.
        :param task: a task from TaskManager.
        :param step: name of the clean step to be performed
        :param data: if the clean step is apply_configuration it holds
                     the settings data.
        :raises: NodeCleaningFailure, on failure to execute of clean step.
        :raises: InstanceDeployFailure, on failure to execute of deploy step.
        """
        node = task.node

        if step not in ('apply_configuration', 'factory_reset'):
            errmsg = (_('Could not find the step %(step)s for the '
                        'node %(node)s.') % {
                            'step': step,
                            'node': node.uuid
                        })
            if node.clean_step:
                raise exception.NodeCleaningFailure(errmsg)
            raise exception.InstanceDeployFailure(reason=errmsg)

        try:
            ilo_object = ilo_common.get_ilo_object(node)
            ilo_object.set_bios_settings(data) if step == (
                'apply_configuration') else ilo_object.reset_bios_to_default()
        except (exception.MissingParameterValue,
                exception.InvalidParameterValue, ilo_error.IloError,
                ilo_error.IloCommandNotSupportedError) as ir_exception:
            errmsg = (_('Step %(step)s failed '
                        'on the node %(node)s with error: %(err)s') % {
                            'step': step,
                            'node': node.uuid,
                            'err': ir_exception
                        })
            if node.clean_step:
                raise exception.NodeCleaningFailure(errmsg)
            raise exception.InstanceDeployFailure(reason=errmsg)

        deploy_opts = deploy_utils.build_agent_options(node)
        task.driver.boot.prepare_ramdisk(task, deploy_opts)
        manager_utils.node_power_action(task, states.REBOOT)

        deploy_utils.set_async_step_flags(node,
                                          reboot=True,
                                          skip_current_step=False)
        driver_internal_info = node.driver_internal_info
        if step == 'apply_configuration':
            driver_internal_info['apply_bios'] = True
        else:
            driver_internal_info['reset_bios'] = True

        node.driver_internal_info = driver_internal_info
        node.save()
        return deploy_utils.get_async_step_return_state(node)
Пример #17
0
def _prepare_agent_vmedia_boot(task):
    """Ejects virtual media devices and prepares for vmedia boot."""
    # Eject all virtual media devices, as we are going to use them
    # during deploy.
    ilo_common.eject_vmedia_devices(task)

    deploy_ramdisk_opts = deploy_utils.build_agent_options(task.node)
    deploy_iso = task.node.driver_info['ilo_deploy_iso']
    _reboot_into(task, deploy_iso, deploy_ramdisk_opts)
Пример #18
0
def _prepare_agent_vmedia_boot(task):
    """Ejects virtual media devices and prepares for vmedia boot."""
    # Eject all virtual media devices, as we are going to use them
    # during deploy.
    ilo_common.eject_vmedia_devices(task)

    deploy_ramdisk_opts = deploy_utils.build_agent_options(task.node)
    deploy_iso = task.node.driver_info['ilo_deploy_iso']
    _reboot_into(task, deploy_iso, deploy_ramdisk_opts)
Пример #19
0
def _prepare_agent_vmedia_boot(task):
    """Ejects virtual media devices and prepares for vmedia boot."""
    # Eject all virtual media devices, as we are going to use them
    # during deploy.
    ilo_common.eject_vmedia_devices(task)

    deploy_ramdisk_opts = deploy_utils.build_agent_options(task.node)
    deploy_iso = task.node.driver_info['ilo_deploy_iso']
    ilo_common.setup_vmedia(task, deploy_iso, deploy_ramdisk_opts)
    manager_utils.node_power_action(task, states.REBOOT)
Пример #20
0
def _prepare_agent_vmedia_boot(task):
    """Ejects virtual media devices and prepares for vmedia boot."""
    # Eject all virtual media devices, as we are going to use them
    # during deploy.
    ilo_common.eject_vmedia_devices(task)

    deploy_ramdisk_opts = deploy_utils.build_agent_options(task.node)
    deploy_iso = task.node.driver_info['ilo_deploy_iso']
    ilo_common.setup_vmedia(task, deploy_iso, deploy_ramdisk_opts)
    manager_utils.node_power_action(task, states.REBOOT)
Пример #21
0
 def _prepare_for_read_raid(self, task, raid_step):
     deploy_opts = deploy_utils.build_agent_options(task.node)
     task.driver.boot.prepare_ramdisk(task, deploy_opts)
     manager_utils.node_power_action(task, states.REBOOT)
     if raid_step == 'create_raid':
         self._set_driver_internal_true_value(
             task, 'ilo_raid_create_in_progress')
     else:
         self._set_driver_internal_true_value(
             task, 'ilo_raid_delete_in_progress')
     self._set_driver_internal_true_value(task, 'cleaning_reboot')
     self._set_driver_internal_false_value(task, 'skip_current_clean_step')
Пример #22
0
 def _prepare_for_read_raid(self, task, raid_step):
     deploy_opts = deploy_utils.build_agent_options(task.node)
     task.driver.boot.prepare_ramdisk(task, deploy_opts)
     manager_utils.node_power_action(task, states.REBOOT)
     if raid_step == 'create_raid':
         self._set_driver_internal_true_value(
             task, 'ilo_raid_create_in_progress')
     else:
         self._set_driver_internal_true_value(
             task, 'ilo_raid_delete_in_progress')
     self._set_driver_internal_true_value(task, 'cleaning_reboot')
     self._set_driver_internal_false_value(task, 'skip_current_clean_step')
Пример #23
0
 def prepare(self, task):
     """Prepare the deployment environment for this node."""
     node = task.node
     # TODO(pas-ha) investigate takeover scenario
     if node.provision_state == states.DEPLOYING:
         # adding network-driver dependent provisioning ports
         manager_utils.node_power_action(task, states.POWER_OFF)
         task.driver.network.add_provisioning_network(task)
     if node.provision_state not in [states.ACTIVE, states.ADOPTING]:
         node.instance_info = build_instance_info_for_deploy(task)
         node.save()
         boot_opt = deploy_utils.build_agent_options(node)
         task.driver.boot.prepare_ramdisk(task, boot_opt)
Пример #24
0
 def prepare(self, task):
     """Prepare the deployment environment for this node."""
     node = task.node
     # TODO(pas-ha) investigate takeover scenario
     if node.provision_state == states.DEPLOYING:
         # adding network-driver dependent provisioning ports
         manager_utils.node_power_action(task, states.POWER_OFF)
         task.driver.network.add_provisioning_network(task)
     if node.provision_state not in [states.ACTIVE, states.ADOPTING]:
         node.instance_info = build_instance_info_for_deploy(task)
         node.save()
         boot_opt = deploy_utils.build_agent_options(node)
         task.driver.boot.prepare_ramdisk(task, boot_opt)
Пример #25
0
    def post_reset(self, task):
        """Perform post reset action to apply the BIOS factory reset.

        Extension point to allow vendor implementations to extend this class
        and override this method to perform a custom action to apply the BIOS
        factory reset to the Redfish service. The default implementation
        performs a reboot.

        :param task: a TaskManager instance containing the node to act on.
        """
        deploy_opts = deploy_utils.build_agent_options(task.node)
        task.driver.boot.prepare_ramdisk(task, deploy_opts)
        self._reboot(task)
Пример #26
0
    def post_configuration(self, task, settings):
        """Perform post configuration action to store the BIOS settings.

        Extension point to allow vendor implementations to extend this class
        and override this method to perform a custom action to write the BIOS
        settings to the Redfish service. The default implementation performs
        a reboot.

        :param task: a TaskManager instance containing the node to act on.
        :param settings: a list of BIOS settings to be updated.
        """
        deploy_opts = deploy_utils.build_agent_options(task.node)
        task.driver.boot.prepare_ramdisk(task, deploy_opts)
        self._reboot(task)
Пример #27
0
    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
        if node.provision_state == states.ACTIVE:
            task.driver.boot.prepare_instance(task)
        else:
            deploy_opts = deploy_utils.build_agent_options(node)
            task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #28
0
    def reset_ilo(self, task):
        """Resets the iLO.

        :param task: a task from TaskManager.
        :raises: NodeCleaningFailure, on failure to execute of clean step.
        :raises: InstanceDeployFailure, on failure to execute of deploy step.
        """
        node = task.node
        _execute_ilo_step(node, 'reset_ilo')

        # Reset iLO ejects virtual media
        # Re-create the environment for agent boot, if required
        task.driver.boot.clean_up_ramdisk(task)
        deploy_opts = deploy_utils.build_agent_options(node)
        task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #29
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        """
        # Nodes deployed by AgentDeploy always boot from disk now. So there
        # is nothing to be done in prepare() when it's called during
        # take over.
        node = task.node
        if node.provision_state != states.ACTIVE:
            node.instance_info = build_instance_info_for_deploy(task)
            node.save()
            if CONF.agent.manage_agent_boot:
                deploy_opts = deploy_utils.build_agent_options(node)
                task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #30
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        """
        # Nodes deployed by AgentDeploy always boot from disk now. So there
        # is nothing to be done in prepare() when it's called during
        # take over.
        node = task.node
        if node.provision_state != states.ACTIVE:
            node.instance_info = build_instance_info_for_deploy(task)
            node.save()
            if CONF.agent.manage_agent_boot:
                deploy_opts = deploy_utils.build_agent_options(node)
                task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #31
0
    def deploy(self, task):
        """Perform a deployment to a node.

        Prepares the options for the agent ramdisk and sets the node to boot
        from virtual media cdrom.

        :param task: a TaskManager instance.
        :returns: states.DEPLOYWAIT
        :raises: ImageCreationFailed, if it failed while creating the floppy
            image.
        :raises: IRMCOperationError, if some operation on iRMC fails.
        """
        deploy_ramdisk_opts = deploy_utils.build_agent_options(task.node)
        _reboot_into_deploy_iso(task, deploy_ramdisk_opts)

        return states.DEPLOYWAIT
Пример #32
0
    def deploy(self, task):
        """Perform a deployment to a node.

        Prepares the options for the agent ramdisk and sets the node to boot
        from virtual media cdrom.

        :param task: a TaskManager instance.
        :returns: states.DEPLOYWAIT
        :raises: ImageCreationFailed, if it failed while creating the floppy
            image.
        :raises: IRMCOperationError, if some operation on iRMC fails.
        """
        deploy_ramdisk_opts = deploy_utils.build_agent_options(task.node)
        _reboot_into_deploy_iso(task, deploy_ramdisk_opts)

        return states.DEPLOYWAIT
Пример #33
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
            or the wrong driver info is specified for power management.
        :raises: StorageError If the storage driver is unable to attach the
            configured volumes.
        :raises: other exceptions by the node's power driver if something
            wrong occurred during the power action.
        :raises: exception.ImageRefValidationFailed if image_source is not
            Glance href and is not HTTP(S) URL.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        node = task.node
        deploy_utils.populate_storage_driver_internal_info(task)
        if node.provision_state == states.DEPLOYING:
            # Adding the node to provisioning network so that the dhcp
            # options get added for the provisioning port.
            manager_utils.node_power_action(task, states.POWER_OFF)
            if task.driver.storage.should_write_image(task):
                # NOTE(vdrok): in case of rebuild, we have tenant network
                # already configured, unbind tenant ports if present
                task.driver.network.unconfigure_tenant_networks(task)
                task.driver.network.add_provisioning_network(task)
            # Signal to storage driver to attach volumes
            task.driver.storage.attach_volumes(task)
            if not task.driver.storage.should_write_image(task):
                # We have nothing else to do as this is handled in the
                # backend storage system, and we can return to the caller
                # as we do not need to boot the agent to deploy.
                return
        if node.provision_state in (states.ACTIVE, states.UNRESCUING):
            # Call is due to conductor takeover
            task.driver.boot.prepare_instance(task)
        elif node.provision_state != states.ADOPTING:
            if node.provision_state not in (states.RESCUING, states.RESCUEWAIT,
                                            states.RESCUE, states.RESCUEFAIL):
                node.instance_info = (
                    deploy_utils.build_instance_info_for_deploy(task))
                node.save()
            if CONF.agent.manage_agent_boot:
                deploy_opts = deploy_utils.build_agent_options(node)
                task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #34
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
            or the wrong driver info is specified for power management.
        :raises: StorageError If the storage driver is unable to attach the
            configured volumes.
        :raises: other exceptions by the node's power driver if something
            wrong occurred during the power action.
        :raises: exception.ImageRefValidationFailed if image_source is not
            Glance href and is not HTTP(S) URL.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        node = task.node
        deploy_utils.populate_storage_driver_internal_info(task)
        if node.provision_state == states.DEPLOYING:
            # Adding the node to provisioning network so that the dhcp
            # options get added for the provisioning port.
            manager_utils.node_power_action(task, states.POWER_OFF)
            if task.driver.storage.should_write_image(task):
                # NOTE(vdrok): in case of rebuild, we have tenant network
                # already configured, unbind tenant ports if present
                task.driver.network.unconfigure_tenant_networks(task)
                task.driver.network.add_provisioning_network(task)
            # Signal to storage driver to attach volumes
            task.driver.storage.attach_volumes(task)
        if node.provision_state == states.ACTIVE:
            # Call is due to conductor takeover
            task.driver.boot.prepare_instance(task)
        elif node.provision_state != states.ADOPTING:

            if task.driver.storage.should_write_image(task):
                instance_info = deploy_utils.build_instance_info_for_deploy(
                    task)
                node.instance_info = instance_info
                node.save()
            if CONF.agent.manage_agent_boot:
                if task.driver.storage.should_write_image(task):
                    deploy_opts = deploy_utils.build_agent_options(node)
                else:
                    deploy_opts = None
                task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #35
0
    def deploy(self, task):
        """Start deployment of the task's node.

        Fetches the instance image, prepares the options for the deployment
        ramdisk, sets the node to boot from virtual media cdrom, and reboots
        the given node.

        :param task: a TaskManager instance containing the node to act on.
        :returns: deploy state DEPLOYWAIT.
        :raises: InstanceDeployFailure, if image size if greater than root
            partition.
        :raises: ImageCreationFailed, if it failed while creating the floppy
            image.
        :raises: IloOperationError, if some operation on iLO fails.
        """
        node = task.node

        # Clear ilo_boot_iso if it's a glance image to force recreate
        # another one again (or use existing one in glance).
        # This is mainly for rebuild scenario.
        if service_utils.is_glance_image(
                node.instance_info.get('image_source')):
            instance_info = node.instance_info
            instance_info.pop('ilo_boot_iso', None)
            node.instance_info = instance_info
            node.save()

        # Eject all virtual media devices, as we are going to use them
        # during deploy.
        ilo_common.eject_vmedia_devices(task)

        iscsi_deploy.cache_instance_image(task.context, node)
        iscsi_deploy.check_image_size(task)

        deploy_ramdisk_opts = iscsi_deploy.build_deploy_ramdisk_options(node)
        agent_opts = deploy_utils.build_agent_options(node)
        deploy_ramdisk_opts.update(agent_opts)
        deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task)
        deploy_ramdisk_opts['BOOTIF'] = deploy_nic_mac
        deploy_iso = node.driver_info['ilo_deploy_iso']

        _reboot_into(task, deploy_iso, deploy_ramdisk_opts)

        return states.DEPLOYWAIT
Пример #36
0
def _post_step_reboot(task, step_type):
    """Reboots a node out of band after a clean/deploy step that requires it.

    If an agent step has 'reboot_requested': True, reboots the node when
    the step is completed. Will put the node in CLEANFAIL/DEPLOYFAIL if
    the node cannot be rebooted.

    :param task: a TaskManager instance
    :param step_type: 'clean' or 'deploy'
    """
    current_step = (task.node.clean_step if step_type == 'clean'
                    else task.node.deploy_step)
    try:
        # NOTE(fellypefca): Call prepare_ramdisk on ensure that the
        # baremetal node boots back into the ramdisk after reboot.
        deploy_opts = deploy_utils.build_agent_options(task.node)
        task.driver.boot.prepare_ramdisk(task, deploy_opts)
        manager_utils.node_power_action(task, states.REBOOT)
    except Exception as e:
        msg = (_('Reboot requested by %(type)s step %(step)s failed for '
                 'node %(node)s: %(err)s') %
               {'step': current_step,
                'node': task.node.uuid,
                'err': e,
                'type': step_type})
        LOG.error(msg, exc_info=not isinstance(e, exception.IronicException))
        # do not set cleaning_reboot if we didn't reboot
        if step_type == 'clean':
            manager_utils.cleaning_error_handler(task, msg)
        else:
            manager_utils.deploying_error_handler(task, msg)
        return

    # Signify that we've rebooted
    driver_internal_info = task.node.driver_internal_info
    field = ('cleaning_reboot' if step_type == 'clean'
             else 'deployment_reboot')
    driver_internal_info[field] = True
    if not driver_internal_info.get('agent_secret_token_pregenerated', False):
        # Wipes out the existing recorded token because the machine will
        # need to re-establish the token.
        driver_internal_info.pop('agent_secret_token', None)
    task.node.driver_internal_info = driver_internal_info
    task.node.save()
Пример #37
0
    def deploy(self, task):
        """Start deployment of the task's node.

        Fetches the instance image, prepares the options for the deployment
        ramdisk, sets the node to boot from virtual media cdrom, and reboots
        the given node.

        :param task: a TaskManager instance containing the node to act on.
        :returns: deploy state DEPLOYWAIT.
        :raises: InstanceDeployFailure, if image size if greater than root
            partition.
        :raises: ImageCreationFailed, if it failed while creating the floppy
            image.
        :raises: IloOperationError, if some operation on iLO fails.
        """
        node = task.node

        # Clear ilo_boot_iso if it's a glance image to force recreate
        # another one again (or use existing one in glance).
        # This is mainly for rebuild scenario.
        if service_utils.is_glance_image(
                node.instance_info.get('image_source')):
            instance_info = node.instance_info
            instance_info.pop('ilo_boot_iso', None)
            node.instance_info = instance_info
            node.save()

        # Eject all virtual media devices, as we are going to use them
        # during deploy.
        ilo_common.eject_vmedia_devices(task)

        iscsi_deploy.cache_instance_image(task.context, node)
        iscsi_deploy.check_image_size(task)

        deploy_ramdisk_opts = iscsi_deploy.build_deploy_ramdisk_options(node)
        agent_opts = deploy_utils.build_agent_options(node)
        deploy_ramdisk_opts.update(agent_opts)
        deploy_nic_mac = deploy_utils.get_single_nic_with_vif_port_id(task)
        deploy_ramdisk_opts['BOOTIF'] = deploy_nic_mac
        deploy_iso = node.driver_info['ilo_deploy_iso']

        _reboot_into(task, deploy_iso, deploy_ramdisk_opts)

        return states.DEPLOYWAIT
Пример #38
0
    def prepare_cleaning(self, task):
        """Boot into the ramdisk to prepare for cleaning.

        :param task: a TaskManager object containing the node
        :raises NodeCleaningFailure: if the previous cleaning ports cannot
                be removed or if new cleaning ports cannot be created
        :returns: None or states.CLEANWAIT for async prepare.
        """
        node = task.node
        conductor_steps.set_node_cleaning_steps(task)
        if not node.driver_internal_info['clean_steps']:
            # no clean steps configured, nothing to do.
            return
        power_state_to_restore = manager_utils.power_on_node_if_needed(task)
        task.driver.network.add_cleaning_network(task)
        manager_utils.restore_power_state_if_needed(
            task, power_state_to_restore)
        boot_opt = deploy_utils.build_agent_options(node)
        task.driver.boot.prepare_ramdisk(task, boot_opt)
        manager_utils.node_power_action(task, states.REBOOT)
        return states.CLEANWAIT
Пример #39
0
    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
        if node.provision_state == states.ACTIVE:
            task.driver.boot.prepare_instance(task)
        else:
            deploy_opts = build_deploy_ramdisk_options(node)

            # NOTE(lucasagomes): We are going to extend the normal PXE config
            # to also contain the agent options so it could be used for
            # both the DIB ramdisk and the IPA ramdisk
            agent_opts = deploy_utils.build_agent_options(node)
            deploy_opts.update(agent_opts)

            task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #40
0
    def prepare_cleaning(self, task):
        """Boot into the ramdisk to prepare for cleaning.

        :param task: a TaskManager object containing the node
        :raises NodeCleaningFailure: if the previous cleaning ports cannot
                be removed or if new cleaning ports cannot be created
        :returns: None or states.CLEANWAIT for async prepare.
        """
        node = task.node
        use_callback = CONF.ansible.use_ramdisk_callback
        if use_callback:
            manager_utils.set_node_cleaning_steps(task)
            if not node.driver_internal_info['clean_steps']:
                # no clean steps configured, nothing to do.
                return
        task.driver.network.add_cleaning_network(task)
        boot_opt = deploy_utils.build_agent_options(node)
        task.driver.boot.prepare_ramdisk(task, boot_opt)
        manager_utils.node_power_action(task, states.REBOOT)
        if use_callback:
            return states.CLEANWAIT

        ip_addr = _get_node_ip(task)
        LOG.debug('IP of node %(node)s is %(ip)s', {
            'node': node.uuid,
            'ip': ip_addr
        })
        driver_internal_info = node.driver_internal_info
        driver_internal_info['ansible_cleaning_ip'] = ip_addr
        node.driver_internal_info = driver_internal_info
        node.save()
        playbook, user, key = _parse_ansible_driver_info(task.node,
                                                         action='clean')
        node_list = [(node.uuid, ip_addr, user, node.extra)]
        extra_vars = _prepare_extra_vars(node_list)

        LOG.debug('Waiting ramdisk on node %s for cleaning', node.uuid)
        _run_playbook(playbook, extra_vars, key, tags=['wait'])
        LOG.info(_LI('Node %s is ready for cleaning'), node.uuid)
Пример #41
0
    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
        if node.provision_state == states.ACTIVE:
            task.driver.boot.prepare_instance(task)
        else:
            deploy_opts = build_deploy_ramdisk_options(node)

            # NOTE(lucasagomes): We are going to extend the normal PXE config
            # to also contain the agent options so it could be used for
            # both the DIB ramdisk and the IPA ramdisk
            agent_opts = deploy_utils.build_agent_options(node)
            deploy_opts.update(agent_opts)

            task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #42
0
    def rescue(self, task):
        """Boot a rescue ramdisk on the node.

        :param task: a TaskManager instance.
        :raises: NetworkError if the tenant ports cannot be removed.
        :raises: InvalidParameterValue when the wrong power state is specified
             or the wrong driver info is specified for power management.
        :raises: other exceptions by the node's power driver if something
             wrong occurred during the power action.
        :raises: any boot interface's prepare_ramdisk exceptions.
        :returns: Returns states.RESCUEWAIT
        """
        manager_utils.node_power_action(task, states.POWER_OFF)
        task.driver.boot.clean_up_instance(task)
        task.driver.network.unconfigure_tenant_networks(task)
        task.driver.network.add_rescuing_network(task)
        if CONF.agent.manage_agent_boot:
            ramdisk_opts = deploy_utils.build_agent_options(task.node)
            # prepare_ramdisk will set the boot device
            task.driver.boot.prepare_ramdisk(task, ramdisk_opts)
        manager_utils.node_power_action(task, states.POWER_ON)

        return states.RESCUEWAIT
Пример #43
0
    def prepare_cleaning(self, task):
        """Boot into the ramdisk to prepare for cleaning.

        :param task: a TaskManager object containing the node
        :raises NodeCleaningFailure: if the previous cleaning ports cannot
                be removed or if new cleaning ports cannot be created
        :returns: None or states.CLEANWAIT for async prepare.
        """
        node = task.node
        use_callback = CONF.ansible.use_ramdisk_callback
        if use_callback:
            manager_utils.set_node_cleaning_steps(task)
            if not node.driver_internal_info['clean_steps']:
                # no clean steps configured, nothing to do.
                return
        task.driver.network.add_cleaning_network(task)
        boot_opt = deploy_utils.build_agent_options(node)
        task.driver.boot.prepare_ramdisk(task, boot_opt)
        manager_utils.node_power_action(task, states.REBOOT)
        if use_callback:
            return states.CLEANWAIT

        ip_addr = _get_node_ip_dhcp(task)
        LOG.debug('IP of node %(node)s is %(ip)s',
                  {'node': node.uuid, 'ip': ip_addr})
        driver_internal_info = node.driver_internal_info
        driver_internal_info['ansible_cleaning_ip'] = ip_addr
        node.driver_internal_info = driver_internal_info
        node.save()
        playbook, user, key = _parse_ansible_driver_info(
            task.node, action='clean')
        node_list = [(node.uuid, ip_addr, user, node.extra)]
        extra_vars = _prepare_extra_vars(node_list)

        LOG.debug('Waiting ramdisk on node %s for cleaning', node.uuid)
        _run_playbook(playbook, extra_vars, key, tags=['wait'])
        LOG.info('Node %s is ready for cleaning', node.uuid)
Пример #44
0
    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.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
            or the wrong driver info is specified for power management.
        :raises: StorageError If the storage driver is unable to attach the
            configured volumes.
        :raises: other exceptions by the node's power driver if something
            wrong occurred during the power action.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        node = task.node
        deploy_utils.populate_storage_driver_internal_info(task)
        if node.provision_state in [states.ACTIVE, states.ADOPTING]:
            task.driver.boot.prepare_instance(task)
        else:
            if node.provision_state == states.DEPLOYING:
                # Adding the node to provisioning network so that the dhcp
                # options get added for the provisioning port.
                manager_utils.node_power_action(task, states.POWER_OFF)
                # NOTE(vdrok): in case of rebuild, we have tenant network
                # already configured, unbind tenant ports if present
                if task.driver.storage.should_write_image(task):
                    task.driver.network.unconfigure_tenant_networks(task)
                    task.driver.network.add_provisioning_network(task)
                task.driver.storage.attach_volumes(task)

            deploy_opts = deploy_utils.build_agent_options(node)
            task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #45
0
    def update_firmware(self, task, **kwargs):
        """Updates the firmware.

        :param task: a TaskManager object.
        :raises: InvalidParameterValue if update firmware mode is not 'ilo'.
                 Even applicable for invalid input cases.
        :raises: NodeCleaningFailure, on failure to execute of clean step.
        :raises: InstanceDeployFailure, on failure to execute of deploy step.
        """
        node = task.node
        fw_location_objs_n_components = []
        firmware_images = kwargs['firmware_images']
        # Note(deray): Processing of firmware images happens here. As part
        # of processing checksum validation is also done for the firmware file.
        # Processing of firmware file essentially means downloading the file
        # on the conductor, validating the checksum of the downloaded content,
        # extracting the raw firmware file from its compact format, if it is,
        # and hosting the file on a web server or a swift store based on the
        # need of the baremetal server iLO firmware update method.
        try:
            for firmware_image_info in firmware_images:
                url, checksum, component = (
                    firmware_processor.get_and_validate_firmware_image_info(
                        firmware_image_info, kwargs['firmware_update_mode']))
                LOG.debug("Processing of firmware file: %(firmware_file)s on "
                          "node: %(node)s ... in progress",
                          {'firmware_file': url, 'node': node.uuid})

                fw_processor = firmware_processor.FirmwareProcessor(url)
                fw_location_obj = fw_processor.process_fw_on(node, checksum)
                fw_location_objs_n_components.append(
                    (fw_location_obj, component))

                LOG.debug("Processing of firmware file: %(firmware_file)s on "
                          "node: %(node)s ... done",
                          {'firmware_file': url, 'node': node.uuid})
        except exception.IronicException as ilo_exc:
            # delete all the files extracted so far from the extracted list
            # and re-raise the exception
            for fw_loc_obj_n_comp_tup in fw_location_objs_n_components:
                fw_loc_obj_n_comp_tup[0].remove()
            LOG.error("Processing of firmware image: %(firmware_image)s "
                      "on node: %(node)s ... failed",
                      {'firmware_image': firmware_image_info,
                       'node': node.uuid})
            if node.clean_step:
                raise exception.NodeCleaningFailure(node=node.uuid,
                                                    reason=ilo_exc)
            raise exception.InstanceDeployFailure(reason=ilo_exc)

        # Updating of firmware images happen here.
        try:
            for fw_location_obj, component in fw_location_objs_n_components:
                fw_location = fw_location_obj.fw_image_location
                LOG.debug("Firmware update for %(firmware_file)s on "
                          "node: %(node)s ... in progress",
                          {'firmware_file': fw_location, 'node': node.uuid})

                _execute_ilo_step(
                    node, 'update_firmware', fw_location, component)

                LOG.debug("Firmware update for %(firmware_file)s on "
                          "node: %(node)s ... done",
                          {'firmware_file': fw_location, 'node': node.uuid})
        except (exception.NodeCleaningFailure,
                exception.InstanceDeployFailure):
            with excutils.save_and_reraise_exception():
                LOG.error("Firmware update for %(firmware_file)s on "
                          "node: %(node)s failed.",
                          {'firmware_file': fw_location, 'node': node.uuid})
        finally:
            for fw_loc_obj_n_comp_tup in fw_location_objs_n_components:
                fw_loc_obj_n_comp_tup[0].remove()

        # Firmware might have ejected the virtual media, if it was used.
        # Re-create the environment for agent boot, if required
        task.driver.boot.clean_up_ramdisk(task)
        deploy_opts = deploy_utils.build_agent_options(node)
        task.driver.boot.prepare_ramdisk(task, deploy_opts)

        LOG.info("All Firmware update operations completed successfully "
                 "for node: %s.", node.uuid)
Пример #46
0
    def delete_configuration(self, task):
        """Delete RAID configuration on the node.

        :param task: TaskManager object containing the node.
        :returns: states.CLEANWAIT (cleaning) or states.DEPLOYWAIT (deployment)
            if deletion is in progress asynchronously or None if it is
            complete.
        """
        node = task.node
        system = redfish_utils.get_system(node)
        vols_to_delete = []
        try:
            for storage in system.storage.get_members():
                controller = (storage.storage_controllers[0]
                              if storage.storage_controllers else None)
                controller_name = None
                if controller and controller.identifiers:
                    controller_name = controller.identifiers[0].durable_name
                for volume in storage.volumes.get_members():
                    if (volume.raid_type or volume.volume_type not in
                            [None, sushy.VOLUME_TYPE_RAW_DEVICE]):
                        vols_to_delete.append((storage.volumes, volume,
                                               controller_name))
        except sushy.exceptions.SushyError as exc:
            error_msg = _('Cannot get the list of volumes to delete for node '
                          '%(node_uuid)s. Reason: %(error)s.' %
                          {'node_uuid': node.uuid, 'error': exc})
            LOG.error(error_msg)
            raise exception.RedfishError(error=exc)

        self.pre_delete_configuration(task, vols_to_delete)

        reboot_required = False
        raid_configs = list()
        for vol_coll, volume, controller_name in vols_to_delete:
            raid_config = dict()
            apply_time = None
            apply_time_support = vol_coll.operation_apply_time_support
            if (apply_time_support
                    and apply_time_support.mapped_supported_values):
                supported_values = apply_time_support.mapped_supported_values
                if sushy.APPLY_TIME_IMMEDIATE in supported_values:
                    apply_time = sushy.APPLY_TIME_IMMEDIATE
                elif sushy.APPLY_TIME_ON_RESET in supported_values:
                    apply_time = sushy.APPLY_TIME_ON_RESET
            response = volume.delete(apply_time=apply_time)
            # only save the async tasks (task_monitors) in raid_config
            if (response is not None
                    and hasattr(response, 'task_monitor_uri')):
                raid_config['operation'] = 'delete'
                raid_config['raid_controller'] = controller_name
                raid_config['task_monitor_uri'] = response.task_monitor_uri
                reboot_required = True
                raid_configs.append(raid_config)

        driver_internal_info = node.driver_internal_info
        driver_internal_info['raid_configs'] = raid_configs
        node.driver_internal_info = driver_internal_info

        return_state = None
        deploy_utils.set_async_step_flags(
            node,
            reboot=reboot_required,
            skip_current_step=True,
            polling=True)
        if reboot_required:
            return_state = deploy_utils.get_async_step_return_state(task.node)
            deploy_opts = deploy_utils.build_agent_options(task.node)
            task.driver.boot.prepare_ramdisk(task, deploy_opts)
            manager_utils.node_power_action(task, states.REBOOT)

        return self.post_delete_configuration(
            task, raid_configs, return_state=return_state)
Пример #47
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
            or the wrong driver info is specified for power management.
        :raises: StorageError If the storage driver is unable to attach the
            configured volumes.
        :raises: other exceptions by the node's power driver if something
            wrong occurred during the power action.
        :raises: exception.ImageRefValidationFailed if image_source is not
            Glance href and is not HTTP(S) URL.
        :raises: exception.InvalidParameterValue if network validation fails.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        node = task.node
        deploy_utils.populate_storage_driver_internal_info(task)
        if node.provision_state == states.DEPLOYING:
            # Validate network interface to ensure that it supports boot
            # options configured on the node.
            try:
                task.driver.network.validate(task)
            except exception.InvalidParameterValue:
                # For 'neutron' network interface validation will fail
                # if node is using 'netboot' boot option while provisioning
                # a whole disk image. Updating 'boot_option' in node's
                # 'instance_info' to 'local for backward compatibility.
                # TODO(stendulker): Fail here once the default boot
                # option is local.
                with excutils.save_and_reraise_exception(reraise=False) as ctx:
                    instance_info = node.instance_info
                    capabilities = instance_info.get('capabilities', {})
                    if 'boot_option' not in capabilities:
                        capabilities['boot_option'] = 'local'
                        instance_info['capabilities'] = capabilities
                        node.instance_info = instance_info
                        node.save()
                        # Re-validate the network interface
                        task.driver.network.validate(task)
                    else:
                        ctx.reraise = True

            # Adding the node to provisioning network so that the dhcp
            # options get added for the provisioning port.
            manager_utils.node_power_action(task, states.POWER_OFF)
            if task.driver.storage.should_write_image(task):
                # NOTE(vdrok): in case of rebuild, we have tenant network
                # already configured, unbind tenant ports if present
                task.driver.network.unconfigure_tenant_networks(task)
                task.driver.network.add_provisioning_network(task)
            # Signal to storage driver to attach volumes
            task.driver.storage.attach_volumes(task)
            if not task.driver.storage.should_write_image(task):
                # We have nothing else to do as this is handled in the
                # backend storage system, and we can return to the caller
                # as we do not need to boot the agent to deploy.
                return
        if node.provision_state in (states.ACTIVE, states.UNRESCUING):
            # Call is due to conductor takeover
            task.driver.boot.prepare_instance(task)
        elif node.provision_state != states.ADOPTING:
            if node.provision_state not in (states.RESCUING, states.RESCUEWAIT,
                                            states.RESCUE, states.RESCUEFAIL):
                node.instance_info = (
                    deploy_utils.build_instance_info_for_deploy(task))
                node.save()
            if CONF.agent.manage_agent_boot:
                deploy_opts = deploy_utils.build_agent_options(node)
                task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #48
0
    def prepare(self, task):
        """Prepare the deployment environment for this node.

        :param task: a TaskManager instance.
        :raises: NetworkError: if the previous cleaning ports cannot be removed
            or if new cleaning ports cannot be created.
        :raises: InvalidParameterValue when the wrong power state is specified
            or the wrong driver info is specified for power management.
        :raises: StorageError If the storage driver is unable to attach the
            configured volumes.
        :raises: other exceptions by the node's power driver if something
            wrong occurred during the power action.
        :raises: exception.ImageRefValidationFailed if image_source is not
            Glance href and is not HTTP(S) URL.
        :raises: exception.InvalidParameterValue if network validation fails.
        :raises: any boot interface's prepare_ramdisk exceptions.
        """
        def _update_instance_info():
            node.instance_info = (
                deploy_utils.build_instance_info_for_deploy(task))
            node.save()

        node = task.node
        deploy_utils.populate_storage_driver_internal_info(task)
        if node.provision_state == states.DEPLOYING:
            # Validate network interface to ensure that it supports boot
            # options configured on the node.
            try:
                task.driver.network.validate(task)
            except exception.InvalidParameterValue:
                # For 'neutron' network interface validation will fail
                # if node is using 'netboot' boot option while provisioning
                # a whole disk image. Updating 'boot_option' in node's
                # 'instance_info' to 'local for backward compatibility.
                # TODO(stendulker): Fail here once the default boot
                # option is local.
                # NOTE(TheJulia): Fixing the default boot mode only
                # masks the failure as the lack of a user definition
                # can be perceived as both an invalid configuration and
                # reliance upon the default configuration. The reality
                # being that in most scenarios, users do not want network
                # booting, so the changed default should be valid.
                with excutils.save_and_reraise_exception(reraise=False) as ctx:
                    instance_info = node.instance_info
                    capabilities = utils.parse_instance_info_capabilities(node)
                    if 'boot_option' not in capabilities:
                        capabilities['boot_option'] = 'local'
                        instance_info['capabilities'] = capabilities
                        node.instance_info = instance_info
                        node.save()
                        # Re-validate the network interface
                        task.driver.network.validate(task)
                    else:
                        ctx.reraise = True
            # Determine if this is a fast track sequence
            fast_track_deploy = manager_utils.is_fast_track(task)
            if fast_track_deploy:
                # The agent has already recently checked in and we are
                # configured to take that as an indicator that we can
                # skip ahead.
                LOG.debug(
                    'The agent for node %(node)s has recently checked '
                    'in, and the node power will remain unmodified.',
                    {'node': task.node.uuid})
            else:
                # Powering off node to setup networking for port and
                # ensure that the state is reset if it is inadvertently
                # on for any unknown reason.
                manager_utils.node_power_action(task, states.POWER_OFF)
            if task.driver.storage.should_write_image(task):
                # NOTE(vdrok): in case of rebuild, we have tenant network
                # already configured, unbind tenant ports if present
                if not fast_track_deploy:
                    power_state_to_restore = (
                        manager_utils.power_on_node_if_needed(task))

                task.driver.network.unconfigure_tenant_networks(task)
                task.driver.network.add_provisioning_network(task)
                if not fast_track_deploy:
                    manager_utils.restore_power_state_if_needed(
                        task, power_state_to_restore)
                else:
                    # Fast track sequence in progress
                    _update_instance_info()
            # Signal to storage driver to attach volumes
            task.driver.storage.attach_volumes(task)
            if (not task.driver.storage.should_write_image(task)
                    or fast_track_deploy):
                # We have nothing else to do as this is handled in the
                # backend storage system, and we can return to the caller
                # as we do not need to boot the agent to deploy.
                # Alternatively, we could be in a fast track deployment
                # and again, we should have nothing to do here.
                return
        if node.provision_state in (states.ACTIVE, states.UNRESCUING):
            # Call is due to conductor takeover
            task.driver.boot.prepare_instance(task)
        elif node.provision_state != states.ADOPTING:
            if node.provision_state not in (states.RESCUING, states.RESCUEWAIT,
                                            states.RESCUE, states.RESCUEFAIL):
                _update_instance_info()
            if CONF.agent.manage_agent_boot:
                deploy_opts = deploy_utils.build_agent_options(node)
                task.driver.boot.prepare_ramdisk(task, deploy_opts)
Пример #49
0
    def erase_devices(self, task, **kwargs):
        """Erase all the drives on the node.

        This method performs out-of-band sanitize disk erase on all the
        supported physical drives in the node. This erase cannot be performed
        on logical drives.

        :param task: a TaskManager instance.
        :raises: InvalidParameterValue, if any of the arguments are invalid.
        :raises: IloError on an error from iLO.
        """
        erase_pattern = kwargs.get('erase_pattern',
                                   {'hdd': 'overwrite', 'ssd': 'block'})
        node = task.node
        self._validate_erase_pattern(erase_pattern, node)
        driver_internal_info = node.driver_internal_info
        LOG.debug("Calling out-of-band sanitize disk erase for node %(node)s",
                  {'node': node.uuid})
        try:
            ilo_object = ilo_common.get_ilo_object(node)
            disk_types = ilo_object.get_available_disk_types()
            LOG.info("Disk type detected are: %(disk_types)s. Sanitize disk "
                     "erase are now exercised for one after another disk type "
                     "for node %(node)s.",
                     {'disk_types': disk_types, 'node': node.uuid})

            if disk_types:
                # First disk-erase will execute for HDD's and after reboot only
                # try for SSD, since both share same redfish api and would be
                # overwritten.
                if not driver_internal_info.get(
                        'ilo_disk_erase_hdd_check') and ('HDD' in disk_types):
                    ilo_object.do_disk_erase('HDD', erase_pattern.get('hdd'))
                    self._set_driver_internal_value(
                        task, True, 'cleaning_reboot',
                        'ilo_disk_erase_hdd_check')
                    self._set_driver_internal_value(
                        task, False, 'skip_current_clean_step')
                    deploy_opts = deploy_utils.build_agent_options(task.node)
                    task.driver.boot.prepare_ramdisk(task, deploy_opts)
                    manager_utils.node_power_action(task, states.REBOOT)
                    return states.CLEANWAIT

                if not driver_internal_info.get(
                        'ilo_disk_erase_ssd_check') and ('SSD' in disk_types):
                    ilo_object.do_disk_erase('SSD', erase_pattern.get('ssd'))
                    self._set_driver_internal_value(
                        task, True, 'ilo_disk_erase_hdd_check',
                        'ilo_disk_erase_ssd_check', 'cleaning_reboot')
                    self._set_driver_internal_value(
                        task, False, 'skip_current_clean_step')
                    deploy_opts = deploy_utils.build_agent_options(task.node)
                    task.driver.boot.prepare_ramdisk(task, deploy_opts)
                    manager_utils.node_power_action(task, states.REBOOT)
                    return states.CLEANWAIT

                # It will wait until disk erase will complete
                if self._wait_for_disk_erase_status(task.node):
                    LOG.info("For node %(uuid)s erase_devices clean "
                             "step is done.", {'uuid': task.node.uuid})
                    self._pop_driver_internal_values(
                        task, 'ilo_disk_erase_hdd_check',
                        'ilo_disk_erase_ssd_check')
            else:
                LOG.info("No drive found to perform out-of-band sanitize "
                         "disk erase for node %(node)s", {'node': node.uuid})
        except ilo_error.IloError as ilo_exception:
            self._pop_driver_internal_values(task,
                                             'ilo_disk_erase_hdd_check',
                                             'ilo_disk_erase_ssd_check',
                                             'cleaning_reboot',
                                             'skip_current_clean_step')
            self._set_clean_failed(task, ilo_exception)