Example #1
0
 def _resume_cleaning(self, task):
     raid_common.update_raid_info(task.node, self.get_logical_disks(task))
     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()
     manager_utils.notify_conductor_resume_clean(task)
Example #2
0
    def _test_update_raid_info(self, current_config, capabilities=None):
        node = self.node
        if capabilities:
            properties = node.properties
            properties['capabilities'] = capabilities
            del properties['local_gb']
            node.properties = properties
        target_raid_config = json.loads(raid_constants.RAID_CONFIG_OKAY)
        node.target_raid_config = target_raid_config
        node.save()
        raid.update_raid_info(node, current_config)
        properties = node.properties
        current = node.raid_config
        target = node.target_raid_config
        self.assertIsNotNone(current['last_updated'])
        self.assertIsInstance(current['logical_disks'][0], dict)
        if current_config['logical_disks'][0].get('is_root_volume'):
            self.assertEqual({'wwn': '600508B100'}, properties['root_device'])
            self.assertEqual(100, properties['local_gb'])
            self.assertIn('raid_level:1', properties['capabilities'])
            if capabilities:
                self.assertIn(capabilities, properties['capabilities'])
        else:
            self.assertNotIn('local_gb', properties)
            self.assertNotIn('root_device', properties)
            if capabilities:
                self.assertNotIn('raid_level:1', properties['capabilities'])

        # Verify node.target_raid_config is preserved.
        self.assertEqual(target_raid_config, target)
Example #3
0
    def _test_update_raid_info(self, current_config,
                               capabilities=None):
        node = obj_utils.create_test_node(self.context,
                                          driver='fake')
        if capabilities:
            properties = node.properties
            properties['capabilities'] = capabilities
            del properties['local_gb']
            node.properties = properties
            node.save()
        raid.update_raid_info(node, current_config)
        properties = node.properties
        current = node.raid_config
        target = node.target_raid_config
        self.assertIsNotNone(current['last_updated'])
        self.assertIsInstance(current['logical_disks'][0], dict)
        if current_config['logical_disks'][0].get('is_root_volume'):
            self.assertEqual({'wwn': '600508B100'},
                             properties['root_device'])
            self.assertEqual(100, properties['local_gb'])
            self.assertIn('raid_level:1', properties['capabilities'])
            if capabilities:
                self.assertIn(capabilities, properties['capabilities'])
        else:
            self.assertNotIn('local_gb', properties)
            self.assertNotIn('root_device', properties)
            if capabilities:
                self.assertNotIn('raid_level:1', properties['capabilities'])

        self.assertEqual({}, target)
Example #4
0
def _commit_raid_config(task):
    """Perform to commit RAID config into node."""

    node = task.node
    node_uuid = task.node.uuid
    raid_config = {'logical_disks': []}

    raid_adapter = _get_raid_adapter(node)

    raid_adapter_info = raid_adapter['Server']['HWConfigurationIrmc'][
        'Adapters']['RAIDAdapter'][0]
    controller = raid_adapter_info['@AdapterId']
    raid_config['logical_disks'].append({'controller': controller})

    logical_drives = raid_adapter_info['LogicalDrives']['LogicalDrive']
    for logical_drive in logical_drives:
        raid_config['logical_disks'].append({'irmc_raid_info': {
            'logical_drive_number': logical_drive['@Number'], 'raid_level':
                logical_drive['RaidLevel'], 'name': logical_drive['Name'],
            ' size': logical_drive['Size']}})
    for physical_drive in \
            raid_adapter_info['PhysicalDisks']['PhysicalDisk']:
        raid_config['logical_disks'].append({'physical_drives': {
            'physical_drive': physical_drive}})
    node.raid_config = raid_config

    raid_common.update_raid_info(node, node.raid_config)
    LOG.info('RAID config is created successfully on node %s',
             node_uuid)

    return states.CLEANWAIT
Example #5
0
    def _test_update_raid_info(self, current_config,
                               capabilities=None):
        node = self.node
        if capabilities:
            properties = node.properties
            properties['capabilities'] = capabilities
            del properties['local_gb']
            node.properties = properties
        target_raid_config = json.loads(raid_constants.RAID_CONFIG_OKAY)
        node.target_raid_config = target_raid_config
        node.save()
        raid.update_raid_info(node, current_config)
        properties = node.properties
        current = node.raid_config
        target = node.target_raid_config
        self.assertIsNotNone(current['last_updated'])
        self.assertIsInstance(current['logical_disks'][0], dict)
        if current_config['logical_disks'][0].get('is_root_volume'):
            self.assertEqual({'wwn': '600508B100'},
                             properties['root_device'])
            self.assertEqual(100, properties['local_gb'])
            self.assertIn('raid_level:1', properties['capabilities'])
            if capabilities:
                self.assertIn(capabilities, properties['capabilities'])
        else:
            self.assertNotIn('local_gb', properties)
            self.assertNotIn('root_device', properties)
            if capabilities:
                self.assertNotIn('raid_level:1', properties['capabilities'])

        # Verify node.target_raid_config is preserved.
        self.assertEqual(target_raid_config, target)
Example #6
0
    def _create_configuration_final(task, command):
        """Clean step hook after a RAID configuration was created.

        This method is invoked as a post clean step hook by the Ironic
        conductor once a create raid configuration is completed successfully.
        The node (properties, capabilities, RAID information) will be updated
        to reflect the actual RAID configuration that was created.

        :param task: a TaskManager instance.
        :param command: A command result structure of the RAID operation
            returned from agent ramdisk on query of the status of command(s).
        :raises: InvalidParameterValue, if 'current_raid_config' has more than
            one root volume or if node.properties['capabilities'] is malformed.
        :raises: IronicException, if clean_result couldn't be found within
            the 'command' argument passed.
        """
        try:
            clean_result = command['command_result']['clean_result']
        except KeyError:
            raise exception.IronicException(
                _("Agent ramdisk didn't return a proper command result while "
                  "cleaning %(node)s. It returned '%(result)s' after command "
                  "execution.") % {'node': task.node.uuid,
                                   'result': command})

        raid.update_raid_info(task.node, clean_result)
Example #7
0
    def _test_update_raid_info(self, current_config, capabilities=None):
        node = obj_utils.create_test_node(self.context, driver="fake")
        if capabilities:
            properties = node.properties
            properties["capabilities"] = capabilities
            del properties["local_gb"]
            node.properties = properties
        target_raid_config = json.loads(raid_constants.RAID_CONFIG_OKAY)
        node.target_raid_config = target_raid_config
        node.save()
        raid.update_raid_info(node, current_config)
        properties = node.properties
        current = node.raid_config
        target = node.target_raid_config
        self.assertIsNotNone(current["last_updated"])
        self.assertIsInstance(current["logical_disks"][0], dict)
        if current_config["logical_disks"][0].get("is_root_volume"):
            self.assertEqual({"wwn": "600508B100"}, properties["root_device"])
            self.assertEqual(100, properties["local_gb"])
            self.assertIn("raid_level:1", properties["capabilities"])
            if capabilities:
                self.assertIn(capabilities, properties["capabilities"])
        else:
            self.assertNotIn("local_gb", properties)
            self.assertNotIn("root_device", properties)
            if capabilities:
                self.assertNotIn("raid_level:1", properties["capabilities"])

        # Verify node.target_raid_config is preserved.
        self.assertEqual(target_raid_config, target)
Example #8
0
    def _create_configuration_final(task, command):
        """Clean step hook after a RAID configuration was created.

        This method is invoked as a post clean step hook by the Ironic
        conductor once a create raid configuration is completed successfully.
        The node (properties, capabilities, RAID information) will be updated
        to reflect the actual RAID configuration that was created.

        :param task: a TaskManager instance.
        :param command: A command result structure of the RAID operation
            returned from agent ramdisk on query of the status of command(s).
        :raises: InvalidParameterValue, if 'current_raid_config' has more than
            one root volume or if node.properties['capabilities'] is malformed.
        :raises: IronicException, if clean_result couldn't be found within
            the 'command' argument passed.
        """
        try:
            clean_result = command['command_result']['clean_result']
        except KeyError:
            raise exception.IronicException(
                _("Agent ramdisk didn't return a proper command result while "
                  "cleaning %(node)s. It returned '%(result)s' after command "
                  "execution.") % {
                      'node': task.node.uuid,
                      'result': command
                  })

        raid.update_raid_info(task.node, clean_result)
Example #9
0
 def _resume_cleaning(self, task):
     raid_common.update_raid_info(
         task.node, self.get_logical_disks(task))
     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()
     manager_utils.notify_conductor_resume_clean(task)
Example #10
0
def _commit_raid_config(task):
    """Perform to commit RAID config into node."""

    node = task.node
    node_uuid = task.node.uuid
    raid_config = {'logical_disks': []}

    raid_adapter = _get_raid_adapter(node)

    raid_adapter_info = raid_adapter['Server']['HWConfigurationIrmc'][
        'Adapters']['RAIDAdapter'][0]
    controller = raid_adapter_info['@AdapterId']
    raid_config['logical_disks'].append({'controller': controller})

    logical_drives = raid_adapter_info['LogicalDrives']['LogicalDrive']
    for logical_drive in logical_drives:
        raid_config['logical_disks'].append({
            'irmc_raid_info': {
                'logical_drive_number': logical_drive['@Number'],
                'raid_level': logical_drive['RaidLevel'],
                'name': logical_drive['Name'],
                ' size': logical_drive['Size']
            }
        })
    for physical_drive in \
            raid_adapter_info['PhysicalDisks']['PhysicalDisk']:
        raid_config['logical_disks'].append(
            {'physical_drives': {
                'physical_drive': physical_drive
            }})
    node.raid_config = raid_config

    raid_common.update_raid_info(node, node.raid_config)
    LOG.info('RAID config is created successfully on node %s', node_uuid)

    return states.CLEANWAIT
Example #11
0
    def create_configuration(self,
                             task,
                             create_root_volume=True,
                             create_nonroot_volumes=True):
        """Create a RAID configuration on a bare metal using agent ramdisk.

        This method creates a RAID configuration on the given node.

        :param task: a TaskManager instance.
        :param create_root_volume: If True, a root volume is created
            during RAID configuration. Otherwise, no root volume is
            created. Default is True.
        :param create_nonroot_volumes: If True, non-root volumes are
            created. If False, no non-root volumes are created. Default
            is True.
        :raises: MissingParameterValue, if node.target_raid_config is missing
            or was found to be empty after skipping root volume and/or non-root
            volumes.
        :raises: NodeCleaningFailure, on failure to execute clean step.
        :raises: InstanceDeployFailure, on failure to execute deploy step.
        """
        node = task.node
        target_raid_config = raid.filter_target_raid_config(
            node,
            create_root_volume=create_root_volume,
            create_nonroot_volumes=create_nonroot_volumes)
        driver_internal_info = node.driver_internal_info
        driver_internal_info['target_raid_config'] = target_raid_config
        node.driver_internal_info = driver_internal_info
        node.save()
        LOG.debug(
            "Calling OOB RAID create_configuration for node %(node)s "
            "with the following target RAID configuration: %(target)s", {
                'node': node.uuid,
                'target': target_raid_config
            })
        ilo_object = ilo_common.get_ilo_object(node)

        try:
            # Raid configuration in progress, checking status
            if not driver_internal_info.get('ilo_raid_create_in_progress'):
                ilo_object.create_raid_configuration(target_raid_config)
                self._prepare_for_read_raid(task, 'create_raid')
                return deploy_utils.get_async_step_return_state(node)
            else:
                # Raid configuration is done, updating raid_config
                raid_conf = (ilo_object.read_raid_configuration(
                    raid_config=target_raid_config))
                fields = ['ilo_raid_create_in_progress']
                if node.clean_step:
                    fields.append('skip_current_clean_step')
                else:
                    fields.append('skip_current_deploy_step')
                self._pop_driver_internal_values(task, *fields)
                if len(raid_conf['logical_disks']):
                    raid.update_raid_info(node, raid_conf)
                    LOG.debug("Node %(uuid)s raid create clean step is done.",
                              {'uuid': node.uuid})
                else:
                    # Raid configuration failed
                    msg = (_("Step create_configuration failed "
                             "on node %(node)s with error: "
                             "Unable to create raid") % {
                                 'node': node.uuid
                             })
                    if node.clean_step:
                        raise exception.NodeCleaningFailure(msg)
                    else:
                        raise exception.InstanceDeployFailure(reason=msg)
        except ilo_error.IloError as ilo_exception:
            operation = (_("Failed to create raid configuration on node %s") %
                         node.uuid)
            fields = ['ilo_raid_create_in_progress']
            if node.clean_step:
                fields.append('skip_current_clean_step')
            else:
                fields.append('skip_current_deploy_step')
            self._pop_driver_internal_values(task, *fields)
            self._set_step_failed(task, operation, ilo_exception)
Example #12
0
 def _resume_cleaning(self, task):
     raid_common.update_raid_info(
         task.node, self.get_logical_disks(task))
     agent_base_vendor._notify_conductor_resume_clean(task)
Example #13
0
    def create_configuration(self, task, create_root_volume=True,
                             create_nonroot_volumes=True):
        """Create a RAID configuration on a bare metal using agent ramdisk.

        This method creates a RAID configuration on the given node.

        :param task: a TaskManager instance.
        :param create_root_volume: If True, a root volume is created
            during RAID configuration. Otherwise, no root volume is
            created. Default is True.
        :param create_nonroot_volumes: If True, non-root volumes are
            created. If False, no non-root volumes are created. Default
            is True.
        :raises: MissingParameterValue, if node.target_raid_config is missing
            or was found to be empty after skipping root volume and/or non-root
            volumes.
        :raises: NodeCleaningFailure, on failure to execute step.
        """
        node = task.node
        target_raid_config = raid.filter_target_raid_config(
            node, create_root_volume=create_root_volume,
            create_nonroot_volumes=create_nonroot_volumes)
        driver_internal_info = node.driver_internal_info
        driver_internal_info['target_raid_config'] = target_raid_config
        LOG.debug("Calling OOB RAID create_configuration for node %(node)s "
                  "with the following target RAID configuration: %(target)s",
                  {'node': node.uuid, 'target': target_raid_config})
        ilo_object = ilo_common.get_ilo_object(node)

        try:
            # Raid configuration in progress, checking status
            if not driver_internal_info.get('ilo_raid_create_in_progress'):
                ilo_object.create_raid_configuration(target_raid_config)
                self._prepare_for_read_raid(task, 'create_raid')
                return states.CLEANWAIT
            else:
                # Raid configuration is done, updating raid_config
                raid_conf = (
                    ilo_object.read_raid_configuration(
                        raid_config=target_raid_config))
                if len(raid_conf['logical_disks']):
                    raid.update_raid_info(node, raid_conf)
                    LOG.debug("Node %(uuid)s raid create clean step is done.",
                              {'uuid': node.uuid})
                    self._pop_driver_internal_values(
                        task, 'ilo_raid_create_in_progress',
                        'cleaning_reboot', 'skip_current_clean_step')
                    node.driver_internal_info = driver_internal_info
                    node.save()
                else:
                    # Raid configuration failed
                    msg = "Unable to create raid"
                    self._pop_driver_internal_values(
                        task, 'ilo_raid_create_in_progress',
                        'cleaning_reboot', 'skip_current_clean_step')
                    node.driver_internal_info = driver_internal_info
                    node.save()
                    raise exception.NodeCleaningFailure(
                        "Clean step create_configuration failed "
                        "on node %(node)s with error: %(err)s" %
                        {'node': node.uuid, 'err': msg})
        except ilo_error.IloError as ilo_exception:
            operation = (_("Failed to create raid configuration on node %s")
                         % node.uuid)
            self._pop_driver_internal_values(task,
                                             'ilo_raid_create_in_progress',
                                             'cleaning_reboot',
                                             'skip_current_clean_step')
            node.driver_internal_info = driver_internal_info
            node.save()
            self._set_clean_failed(task, operation, ilo_exception)
Example #14
0
 def _resume_cleaning(self, task):
     raid_common.update_raid_info(task.node, task.node.raid_config)
     manager_utils.notify_conductor_resume_clean(task)
Example #15
0
    def _query_raid_config_fgi_status(self, manager, context):
        """Periodic tasks to check the progress of running RAID config."""

        filters = {'reserved': False, 'provision_state': states.CLEANWAIT,
                   'maintenance': False}
        fields = ['raid_config']
        node_list = manager.iter_nodes(fields=fields, filters=filters)
        for (node_uuid, driver, conductor_group, raid_config) in node_list:
            try:
                lock_purpose = 'checking async RAID configuration tasks'
                with task_manager.acquire(context, node_uuid,
                                          purpose=lock_purpose,
                                          shared=True) as task:
                    node = task.node
                    node_uuid = task.node.uuid
                    if not isinstance(task.driver.raid, IRMCRAID):
                        continue
                    if task.node.target_raid_config is None:
                        continue
                    if not raid_config or raid_config.get('fgi_status'):
                        continue
                    task.upgrade_lock()
                    if node.provision_state != states.CLEANWAIT:
                        continue
                    # Avoid hitting clean_callback_timeout expiration
                    node.touch_provisioning()

                    try:
                        report = irmc_common.get_irmc_report(node)
                    except client.scci.SCCIInvalidInputError:
                        raid_config.update({'fgi_status': RAID_FAILED})
                        raid_common.update_raid_info(node, raid_config)
                        self._set_clean_failed(task, RAID_FAILED)
                        continue
                    except client.scci.SCCIClientError:
                        raid_config.update({'fgi_status': RAID_FAILED})
                        raid_common.update_raid_info(node, raid_config)
                        self._set_clean_failed(task, RAID_FAILED)
                        continue

                    fgi_status_dict = _get_fgi_status(report, node_uuid)
                    # Note(trungnv): Allow to check until RAID mechanism to be
                    # completed with RAID information in report.
                    if fgi_status_dict == 'completing':
                        continue
                    if not fgi_status_dict:
                        raid_config.update({'fgi_status': RAID_FAILED})
                        raid_common.update_raid_info(node, raid_config)
                        self._set_clean_failed(task, fgi_status_dict)
                        continue
                    if all(fgi_status == 'Idle' for fgi_status in
                           fgi_status_dict.values()):
                        raid_config.update({'fgi_status': RAID_COMPLETED})
                        LOG.info('RAID configuration has completed on '
                                 'node %(node)s with fgi_status is %(fgi)s',
                                 {'node': node_uuid, 'fgi': RAID_COMPLETED})
                        self._resume_cleaning(task)

            except exception.NodeNotFound:
                LOG.info('During query_raid_config_job_status, node '
                         '%(node)s was not found raid_config and presumed '
                         'deleted by another process.', {'node': node_uuid})
            except exception.NodeLocked:
                LOG.info('During query_raid_config_job_status, node '
                         '%(node)s was already locked by another process. '
                         'Skip.', {'node': node_uuid})
Example #16
0
 def _resume_cleaning(self, task):
     raid_common.update_raid_info(task.node, self.get_logical_disks(task))
     agent_base_vendor._notify_conductor_resume_clean(task)
Example #17
0
    def _query_raid_config_fgi_status(self, manager, context):
        """Periodic tasks to check the progress of running RAID config."""

        filters = {
            'reserved': False,
            'provision_state': states.CLEANWAIT,
            'maintenance': False
        }
        fields = ['raid_config']
        node_list = manager.iter_nodes(fields=fields, filters=filters)
        for (node_uuid, driver, conductor_group, raid_config) in node_list:
            try:
                lock_purpose = 'checking async RAID configuration tasks'
                with task_manager.acquire(context,
                                          node_uuid,
                                          purpose=lock_purpose,
                                          shared=True) as task:
                    node = task.node
                    node_uuid = task.node.uuid
                    if not isinstance(task.driver.raid, IRMCRAID):
                        continue
                    if task.node.target_raid_config is None:
                        continue
                    if not raid_config or raid_config.get('fgi_status'):
                        continue
                    task.upgrade_lock()
                    if node.provision_state != states.CLEANWAIT:
                        continue
                    # Avoid hitting clean_callback_timeout expiration
                    node.touch_provisioning()

                    try:
                        report = irmc_common.get_irmc_report(node)
                    except client.scci.SCCIInvalidInputError:
                        raid_config.update({'fgi_status': RAID_FAILED})
                        raid_common.update_raid_info(node, raid_config)
                        self._set_clean_failed(task, RAID_FAILED)
                        continue
                    except client.scci.SCCIClientError:
                        raid_config.update({'fgi_status': RAID_FAILED})
                        raid_common.update_raid_info(node, raid_config)
                        self._set_clean_failed(task, RAID_FAILED)
                        continue

                    fgi_status_dict = _get_fgi_status(report, node_uuid)
                    # Note(trungnv): Allow to check until RAID mechanism to be
                    # completed with RAID information in report.
                    if fgi_status_dict == 'completing':
                        continue
                    if not fgi_status_dict:
                        raid_config.update({'fgi_status': RAID_FAILED})
                        raid_common.update_raid_info(node, raid_config)
                        self._set_clean_failed(task, fgi_status_dict)
                        continue
                    if all(fgi_status == 'Idle'
                           for fgi_status in fgi_status_dict.values()):
                        raid_config.update({'fgi_status': RAID_COMPLETED})
                        LOG.info(
                            'RAID configuration has completed on '
                            'node %(node)s with fgi_status is %(fgi)s', {
                                'node': node_uuid,
                                'fgi': RAID_COMPLETED
                            })
                        self._resume_cleaning(task)

            except exception.NodeNotFound:
                LOG.info(
                    'During query_raid_config_job_status, node '
                    '%(node)s was not found raid_config and presumed '
                    'deleted by another process.', {'node': node_uuid})
            except exception.NodeLocked:
                LOG.info(
                    'During query_raid_config_job_status, node '
                    '%(node)s was already locked by another process. '
                    'Skip.', {'node': node_uuid})
Example #18
0
 def _resume_cleaning(self, task):
     raid_common.update_raid_info(task.node, task.node.raid_config)
     manager_utils.notify_conductor_resume_clean(task)
Example #19
0
 def _resume_cleaning(self, task):
     raid_common.update_raid_info(task.node, self.get_logical_disks(task))
     manager_utils.notify_conductor_resume_clean(task)