Example #1
0
    def _validate_volume_boot(self, task):
        """Validate information for volume boot with this interface.

        This interface requires physical information of connectors to
        configure remote boot to iRMC. Physical information of LAN ports
        is also required since VIOM feature manages all adapters.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue: If invalid value is set to resources.
        :raises: MissingParameterValue: If some value is not set to resources.
        """

        if not deploy_utils.get_remote_boot_volume(task):
            # No boot volume. Nothing to validate.
            return

        irmc_common.parse_driver_info(task.node)

        for port in task.ports:
            self._validate_lan_port(task.node, port)

        for vt in task.volume_targets:
            if vt.volume_type == 'iscsi':
                self._validate_iscsi_connectors(task)
            elif vt.volume_type == 'fibre_channel':
                self._validate_fc_connectors(task)
Example #2
0
 def test_parse_driver_info_missing_multiple_params(self):
     del self.node.driver_info['irmc_password']
     del self.node.driver_info['irmc_address']
     try:
         irmc_common.parse_driver_info(self.node)
         self.fail("parse_driver_info did not throw exception.")
     except exception.MissingParameterValue as e:
         self.assertIn('irmc_password', str(e))
         self.assertIn('irmc_address', str(e))
Example #3
0
    def validate(self, task):
        """Validate the driver-specific inspection information.

        This method validates whether the 'driver_info' property of the
        supplied node contains the required information for this driver.

        :param task: a TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if required driver_info attribute
                 is missing or invalid on the node.
        :raises: MissingParameterValue if a required parameter is missing.
        """
        irmc_common.parse_driver_info(task.node)
Example #4
0
    def validate(self, task):
        """Validate the driver-specific management information.

        This method validates whether the 'driver_info' property of the
        supplied node contains the required information for this driver.

        :param task: A TaskManager instance containing the node to act on.
        :raises: InvalidParameterValue if required parameters are invalid.
        :raises: MissingParameterValue if a required parameter is missing.
        """
        irmc_common.parse_driver_info(task.node)
        irmc_common.update_ipmi_properties(task)
        super(IRMCManagement, self).validate(task)
Example #5
0
    def apply_configuration(self, task, settings):
        """Applies BIOS configuration on the given node.

        This method takes the BIOS settings from the settings param and
        applies BIOS configuration on the given node.
        After the BIOS configuration is done, self.cache_bios_settings() may
        be called to sync the node's BIOS-related information with the BIOS
        configuration applied on the node.
        It will also validate the given settings before applying any
        settings and manage failures when setting an invalid BIOS config.
        In the case of needing password to update the BIOS config, it will be
        taken from the driver_info properties.

        :param task: a TaskManager instance.
        :param settings: Dictionary containing the BIOS configuration. It
            may be an empty dictionary as well.
        :raises: IRMCOperationError,if apply bios settings failed.
        """

        irmc_info = irmc_common.parse_driver_info(task.node)

        try:
            LOG.info('Apply BIOS configuration for node %(node_uuid)s: '
                     '%(settings)s', {'settings': settings,
                                      'node_uuid': task.node.uuid})
            irmc.elcm.set_bios_configuration(irmc_info, settings)
            # NOTE(trungnv): Fix failed cleaning during rebooting node
            # when combine OOB and IB steps in manual clean.
            self._resume_cleaning(task)
        except irmc.scci.SCCIError as e:
            LOG.error('Failed to apply BIOS configuration on node '
                      '%(node_uuid)s. Error: %(error)s',
                      {'node_uuid': task.node.uuid, 'error': e})
            raise exception.IRMCOperationError(
                operation='Apply BIOS configuration', error=e)
Example #6
0
def backup_bios_config(task):
    """Backup BIOS config from a node.

    :param task: a TaskManager instance containing the node to act on.
    :raises: IRMCOperationError on failure.
    """
    node_uuid = task.node.uuid

    # Skip this operation if the clean step 'restore' is disabled
    if CONF.irmc.clean_priority_restore_irmc_bios_config == 0:
        LOG.debug('Skipped the operation backup_BIOS_config for node %s '
                  'as the clean step restore_BIOS_config is disabled.',
                  node_uuid)
        return

    irmc_info = irmc_common.parse_driver_info(task.node)

    try:
        # Backup bios config
        result = irmc.elcm.backup_bios_config(irmc_info)
    except irmc.scci.SCCIError as e:
        LOG.error('Failed to backup BIOS config for node %(node)s. '
                  'Error: %(error)s', {'node': node_uuid, 'error': e})
        raise exception.IRMCOperationError(operation='backup BIOS config',
                                           error=e)

    # Save bios config into the driver_internal_info
    internal_info = task.node.driver_internal_info
    internal_info['irmc_bios_config'] = result['bios_config']
    task.node.driver_internal_info = internal_info
    task.node.save()

    LOG.info('BIOS config is backed up successfully for node %s',
             node_uuid)
Example #7
0
    def _configure_boot_from_volume(self, task):
        """Set information for booting from a remote volume to iRMC.

        :param task: a TaskManager instance containing the node to act on.
        :raises: IRMCOperationError if iRMC operation failed
        """

        irmc_info = irmc_common.parse_driver_info(task.node)
        viom_conf = viom.VIOMConfiguration(irmc_info,
                                           identification=task.node.uuid)

        self._register_lan_ports(viom_conf, task)

        for vt in task.volume_targets:
            if vt.volume_type == 'iscsi':
                self._set_iscsi_target(task, viom_conf, vt)
            elif vt.volume_type == 'fibre_channel':
                self._set_fc_target(task, viom_conf, vt)

        try:
            LOG.debug('Set VIOM configuration for node %(node)s: %(table)s',
                      {'node': task.node.uuid,
                       'table': viom_conf.dump_json()})
            viom_conf.apply()
        except scci.SCCIError as e:
            LOG.error('iRMC failed to set VIOM configuration for node '
                      '%(node)s: %(error)s',
                      {'node': task.node.uuid,
                       'error': e})
            raise exception.IRMCOperationError(
                operation='Configure VIOM', error=e)
Example #8
0
    def cache_bios_settings(self, task):
        """Store or update BIOS settings on the given node.

        This method stores BIOS properties to the bios settings db

        :param task: a TaskManager instance.
        :raises: IRMCOperationError,if get bios settings failed.
        :returns: None if it is complete.
        """

        irmc_info = irmc_common.parse_driver_info(task.node)
        node_id = task.node.id
        try:
            settings = irmc.elcm.get_bios_settings(irmc_info)
        except irmc.scci.SCCIError as e:
            LOG.error('Failed to retrieve the current BIOS settings for node '
                      '%(node)s. Error: %(error)s', {'node': task.node.uuid,
                                                     'error': e})
            raise exception.IRMCOperationError(operation='Cache BIOS settings',
                                               error=e)
        create_list, update_list, delete_list, nochange_list = (
            objects.BIOSSettingList.sync_node_setting(task.context, node_id,
                                                      settings))
        if len(create_list) > 0:
            objects.BIOSSettingList.create(task.context, node_id, create_list)
        if len(update_list) > 0:
            objects.BIOSSettingList.save(task.context, node_id, update_list)
        if len(delete_list) > 0:
            delete_names = [setting['name'] for setting in delete_list]
            objects.BIOSSettingList.delete(task.context, node_id,
                                           delete_names)
Example #9
0
    def test_parse_driver_option_default(self):
        self.node.driver_info = {"irmc_address": "1.2.3.4", "irmc_username": "******", "irmc_password": "******"}
        info = irmc_common.parse_driver_info(self.node)

        self.assertEqual("basic", info.get("irmc_auth_method"))
        self.assertEqual(443, info.get("irmc_port"))
        self.assertEqual(60, info.get("irmc_client_timeout"))
        self.assertEqual("ipmitool", info.get("irmc_sensor_method"))
Example #10
0
    def test_parse_driver_info(self):
        info = irmc_common.parse_driver_info(self.node)

        self.assertIsNotNone(info.get('irmc_address'))
        self.assertIsNotNone(info.get('irmc_username'))
        self.assertIsNotNone(info.get('irmc_password'))
        self.assertIsNotNone(info.get('irmc_client_timeout'))
        self.assertIsNotNone(info.get('irmc_port'))
        self.assertIsNotNone(info.get('irmc_auth_method'))
Example #11
0
    def test_parse_driver_info(self):
        info = irmc_common.parse_driver_info(self.node)

        self.assertIsNotNone(info.get("irmc_address"))
        self.assertIsNotNone(info.get("irmc_username"))
        self.assertIsNotNone(info.get("irmc_password"))
        self.assertIsNotNone(info.get("irmc_client_timeout"))
        self.assertIsNotNone(info.get("irmc_port"))
        self.assertIsNotNone(info.get("irmc_auth_method"))
        self.assertIsNotNone(info.get("irmc_sensor_method"))
Example #12
0
    def setUp(self):
        super(IRMCManagementTestCase, self).setUp()
        driver_info = INFO_DICT

        mgr_utils.mock_the_extension_manager(driver="fake_irmc")
        self.driver = driver_factory.get_driver("fake_irmc")
        self.node = obj_utils.create_test_node(self.context,
                                               driver='fake_irmc',
                                               driver_info=driver_info)
        self.info = irmc_common.parse_driver_info(self.node)
Example #13
0
 def test_set_secure_boot_mode_fail(self, mock_scci, mock_elcm):
     irmc_common.scci.SCCIError = Exception
     mock_elcm.set_secure_boot_mode.side_effect = Exception
     with task_manager.acquire(self.context, self.node.uuid,
                               shared=False) as task:
         self.assertRaises(exception.IRMCOperationError,
                           irmc_common.set_secure_boot_mode,
                           task.node, True)
         info = irmc_common.parse_driver_info(task.node)
         mock_elcm.set_secure_boot_mode.assert_called_once_with(
             info, True)
Example #14
0
def _restore_bios_config(task):
    """Restore BIOS config to a node.

    :param task: a TaskManager instance containing the node to act on.
    :raises: IRMCOperationError if the operation fails.
    """
    node_uuid = task.node.uuid

    # Get bios config stored in the node object
    bios_config = task.node.driver_internal_info.get('irmc_bios_config')
    if not bios_config:
        LOG.info('Skipped operation "restore BIOS config" on node %s '
                 'as the backup data not found.', node_uuid)
        return

    def _remove_bios_config(task, reboot_flag=False):
        """Remove backup bios config from the node."""
        internal_info = task.node.driver_internal_info
        internal_info.pop('irmc_bios_config', None)
        # NOTE(tiendc): If reboot flag is raised, then the BM will
        # reboot and cause a bug if the next clean step is in-band.
        # See https://storyboard.openstack.org/#!/story/2002731
        if reboot_flag:
            internal_info['cleaning_reboot'] = True
        task.node.driver_internal_info = internal_info
        task.node.save()

    irmc_info = irmc_common.parse_driver_info(task.node)

    try:
        # Restore bios config
        irmc.elcm.restore_bios_config(irmc_info, bios_config)
    except irmc.scci.SCCIError as e:
        # If the input bios config is not correct or corrupted, then
        # we should remove it from the node object.
        if isinstance(e, irmc.scci.SCCIInvalidInputError):
            _remove_bios_config(task)

        LOG.error('Failed to restore BIOS config on node %(node)s. '
                  'Error: %(error)s', {'node': node_uuid, 'error': e})
        raise exception.IRMCOperationError(operation='restore BIOS config',
                                           error=e)

    # Remove the backup data after restoring
    _remove_bios_config(task, reboot_flag=True)

    LOG.info('BIOS config is restored successfully on node %s',
             node_uuid)

    # Change power state to ON as server is automatically
    # shutdown after the operation.
    manager_utils.node_power_action(task, states.POWER_ON)
Example #15
0
    def setUp(self):
        super(IRMCManagementFunctionsTestCase, self).setUp()
        driver_info = INFO_DICT

        mgr_utils.mock_the_extension_manager(driver="fake_irmc")
        self.driver = driver_factory.get_driver("fake_irmc")
        self.node = obj_utils.create_test_node(self.context,
                                               driver='fake_irmc',
                                               driver_info=driver_info)
        self.info = irmc_common.parse_driver_info(self.node)

        irmc_management.irmc.scci.SCCIError = Exception
        irmc_management.irmc.scci.SCCIInvalidInputError = ValueError
Example #16
0
    def get_sensors_data(self, task):
        """Get sensors data method.

        It gets sensor data from the task's node via SCCI, and convert the data
        from XML to the dict format.

        :param task: A TaskManager instance.
        :raises: FailedToGetSensorData when getting the sensor data fails.
        :raises: FailedToParseSensorData when parsing sensor data fails.
        :raises: InvalidParameterValue if required parameters are invalid.
        :raises: MissingParameterValue if a required parameter is missing.
        :returns: Returns a consistent formatted dict of sensor data grouped
                  by sensor type, which can be processed by Ceilometer.
                  Example::

                      {
                        'Sensor Type 1': {
                          'Sensor ID 1': {
                            'Sensor Reading': 'Value1 Units1',
                            'Sensor ID': 'Sensor ID 1',
                            'Units': 'Units1'
                          },
                          'Sensor ID 2': {
                            'Sensor Reading': 'Value2 Units2',
                            'Sensor ID': 'Sensor ID 2',
                            'Units': 'Units2'
                          }
                        },
                        'Sensor Type 2': {
                          'Sensor ID 3': {
                            'Sensor Reading': 'Value3 Units3',
                            'Sensor ID': 'Sensor ID 3',
                            'Units': 'Units3'
                          },
                          'Sensor ID 4': {
                            'Sensor Reading': 'Value4 Units4',
                            'Sensor ID': 'Sensor ID 4',
                            'Units': 'Units4'
                          }
                        }
                      }

        """
        # irmc_common.parse_driver_info() makes sure that
        # d_info['irmc_sensor_method'] is either 'scci' or 'ipmitool'.
        d_info = irmc_common.parse_driver_info(task.node)
        sensor_method = d_info["irmc_sensor_method"]
        if sensor_method == "scci":
            return _get_sensors_data(task)
        elif sensor_method == "ipmitool":
            return super(IRMCManagement, self).get_sensors_data(task)
Example #17
0
    def test_parse_driver_info(self):
        info = irmc_common.parse_driver_info(self.node)

        self.assertEqual('1.2.3.4', info['irmc_address'])
        self.assertEqual('admin0', info['irmc_username'])
        self.assertEqual('fake0', info['irmc_password'])
        self.assertEqual(60, info['irmc_client_timeout'])
        self.assertEqual(80, info['irmc_port'])
        self.assertEqual('digest', info['irmc_auth_method'])
        self.assertEqual('ipmitool', info['irmc_sensor_method'])
        self.assertEqual('v2c', info['irmc_snmp_version'])
        self.assertEqual(161, info['irmc_snmp_port'])
        self.assertEqual('public', info['irmc_snmp_community'])
        self.assertFalse(info['irmc_snmp_security'])
Example #18
0
    def test_parse_driver_info(self):
        info = irmc_common.parse_driver_info(self.node)

        self.assertIsNotNone(info['irmc_address'])
        self.assertIsNotNone(info['irmc_username'])
        self.assertIsNotNone(info['irmc_password'])
        self.assertIsNotNone(info['irmc_client_timeout'])
        self.assertIsNotNone(info['irmc_port'])
        self.assertIsNotNone(info['irmc_auth_method'])
        self.assertIsNotNone(info['irmc_sensor_method'])
        self.assertIsNotNone(info['irmc_snmp_version'])
        self.assertIsNotNone(info['irmc_snmp_port'])
        self.assertIsNotNone(info['irmc_snmp_community'])
        self.assertFalse(info['irmc_snmp_security'])
Example #19
0
 def test_cache_bios_settings(self, get_bios_settings_mock, delete_mock,
                              save_mock, create_mock,
                              sync_node_setting_mock):
     settings = [{
         "name": "launch_csm_enabled",
         "value": True
     }, {
         "name": "hyper_threading_enabled",
         "value": True
     }, {
         "name": "cpu_vt_enabled",
         "value": True
     }]
     with task_manager.acquire(self.context, self.node.uuid) as task:
         irmc_info = irmc_common.parse_driver_info(task.node)
         get_bios_settings_mock.return_value = settings
         sync_node_setting_mock.return_value = \
             (
                 [
                     {
                         "name": "launch_csm_enabled",
                         "value": True
                     }],
                 [
                     {
                         "name": "hyper_threading_enabled",
                         "value": True
                     }],
                 [
                     {
                         "name": "cpu_vt_enabled",
                         "value": True
                     }],
                 []
             )
         task.driver.bios.cache_bios_settings(task)
         get_bios_settings_mock.assert_called_once_with(irmc_info)
         sync_node_setting_mock.assert_called_once_with(
             task.context, task.node.id, settings)
         create_mock.assert_called_once_with(
             task.context, task.node.id,
             sync_node_setting_mock.return_value[0])
         save_mock.assert_called_once_with(
             task.context, task.node.id,
             sync_node_setting_mock.return_value[1])
         delete_names = \
             [setting['name'] for setting in
              sync_node_setting_mock.return_value[2]]
         delete_mock.assert_called_once_with(task.context, task.node.id,
                                             delete_names)
Example #20
0
    def test_parse_driver_info(self):
        info = irmc_common.parse_driver_info(self.node)

        self.assertEqual('1.2.3.4', info['irmc_address'])
        self.assertEqual('admin0', info['irmc_username'])
        self.assertEqual('fake0', info['irmc_password'])
        self.assertEqual(60, info['irmc_client_timeout'])
        self.assertEqual(80, info['irmc_port'])
        self.assertEqual('digest', info['irmc_auth_method'])
        self.assertEqual('ipmitool', info['irmc_sensor_method'])
        self.assertEqual('v2c', info['irmc_snmp_version'])
        self.assertEqual(161, info['irmc_snmp_port'])
        self.assertEqual('public', info['irmc_snmp_community'])
        self.assertFalse(info['irmc_snmp_security'])
Example #21
0
def _restore_bios_config(task):
    """Restore BIOS config to a node.

    :param task: a TaskManager instance containing the node to act on.
    :raises: IRMCOperationError if the operation fails.
    """
    node_uuid = task.node.uuid

    # Get bios config stored in the node object
    bios_config = task.node.driver_internal_info.get('irmc_bios_config')
    if not bios_config:
        LOG.info('Skipped operation "restore BIOS config" on node %s '
                 'as the backup data not found.', node_uuid)
        return

    def _remove_bios_config(task):
        """Remove backup bios config from the node."""
        internal_info = task.node.driver_internal_info
        internal_info.pop('irmc_bios_config', None)
        task.node.driver_internal_info = internal_info
        task.node.save()

    irmc_info = irmc_common.parse_driver_info(task.node)

    try:
        # Restore bios config
        irmc.elcm.restore_bios_config(irmc_info, bios_config)
    except irmc.scci.SCCIError as e:
        # If the input bios config is not correct or corrupted, then
        # we should remove it from the node object.
        if isinstance(e, irmc.scci.SCCIInvalidInputError):
            _remove_bios_config(task)

        LOG.error('Failed to restore BIOS config on node %(node)s. '
                  'Error: %(error)s', {'node': node_uuid, 'error': e})
        raise exception.IRMCOperationError(operation='restore BIOS config',
                                           error=e)

    # Remove the backup data after restoring
    _remove_bios_config(task)

    LOG.info('BIOS config is restored successfully on node %s',
             node_uuid)

    # Change power state to ON as server is automatically
    # shutdown after the operation.
    manager_utils.node_power_action(task, states.POWER_ON)
Example #22
0
    def _cleanup_boot_from_volume(self, task, reboot=False):
        """Clear remote boot configuration.

        :param task: a task from TaskManager.
        :param reboot: True if reboot node soon
        :raises: IRMCOperationError if iRMC operation failed
        """
        irmc_info = irmc_common.parse_driver_info(task.node)
        try:
            viom_conf = viom.VIOMConfiguration(irmc_info, task.node.uuid)
            viom_conf.terminate(reboot=reboot)
        except scci.SCCIError as e:
            LOG.error('iRMC failed to terminate VIOM configuration from '
                      'node %(node)s: %(error)s', {'node': task.node.uuid,
                                                   'error': e})
            raise exception.IRMCOperationError(operation='Terminate VIOM',
                                               error=e)
Example #23
0
    def _cleanup_boot_from_volume(self, task, reboot=False):
        """Clear remote boot configuration.

        :param task: a task from TaskManager.
        :param reboot: True if reboot node soon
        :raises: IRMCOperationError if iRMC operation failed
        """
        irmc_info = irmc_common.parse_driver_info(task.node)
        try:
            viom_conf = viom.VIOMConfiguration(irmc_info, task.node.uuid)
            viom_conf.terminate(reboot=reboot)
        except scci.SCCIError as e:
            LOG.error('iRMC failed to terminate VIOM configuration from '
                      'node %(node)s: %(error)s', {'node': task.node.uuid,
                                                   'error': e})
            raise exception.IRMCOperationError(operation='Terminate VIOM',
                                               error=e)
Example #24
0
def _get_mac_addresses(node):
    """Get mac addresses of the node.

    :param node: node object.
    :raises: SNMPFailure if SNMP operation failed.
    :returns: a list of mac addresses.
    """
    d_info = irmc_common.parse_driver_info(node)
    snmp_client = snmp.SNMPClient(d_info['irmc_address'],
                                  d_info['irmc_snmp_port'],
                                  d_info['irmc_snmp_version'],
                                  d_info['irmc_snmp_community'],
                                  d_info['irmc_snmp_security'])

    node_classes = snmp_client.get_next(NODE_CLASS_OID)
    mac_addresses = snmp_client.get_next(MAC_ADDRESS_OID)

    return [a for c, a in zip(node_classes, mac_addresses)
            if c == NODE_CLASS_OID_VALUE['primary']]
Example #25
0
 def test_apply_configuration(self, get_bios_settings_mock,
                              set_bios_configuration_mock):
     settings = [{
         "name": "launch_csm_enabled",
         "value": True
     }, {
         "name": "hyper_threading_enabled",
         "value": True
     }, {
         "name": "cpu_vt_enabled",
         "value": True
     }]
     with task_manager.acquire(self.context, self.node.uuid) as task:
         irmc_info = irmc_common.parse_driver_info(task.node)
         task.node.save = mock.Mock()
         get_bios_settings_mock.return_value = settings
         task.driver.bios.apply_configuration(task, settings)
         set_bios_configuration_mock.assert_called_once_with(
             irmc_info, settings)
Example #26
0
    def apply_configuration(self, task, settings):
        """Applies BIOS configuration on the given node.

        This method takes the BIOS settings from the settings param and
        applies BIOS configuration on the given node.
        After the BIOS configuration is done, self.cache_bios_settings() may
        be called to sync the node's BIOS-related information with the BIOS
        configuration applied on the node.
        It will also validate the given settings before applying any
        settings and manage failures when setting an invalid BIOS config.
        In the case of needing password to update the BIOS config, it will be
        taken from the driver_info properties.

        :param task: a TaskManager instance.
        :param settings: Dictionary containing the BIOS configuration. It
            may be an empty dictionary as well.
        :raises: IRMCOperationError,if apply bios settings failed.
        """

        irmc_info = irmc_common.parse_driver_info(task.node)

        try:
            LOG.info(
                'Apply BIOS configuration for node %(node_uuid)s: '
                '%(settings)s', {
                    'settings': settings,
                    'node_uuid': task.node.uuid
                })
            irmc.elcm.set_bios_configuration(irmc_info, settings)
            # NOTE(trungnv): Fix failed cleaning during rebooting node
            # when combine OOB and IB steps in manual clean.
            self._resume_cleaning(task)
        except irmc.scci.SCCIError as e:
            LOG.error(
                'Failed to apply BIOS configuration on node '
                '%(node_uuid)s. Error: %(error)s', {
                    'node_uuid': task.node.uuid,
                    'error': e
                })
            raise exception.IRMCOperationError(
                operation='Apply BIOS configuration', error=e)
Example #27
0
def _get_mac_addresses(node):
    """Get mac addresses of the node.

    :param node: node object.
    :raises: SNMPFailure if SNMP operation failed.
    :returns: a list of mac addresses.
    """
    d_info = irmc_common.parse_driver_info(node)
    snmp_client = snmp.SNMPClient(d_info['irmc_address'],
                                  d_info['irmc_snmp_port'],
                                  d_info['irmc_snmp_version'],
                                  d_info['irmc_snmp_community'],
                                  d_info['irmc_snmp_security'])

    node_classes = snmp_client.get_next(NODE_CLASS_OID)
    mac_addresses = snmp_client.get_next(MAC_ADDRESS_OID)

    return [
        a for c, a in zip(node_classes, mac_addresses)
        if c == NODE_CLASS_OID_VALUE['primary']
    ]
Example #28
0
def backup_bios_config(task):
    """Backup BIOS config from a node.

    :param task: a TaskManager instance containing the node to act on.
    :raises: IRMCOperationError on failure.
    """
    node_uuid = task.node.uuid

    # Skip this operation if the clean step 'restore' is disabled
    if CONF.irmc.clean_priority_restore_irmc_bios_config == 0:
        LOG.debug(
            'Skipped the operation backup_BIOS_config for node %s '
            'as the clean step restore_BIOS_config is disabled.', node_uuid)
        return

    irmc_info = irmc_common.parse_driver_info(task.node)

    try:
        # Backup bios config
        result = irmc.elcm.backup_bios_config(irmc_info)
    except irmc.scci.SCCIError as e:
        LOG.error(
            'Failed to backup BIOS config for node %(node)s. '
            'Error: %(error)s', {
                'node': node_uuid,
                'error': e
            })
        raise exception.IRMCOperationError(operation='backup BIOS config',
                                           error=e)

    # Save bios config into the driver_internal_info
    internal_info = task.node.driver_internal_info
    internal_info['irmc_bios_config'] = result['bios_config']
    task.node.driver_internal_info = internal_info
    task.node.save()

    LOG.info('BIOS config is backed up successfully for node %s', node_uuid)
Example #29
0
def _inspect_hardware(node, existing_traits=None, **kwargs):
    """Inspect the node and get hardware information.

    :param node: node object.
    :param existing_traits: existing traits list.
    :param kwargs: the dictionary of additional parameters.
    :raises: HardwareInspectionFailure, if unable to get essential
             hardware properties.
    :returns: a pair of dictionary and list, the dictionary contains
              keys as in IRMCInspect.ESSENTIAL_PROPERTIES and its inspected
              values, the list contains mac addresses.
    """
    capabilities_props = set(CAPABILITIES_PROPERTIES)
    new_traits = list(existing_traits) if existing_traits else []

    # Remove all capabilities item which will be inspected in the existing
    # capabilities of node
    if 'capabilities' in node.properties:
        existing_cap = node.properties['capabilities'].split(',')
        for item in capabilities_props:
            for prop in existing_cap:
                if item == prop.split(':')[0]:
                    existing_cap.remove(prop)
        node.properties['capabilities'] = ",".join(existing_cap)

    # get gpu_ids, fpga_ids in ironic configuration
    gpu_ids = [gpu_id.lower() for gpu_id in CONF.irmc.gpu_ids]
    fpga_ids = [fpga_id.lower() for fpga_id in CONF.irmc.fpga_ids]

    # if gpu_ids = [], pci_gpu_devices will not be inspected
    if len(gpu_ids) == 0:
        capabilities_props.remove('pci_gpu_devices')

    # if fpga_ids = [], cpu_fpga will not be inspected
    if len(fpga_ids) == 0:
        capabilities_props.remove('cpu_fpga')

    try:
        report = irmc_common.get_irmc_report(node)
        props = scci.get_essential_properties(report,
                                              IRMCInspect.ESSENTIAL_PROPERTIES)
        d_info = irmc_common.parse_driver_info(node)
        capabilities = scci.get_capabilities_properties(d_info,
                                                        capabilities_props,
                                                        gpu_ids,
                                                        fpga_ids=fpga_ids,
                                                        **kwargs)
        if capabilities:
            if capabilities.get('pci_gpu_devices') == 0:
                capabilities.pop('pci_gpu_devices')

            cpu_fpga = capabilities.pop('cpu_fpga', 0)
            if cpu_fpga == 0 and 'CUSTOM_CPU_FPGA' in new_traits:
                new_traits.remove('CUSTOM_CPU_FPGA')
            elif cpu_fpga != 0 and 'CUSTOM_CPU_FPGA' not in new_traits:
                new_traits.append('CUSTOM_CPU_FPGA')

            if capabilities.get('trusted_boot') is False:
                capabilities.pop('trusted_boot')
            capabilities = utils.get_updated_capabilities(
                node.properties.get('capabilities'), capabilities)
            if capabilities:
                props['capabilities'] = capabilities

        macs = _get_mac_addresses(node)
    except (scci.SCCIInvalidInputError, scci.SCCIClientError,
            exception.SNMPFailure) as e:
        error = (_("Inspection failed for node %(node_id)s "
                   "with the following error: %(error)s") % {
                       'node_id': node.uuid,
                       'error': e
                   })
        raise exception.HardwareInspectionFailure(error=error)

    return props, macs, new_traits
Example #30
0
 def setUp(self):
     super(IRMCManagementTestCase, self).setUp()
     self.info = irmc_common.parse_driver_info(self.node)
Example #31
0
def _wait_power_state(task, target_state, timeout=None):
    """Wait for having changed to the target power state.

    :param task: A TaskManager instance containing the node to act on.
    :raises: IRMCOperationError if the target state acknowledge failed.
    :raises: SNMPFailure if SNMP request failed.
    """
    node = task.node
    d_info = irmc_common.parse_driver_info(node)
    snmp_client = snmp.SNMPClient(d_info['irmc_address'],
                                  d_info['irmc_snmp_port'],
                                  d_info['irmc_snmp_version'],
                                  d_info['irmc_snmp_community'],
                                  d_info['irmc_snmp_security'])

    interval = CONF.irmc.snmp_polling_interval
    retry_timeout_soft = timeout or CONF.conductor.soft_power_off_timeout
    max_retry = int(retry_timeout_soft / interval)

    def _wait(mutable):
        mutable['boot_status_value'] = snmp_client.get(BOOT_STATUS_OID)
        LOG.debug(
            "iRMC SNMP agent of %(node_id)s returned "
            "boot status value %(bootstatus)s on attempt %(times)s.", {
                'node_id': node.uuid,
                'bootstatus': BOOT_STATUS[mutable['boot_status_value']],
                'times': mutable['times']
            })

        if _is_expected_power_state(target_state,
                                    mutable['boot_status_value']):
            mutable['state'] = target_state
            raise loopingcall.LoopingCallDone()

        mutable['times'] += 1
        if mutable['times'] > max_retry:
            mutable['state'] = states.ERROR
            raise loopingcall.LoopingCallDone()

    store = {'state': None, 'times': 0, 'boot_status_value': None}
    timer = loopingcall.FixedIntervalLoopingCall(_wait, store)
    timer.start(interval=interval).wait()

    if store['state'] == target_state:
        # iRMC acknowledged the target state
        node.last_error = None
        node.power_state = (states.POWER_OFF if target_state
                            == states.SOFT_POWER_OFF else states.POWER_ON)
        node.target_power_state = states.NOSTATE
        node.save()
        LOG.info(
            'iRMC successfully set node %(node_id)s '
            'power state to %(bootstatus)s.', {
                'node_id': node.uuid,
                'bootstatus': BOOT_STATUS[store['boot_status_value']]
            })
    else:
        # iRMC failed to acknowledge the target state
        last_error = (_('iRMC returned unexpected boot status value %s') %
                      BOOT_STATUS[store['boot_status_value']])
        node.last_error = last_error
        node.power_state = states.ERROR
        node.target_power_state = states.NOSTATE
        node.save()
        LOG.error(
            'iRMC failed to acknowledge the target state for node '
            '%(node_id)s. Error: %(last_error)s', {
                'node_id': node.uuid,
                'last_error': last_error
            })
        error = _('unexpected boot status value')
        raise exception.IRMCOperationError(operation=target_state, error=error)
Example #32
0
    def setUp(self):
        super(IRMCManagementFunctionsTestCase, self).setUp()
        self.info = irmc_common.parse_driver_info(self.node)

        irmc_management.irmc.scci.SCCIError = Exception
        irmc_management.irmc.scci.SCCIInvalidInputError = ValueError
Example #33
0
def _wait_power_state(task, target_state, timeout=None):
    """Wait for having changed to the target power state.

    :param task: A TaskManager instance containing the node to act on.
    :raises: IRMCOperationError if the target state acknowledge failed.
    :raises: SNMPFailure if SNMP request failed.
    """
    node = task.node
    d_info = irmc_common.parse_driver_info(node)
    snmp_client = snmp.SNMPClient(d_info['irmc_address'],
                                  d_info['irmc_snmp_port'],
                                  d_info['irmc_snmp_version'],
                                  d_info['irmc_snmp_community'],
                                  d_info['irmc_snmp_security'])

    interval = CONF.irmc.snmp_polling_interval
    retry_timeout_soft = timeout or CONF.conductor.soft_power_off_timeout
    max_retry = int(retry_timeout_soft / interval)

    def _wait(mutable):
        mutable['boot_status_value'] = snmp_client.get(BOOT_STATUS_OID)
        LOG.debug("iRMC SNMP agent of %(node_id)s returned "
                  "boot status value %(bootstatus)s on attempt %(times)s.",
                  {'node_id': node.uuid,
                   'bootstatus': BOOT_STATUS[mutable['boot_status_value']],
                   'times': mutable['times']})

        if _is_expected_power_state(target_state,
                                    mutable['boot_status_value']):
            mutable['state'] = target_state
            raise loopingcall.LoopingCallDone()

        mutable['times'] += 1
        if mutable['times'] > max_retry:
            mutable['state'] = states.ERROR
            raise loopingcall.LoopingCallDone()

    store = {'state': None, 'times': 0, 'boot_status_value': None}
    timer = loopingcall.FixedIntervalLoopingCall(_wait, store)
    timer.start(interval=interval).wait()

    if store['state'] == target_state:
        # iRMC acknowledged the target state
        node.last_error = None
        node.power_state = (states.POWER_OFF
                            if target_state == states.SOFT_POWER_OFF
                            else states.POWER_ON)
        node.target_power_state = states.NOSTATE
        node.save()
        LOG.info('iRMC successfully set node %(node_id)s '
                 'power state to %(bootstatus)s.',
                 {'node_id': node.uuid,
                  'bootstatus': BOOT_STATUS[store['boot_status_value']]})
    else:
        # iRMC failed to acknowledge the target state
        last_error = (_('iRMC returned unexpected boot status value %s') %
                      BOOT_STATUS[store['boot_status_value']])
        node.last_error = last_error
        node.power_state = states.ERROR
        node.target_power_state = states.NOSTATE
        node.save()
        LOG.error('iRMC failed to acknowledge the target state for node '
                  '%(node_id)s. Error: %(last_error)s',
                  {'node_id': node.uuid, 'last_error': last_error})
        error = _('unexpected boot status value')
        raise exception.IRMCOperationError(operation=target_state,
                                           error=error)
Example #34
0
 def setUp(self):
     super(IRMCManagementTestCase, self).setUp()
     self.info = irmc_common.parse_driver_info(self.node)
Example #35
0
 def test_set_secure_boot_mode_disable(self, mock_elcm):
     mock_elcm.set_secure_boot_mode.return_value = 'set_secure_boot_mode'
     info = irmc_common.parse_driver_info(self.node)
     irmc_common.set_secure_boot_mode(self.node, False)
     mock_elcm.set_secure_boot_mode.assert_called_once_with(info, False)
Example #36
0
 def test_set_secure_boot_mode_disable(self, mock_elcm):
     mock_elcm.set_secure_boot_mode.return_value = 'set_secure_boot_mode'
     info = irmc_common.parse_driver_info(self.node)
     irmc_common.set_secure_boot_mode(self.node, False)
     mock_elcm.set_secure_boot_mode.assert_called_once_with(
         info, False)
Example #37
0
def _inspect_hardware(node, existing_traits=None, **kwargs):
    """Inspect the node and get hardware information.

    :param node: node object.
    :param existing_traits: existing traits list.
    :param kwargs: the dictionary of additional parameters.
    :raises: HardwareInspectionFailure, if unable to get essential
             hardware properties.
    :returns: a pair of dictionary and list, the dictionary contains
              keys as in IRMCInspect.ESSENTIAL_PROPERTIES and its inspected
              values, the list contains mac addresses.
    """
    capabilities_props = set(CAPABILITIES_PROPERTIES)
    new_traits = list(existing_traits) if existing_traits else []

    # Remove all capabilities item which will be inspected in the existing
    # capabilities of node
    if 'capabilities' in node.properties:
        existing_cap = node.properties['capabilities'].split(',')
        for item in capabilities_props:
            for prop in existing_cap:
                if item == prop.split(':')[0]:
                    existing_cap.remove(prop)
        node.properties['capabilities'] = ",".join(existing_cap)

    # get gpu_ids, fpga_ids in ironic configuration
    gpu_ids = [gpu_id.lower() for gpu_id in CONF.irmc.gpu_ids]
    fpga_ids = [fpga_id.lower() for fpga_id in CONF.irmc.fpga_ids]

    # if gpu_ids = [], pci_gpu_devices will not be inspected
    if len(gpu_ids) == 0:
        capabilities_props.remove('pci_gpu_devices')

    # if fpga_ids = [], cpu_fpga will not be inspected
    if len(fpga_ids) == 0:
        capabilities_props.remove('cpu_fpga')

    try:
        report = irmc_common.get_irmc_report(node)
        props = scci.get_essential_properties(
            report, IRMCInspect.ESSENTIAL_PROPERTIES)
        d_info = irmc_common.parse_driver_info(node)
        capabilities = scci.get_capabilities_properties(
            d_info,
            capabilities_props,
            gpu_ids,
            fpga_ids=fpga_ids,
            **kwargs)
        if capabilities:
            if capabilities.get('pci_gpu_devices') == 0:
                capabilities.pop('pci_gpu_devices')

            cpu_fpga = capabilities.pop('cpu_fpga', 0)
            if cpu_fpga == 0 and 'CUSTOM_CPU_FPGA' in new_traits:
                new_traits.remove('CUSTOM_CPU_FPGA')
            elif cpu_fpga != 0 and 'CUSTOM_CPU_FPGA' not in new_traits:
                new_traits.append('CUSTOM_CPU_FPGA')

            if capabilities.get('trusted_boot') is False:
                capabilities.pop('trusted_boot')
            capabilities = utils.get_updated_capabilities(
                node.properties.get('capabilities'), capabilities)
            if capabilities:
                props['capabilities'] = capabilities

        macs = _get_mac_addresses(node)
    except (scci.SCCIInvalidInputError,
            scci.SCCIClientError,
            exception.SNMPFailure) as e:
        error = (_("Inspection failed for node %(node_id)s "
                   "with the following error: %(error)s") %
                 {'node_id': node.uuid, 'error': e})
        raise exception.HardwareInspectionFailure(error=error)

    return props, macs, new_traits
Example #38
0
    def setUp(self):
        super(IRMCManagementFunctionsTestCase, self).setUp()
        self.info = irmc_common.parse_driver_info(self.node)

        irmc_management.irmc.scci.SCCIError = Exception
        irmc_management.irmc.scci.SCCIInvalidInputError = ValueError