Esempio n. 1
0
def ipmi_set_bootdev(bootdev,
                     persist=False,
                     config_path=None,
                     client_list=None):
    log = logger.getlogger()
    inv = Inventory(cfg_file=config_path)

    if type(persist) is not bool:
        persist = (persist == 'True')

    # if client list passed, then use the passed client list,
    # otherwise use the entire inventory list. This allows a
    # subset of nodes to have their bootdev updated during install
    if not client_list:
        client_list = inv.get_nodes_pxe_ipaddr(0)
    max_attempts = 5
    attempt = 0
    clients_left = client_list[:]
    clients_left.sort()
    while clients_left and attempt < max_attempts:
        nodes = {}
        attempt += 1
        if attempt > 1:
            print('Retrying set bootdev. Attempt {} of {}'.format(
                attempt, max_attempts))
            print('Clients remaining: {}'.format(clients_left))
        clients_set = []
        bmc_dict = {}
        for index, hostname in enumerate(inv.yield_nodes_hostname()):
            ipv4 = inv.get_nodes_ipmi_ipaddr(0, index)
            ipv4_pxe = inv.get_nodes_pxe_ipaddr(0, index)
            if ipv4_pxe not in clients_left:
                continue
            rack_id = inv.get_nodes_rack_id(index)
            userid = inv.get_nodes_ipmi_userid(index)
            password = inv.get_nodes_ipmi_password(index)
            nodes[ipv4_pxe] = [rack_id, ipv4]
            for i in range(2):
                try:
                    bmc_dict[ipv4_pxe] = ipmi_command.Command(
                        bmc=ipv4, userid=userid, password=password)
                except pyghmi_exception.IpmiException as error:
                    log.error('IPMI login try {}, address {} - {}'.format(
                        i, ipv4, error.message))
                    time.sleep(1)
                else:
                    break

        for client in clients_left:
            if client in bmc_dict:
                try:
                    status = bmc_dict[client].set_bootdev(bootdev, persist)
                    if attempt in [2, 4, 8]:
                        print('{} - {}'.format(client, status))
                except pyghmi_exception.IpmiException as error:
                    msg = ('set_bootdev failed (device=%s persist=%s), '
                           'Rack: %s - IP: %s, %s' %
                           (bootdev, persist, nodes[client][0],
                            nodes[client][1], str(error)))
                    log.warning(msg)
                finally:
                    if 'error' in status:
                        log.error(status)

        time.sleep(2)

        for client in clients_left:
            if client in bmc_dict:
                try:
                    status = bmc_dict[client].get_bootdev()
                    if attempt in [2, 4, 8]:
                        print('{} - {}'.format(client, status))
                except pyghmi_exception.IpmiException as error:
                    msg = ('get_bootdev failed - '
                           'Rack: %s - IP: %s, %s' %
                           (rack_id, ipv4, str(error)))
                    log.error(msg)
                else:
                    if status['bootdev'] == bootdev and str(status['persistent']) \
                            == str(persist):
                        log.debug(
                            'set_bootdev successful (device=%s persist=%s) - '
                            'Rack: %s - IP: %s' %
                            (bootdev, persist, nodes[client][0],
                             nodes[client][1]))
                        clients_set += [client]
                finally:
                    if 'error' in status:
                        log.error(status)
                bmc_dict[client].ipmi_session.logout()

        for client in clients_set:
            clients_left.remove(client)

        if attempt == max_attempts and clients_left:
            log.error('Failed to set boot device for some clients')
            log.debug(clients_left)

        del bmc_dict
    log.info('Set boot device to {} on {} of {} client devices.'.format(
        bootdev,
        len(client_list) - len(clients_left), len(client_list)))
Esempio n. 2
0
def ipmi_set_power(state, config_path=None, client_list=None, max_attempts=5,
                   wait=6):
    """Set power on or off
    Args:
        state (str) : 'on' or 'off'
        client_list (list of str): list of IP addresses
    """
    log = logger.getlogger()
    inv = Inventory(config_path)
    wait = float(wait)
    max_attempts = int(max_attempts)

    if not client_list:
        log.debug('Retrieving IPMI address list from inventory')
        client_list = inv.get_nodes_ipmi_ipaddr(0)

    clients_left = client_list[:]
    attempt = 0

    none_cnt = 0
    for client in client_list:
        if client is None:
            none_cnt += 1
            log.warning('client node ip address is "None"')
            clients_left.remove(None)

    clients_left.sort()
    while clients_left and attempt < max_attempts:
        nodes = {}
        attempt += 1
        if attempt > 1:
            print('Retrying set power {}. Attempt {} of {}'
                  .format(state, attempt, max_attempts))
            print('Clients remaining: {}'.format(clients_left))
        clients_set = []
        bmc_dict = {}
        for index, hostname in enumerate(inv.yield_nodes_hostname()):
            ipv4 = inv.get_nodes_ipmi_ipaddr(0, index)
            if ipv4 is None or ipv4 not in clients_left:
                continue
            rack_id = inv.get_nodes_rack_id(index)
            userid = inv.get_nodes_ipmi_userid(index)
            password = inv.get_nodes_ipmi_password(index)
            nodes[ipv4] = [rack_id, ipv4]
            for i in range(2):
                try:
                    bmc_dict[ipv4] = ipmi_command.Command(
                        bmc=ipv4,
                        userid=userid,
                        password=password)
                except pyghmi_exception.IpmiException as error:
                    log.error('IPMI login attempt {}, address {}\nIPMI error'
                              'message: {}'.format(i, ipv4, error.message))
                    time.sleep(1)
                else:
                    break

        for client in clients_left:
            if client in bmc_dict:
                try:
                    log.debug('Setting power state to {}. Device: {}'
                              .format(state, client))
                    status = bmc_dict[client].set_power(state, wait)
                    if attempt in [2, 4, 8]:
                        print('{} - {}'.format(client, status))
                except pyghmi_exception.IpmiException as error:
                    msg = ('set_power failed Rack: %s - IP: %s, \n%s' %
                           (nodes[client][0], nodes[client][1], str(error)))
                    log.error(msg)
                else:
                    # Allow delay between turn on to limit power surge
                    if state == 'on':
                        time.sleep(0.5)
                finally:
                    if 'error' in status:
                        log.error(status)

        time.sleep(wait + attempt)

        for client in clients_left:
            if client in bmc_dict:
                try:
                    status = bmc_dict[client].get_power()
                    if attempt in [2, 4, 8]:
                        print('{} - {}'.format(client, status))
                except pyghmi_exception.IpmiException as error:
                    msg = ('get_power failed - Rack: %s - IP: %s, %s' %
                           (rack_id, ipv4, str(error)))
                    log.error(msg)
                else:
                    if status['powerstate'] == state:
                        log.debug('set_power successful Rack: %s - IP: %s' %
                                  (nodes[client][0], nodes[client][1]))
                        clients_set += [client]
                finally:
                    if 'error' in status:
                        log.error(status)
                bmc_dict[client].ipmi_session.logout()

        for client in clients_set:
            clients_left.remove(client)

        if attempt == max_attempts and clients_left:
            log.error('Failed to power {} some clients'.format(state))
            log.error(clients_left)

        del bmc_dict

    log.info('Powered {} {} of {} client devices.'
             .format(state, len(client_list) - (len(clients_left) + none_cnt),
                     len(client_list)))

    if state == 'off':
        print('Pausing 60 sec for client power off')
        time.sleep(60)

    if clients_left:
        return False
    return True