Example #1
0
    def test_get_uuid_x86_64(self, mock_uname, mock_popen):
        # This is more complex and 'magic' than I'd like :/
        process_mock = mock.Mock()
        attrs = {'communicate.return_value': ('83462C81-52BA-11CB-870F', '')}
        process_mock.configure_mock(**attrs)
        mock_popen.return_value = process_mock

        hw_list = []
        system_uuid = detect_utils.get_uuid(hw_list)
        mock_popen.assert_has_calls([
            mock.call("dmidecode -t 1 | grep UUID | " "awk '{print $2}'",
                      shell=True, stdout=subprocess.PIPE,
                      universal_newlines=True)])
        self.assertEqual('83462C81-52BA-11CB-870F', system_uuid)
Example #2
0
 def test_get_uuid_ppc64le_no_hw_list(self, mock_uname):
     hw_list = []
     self.assertIsNone(detect_utils.get_uuid(hw_list))
Example #3
0
 def test_get_uuid_ppc64le_missing_vendor(self, mock_uname):
     hw_list = [('sys_cls', 'sys_type', 'serial', '1234567A')]
     self.assertIsNone(detect_utils.get_uuid(hw_list))
Example #4
0
 def test_get_uuid_ppc64le_missing_serial(self, mock_uname):
     hw_list = [('sys_cls', 'sys_type', 'vendor', 'IBM')]
     self.assertIsNone(detect_utils.get_uuid(hw_list))
Example #5
0
 def test_get_uuid_ppc64le_ok_read(self, mock_uname):
     hw_list = [('sys_cls', 'sys_type', 'vendor', 'IBM'),
                ('sys_cls', 'sys_type', 'serial', '1234567A')]
     self.assertEqual('a2724b67-c27e-5e5f-aa2b-3089a2bd8f41',
                      detect_utils.get_uuid(hw_list))
Example #6
0
 def test_get_uuid_ppc64le_ok_generate(self, mock_access, mock_uname):
     expected_uuid = 'a2724b67-c27e-5e5f-aa2b-3089a2bd8f41'
     fileobj = mock.mock_open(read_data=expected_uuid)
     with mock.patch('builtins.open', fileobj, create=True):
         uuid = detect_utils.get_uuid([])
     self.assertEqual(expected_uuid, uuid)
Example #7
0
def detect(output=None):
    """Detect system characteristics from the output of lshw."""

    hw_lst = []

    def _find_element(xml,
                      xml_spec,
                      sys_subtype,
                      sys_type='product',
                      sys_cls='system',
                      attrib=None,
                      transform=None):
        """Lookup an xml element and populate hw_lst when found."""
        elt = xml.findall(xml_spec)
        if len(elt) >= 1:
            if attrib:
                txt = elt[0].attrib[attrib]
            else:
                txt = elt[0].text
            if transform:
                txt = transform(txt)
            hw_lst.append((sys_cls, sys_type, sys_subtype, txt))
            return txt
        return None

    # handle output injection for testing purpose
    if output:
        status = 0
    else:
        status, output = detect_utils.cmd('lshw -xml')
    if status == 0:
        mobo_id = ''
        nic_id = ''
        xml = ET.fromstring(output)
        _find_element(xml, "./node/serial", 'serial')
        _find_element(xml, "./node/product", 'name')
        _find_element(xml, "./node/vendor", 'vendor')
        _find_element(xml, "./node/version", 'version')
        uuid = detect_utils.get_uuid(hw_lst)

        if uuid:
            # If we have an uuid, we shall check if it's part of a
            # known list of broken uuid
            # If so let's delete the uuid instead of reporting a stupid thing
            if uuid in ['Not']:
                uuid = ''
            else:
                hw_lst.append(('system', 'product', 'uuid', uuid))

        for elt in xml.findall(".//node[@id='core']"):
            name = elt.find('physid')
            if name is not None:
                _find_element(elt, 'product', 'name', 'motherboard', 'system')
                _find_element(elt, 'vendor', 'vendor', 'motherboard', 'system')
                _find_element(elt, 'version', 'version', 'motherboard',
                              'system')
                _find_element(elt, 'serial', 'serial', 'motherboard', 'system')
                mobo_id = detect_utils.get_value(hw_lst, 'system',
                                                 'motherboard', 'serial')

        for elt in xml.findall(".//node[@id='firmware']"):
            name = elt.find('physid')
            if name is not None:
                _find_element(elt, 'version', 'version', 'bios', 'firmware')
                _find_element(elt, 'date', 'date', 'bios', 'firmware')
                _find_element(elt, 'vendor', 'vendor', 'bios', 'firmware')

        bank_count = 0
        for elt in xml.findall(".//node[@class='memory']"):
            if not elt.attrib['id'].startswith('memory'):
                continue
            try:
                location = re.search('memory(:.*)', elt.attrib['id']).group(1)
            except AttributeError:
                location = ''
            name = elt.find('physid')
            if name is not None:
                _find_element(elt, 'size', 'size', 'total', 'memory')
                for bank_list in elt.findall(".//node[@id]"):
                    if 'bank:' in bank_list.get('id'):
                        bank_count = bank_count + 1
                        for bank in elt.findall(".//node[@id='%s']" %
                                                (bank_list.get('id'))):
                            bank_id = bank_list.get('id').replace(
                                "bank:", "bank" + location + ":")
                            _find_element(bank, 'size', 'size', bank_id,
                                          'memory')
                            _find_element(bank, 'clock', 'clock', bank_id,
                                          'memory')
                            _find_element(bank, 'description', 'description',
                                          bank_id, 'memory')
                            _find_element(bank, 'vendor', 'vendor', bank_id,
                                          'memory')
                            _find_element(bank, 'product', 'product', bank_id,
                                          'memory')
                            _find_element(bank, 'serial', 'serial', bank_id,
                                          'memory')
                            _find_element(bank, 'slot', 'slot', bank_id,
                                          'memory')
        if bank_count > 0:
            hw_lst.append(('memory', 'banks', 'count', str(bank_count)))

        for elt in xml.findall(".//node[@class='network']"):
            name = elt.find('logicalname')
            if name is not None:
                _find_element(elt, 'businfo', 'businfo', name.text, 'network')
                _find_element(elt, 'vendor', 'vendor', name.text, 'network')
                _find_element(elt, 'product', 'product', name.text, 'network')
                _find_element(elt, "configuration/setting[@id='firmware']",
                              'firmware', name.text, 'network', 'value')
                _find_element(elt, 'size', 'size', name.text, 'network')
                ipv4 = _find_element(elt, "configuration/setting[@id='ip']",
                                     'ipv4', name.text, 'network', 'value')
                if ipv4 is not None:
                    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
                    try:
                        netmask = socket.inet_ntoa(
                            fcntl.ioctl(
                                sock, SIOCGIFNETMASK,
                                struct.pack('256s',
                                            name.text.encode('utf-8')))[20:24])
                        hw_lst.append(
                            ('network', name.text, 'ipv4-netmask', netmask))
                        cidr = detect_utils.get_cidr(netmask)
                        hw_lst.append(
                            ('network', name.text, 'ipv4-cidr', cidr))
                        net = (ipaddress.IPv4Interface(
                            '%s/%s' % (ipv4, cidr)).network.network_address)
                        hw_lst.append(
                            ('network', name.text, 'ipv4-network', str(net)))
                    except Exception as excpt:
                        sys.stderr.write('unable to get info for %s: %s\n' %
                                         (name.text, str(excpt)))

                _find_element(elt, "configuration/setting[@id='link']", 'link',
                              name.text, 'network', 'value')
                _find_element(elt, "configuration/setting[@id='driver']",
                              'driver', name.text, 'network', 'value')
                _find_element(elt, "configuration/setting[@id='duplex']",
                              'duplex', name.text, 'network', 'value')
                _find_element(elt, "configuration/setting[@id='speed']",
                              'speed', name.text, 'network', 'value')
                _find_element(elt, "configuration/setting[@id='latency']",
                              'latency', name.text, 'network', 'value')
                _find_element(elt,
                              "configuration/setting[@id='autonegotiation']",
                              'autonegotiation', name.text, 'network', 'value')

                # lshw is not able to get the complete mac addr for ib
                # devices Let's workaround it with an ip command.
                if name.text.startswith('ib'):
                    cmds = "ip addr show %s | grep link | awk '{print $2}'"
                    status_ip, output_ip = detect_utils.cmd(cmds % name.text)
                    if status_ip == 0:
                        hw_lst.append(('network', name.text, 'serial',
                                       output_ip.split('\n')[0].lower()))
                else:
                    _find_element(elt,
                                  'serial',
                                  'serial',
                                  name.text,
                                  'network',
                                  transform=lambda x: x.lower())

                if not nic_id:
                    nic_id = detect_utils.get_value(hw_lst, 'network',
                                                    name.text, 'serial')
                    nic_id = nic_id.replace(':', '')

                detect_utils.get_ethtool_status(hw_lst, name.text)
                detect_utils.get_lld_status(hw_lst, name.text)

        detect_utils.fix_bad_serial(hw_lst, uuid, mobo_id, nic_id)

    else:
        sys.stderr.write("Unable to run lshw: %s\n" % output)
        return []

    detect_utils.get_cpus(hw_lst)

    osvendor_cmd = detect_utils.output_lines("lsb_release -is")
    for line in osvendor_cmd:
        hw_lst.append(('system', 'os', 'vendor', line.rstrip('\n').strip()))

    osinfo_cmd = detect_utils.output_lines("lsb_release -ds | tr -d '\"'")
    for line in osinfo_cmd:
        hw_lst.append(('system', 'os', 'version', line.rstrip('\n').strip()))

    uname_cmd = detect_utils.output_lines("uname -r")
    for line in uname_cmd:
        hw_lst.append(
            ('system', 'kernel', 'version', line.rstrip('\n').strip()))

    arch_cmd = detect_utils.output_lines("uname -i")
    for line in arch_cmd:
        hw_lst.append(('system', 'kernel', 'arch', line.rstrip('\n').strip()))

    cmdline_cmd = detect_utils.output_lines("cat /proc/cmdline")
    for line in cmdline_cmd:
        hw_lst.append(
            ('system', 'kernel', 'cmdline', line.rstrip('\n').strip()))
    return hw_lst