Exemplo n.º 1
0
def get_hw_compatible_hosts(hosts):
    """
    Given a list of hosts return a dict of hardware compatible ones, if any.

    Arguments:
    - Hosts (list)

    Returns:
    - Dict mapping hash to hosts
    """

    hardware = {}
    hardware_hash = {}
    for host in hosts:
        rc, out = cli.system("host-disk-list {} --nowrap".format(host))
        table_ = table_parser.table(out)
        device_nodes = table_parser.get_column(table_, "device_node")
        device_type = table_parser.get_column(table_, "device_type")
        size_gib = table_parser.get_column(table_, "size_gib")
        hardware[host] = list(zip(device_nodes, device_type, size_gib))
        LOG.info("Hardware present on host {}: {}".format(
            host, hardware[host]))
        hardware_hash[host] = hash(str(hardware[host]))
        LOG.info("Host {} has hash {}".format(host, hardware_hash[host]))

    # Create reverse lookup of hash to hosts
    hash_to_hosts = {}
    for key, value in hardware_hash.items():
        hash_to_hosts.setdefault(value, []).append(key)

    LOG.info(
        "These are the hardware compatible hosts: {}".format(hash_to_hosts))
    return hash_to_hosts
def check_device_list_against_pci_list(lspci_list_info, sysinv_device_list_tab):
    """
    Checks the host pci info against the output of cli system host-device-list
    Args:
        lspci_list_info: host's pci co-processor list from lspci command
        sysinv_device_list_tab: pci list from cli system host-device-list

    Returns:

    """

    LOG.info("Checking all devices are included in the list")
    sysinv_device_list_tab = table_parser.filter_table(sysinv_device_list_tab, **{'class id': DevClassID.QAT_VF})

    assert len(lspci_list_info) == len(sysinv_device_list_tab['values']), \
        "host devices list:{} and pci list:{} mismatch".format(sysinv_device_list_tab['values'], lspci_list_info)

    # check if pci attribute values are the identical
    for pci in lspci_list_info:
        sysinv_tab = table_parser.filter_table(sysinv_device_list_tab, **{'name': pci['pci_name']})
        assert pci['vendor_name'] == table_parser.get_column(sysinv_tab, 'vendor name')[0]
        assert pci['vendor_id'] == table_parser.get_column(sysinv_tab, 'vendor id')[0]
        assert pci['device_id'] == table_parser.get_column(sysinv_tab, 'device id')[0]
        assert pci['class_id'] == table_parser.get_column(sysinv_tab, 'class id')[0]
        assert pci['pci_address'] == table_parser.get_column(sysinv_tab, 'address')[0]

    LOG.info("All host devices are listed")
Exemplo n.º 3
0
def test_lldp_neighbor_remote_port():
    """
    Tests if LLDP Neighbor remote_port exists on all hosts

    Test Steps:
        - Checks LLDP Neighbor remote_port to ensure it exists
    """

    remote_port_missing = False

    LOG.tc_step("Parsing host-list for hostnames")
    hosts_tab = table_parser.table(cli.system('host-list')[1])
    all_hosts = table_parser.get_column(hosts_tab, 'hostname')

    for host_name in all_hosts:

        LOG.tc_step(
            "Parsing host-lldp-neighbor-list for remote_ports on the " +
            host_name + " host")
        host = table_parser.table(
            cli.system('host-lldp-neighbor-list',
                       '--nowrap {}'.format(host_name))[1])
        host_remote_ports = table_parser.get_column(host, 'remote_port')

        for remote_port in host_remote_ports:

            LOG.tc_step("Checking LLDP remote_port to ensure it exists")
            if remote_port.lower() == 'none' or remote_port == '':
                LOG.tc_step("Port missing")
                remote_port_missing = True

    assert remote_port_missing is False, "Some remote ports are missing from 'system host-lldp-neighbor-list'"
Exemplo n.º 4
0
def check_timestamps_order(table_):
    timestamps = table_parser.get_column(table_, 'Time Stamp')
    for i in range(len(timestamps) - 1):
        current_stamp = timestamps[i]
        prev_stamp = timestamps[i + 1]
        assert current_stamp >= prev_stamp, "Time Stamp {} is smaller than previous stamp in table: \n{}".\
            format(current_stamp, table_)
Exemplo n.º 5
0
def test_system_ntp_modify():
    """
    Test that ntp servers were initially configured and can be reconfigured

    Test Steps:
        - Execute system ntp-show
        - Verify that ntpservers field contains a list of 3 ntp servers
        - Update ntp with new ntp servers
        - Lock/unlock controllers to get rid of config out of date alarm
        - After lock and unlock verify that alarms cleared
    """

    LOG.tc_step("Check 'system ntp-show' contains expected fields")
    table_ = table_parser.table(cli.system('ntp-show')[1])
    expt_sub_fields = ['uuid', 'ntpservers', 'isystem_uuid', 'created_at', 'updated_at']

    actual_fields = table_parser.get_column(table_, 'Property')
    LOG.tc_step("Actual ntp fields Names are {}".format(actual_fields))
    assert set(expt_sub_fields) <= set(actual_fields), "Some expected fields are not included in system show table."

    LOG.tc_step("Modify 'system ntp-modify' and verify that it contains expected fields")
    ntp_pool = NtpPool.NTP_POOL_1
    if sorted(system_helper.get_ntp_values(fields='ntpservers')[0].split(',')) == sorted(ntp_pool.split(',')):
        ntp_pool = NtpPool.NTP_POOL_2

    system_helper.modify_ntp(ntp_servers=ntp_pool)
Exemplo n.º 6
0
def _test_modify_non_existing_cpu_negative(lock_):
    """
    TC1940 cpu data can't be modified for a non existing cpu

    Test Steps:
        - Choose a host to lock and find how many phys cores it has
        - Attempt to change the cpu settings for a phys core that doesn't exist
        - Verify that the cli is rejected

    """
    host = lock_
    table_ = host_helper.get_host_cpu_list_table(host)
    cores = set(table_parser.get_column(table_, 'phy_core'))
    fake_proc_num = 2
    while fake_proc_num in cores:
        fake_proc_num += 1
    fake_proc = 'p{}'.format(fake_proc_num)
    map_ = {fake_proc: 1}
    LOG.tc_step("Attempt to modify fake processor {}'s function to vSwitch".format(fake_proc))
    code, out = host_helper.modify_host_cpu(host, 'vSwitch', fail_ok=True, **map_)
    assert 0 != code, "FAIL: Modifying a non existing processor was not rejected"

    hosts = system_helper.get_hosts()
    name = hosts[len(hosts) - 1] + "a"
    while True:
        if name not in hosts:
            break
        name += "a"
    LOG.tc_step("Attempt to modify fake host {}'s processor p0 function to vSwitch".format(name))
    code, out = host_helper.modify_host_cpu(name, 'vSwitch', p0=1, fail_ok=True)
    LOG.tc_step("Verifying that the cli was rejected")
    assert 1 == code, "FAIL: Modifying a cpu on a non-existant host was not rejected"
Exemplo n.º 7
0
def get_alarms(header='alarm_id',
               name=None,
               strict=False,
               auth_info=Tenant.get('admin'),
               con_ssh=None):
    """

    Args:
        header
        name:
        strict:
        auth_info:
        con_ssh:

    Returns:

    """

    table_ = table_parser.table(cli.openstack('alarm list',
                                              ssh_client=con_ssh,
                                              auth_info=auth_info)[1],
                                combine_multiline_entry=True)
    if name is None:
        return table_parser.get_column(table_, header)

    return table_parser.get_values(table_, header, Name=name, strict=strict)
Exemplo n.º 8
0
    def teardown():
        LOG.fixture_step("Unsuppress all events")
        system_helper.unsuppress_all_events(fail_ok=True)

        LOG.fixture_step("Delete 300.005 alarm(s)")
        active_alarm_tab = system_helper.get_alarms_table(
            query_key='alarm_id', query_value='300.005')
        alarm_uuids = table_parser.get_column(active_alarm_tab, 'UUID')
        system_helper.delete_alarms(alarm_uuids)
Exemplo n.º 9
0
def pre_check_upgrade():
    # con_ssh = ControllerClient.get_active_controller()

    ProjVar.set_var(SOURCE_OPENRC=True)
    is_simplex = system_helper.is_aio_simplex()
    # check if all nodes are unlocked

    admin_states = system_helper.get_hosts(field='administrative')
    assert set(admin_states) == {'unlocked'}

    # check no active alarms in system

    table_ = table_parser.table(cli.system('alarm-list')[1])
    alarm_severity_list = table_parser.get_column(table_, "Severity")

    LOG.info("Alarm Severity List: {}".format(alarm_severity_list))
    assert "major" or "critical" not in alarm_severity_list, \
        "Active alarms in system. Clear alarms before beginning upgrade"

    # check if system is patch current
    assert patching_helper.is_patch_current(
        con_ssh), "System is not patch current"

    # check if Controller-0 is the active
    active_controller = system_helper.get_active_controller_name(
        con_ssh=con_ssh)
    assert active_controller == "controller-0", "The active controller is " \
                                                "not controller-0. Make controller-0 " \
                                                "active before starting upgrade. Current " \
                                                "active controller is {}".format(active_controller)

    # check if upgrade version is supported
    current_version = system_helper.get_sw_version()
    upgrade_version = UpgradeVars.get_upgrade_var('upgrade_version')
    backup_dest_path = BackupVars.get_backup_var('BACKUP_DEST_PATH')

    if upgrade_version is None:
        upgrade_version = [
            u[1] for u in SUPPORTED_UPGRADES if u[0] == current_version
        ][0]
        UpgradeVars.set_upgrade_var(upgrade_version=upgrade_version)
        UpgradeVars.set_upgrade_var(tis_build_dir=BuildServerPath.
                                    LATEST_HOST_BUILD_PATHS[upgrade_version])
        UpgradeVars.set_upgrade_var(
            patch_dir=BuildServerPath.PATCH_DIR_PATHS[upgrade_version])
    LOG.info("Current version = {}; Upgrade version = {}".format(
        current_version, upgrade_version))

    if upgrade_version == "16.10":
        UpgradeVars.set_upgrade_var(orchestration_after=None)

    assert [current_version, upgrade_version
            ] in SUPPORTED_UPGRADES, "Upgrade from {} to {} is not supported"

    if is_simplex:
        assert backup_dest_path is not None, "Simplex Upgrade need backup destianation path please add " \
                                             "--backup_path=< >"
Exemplo n.º 10
0
def get_upgrade_state(con_ssh=None):

    output = cli.system('upgrade-show', ssh_client=con_ssh)[1]

    if ("+" and "-" and "|") in output:
        table_ = table_parser.table(output)
        table_ = table_parser.filter_table(table_, Property="state")
        return table_parser.get_column(table_, "Value")
    else:
        return output
Exemplo n.º 11
0
def _wait_for_upgrade_data_migration_complete(timeout=1800, check_interval=60, auth_info=Tenant.get('admin_platform'),
                                              fail_ok=False, con_ssh=None):
    """
    Waits until upgrade data migration is complete or fail
    Args:
        timeout (int): MAX seconds to wait for data migration to complete
        fail_ok (bool): if true return error code
        con_ssh (SSHClient):
        auth_info (str):

    Returns (tuple):
        (0, "Upgrade data migration complete.")
        (1, "Upgrade dat migration failed. Applicable only if ail_ok")
        (2, "Upgrade data migration timeout out before complete. Applicable only if fail_ok")
        (3, "Timeout waiting the Host upgrade data migration to complete. Applicable if fail_ok ")

    """

    endtime = time.time() + timeout
    while time.time() < endtime:
        upgrade_progress_tab = table_parser.table(
            cli.system('upgrade-show', ssh_client=con_ssh, auth_info=auth_info)[1])
        upgrade_progress_tab = table_parser.filter_table(upgrade_progress_tab, Property="state")
        if "data-migration-complete" in table_parser.get_column(upgrade_progress_tab, 'Value'):
            LOG.info("Upgrade data migration is complete")
            return 0, "Upgrade data migration is complete"
        elif "data-migration-failed" in table_parser.get_column(upgrade_progress_tab, 'Value'):
            err_msg = "Host Upgrade data migration failed."
            LOG.warning(err_msg)
            if fail_ok:
                return 1, err_msg
            else:
                raise exceptions.HostError(err_msg)

        time.sleep(check_interval)

    err_msg = "Timed out waiting for upgrade data migration to complete state"
    if fail_ok:
        LOG.warning(err_msg)
        return 3, err_msg
    else:
        raise exceptions.HostError(err_msg)
Exemplo n.º 12
0
def get_sensor_names(host, sensor_group=False):
    """

    Args:
        host: Host to query
        sensor_group

    Returns:
        the sensor name
    """

    sensor_table = get_sensors_table(host, sensor_group)
    names = table_parser.get_column(sensor_table, 'name')
    return names
Exemplo n.º 13
0
def get_hosts_upgrade_running_release(hostnames, con_ssh=None):
    """
    Gets the running_release of host(s)
    Args:
        hostnames (str/list): specifies the host or list of hosts
        con_ssh:

    Returns: list of running release ids.

    """
    if isinstance(hostnames, str):
        hostnames = [hostnames]

    table_ = table_parser.table(cli.system('host-upgrade-list', ssh_client=con_ssh)[1])
    table_ = table_parser.filter_table(hostname=hostnames, table_=table_)
    return table_parser.get_column(table_, "running_release")
Exemplo n.º 14
0
def get_hosts_upgrade_target_release(hostnames, con_ssh=None):
    """
    Gets the target release of a upgrade hosts
    Args:
        hostnames(str/list):  specifies the host or list of hosts
        con_ssh:

    Returns:  list of target releases.

    """
    if isinstance(hostnames, str):
        hostnames = [hostnames]

    table_ = table_parser.table(cli.system('host-upgrade-list', ssh_client=con_ssh)[1])
    table_ = table_parser.filter_table(table_, hostname=hostnames)
    return table_parser.get_column(table_, "target_release")
Exemplo n.º 15
0
def traffic_with_preset_configs(ixncfg, ixia_session=None):
    with ExitStack() as stack:
        if ixia_session is None:
            LOG.info("ixia_session not supplied, creating")
            from keywords import ixia_helper
            ixia_session = ixia_helper.IxiaSession()
            ixia_session.connect()
            stack.callback(ixia_session.disconnect)

        ixia_session.load_config(ixncfg)

        subnet_table = table_parser.table(
            cli.openstack('subnet list', auth_info=Tenant.get('admin'))[1])
        cidrs = list(
            map(ipaddress.ip_network,
                table_parser.get_column(subnet_table, 'Subnet')))
        for vport in ixia_session.getList(ixia_session.getRoot(), 'vport'):
            for interface in ixia_session.getList(vport, 'interface'):
                if ixia_session.testAttributes(interface, enabled='true'):
                    ipv4_interface = ixia_session.getList(interface, 'ipv4')[0]
                    gw = ipaddress.ip_address(
                        ixia_session.getAttribute(ipv4_interface, 'gateway'))
                    vlan_interface = ixia_session.getList(interface, 'vlan')[0]
                    for cidr in cidrs:
                        if gw in cidr:
                            net_id = table_parser.get_values(subnet_table,
                                                             'Network',
                                                             cidr=cidr)[0]
                            table = table_parser.table(
                                cli.openstack(
                                    'network show',
                                    net_id,
                                    auth_info=Tenant.get('admin'))[1])
                            seg_id = table_parser.get_value_two_col_table(
                                table, "provider:segmentation_id")
                            ixia_session.configure(vlan_interface,
                                                   vlanEnable=True,
                                                   vlanId=str(seg_id))
                            LOG.info(
                                "vport {} interface {} gw {} vlan updated to {}"
                                .format(vport, interface, gw, seg_id))
Exemplo n.º 16
0
def wait_for_delete_imported_load(load_id, timeout=120, check_interval=5, fail_ok=False, con_ssh=None,
                                  auth_info=Tenant.get('admin_platform')):
    LOG.info("Waiting for imported load  {} to be deleted from the load-list ".format(load_id))
    end_time = time.time() + timeout
    while time.time() < end_time:
        table_ = table_parser.table(cli.system('load-list', ssh_client=con_ssh, auth_info=auth_info)[1])

        table_ = table_parser.filter_table(table_, **{'id': load_id})
        if len(table_parser.get_values(table_, 'id')) == 0:
            return True
        else:
            if 'deleting' in table_parser.get_column(table_, 'state'):
                cli.system('load-delete', load_id, ssh_client=con_ssh, fail_ok=True)
        time.sleep(check_interval)

    else:
        err_msg = "Timed out waiting for load {} to get deleted".format(load_id)
        if fail_ok:
            LOG.warning(err_msg)
            return False
        else:
            raise exceptions.TimeoutException(err_msg)
Exemplo n.º 17
0
def get_system_health_query_upgrade(con_ssh=None):
    """
    Queries the upgrade health of a system in use.
    Args:
        con_ssh:

    Returns: tuple
        (0, None) - success
        (1, dict(error msg) ) -  health query reported 1 or more failures other than missing manifest and alarm
        (2, dict(error msg) ) -  health query reported missing manifest and atleast one alarm
        (3, dict(error msg) ) -  health query reported only minor alarm
        (4, dict(error msg) ) -  health query reported only missing manifest

    """

    output = (cli.system('health-query-upgrade', ssh_client=con_ssh)[1]).splitlines()
    failed = {}
    ok = {}

    for line in output:
        if ":" in line:
            k, v = line.split(":")
            if "[OK]" in v.strip():
                ok[k.strip()] = v.strip()
            elif "[Fail]" in v.strip():
                failed[k.strip()] = v.strip()
        elif "Missing manifests" in line:
            failed[line] = line

    if len(failed) == 0:
        LOG.info("system health is OK to start upgrade......")
        return 0, None

    alarms = any("No alarms" in h for h in failed.keys())
    manifest = any("Missing manifests" in h for h in failed.keys())
    cinder_config = any("Cinder configuration" in h for h in failed.keys())
    err_msg = "System health query upgrade failed: {}".format(failed)
    if len(failed) > 3:
        # more than three health check failures
        LOG.error(err_msg)
        return 1, failed

    if len(failed) == 3:
        # check if the two failures are alarms and manifest,  otherwise return error.
        if not alarms or not manifest or not cinder_config:
            LOG.error(err_msg)
            return 1, failed
    else:
        # Only one health check failure. Return error if not alarm or manifest
        if not alarms and not manifest and not cinder_config:
            LOG.error(err_msg)
            return 1, failed

    if alarms:
        # Check if it alarm
        table_ = table_parser.table(cli.fm('alarm-list')[1])
        alarm_severity_list = table_parser.get_column(table_, "Severity")
        if len(alarm_severity_list) > 0 and \
                ("major" not in alarm_severity_list and "critical" not in alarm_severity_list):
            # minor alarm present
            LOG.warn("System health query upgrade found minor alarms: {}".format(alarm_severity_list))

        else:
            # major/critical alarm present
            LOG.error("System health query upgrade found major or critical alarms: {}".format(alarm_severity_list))
            return 1, failed

    if manifest and alarms:
        return 2, failed

    elif alarms:
        # only minor alarm
        return 3, failed
    else:
        # only missing manifests
        return 4, failed
Exemplo n.º 18
0
def test_system_alarms_and_events_on_lock_unlock_compute(no_simplex):
    """
    Verify fm alarm-show command

    Test Steps:
    - Delete active alarms
    - Lock a host
    - Check active alarm generated for host lock
    - Check relative values are the same in fm alarm-list and fm alarm-show
    <uuid>
    - Check host lock 'set' event logged via fm event-list
    - Unlock host
    - Check active alarms cleared via fm alarm-list
    - Check host lock 'clear' event logged via fm event-list
    """

    # Remove following step because it's unnecessary and fails the test when
    # alarm is re-generated
    # # Clear the alarms currently present
    # LOG.tc_step("Clear the alarms table")
    # system_helper.delete_alarms()

    # Raise a new alarm by locking a compute node
    # Get the compute
    compute_host = host_helper.get_up_hypervisors()[0]
    if compute_host == system_helper.get_active_controller_name():
        compute_host = system_helper.get_standby_controller_name()
        if not compute_host:
            skip('Standby controller unavailable')

    LOG.tc_step("Lock a nova hypervisor host {}".format(compute_host))
    pre_lock_time = common.get_date_in_format()
    HostsToRecover.add(compute_host)
    host_helper.lock_host(compute_host)

    LOG.tc_step("Check host lock alarm is generated")
    post_lock_alarms = \
        system_helper.wait_for_alarm(field='UUID', entity_id=compute_host,
                                     reason=compute_host,
                                     alarm_id=EventLogID.HOST_LOCK,
                                     strict=False,
                                     fail_ok=False)[1]

    LOG.tc_step(
        "Check related fields in fm alarm-list and fm alarm-show are of the "
        "same values")
    post_lock_alarms_tab = system_helper.get_alarms_table(uuid=True)

    alarms_l = ['Alarm ID', 'Entity ID', 'Severity', 'Reason Text']
    alarms_s = ['alarm_id', 'entity_instance_id', 'severity', 'reason_text']

    # Only 1 alarm since we are now checking the specific alarm ID
    for post_alarm in post_lock_alarms:
        LOG.tc_step(
            "Verify {} for alarm {} in alarm-list are in sync with "
            "alarm-show".format(
                alarms_l, post_alarm))

        alarm_show_tab = table_parser.table(cli.fm('alarm-show', post_alarm)[1])
        alarm_list_tab = table_parser.filter_table(post_lock_alarms_tab,
                                                   UUID=post_alarm)

        for i in range(len(alarms_l)):
            alarm_l_val = table_parser.get_column(alarm_list_tab,
                                                  alarms_l[i])[0]
            alarm_s_val = table_parser.get_value_two_col_table(alarm_show_tab,
                                                               alarms_s[i])

            assert alarm_l_val == alarm_s_val, \
                "{} value in alarm-list: {} is different than alarm-show: " \
                "{}".format(alarms_l[i], alarm_l_val, alarm_s_val)

    LOG.tc_step("Check host lock is logged via fm event-list")
    system_helper.wait_for_events(entity_instance_id=compute_host,
                                  start=pre_lock_time, timeout=60,
                                  event_log_id=EventLogID.HOST_LOCK,
                                  fail_ok=False, **{'state': 'set'})

    pre_unlock_time = common.get_date_in_format()
    LOG.tc_step("Unlock {}".format(compute_host))
    host_helper.unlock_host(compute_host)

    LOG.tc_step("Check host lock active alarm cleared")
    alarm_sets = [(EventLogID.HOST_LOCK, compute_host)]
    system_helper.wait_for_alarms_gone(alarm_sets, fail_ok=False)

    LOG.tc_step("Check host lock clear event logged")
    system_helper.wait_for_events(event_log_id=EventLogID.HOST_LOCK,
                                  start=pre_unlock_time,
                                  entity_instance_id=compute_host,
                                  fail_ok=False, **{'state': 'clear'})
Exemplo n.º 19
0
def test_vm_numa_node_settings(vcpus, numa_nodes, numa_node0, numa_node1,
                               no_simplex, check_numa_num):
    """
    Test NUMA nodes settings in flavor extra specs are successfully applied to a vm

    Args:
        vcpus (int): Number of vcpus to set when creating flavor
        numa_nodes (int): Number of NUMA nodes to set in flavor extra specs
        numa_node0 (int): node.0 value in flavor extra specs
        numa_node1 (int): node.1 value in flavor extra specs

    Test Steps:
        - Create a flavor with given number of vcpus specified
        - Add numa_nodes related extra specs
        - Boot a vm with flavor
        - Run vm-topology
        - Verify vcpus, numa nodes, cpulist for specific vm reflects the settings in flavor
        - Ensure that all virtual NICs are associated with guest virtual numa node 0 (tests TC5069)

    Teardown:
        - Delete created vm, volume, and flavor

    """
    if check_numa_num < numa_nodes:
        skip("Number of processors - {} is less than required numa nodes - {}".
             format(check_numa_num, numa_nodes))

    LOG.tc_step("Create flavor with {} vcpus".format(vcpus))
    flavor = nova_helper.create_flavor('numa_vm', vcpus=vcpus)[1]
    ResourceCleanup.add('flavor', flavor, scope='function')

    extra_specs = {
        FlavorSpec.CPU_POLICY: 'dedicated',
        FlavorSpec.NUMA_NODES: numa_nodes,
        FlavorSpec.NUMA_0: numa_node0
    }
    if numa_node1 is not None:
        extra_specs[FlavorSpec.NUMA_1] = numa_node1

    LOG.tc_step("Set following extra specs for flavor {}: {}.".format(
        extra_specs, flavor))
    nova_helper.set_flavor(flavor, **extra_specs)

    LOG.tc_step("Boot vm with flavor {}.".format(flavor))
    vm_id = vm_helper.boot_vm(flavor=flavor, cleanup='function')[1]

    LOG.tc_step("Verify cpu info for vm {} via vm-topology.".format(vm_id))
    nova_tab, libvirt_tab = system_helper.get_vm_topology_tables(
        'servers', 'libvirt')

    # Filter out the line for vm under test
    nova_tab = table_parser.filter_table(nova_tab, ID=vm_id)
    libvirt_tab = table_parser.filter_table(libvirt_tab, uuid=vm_id)

    instance_topology = table_parser.get_column(nova_tab,
                                                'instance_topology')[0]
    cpulist = table_parser.get_column(libvirt_tab, 'cpulist')[0]
    if '-' in cpulist:
        cpulist = cpulist.split(sep='-')
        cpulist_len = int(cpulist[1]) - int(cpulist[0]) + 1
    else:
        cpulist_len = len(cpulist.split(sep=','))
    vcpus_libvirt = int(table_parser.get_column(libvirt_tab, 'vcpus')[0])
    nodelist = table_parser.get_column(libvirt_tab, 'nodelist')[0]

    if isinstance(instance_topology, str):
        instance_topology = [instance_topology]

    # Each numa node will have an entry for given instance, thus number of entries should be the same as number of
    # numa nodes for the vm
    assert numa_nodes == len(instance_topology), \
        "Number of numa node entries for vm {} is different than number of NUMA nodes set in flavor".format(vm_id)

    expected_node_vals = [
        int(val) for val in [numa_node0, numa_node1] if val is not None
    ]
    actual_node_vals = []
    for actual_node_info in instance_topology:
        actual_node_val = int(
            re.findall(InstanceTopology.NODE, actual_node_info)[0])
        actual_node_vals.append(actual_node_val)

    assert expected_node_vals == actual_node_vals, \
        "Individual NUMA node value(s) for vm {} is different than numa_node setting in flavor".format(vm_id)

    assert vcpus == vcpus_libvirt, \
        "Number of vcpus for vm {} in libvirt view is different than what's set in flavor.".format(vm_id)

    assert vcpus == cpulist_len, \
        "Number of entries in cpulist for vm {} in libvirt view is different than number of vcpus set in flavor".format(
                vm_id)

    if '-' in nodelist:
        nodelist = nodelist.split(sep='-')
        nodelist_len = int(nodelist[1]) - int(nodelist[0]) + 1
    else:
        nodelist_len = 1 if nodelist else 0

    assert numa_nodes == nodelist_len, \
        "nodelist for vm {} in libvirt view does not match number of numa nodes set in flavor".format(vm_id)

    if system_helper.is_avs():
        # TC5069
        LOG.tc_step(
            "Check via vshell that all vNICs are associated with the host NUMA node that guest numa0 maps to"
        )
        host = vm_helper.get_vm_host(vm_id)
        actual_ports = network_helper.get_ports(vm_id)
        with host_helper.ssh_to_host(host) as compute_ssh:
            for port_id in actual_ports:
                ports_tab = table_parser.table(
                    compute_ssh.exec_cmd("vshell port-show {}".format(port_id),
                                         fail_ok=False)[1])
                socket_id = int(
                    table_parser.get_value_two_col_table(ports_tab,
                                                         field='socket-id'))
                assert socket_id == numa_node0, "NIC is not associated with numa-node0"
Exemplo n.º 20
0
def create_flavor(name=None,
                  flavor_id=None,
                  vcpus=1,
                  ram=1024,
                  root_disk=None,
                  ephemeral=None,
                  swap=None,
                  is_public=None,
                  rxtx_factor=None,
                  project=None,
                  project_domain=None,
                  description=None,
                  guest_os=None,
                  fail_ok=False,
                  auth_info=Tenant.get('admin'),
                  con_ssh=None,
                  storage_backing=None,
                  rtn_id=True,
                  cleanup=None,
                  add_default_specs=True,
                  properties=None):
    """
    Create a flavor with given criteria.

    Args:
        name (str): substring of flavor name. Whole name will be <name>-<auto_count>.
            e,g., 'myflavor-1'. If None, name will be set to 'flavor'.
        flavor_id (str): auto generated by default unless specified.
        vcpus (int):
        ram (int):
        root_disk (int):
        ephemeral (int):
        swap (int|None):
        is_public (bool):
        rxtx_factor (str):
        project
        project_domain
        description
        guest_os (str|None): guest name such as 'tis-centos-guest' or None - default tis
            guest assumed
        fail_ok (bool): whether it's okay to fail to create a flavor. Default to False.
        auth_info (dict): This is set to Admin by default. Can be set to other tenant for
            negative test.
        con_ssh (SSHClient):
        storage_backing (str): storage backing in extra flavor. Auto set storage backing based on
            system config if None. Valid values: 'local_image', 'remote'
        rtn_id (bool): return id or name
        cleanup (str|None): cleanup scope. function, class, module, or session
        add_default_specs (False): Whether to automatically add extra specs that are needed to
            launch vm
        properties (str|list|dict)

    Returns (tuple): (rtn_code (int), flavor_id/err_msg (str))
        (0, <flavor_id/name>): flavor created successfully
        (1, <stderr>): create flavor cli rejected

    """

    table_ = table_parser.table(
        cli.openstack('flavor list', ssh_client=con_ssh,
                      auth_info=auth_info)[1])
    existing_names = table_parser.get_column(table_, 'Name')

    if name is None:
        name = 'flavor'
    flavor_name = common.get_unique_name(name_str=name,
                                         existing_names=existing_names,
                                         resource_type='flavor')

    if root_disk is None:
        if not guest_os:
            guest_os = GuestImages.DEFAULT['guest']
        root_disk = GuestImages.IMAGE_FILES[guest_os][1]

    args_dict = {
        '--ephemeral': ephemeral,
        '--swap': swap,
        '--rxtx-factor': rxtx_factor,
        '--disk': root_disk,
        '--ram': ram,
        '--vcpus': vcpus,
        '--id': flavor_id,
        '--project': project,
        '--project-domain': project_domain,
        '--description': description,
        '--public': True if is_public else None,
        '--private': True if is_public is False else None,
        '--property': properties,
    }
    args = '{} {}'.format(common.parse_args(args_dict, repeat_arg=True),
                          flavor_name)

    LOG.info("Creating flavor {}...".format(flavor_name))
    LOG.info("openstack flavor create option: {}".format(args))
    exit_code, output = cli.openstack('flavor create',
                                      args,
                                      ssh_client=con_ssh,
                                      fail_ok=fail_ok,
                                      auth_info=auth_info)
    if exit_code > 1:
        return 1, output

    table_ = table_parser.table(output)
    flavor_id = table_parser.get_value_two_col_table(table_, 'id')
    LOG.info("Flavor {} created successfully.".format(flavor_name))

    if cleanup:
        ResourceCleanup.add('flavor', flavor_id, scope=cleanup)

    if add_default_specs:
        extra_specs = {FlavorSpec.MEM_PAGE_SIZE: 'large'}
        # extra_specs = {FlavorSpec.MEM_PAGE_SIZE: 'small'}
        default_flavor_backing = ProjVar.get_var('DEFAULT_INSTANCE_BACKING')
        sys_inst_backing = ProjVar.get_var('INSTANCE_BACKING')
        if not default_flavor_backing:
            from keywords import host_helper
            sys_inst_backing = host_helper.get_hosts_per_storage_backing(
                auth_info=auth_info, con_ssh=con_ssh, refresh=True)
        configured_backings = [
            backing for backing in sys_inst_backing
            if sys_inst_backing.get(backing)
        ]
        LOG.debug(
            "configured backing:{} sys inst backing: {}, required storage backing: {}"
            .format(configured_backings, sys_inst_backing, storage_backing))

        if storage_backing and storage_backing not in configured_backings:
            raise ValueError(
                'Required local_storage {} is not configured on any nova hypervisor'
                .format(storage_backing))

        if len(configured_backings) > 1:
            extra_specs[FlavorSpec.STORAGE_BACKING] = storage_backing if storage_backing else \
                ProjVar.get_var('DEFAULT_INSTANCE_BACKING')

        if extra_specs:
            LOG.info("Setting flavor specs: {}".format(extra_specs))
            set_flavor(flavor_id,
                       con_ssh=con_ssh,
                       auth_info=auth_info,
                       **extra_specs)

    flavor = flavor_id if rtn_id else flavor_name
    return 0, flavor, storage_backing
Exemplo n.º 21
0
def get_upgraded_host_names(upgrade_release, con_ssh=None):

    table_ = table_parser.table(cli.system('host-upgrade-list', ssh_client=con_ssh)[1])
    table_ = table_parser.filter_table(table_, target_release=upgrade_release)
    return table_parser.get_column(table_, "hostname")
Exemplo n.º 22
0
def vm_tenant2_image_unavailable():
    table_ = table_parser.table(
        cli.openstack('server list', ssh_client=None)
        [1])  # auth_info unspecified, so it will run cli with primary tenant
    return 'tenant2-image' not in table_parser.get_column(table_, 'Name')
Exemplo n.º 23
0
def get_system_health_query_upgrade_2(con_ssh=None):
    """
    Queries the upgrade health of a system in use.
    Args:
        con_ssh:

    Returns: tuple
        (0, None) - success
        (1, dict(error msg) ) -  health query reported 1 or more failures other than missing manifest and alarm
        (2, dict(error msg) ) -  health query reported missing manifest and atleast one alarm
        (3, dict(error msg) ) -  health query reported only minor alarm
        (4, dict(error msg) ) -  health query reported only missing manifest

    """

    output = (cli.system('health-query-upgrade', ssh_client=con_ssh)[1]).splitlines()
    failed = {}
    ok = {}

    for line in output:
        if ":" in line:
            k, v = line.split(":")
            if "[OK]" in v.strip():
                ok[k.strip()] = v.strip()
            elif "[Fail]" in v.strip():
                failed[k.strip()] = v.strip()
            elif "Hosts missing placement configuration" in k:
                failed[k.strip()] = v.strip()
            elif "Incomplete configuration" in k:
                failed[k.strip()] = v.strip()
            elif "Locked or disabled hosts" in k:
                failed[k.strip()] = v.strip()

        elif "Missing manifests" in line:
            failed[line] = line
        elif "alarms found" in line:
            if len(line.split(',')) > 1:
                failed["managment affecting"] = int(line.split(',')[1].strip()[1])

    if len(failed) == 0:
        LOG.info("system health is OK to start upgrade......")
        return 0, None,  None

    actions = {"lock_unlock": [[], ""],
               "force_upgrade": [False, ''],
               "swact": [False, ''],
               }

    for k, v in failed.items():
        if "No alarms" in k:
            table_ = table_parser.table(cli.fm('alarm-list --uuid')[1])
            alarm_severity_list = table_parser.get_column(table_, "Severity")
            if len(alarm_severity_list) > 0 \
                    and "major" not in alarm_severity_list \
                    and "critical" not in alarm_severity_list:
                # minor alarm present
                LOG.warn("System health query upgrade found minor alarms: {}".format(alarm_severity_list))
                actions["force_upgrade"] = [True, "Minor alarms present"]

        elif "managment affecting" in k:
            if v == 0:
                # non management affecting alarm present  use  foce upgrade
                LOG.warn("System health query upgrade found non managment affecting alarms: {}"
                         .format(k))
                actions["force_upgrade"] = [True, "Non managment affecting  alarms present"]

            else:
                # major/critical alarm present,  management affecting
                LOG.error("System health query upgrade found major or critical alarms.")
                return 1, failed, None

        elif "Missing manifests" in k:
            # manifest = True
            if "controller-1" in k:
                if "controller-1" not in actions["lock_unlock"][0]:
                    actions["lock_unlock"][0].append("controller-1")
            if "controller-0" in k:
                if "controller-0" not in actions["lock_unlock"][0]:
                    actions["lock_unlock"][0].append("controller-0")

            actions["lock_unlock"][1] += "Missing manifests;"

        elif any(s in k for s in ("Cinder configuration", "Incomplete configuration")):
            # cinder_config = True
            actions["swact"] = [True, actions["swact"][1] + "Invalid Cinder configuration;"]

        elif "Placement Services Enabled" in k or "Hosts missing placement configuration" in k:
            # placement_services = True
            if "controller-1" in v:
                if "controller-1" not in actions["lock_unlock"][0]:
                    actions["lock_unlock"][0].append("controller-1")
            if "controller-0" in v:
                if "controller-0" not in actions["lock_unlock"][0]:
                    actions["lock_unlock"][0].append("controller-0")
            actions["lock_unlock"][1] += "Missing placement configuration;"
        else:
            err_msg = "System health query upgrade failed: {}".format(failed)
            LOG.error(err_msg)
            return 1, failed,  None

    return 2, failed, actions