def _get_nm_address(task): """Get Intel Node Manager target channel and address. :param task: a TaskManager instance. :raises: IPMIFailure if Intel Node Manager is not detected on a node or if an error happens during detection. :returns: a tuple with IPMI channel and address of Intel Node Manager. """ node = task.node driver_internal_info = node.driver_internal_info def _save_to_node(channel, address): driver_internal_info['intel_nm_channel'] = channel driver_internal_info['intel_nm_address'] = address node.driver_internal_info = driver_internal_info node.save() channel = driver_internal_info.get('intel_nm_channel') address = driver_internal_info.get('intel_nm_address') if channel and address: return channel, address if channel is False and address is False: raise exception.IPMIFailure( _('Driver data indicates that Intel ' 'Node Manager detection failed.')) LOG.info(_LI('Start detection of Intel Node Manager on node %s'), node.uuid) sdr_filename = os.path.join(CONF.tempdir, node.uuid + '.sdr') res = None try: ipmitool.dump_sdr(task, sdr_filename) res = nm_commands.parse_slave_and_channel(sdr_filename) finally: ironic_utils.unlink_without_raise(sdr_filename) if res is None: _save_to_node(False, False) raise exception.IPMIFailure(_('Intel Node Manager is not detected.')) address, channel = res LOG.debug( 'Intel Node Manager sensors present in SDR on node %(node)s, ' 'channel %(channel)s address %(address)s.', { 'node': node.uuid, 'channel': channel, 'address': address }) # SDR can contain wrong info, try simple command node.driver_info['ipmi_bridging'] = 'single' node.driver_info['ipmi_target_channel'] = channel node.driver_info['ipmi_target_address'] = address try: ipmitool.send_raw(task, _command_to_string(nm_commands.get_version(None))) _save_to_node(channel, address) return channel, address except exception.IPMIFailure: _save_to_node(False, False) raise exception.IPMIFailure( _('Intel Node Manager sensors record ' 'present in SDR but Node Manager is not ' 'responding.'))
def _enable_boot_config(node): """Enable boot configuration of AMT Client. :param node: a node object :raises: AMTFailure :raises: AMTConnectFailure """ amt_common.awake_amt_interface(node) client = amt_common.get_wsman_client(node) method = 'SetBootConfigRole' doc = _generate_enable_boot_config_input() options = pywsman.ClientOptions() options.add_selector('Name', 'Intel(r) AMT Boot Service') try: client.wsman_invoke(options, resource_uris.CIM_BootService, method, doc) except (exception.AMTFailure, exception.AMTConnectFailure) as e: with excutils.save_and_reraise_exception(): LOG.exception( _LE("Failed to enable boot config for node " "%(node_id)s with error: %(error)s."), { 'node_id': node.uuid, 'error': e }) else: LOG.info(_LI("Successfully enabled boot config for node %(node_id)s."), {'node_id': node.uuid})
def set_power_state(self, task, pstate): """Wakes the task's node on power on. Powering off is not supported. Wakes the task's node on. Wake-On-Lan does not support powering the task's node off so, just log it. :param task: a TaskManager instance containing the node to act on. :param pstate: The desired power state, one of ironic.common.states POWER_ON, POWER_OFF. :raises: InvalidParameterValue if parameters are invalid. :raises: MissingParameterValue if required parameters are missing. :raises: WOLOperationError if an error occur when sending the magic packets """ node = task.node params = _parse_parameters(task) if pstate == states.POWER_ON: _send_magic_packets(task, params['host'], params['port']) elif pstate == states.POWER_OFF: LOG.info( _LI('Power off called for node %s. Wake-On-Lan does not ' 'support this operation. Manual intervention ' 'required to perform this action.'), node.uuid) else: raise ironic_exception.InvalidParameterValue( _("set_power_state called for Node %(node)s with invalid " "power state %(pstate)s.") % { 'node': node.uuid, 'pstate': pstate })
def _set_boot_device_order(node, boot_device): """Set boot device order configuration of AMT Client. :param node: a node object :param boot_device: the boot device :raises: AMTFailure :raises: AMTConnectFailure """ amt_common.awake_amt_interface(node) client = amt_common.get_wsman_client(node) device = amt_common.BOOT_DEVICES_MAPPING[boot_device] doc = _generate_change_boot_order_input(device) method = 'ChangeBootOrder' options = pywsman.ClientOptions() options.add_selector('InstanceID', 'Intel(r) AMT: Boot Configuration 0') try: client.wsman_invoke(options, resource_uris.CIM_BootConfigSetting, method, doc) except (exception.AMTFailure, exception.AMTConnectFailure) as e: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Failed to set boot device %(boot_device)s for " "node %(node_id)s with error: %(error)s."), {'boot_device': boot_device, 'node_id': node.uuid, 'error': e}) else: LOG.info(_LI("Successfully set boot device %(boot_device)s for " "node %(node_id)s"), {'boot_device': boot_device, 'node_id': node.uuid})
def _set_power_state(node, target_state): """Set power state of the AMT Client. :param node: a node object. :param target_state: desired power state. :raises: AMTFailure :raises: AMTConnectFailure """ amt_common.awake_amt_interface(node) client = amt_common.get_wsman_client(node) method = 'RequestPowerStateChange' options = pywsman.ClientOptions() options.add_selector('Name', 'Intel(r) AMT Power Management Service') doc = _generate_power_action_input(AMT_POWER_MAP[target_state]) try: client.wsman_invoke(options, resource_uris.CIM_PowerManagementService, method, doc) except (exception.AMTFailure, exception.AMTConnectFailure) as e: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Failed to set power state %(state)s for " "node %(node_id)s with error: %(error)s."), {'state': target_state, 'node_id': node.uuid, 'error': e}) else: LOG.info(_LI("Power state set to %(state)s for node %(node_id)s"), {'state': target_state, 'node_id': node.uuid})
def set_power_state(self, task, pstate): """Wakes the task's node on power on. Powering off is not supported. Wakes the task's node on. Wake-On-Lan does not support powering the task's node off so, just log it. :param task: a TaskManager instance containing the node to act on. :param pstate: The desired power state, one of ironic.common.states POWER_ON, POWER_OFF. :raises: InvalidParameterValue if parameters are invalid. :raises: MissingParameterValue if required parameters are missing. :raises: WOLOperationError if an error occur when sending the magic packets """ node = task.node params = _parse_parameters(task) if pstate == states.POWER_ON: _send_magic_packets(task, params['host'], params['port']) elif pstate == states.POWER_OFF: LOG.info(_LI('Power off called for node %s. Wake-On-Lan does not ' 'support this operation. Manual intervention ' 'required to perform this action.'), node.uuid) else: raise ironic_exception.InvalidParameterValue(_( "set_power_state called for Node %(node)s with invalid " "power state %(pstate)s.") % {'node': node.uuid, 'pstate': pstate})
def _set_power_state(node, target_state): """Set power state of the AMT Client. :param node: a node object. :param target_state: desired power state. :raises: AMTFailure :raises: AMTConnectFailure """ amt_common.awake_amt_interface(node) client = amt_common.get_wsman_client(node) method = 'RequestPowerStateChange' options = pywsman.ClientOptions() options.add_selector('Name', 'Intel(r) AMT Power Management Service') doc = _generate_power_action_input(AMT_POWER_MAP[target_state]) try: client.wsman_invoke(options, resource_uris.CIM_PowerManagementService, method, doc) except (exception.AMTFailure, exception.AMTConnectFailure) as e: with excutils.save_and_reraise_exception(): LOG.exception( _LE("Failed to set power state %(state)s for " "node %(node_id)s with error: %(error)s."), { 'state': target_state, 'node_id': node.uuid, 'error': e }) else: LOG.info(_LI("Power state set to %(state)s for node %(node_id)s"), { 'state': target_state, 'node_id': node.uuid })
def _get_nm_address(task): """Get Intel Node Manager target channel and address. :param task: a TaskManager instance. :raises: IPMIFailure if Intel Node Manager is not detected on a node or if an error happens during detection. :returns: a tuple with IPMI channel and address of Intel Node Manager. """ node = task.node driver_internal_info = node.driver_internal_info def _save_to_node(channel, address): driver_internal_info['intel_nm_channel'] = channel driver_internal_info['intel_nm_address'] = address node.driver_internal_info = driver_internal_info node.save() channel = driver_internal_info.get('intel_nm_channel') address = driver_internal_info.get('intel_nm_address') if channel and address: return channel, address if channel is False and address is False: raise exception.IPMIFailure(_('Driver data indicates that Intel ' 'Node Manager detection failed.')) LOG.info(_LI('Start detection of Intel Node Manager on node %s'), node.uuid) sdr_filename = os.path.join(CONF.tempdir, node.uuid + '.sdr') res = None try: ipmitool.dump_sdr(task, sdr_filename) res = nm_commands.parse_slave_and_channel(sdr_filename) finally: ironic_utils.unlink_without_raise(sdr_filename) if res is None: _save_to_node(False, False) raise exception.IPMIFailure(_('Intel Node Manager is not detected.')) address, channel = res LOG.debug('Intel Node Manager sensors present in SDR on node %(node)s, ' 'channel %(channel)s address %(address)s.', {'node': node.uuid, 'channel': channel, 'address': address}) # SDR can contain wrong info, try simple command node.driver_info['ipmi_bridging'] = 'single' node.driver_info['ipmi_target_channel'] = channel node.driver_info['ipmi_target_address'] = address try: ipmitool.send_raw(task, _command_to_string(nm_commands.get_version(None))) _save_to_node(channel, address) return channel, address except exception.IPMIFailure: _save_to_node(False, False) raise exception.IPMIFailure(_('Intel Node Manager sensors record ' 'present in SDR but Node Manager is not ' 'responding.'))
def reboot(self, task): """Not supported. Cycles the power to the task's node. This operation is not fully supported by the Wake-On-Lan driver. So this method will just try to power the task's node on. :param task: a TaskManager instance containing the node to act on. :raises: InvalidParameterValue if parameters are invalid. :raises: MissingParameterValue if required parameters are missing. :raises: WOLOperationError if an error occur when sending the magic packets """ LOG.info(_LI('Reboot called for node %s. Wake-On-Lan does ' 'not fully support this operation. Trying to ' 'power on the node.'), task.node.uuid) self.set_power_state(task, states.POWER_ON)
def reboot(self, task): """Not supported. Cycles the power to the task's node. This operation is not fully supported by the Wake-On-Lan driver. So this method will just try to power the task's node on. :param task: a TaskManager instance containing the node to act on. :raises: InvalidParameterValue if parameters are invalid. :raises: MissingParameterValue if required parameters are missing. :raises: WOLOperationError if an error occur when sending the magic packets """ LOG.info( _LI('Reboot called for node %s. Wake-On-Lan does ' 'not fully support this operation. Trying to ' 'power on the node.'), task.node.uuid) self.set_power_state(task, states.POWER_ON)
def _set_boot_device_order(node, boot_device): """Set boot device order configuration of AMT Client. :param node: a node object :param boot_device: the boot device :raises: AMTFailure :raises: AMTConnectFailure """ amt_common.awake_amt_interface(node) client = amt_common.get_wsman_client(node) device = amt_common.BOOT_DEVICES_MAPPING[boot_device] doc = _generate_change_boot_order_input(device) method = 'ChangeBootOrder' options = pywsman.ClientOptions() options.add_selector('InstanceID', 'Intel(r) AMT: Boot Configuration 0') try: client.wsman_invoke(options, resource_uris.CIM_BootConfigSetting, method, doc) except (exception.AMTFailure, exception.AMTConnectFailure) as e: with excutils.save_and_reraise_exception(): LOG.exception( _LE("Failed to set boot device %(boot_device)s for " "node %(node_id)s with error: %(error)s."), { 'boot_device': boot_device, 'node_id': node.uuid, 'error': e }) else: LOG.info( _LI("Successfully set boot device %(boot_device)s for " "node %(node_id)s"), { 'boot_device': boot_device, 'node_id': node.uuid })
def _enable_boot_config(node): """Enable boot configuration of AMT Client. :param node: a node object :raises: AMTFailure :raises: AMTConnectFailure """ amt_common.awake_amt_interface(node) client = amt_common.get_wsman_client(node) method = 'SetBootConfigRole' doc = _generate_enable_boot_config_input() options = pywsman.ClientOptions() options.add_selector('Name', 'Intel(r) AMT Boot Service') try: client.wsman_invoke(options, resource_uris.CIM_BootService, method, doc) except (exception.AMTFailure, exception.AMTConnectFailure) as e: with excutils.save_and_reraise_exception(): LOG.exception(_LE("Failed to enable boot config for node " "%(node_id)s with error: %(error)s."), {'node_id': node.uuid, 'error': e}) else: LOG.info(_LI("Successfully enabled boot config for node %(node_id)s."), {'node_id': node.uuid})