コード例 #1
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)

        manager_utils.node_power_action(task, states.REBOOT)

        return deploy_utils.get_async_step_return_state(task.node)
コード例 #2
0
ファイル: test_utils.py プロジェクト: Hellcatlk/ironic
    def test_get_update_service(self):
        redfish_utils._get_connection = mock.Mock()
        mock_update_service = mock.Mock()
        redfish_utils._get_connection.return_value = mock_update_service

        result = redfish_utils.get_update_service(self.node)

        self.assertEqual(mock_update_service, result)
コード例 #3
0
    def _check_node_firmware_update(self, task):
        """Check the progress of running firmware update on a node."""

        node = task.node

        firmware_updates = node.driver_internal_info['firmware_updates']
        current_update = firmware_updates[0]

        try:
            update_service = redfish_utils.get_update_service(node)
        except exception.RedfishConnectionError as e:
            # If the BMC firmware is being updated, the BMC will be
            # unavailable for some amount of time.
            LOG.warning(
                'Unable to communicate with firmware update service '
                'on node %(node)s. Will try again on the next poll. '
                'Error: %(error)s', {
                    'node': node.uuid,
                    'error': e
                })
            return

        wait_start_time = current_update.get('wait_start_time')
        if wait_start_time:
            wait_start = timeutils.parse_isotime(wait_start_time)

            elapsed_time = timeutils.utcnow(True) - wait_start
            if elapsed_time.seconds >= current_update['wait']:
                LOG.debug(
                    'Finished waiting after firmware update '
                    '%(firmware_image)s on node %(node)s. '
                    'Elapsed time: %(seconds)s seconds', {
                        'firmware_image': current_update['url'],
                        'node': node.uuid,
                        'seconds': elapsed_time.seconds
                    })
                current_update.pop('wait', None)
                current_update.pop('wait_start_time', None)

                task.upgrade_lock()
                self._continue_firmware_updates(task, update_service,
                                                firmware_updates)
            else:
                LOG.debug(
                    'Continuing to wait after firmware update '
                    '%(firmware_image)s on node %(node)s. '
                    'Elapsed time: %(seconds)s seconds', {
                        'firmware_image': current_update['url'],
                        'node': node.uuid,
                        'seconds': elapsed_time.seconds
                    })

            return

        try:
            task_monitor = update_service.get_task_monitor(
                current_update['task_monitor'])
        except sushy.exceptions.ResourceNotFoundError:
            # The BMC deleted the Task before we could query it
            LOG.warning(
                'Firmware update completed for node %(node)s, '
                'firmware %(firmware_image)s, but success of the '
                'update is unknown.  Assuming update was successful.', {
                    'node': node.uuid,
                    'firmware_image': current_update['url']
                })
            task.upgrade_lock()
            self._continue_firmware_updates(task, update_service,
                                            firmware_updates)
            return

        if not task_monitor.is_processing:
            # The last response does not necessarily contain a Task,
            # so get it
            sushy_task = task_monitor.get_task()

            # Only parse the messages if the BMC did not return parsed
            # messages
            messages = []
            if not sushy_task.messages[0].message:
                sushy_task.parse_messages()

            messages = [m.message for m in sushy_task.messages]

            if (sushy_task.task_state == sushy.TASK_STATE_COMPLETED
                    and sushy_task.task_status
                    in [sushy.HEALTH_OK, sushy.HEALTH_WARNING]):
                LOG.info(
                    'Firmware update succeeded for node %(node)s, '
                    'firmware %(firmware_image)s: %(messages)s', {
                        'node': node.uuid,
                        'firmware_image': current_update['url'],
                        'messages': ", ".join(messages)
                    })

                task.upgrade_lock()
                self._continue_firmware_updates(task, update_service,
                                                firmware_updates)
            else:
                error_msg = (_('Firmware update failed for node %(node)s, '
                               'firmware %(firmware_image)s. '
                               'Error: %(errors)s') % {
                                   'node': node.uuid,
                                   'firmware_image': current_update['url'],
                                   'errors': ",  ".join(messages)
                               })
                LOG.error(error_msg)

                task.upgrade_lock()
                self._clear_firmware_updates(node)
                manager_utils.cleaning_error_handler(task, error_msg)
        else:
            LOG.debug(
                'Firmware update in progress for node %(node)s, '
                'firmware %(firmware_image)s.', {
                    'node': node.uuid,
                    'firmware_image': current_update['url']
                })