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'] ]
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)