Package up2date_client :: Module hardware
[hide private]
[frames] | no frames]

Source Code for Module up2date_client.hardware

  1  # 
  2  # Copyright (c) 1999--2018 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU General Public License, 
  5  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  6  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  8  # along with this software; if not, see 
  9  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 10  # 
 11  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 12  # granted to use or replicate Red Hat trademarks that are incorporated 
 13  # in this software or its documentation. 
 14  # 
 15   
 16  # This thing gets the hardware configuraion out of a system 
 17  """Used to read hardware info from kudzu, /proc, etc""" 
 18  from socket import gethostname, getaddrinfo, AF_INET, AF_INET6 
 19  import socket 
 20  import re 
 21  import os 
 22  import sys 
 23  from up2date_client import config 
 24  from up2date_client import rhnserver 
 25   
 26  from rhn.i18n import ustr 
 27   
 28  try: 
 29      long 
 30  except NameError: # long is not defined in python3 
 31      long = int 
 32   
 33   
 34  # network module for python 2 
 35  try: 
 36      import ethtool 
 37      ethtool_present = True 
 38  except ImportError: 
 39      ethtool_present = False 
 40   
 41  # network module for python3 (Fedora >= 23) 
 42  try: 
 43      import netifaces 
 44      import ipaddress 
 45      netifaces_present = True 
 46  except ImportError: 
 47      netifaces_present = False 
 48   
 49  import gettext 
 50  t = gettext.translation('rhn-client-tools', fallback=True) 
 51  # Python 3 translations don't have a ugettext method 
 52  if not hasattr(t, 'ugettext'): 
 53      t.ugettext = t.gettext 
 54  _ = t.ugettext 
 55   
 56  import dbus 
 57  import dmidecode 
 58  from up2date_client import up2dateLog 
 59   
 60  try: 
 61      from up2date_client.hardware_udev import get_devices, get_computer_info 
 62      using_gudev = 1 
 63  except ImportError: 
 64      try: # F13 and EL6 
 65          from up2date_client.hardware_gudev import get_devices, get_computer_info 
 66          using_gudev = 1 
 67      except ImportError: 
 68          from up2date_client.hardware_hal import check_hal_dbus_status, get_hal_computer, read_hal 
 69          using_gudev = 0 
 70   
 71  # Some systems don't have the _locale module installed 
 72  try: 
 73      import locale 
 74  except ImportError: 
 75      locale = None 
 76   
 77  sys.path.append("/usr/share/rhsm") 
 78  try: 
 79      from subscription_manager.hwprobe import Hardware as SubManHardware 
 80      subscription_manager_available = True 
 81  except ImportError: 
 82      subscription_manager_available = False 
 83   
 84  # this does not change, we can cache it 
 85  _dmi_data           = None 
 86  _dmi_not_available  = 0 
 87   
88 -def dmi_warnings():
89 if not hasattr(dmidecode, 'get_warnings'): 90 return None 91 92 return dmidecode.get_warnings()
93 94 dmi_warn = dmi_warnings() 95 if dmi_warn: 96 dmidecode.clear_warnings() 97 log = up2dateLog.initLog() 98 log.log_debug("Warnings collected during dmidecode import: %s" % dmi_warn) 99
100 -def _initialize_dmi_data():
101 """ Initialize _dmi_data unless it already exist and returns it """ 102 global _dmi_data, _dmi_not_available 103 if _dmi_data is None: 104 if _dmi_not_available: 105 # do not try to initialize it again and again if not available 106 return None 107 else : 108 dmixml = dmidecode.dmidecodeXML() 109 dmixml.SetResultType(dmidecode.DMIXML_DOC) 110 # Get all the DMI data and prepare a XPath context 111 try: 112 data = dmixml.QuerySection('all') 113 dmi_warn = dmi_warnings() 114 if dmi_warn: 115 dmidecode.clear_warnings() 116 log = up2dateLog.initLog() 117 log.log_debug("dmidecode warnings: %s" % dmi_warn) 118 except: 119 # DMI decode FAIL, this can happend e.g in PV guest 120 _dmi_not_available = 1 121 dmi_warn = dmi_warnings() 122 if dmi_warn: 123 dmidecode.clear_warnings() 124 return None 125 _dmi_data = data.xpathNewContext() 126 return _dmi_data
127
128 -def get_dmi_data(path):
129 """ Fetch DMI data from given section using given path. 130 If data could not be retrieved, returns empty string. 131 General method and should not be used outside of this module. 132 """ 133 dmi_data = _initialize_dmi_data() 134 if dmi_data is None: 135 return '' 136 data = dmi_data.xpathEval(path) 137 if data != []: 138 return data[0].content 139 else: 140 # The path do not exist 141 return ''
142
143 -def dmi_vendor():
144 """ Return Vendor from dmidecode bios information. 145 If this value could not be fetch, returns empty string. 146 """ 147 return get_dmi_data('/dmidecode/BIOSinfo/Vendor')
148
149 -def dmi_system_uuid():
150 """ Return UUID from dmidecode system information. 151 If this value could not be fetch, returns empty string. 152 """ 153 # if guest was created manualy it can have empty UUID, in this 154 # case dmidecode set attribute unavailable to 1 155 uuid = get_dmi_data("/dmidecode/SystemInfo/SystemUUID[not(@unavailable='1')]") 156 if not uuid: 157 uuid = '' 158 return uuid
159
160 -def read_installinfo():
161 if not os.access("/etc/sysconfig/installinfo", os.R_OK): 162 return {} 163 installinfo = open("/etc/sysconfig/installinfo", "r").readlines() 164 installdict = {} 165 installdict['class'] = "INSTALLINFO" 166 for info in installinfo: 167 if not len(info): 168 continue 169 vals = info.split('=') 170 if len(vals) <= 1: 171 continue 172 strippedstring = vals[0].strip() 173 vals[0] = strippedstring 174 175 installdict[vals[0]] = ''.join(vals[1:]).strip() 176 return installdict
177
178 -def cpu_count():
179 """ returns number of CPU in system 180 181 Beware that it can be different from number of active CPU (e.g. on s390x architecture 182 """ 183 try: 184 cpu_dir = os.listdir('/sys/devices/system/cpu/') 185 except OSError: 186 cpu_dir = [] 187 188 re_cpu = re.compile(r"^cpu[0-9]+$") 189 return len([i for i in cpu_dir if re_cpu.match(i)])
190 191 # get the number of sockets available on this machine
192 -def __get_number_sockets():
193 try: 194 if subscription_manager_available: 195 return SubManHardware().getCpuInfo()['cpu.cpu_socket(s)'] 196 except: 197 pass # something went wrong, let's figure it out ourselves 198 199 number_sockets = 0 200 # Try lscpu command if available 201 if os.access("/usr/bin/lscpu", os.X_OK): 202 try: 203 lines = os.popen("/usr/bin/lscpu -p").readlines() 204 max_socket_index = -1 205 for line in lines: 206 if line.startswith('#'): 207 continue 208 # get the socket index from the output 209 socket_index = int(line.split(',')[2]) 210 if socket_index > max_socket_index: 211 max_socket_index = socket_index 212 if max_socket_index > -1: 213 return 1 + max_socket_index 214 except: 215 pass 216 217 # Next try parsing /proc/cpuinfo 218 if os.access("/proc/cpuinfo", os.R_OK): 219 try: 220 lines = open("/proc/cpuinfo", 'r').readlines() 221 socket_ids = set() 222 for line in lines: 223 if 'physical id' in line: 224 socket_index = int(line.split(':')[1].strip()) 225 socket_ids.add(socket_index) 226 if len(socket_ids) > 0: 227 return len(socket_ids) 228 except: 229 pass 230 231 # Next try dmidecode 232 if os.access("/usr/sbin/dmidecode", os.X_OK): 233 try: 234 lines = os.popen("/usr/sbin/dmidecode -t processor").readlines() 235 count = 0 236 for line in lines: 237 if 'Processor Information' in line: 238 count += 1 239 if count > 0: 240 return count 241 except: 242 pass 243 244 return None
245 246 # This has got to be one of the ugliest fucntions alive
247 -def read_cpuinfo():
248 def get_entry(a, entry): 249 e = entry.lower() 250 if not e in a: 251 return "" 252 return a[e]
253 254 # read cpu list and return number of cpus and list as dictionary 255 def get_cpulist_as_dict(cpulist): 256 count = 0 257 tmpdict = {} 258 for cpu in cpulist.split("\n\n"): 259 if not len(cpu): 260 continue 261 count = count + 1 262 if count > 1: 263 break # no need to parse rest 264 for cpu_attr in cpu.split("\n"): 265 if not len(cpu_attr): 266 continue 267 vals = cpu_attr.split(":") 268 if len(vals) != 2: 269 # XXX: make at least some effort to recover this data... 270 continue 271 name, value = vals[0].strip(), vals[1].strip() 272 tmpdict[name.lower()] = value 273 return tmpdict 274 275 if not os.access("/proc/cpuinfo", os.R_OK): 276 return {} 277 278 # Okay, the kernel likes to give us the information we need in the 279 # standard "C" locale. 280 if locale: 281 # not really needed if you don't plan on using atof() 282 locale.setlocale(locale.LC_NUMERIC, "C") 283 284 cpulist = open("/proc/cpuinfo", "r").read() 285 uname = os.uname()[4].lower() 286 count = cpu_count() 287 288 # This thing should return a hwdict that has the following 289 # members: 290 # 291 # class, desc (required to identify the hardware device) 292 # count, type, model, model_number, model_ver, model_rev 293 # bogomips, platform, speed, cache 294 295 hwdict = { 'class': "CPU", 296 "desc" : "Processor", 297 } 298 if uname[0] == "i" and uname[-2:] == "86" or (uname == "x86_64"): 299 # IA32 compatible enough 300 tmpdict = get_cpulist_as_dict(cpulist) 301 302 if uname == "x86_64": 303 hwdict['platform'] = 'x86_64' 304 else: 305 hwdict['platform'] = "i386" 306 307 hwdict['count'] = count 308 hwdict['type'] = get_entry(tmpdict, 'vendor_id') 309 hwdict['model'] = get_entry(tmpdict, 'model name') 310 hwdict['model_number'] = get_entry(tmpdict, 'cpu family') 311 hwdict['model_ver'] = get_entry(tmpdict, 'model') 312 hwdict['model_rev'] = get_entry(tmpdict, 'stepping') 313 hwdict['cache'] = get_entry(tmpdict, 'cache size') 314 hwdict['bogomips'] = get_entry(tmpdict, 'bogomips') 315 hwdict['other'] = get_entry(tmpdict, 'flags') 316 mhz_speed = get_entry(tmpdict, 'cpu mhz') 317 if mhz_speed == "": 318 # damn, some machines don't report this 319 mhz_speed = "-1" 320 try: 321 hwdict['speed'] = int(round(float(mhz_speed)) - 1) 322 except ValueError: 323 hwdict['speed'] = -1 324 elif uname in["alpha", "alphaev6"]: 325 # Treat it as an an Alpha 326 tmpdict = get_cpulist_as_dict(cpulist) 327 328 hwdict['platform'] = "alpha" 329 hwdict['count'] = get_entry(tmpdict, 'cpus detected') 330 hwdict['type'] = get_entry(tmpdict, 'cpu') 331 hwdict['model'] = get_entry(tmpdict, 'cpu model') 332 hwdict['model_number'] = get_entry(tmpdict, 'cpu variation') 333 hwdict['model_version'] = "%s/%s" % (get_entry(tmpdict, 'system type'), 334 get_entry(tmpdict,'system variation')) 335 hwdict['model_rev'] = get_entry(tmpdict, 'cpu revision') 336 hwdict['cache'] = "" # pitty the kernel doesn't tell us this. 337 hwdict['bogomips'] = get_entry(tmpdict, 'bogomips') 338 hwdict['other'] = get_entry(tmpdict, 'platform string') 339 hz_speed = get_entry(tmpdict, 'cycle frequency [Hz]') 340 # some funky alphas actually report in the form "462375000 est." 341 hz_speed = hz_speed.split() 342 try: 343 hwdict['speed'] = int(round(float(hz_speed[0]))) / 1000000 344 except ValueError: 345 hwdict['speed'] = -1 346 elif uname in ["ia64"]: 347 tmpdict = get_cpulist_as_dict(cpulist) 348 349 hwdict['platform'] = uname 350 hwdict['count'] = count 351 hwdict['type'] = get_entry(tmpdict, 'vendor') 352 hwdict['model'] = get_entry(tmpdict, 'family') 353 hwdict['model_ver'] = get_entry(tmpdict, 'archrev') 354 hwdict['model_rev'] = get_entry(tmpdict, 'revision') 355 hwdict['bogomips'] = get_entry(tmpdict, 'bogomips') 356 mhz_speed = tmpdict['cpu mhz'] 357 try: 358 hwdict['speed'] = int(round(float(mhz_speed)) - 1) 359 except ValueError: 360 hwdict['speed'] = -1 361 hwdict['other'] = get_entry(tmpdict, 'features') 362 363 elif uname in ['ppc64']: 364 tmpdict = get_cpulist_as_dict(cpulist) 365 366 hwdict['platform'] = uname 367 hwdict['count'] = count 368 hwdict['model'] = get_entry(tmpdict, "cpu") 369 hwdict['model_ver'] = get_entry(tmpdict, 'revision') 370 hwdict['bogomips'] = get_entry(tmpdict, 'bogomips') 371 hwdict['type'] = get_entry(tmpdict, 'machine') 372 # strings are postpended with "mhz" 373 mhz_speed = get_entry(tmpdict, 'clock')[:-3] 374 try: 375 hwdict['speed'] = int(round(float(mhz_speed)) - 1) 376 except ValueError: 377 hwdict['speed'] = -1 378 379 elif uname in ['s390', 's390x']: 380 tmpdict = {} 381 for cpu in cpulist.split("\n"): 382 vals = cpu.split(": ") 383 if len(vals) != 2: 384 continue 385 tmpdict[vals[0].strip()] = vals[1].strip() 386 387 hwdict['platform'] = uname 388 hwdict['type'] = get_entry(tmpdict,'vendor_id') 389 hwdict['model'] = uname 390 hwdict['count'] = count 391 hwdict['bogomips'] = get_entry(tmpdict, 'bogomips per cpu') 392 hwdict['model_number'] = "" 393 hwdict['model_ver'] = "" 394 hwdict['model_rev'] = "" 395 hwdict['cache'] = "" 396 hwdict['other'] = get_entry(tmpdict, 'features') 397 hwdict['speed'] = 0 398 399 400 else: 401 # XXX: expand me. Be nice to others 402 hwdict['platform'] = uname 403 hwdict['count'] = count 404 hwdict['type'] = uname 405 hwdict['model'] = uname 406 hwdict['model_number'] = "" 407 hwdict['model_ver'] = "" 408 hwdict['model_rev'] = "" 409 hwdict['cache'] = "" 410 hwdict['bogomips'] = "" 411 hwdict['other'] = "" 412 hwdict['speed'] = 0 413 414 # make sure we get the right number here 415 if not hwdict["count"]: 416 hwdict["count"] = 1 417 else: 418 try: 419 hwdict["count"] = int(hwdict["count"]) 420 except: 421 hwdict["count"] = 1 422 else: 423 if hwdict["count"] == 0: # we have at least one 424 hwdict["count"] = 1 425 426 # Network communication doesn't really belong in here. Sadly though 427 # this is the only single place we can put this check. If it's not 428 # here then it would need to be in five or six other places, which 429 # is not good from a DRY and quality-assurance perspective. 430 s = rhnserver.RhnServer() 431 if s.capabilities.hasCapability('cpu_sockets'): 432 # If we know it add in the number of sockets 433 number_sockets = __get_number_sockets() 434 if number_sockets: 435 hwdict['socket_count'] = number_sockets 436 437 # This whole things hurts a lot. 438 return hwdict 439
440 -def read_memory():
441 un = os.uname() 442 kernel = un[2] 443 if kernel[:3] >= "2.6": 444 return read_memory_2_6() 445 if kernel[:3] == "2.4": 446 return read_memory_2_4()
447
448 -def read_memory_2_4():
449 if not os.access("/proc/meminfo", os.R_OK): 450 return {} 451 452 meminfo = open("/proc/meminfo", "r").read() 453 lines = meminfo.split("\n") 454 curline = lines[1] 455 memlist = curline.split() 456 memdict = {} 457 memdict['class'] = "MEMORY" 458 megs = int(long(memlist[1])/(1024*1024)) 459 if megs < 32: 460 megs = megs + (4 - (megs % 4)) 461 else: 462 megs = megs + (16 - (megs % 16)) 463 memdict['ram'] = str(megs) 464 curline = lines[2] 465 memlist = curline.split() 466 # otherwise, it breaks on > ~4gigs of swap 467 megs = int(long(memlist[1])/(1024*1024)) 468 memdict['swap'] = str(megs) 469 return memdict
470
471 -def read_memory_2_6():
472 if not os.access("/proc/meminfo", os.R_OK): 473 return {} 474 meminfo = open("/proc/meminfo", "r").read() 475 lines = meminfo.split("\n") 476 meminfo_dict = {} 477 for line in lines: 478 blobs = line.split(":", 1) 479 key = blobs[0] 480 if len(blobs) == 1: 481 continue 482 #print(blobs) 483 value = blobs[1].strip() 484 meminfo_dict[key] = value 485 486 memdict = {} 487 memdict["class"] = "MEMORY" 488 489 total_str = meminfo_dict['MemTotal'] 490 blips = total_str.split(" ") 491 total_k = long(blips[0]) 492 megs = long(total_k/(1024)) 493 494 swap_str = meminfo_dict['SwapTotal'] 495 blips = swap_str.split(' ') 496 swap_k = long(blips[0]) 497 swap_megs = long(swap_k/(1024)) 498 499 memdict['ram'] = str(megs) 500 memdict['swap'] = str(swap_megs) 501 return memdict
502 503
504 -def findHostByRoute():
505 """ returns [hostname, intf, intf6] 506 507 Where hostname is you FQDN of this machine. 508 And intf is numeric IPv4 address. And intf6 is IPv6 address. 509 """ 510 cfg = config.initUp2dateConfig() 511 sl = config.getServerlURL() 512 513 st = {'https':443, 'http':80} 514 hostname = None 515 intf = None 516 intf6 = None 517 for serverUrl in sl: 518 server = serverUrl.split('/')[2] 519 servertype = serverUrl.split(':')[0] 520 port = st[servertype] 521 522 for family in (AF_INET6, AF_INET): 523 try: 524 s = socket.socket(family) 525 except socket.error: 526 continue 527 528 if cfg['enableProxy']: 529 server_port = config.getProxySetting() 530 (server, port) = server_port.split(':') 531 port = int(port) 532 533 try: 534 s.settimeout(5) 535 s.connect((server, port)) 536 intf_tmp = s.getsockname()[0] 537 if family == AF_INET: 538 intf = intf_tmp 539 else: 540 intf6 = intf_tmp 541 hostname_tmp = socket.getfqdn(intf_tmp) 542 if hostname_tmp != intf_tmp: 543 hostname = hostname_tmp 544 except socket.error: 545 s.close() 546 continue 547 s.close() 548 549 # Override hostname with the value from /etc/hostname 550 if os.path.isfile("/etc/hostname") and os.access("/etc/hostname", os.R_OK): 551 hostnameinfo = open("/etc/hostname", "r").readlines() 552 553 for info in hostnameinfo: 554 if not len(info): 555 continue 556 hostname = info.strip() 557 558 # Override hostname with the one in /etc/sysconfig/network 559 # for bz# 457953 560 elif os.path.isfile("/etc/sysconfig/network") and os.access("/etc/sysconfig/network", os.R_OK): 561 networkinfo = open("/etc/sysconfig/network", "r").readlines() 562 563 for info in networkinfo: 564 if not len(info): 565 continue 566 vals = info.split('=') 567 if len(vals) <= 1: 568 continue 569 if vals[0].strip() == "HOSTNAME": 570 # /etc/sysconfig/network is of shell syntax, 571 # so values can be quoted 572 hostname = ''.join(vals[1:]).strip('"\' \t\n') 573 break 574 575 if hostname == None or hostname == 'localhost.localdomain': 576 hostname = "unknown" 577 return hostname, intf, intf6
578
579 -def get_slave_hwaddr(master, slave):
580 hwaddr = "" 581 try: 582 bonding = open('/proc/net/bonding/%s' % master, "r") 583 except: 584 return hwaddr 585 586 slave_found = False 587 for line in bonding.readlines(): 588 if slave_found and line.find("Permanent HW addr: ") != -1: 589 hwaddr = line.split()[3] 590 break 591 592 if line.find("Slave Interface: ") != -1: 593 ifname = line.split()[2] 594 if ifname == slave: 595 slave_found = True 596 597 bonding.close() 598 return hwaddr
599
600 -def read_network():
601 netdict = {} 602 netdict['class'] = "NETINFO" 603 604 netdict['hostname'], netdict['ipaddr'], netdict['ip6addr'] = findHostByRoute() 605 606 if netdict['hostname'] == "unknown": 607 netdict['hostname'] = gethostname() 608 if "." not in netdict['hostname']: 609 netdict['hostname'] = socket.getfqdn() 610 611 if netdict['ipaddr'] is None: 612 try: 613 list_of_addrs = getaddrinfo(netdict['hostname'], None) 614 ipv4_addrs = filter(lambda x:x[0]==socket.AF_INET, list_of_addrs) 615 # take first ipv4 addr 616 netdict['ipaddr'] = ipv4_addrs[0][4][0] 617 except: 618 netdict['ipaddr'] = "127.0.0.1" 619 620 if netdict['ip6addr'] is None: 621 try: 622 list_of_addrs = getaddrinfo(netdict['hostname'], None) 623 ipv6_addrs = filter(lambda x:x[0]==socket.AF_INET6, list_of_addrs) 624 # take first ipv6 addr 625 netdict['ip6addr'] = ipv6_addrs[0][4][0] 626 except: 627 netdict['ip6addr'] = "::1" 628 629 if netdict['ipaddr'] is None: 630 netdict['ipaddr'] = '' 631 if netdict['ip6addr'] is None: 632 netdict['ip6addr'] = '' 633 return netdict
634
635 -def read_network_interfaces():
636 intDict = {} 637 intDict['class'] = "NETINTERFACES" 638 639 if not ethtool_present and not netifaces_present: 640 # ethtool is not available on non-linux platforms (as kfreebsd), skip it 641 sys.stderr.write("Warning: information about network interfaces could not be retrieved on this platform.\n") 642 return intDict 643 644 if ethtool_present: 645 interfaces = list(set(ethtool.get_devices() + ethtool.get_active_devices())) 646 else: 647 interfaces = netifaces.interfaces() 648 649 for interface in interfaces: 650 try: 651 if ethtool_present: 652 hwaddr = ethtool.get_hwaddr(interface) 653 else: 654 hwaddr = netifaces.ifaddresses(interface)[netifaces.AF_LINK][0]['addr'] 655 except: 656 hwaddr = "" 657 658 # slave devices can have their hwaddr changed 659 try: 660 master = os.readlink('/sys/class/net/%s/master' % interface) 661 except: 662 master = None 663 664 if master: 665 master_interface = os.path.basename(master) 666 hwaddr = get_slave_hwaddr(master_interface, interface) 667 668 try: 669 if ethtool_present: 670 module = ethtool.get_module(interface) 671 else: 672 driver_file = open('/sys/class/net/%s/device/uevent' % interface, 'r') 673 module = driver_file.readline().split('=')[1].strip() 674 driver_file.close() 675 except: 676 if interface == 'lo': 677 module = "loopback" 678 else: 679 module = "Unknown" 680 681 try: 682 if ethtool_present: 683 ipaddr = ethtool.get_ipaddr(interface) 684 else: 685 ipaddr = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr'] 686 except: 687 ipaddr = "" 688 689 try: 690 if ethtool_present: 691 netmask = ethtool.get_netmask(interface) 692 else: 693 netmask = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['netmask'] 694 except: 695 netmask = "" 696 697 try: 698 if ethtool_present: 699 broadcast = ethtool.get_broadcast(interface) 700 else: 701 broadcast = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['broadcast'] 702 except: 703 broadcast = "" 704 705 ip6_list = [] 706 if ethtool_present: 707 dev_info = ethtool.get_interfaces_info(interface) 708 for info in dev_info: 709 # one interface may have more IPv6 addresses 710 for ip6 in info.get_ipv6_addresses(): 711 scope = ip6.scope 712 if scope == 'global': 713 scope = 'universe' 714 ip6_list.append({ 715 'scope': scope, 716 'addr': ip6.address, 717 'netmask': ip6.netmask 718 }) 719 720 else: 721 try: 722 for dev_info in netifaces.ifaddresses(interface)[netifaces.AF_INET6]: 723 ip6_addr = dev_info['addr'].split('%')[0] 724 725 scope_info = ipaddress.IPv6Address(ip6_addr) 726 if scope_info.is_global: 727 scope = 'universe' 728 elif scope_info.is_link_local: 729 scope = 'link' 730 elif scope_info.is_loopback: 731 scope = 'host' 732 elif scope_info.is_site_local: 733 scope = 'site' 734 735 # count number of '1' bits in netmask returned by netifaces 736 ip6_netmask = dev_info['netmask'] 737 netmask_bits = 0 738 for two_octets in ip6_netmask.split(':'): 739 if not two_octets: 740 break 741 elif two_octets.lower() == 'ffff': 742 netmask_bits += 16 743 else: 744 # remove '0b' from begin and find last '1' in the string 745 netmask_bits += 1 + bin(int(two_octets.split('/')[0], 16))[2:].rindex('1') 746 747 ip6_list.append({ 748 'scope': scope, 749 'addr': ip6_addr, 750 'netmask': netmask_bits 751 }) 752 except KeyError: 753 pass # no ipv6 for this interface 754 755 intDict[interface] = {'hwaddr': hwaddr, 756 'ipaddr': ipaddr, 757 'netmask': netmask, 758 'broadcast': broadcast, 759 'module': module, 760 'ipv6': ip6_list} 761 762 return intDict
763 764 765 # Read DMI information via hal.
766 -def read_dmi():
767 dmidict = {} 768 dmidict["class"] = "DMI" 769 770 # Try to obtain DMI info if architecture is i386, x86_64 or ia64 771 uname = os.uname()[4].lower() 772 if not (uname[0] == "i" and uname[-2:] == "86") and not (uname == "x86_64"): 773 return dmidict 774 775 # System Information 776 vendor = dmi_vendor() 777 if vendor: 778 dmidict["vendor"] = vendor 779 780 product = get_dmi_data('/dmidecode/SystemInfo/ProductName') 781 if product: 782 dmidict["product"] = product 783 784 version = get_dmi_data('/dmidecode/SystemInfo/Version') 785 if version: 786 system = product + " " + version 787 dmidict["system"] = system 788 789 # BaseBoard Information 790 dmidict["board"] = get_dmi_data('/dmidecode/BaseBoardInfo/Manufacturer') 791 792 # Bios Information 793 vendor = get_dmi_data('/dmidecode/BIOSinfo/Vendor') 794 if vendor: 795 dmidict["bios_vendor"] = vendor 796 version = get_dmi_data('/dmidecode/BIOSinfo/Version') 797 if version: 798 dmidict["bios_version"] = version 799 release = get_dmi_data('/dmidecode/BIOSinfo/ReleaseDate') 800 if release: 801 dmidict["bios_release"] = release 802 803 # Chassis Information 804 # The hairy part is figuring out if there is an asset tag/serial number of importance 805 chassis_serial = get_dmi_data('/dmidecode/ChassisInfo/SerialNumber') 806 chassis_tag = get_dmi_data('/dmidecode/ChassisInfo/AssetTag') 807 board_serial = get_dmi_data('/dmidecode/BaseBoardInfo/SerialNumber') 808 809 system_serial = get_dmi_data('/dmidecode/SystemInfo/SerialNumber') 810 811 dmidict["asset"] = "(%s: %s) (%s: %s) (%s: %s) (%s: %s)" % ("chassis", chassis_serial, 812 "chassis", chassis_tag, 813 "board", board_serial, 814 "system", system_serial) 815 816 # Clean up empty entries 817 for k in list(dmidict.keys()): 818 if dmidict[k] is None: 819 del dmidict[k] 820 # Finished 821 822 return dmidict
823
824 -def get_hal_system_and_smbios():
825 try: 826 if using_gudev: 827 props = get_computer_info() 828 else: 829 computer = get_hal_computer() 830 props = computer.GetAllProperties() 831 except Exception: 832 log = up2dateLog.initLog() 833 msg = "Error reading system and smbios information: %s\n" % (sys.exc_info()[1]) 834 log.log_debug(msg) 835 return {} 836 system_and_smbios = {} 837 838 for key in props: 839 if key.startswith('system'): 840 system_and_smbios[ustr(key)] = ustr(props[key]) 841 842 system_and_smbios.update(get_smbios()) 843 return system_and_smbios
844
845 -def get_smbios():
846 """ Returns dictionary with values we are interested for. 847 For historical reason it is in format, which use HAL. 848 Currently in dictionary are keys: 849 smbios.system.uuid, smbios.bios.vendor, smbios.system.serial, 850 smbios.system.manufacturer. 851 """ 852 _initialize_dmi_data() 853 if _dmi_not_available: 854 return {} 855 else: 856 return { 857 'smbios.system.uuid': dmi_system_uuid(), 858 'smbios.bios.vendor': dmi_vendor(), 859 'smbios.system.serial': get_dmi_data('/dmidecode/SystemInfo/SerialNumber'), 860 'smbios.system.manufacturer': get_dmi_data('/dmidecode/SystemInfo/Manufacturer'), 861 'smbios.system.product': get_dmi_data('/dmidecode/SystemInfo/ProductName'), 862 'smbios.system.skunumber': get_dmi_data('/dmidecode/SystemInfo/SKUnumber'), 863 'smbios.system.family': get_dmi_data('/dmidecode/SystemInfo/Family'), 864 'smbios.system.version': get_dmi_data('/dmidecode/SystemInfo/Version'), 865 }
866 867 # this one reads it all
868 -def Hardware():
869 if using_gudev: 870 allhw = get_devices() 871 else: 872 hal_status, dbus_status = check_hal_dbus_status() 873 hwdaemon = 1 874 if hal_status or dbus_status: 875 # if status != 0 haldaemon or messagebus service not running. 876 # set flag and dont try probing hardware and DMI info 877 # and warn the user. 878 log = up2dateLog.initLog() 879 msg = "Warning: haldaemon or messagebus service not running. Cannot probe hardware and DMI information.\n" 880 log.log_me(msg) 881 hwdaemon = 0 882 allhw = [] 883 884 if hwdaemon: 885 try: 886 ret = read_hal() 887 if ret: 888 allhw = ret 889 except: 890 # bz253596 : Logging Dbus Error messages instead of printing on stdout 891 log = up2dateLog.initLog() 892 msg = "Error reading hardware information: %s\n" % (sys.exc_info()[0]) 893 log.log_me(msg) 894 895 # all others return individual arrays 896 897 # cpu info 898 try: 899 ret = read_cpuinfo() 900 if ret: allhw.append(ret) 901 except: 902 print(_("Error reading cpu information:"), sys.exc_info()[0]) 903 904 # memory size info 905 try: 906 ret = read_memory() 907 if ret: allhw.append(ret) 908 except: 909 print(_("Error reading system memory information:"), sys.exc_info()[0]) 910 911 cfg = config.initUp2dateConfig() 912 if not cfg["skipNetwork"]: 913 # minimal networking info 914 try: 915 ret = read_network() 916 if ret: 917 allhw.append(ret) 918 except: 919 print(_("Error reading networking information:"), sys.exc_info()[0]) 920 # dont like catchall exceptions but theres not 921 # really anything useful we could do at this point 922 # and its been trouble prone enough 923 924 # minimal DMI info 925 try: 926 ret = read_dmi() 927 if ret: 928 allhw.append(ret) 929 except: 930 # bz253596 : Logging Dbus Error messages instead of printing on stdout 931 log = up2dateLog.initLog() 932 msg = "Error reading DMI information: %s\n" % (sys.exc_info()[0]) 933 log.log_me(msg) 934 935 try: 936 ret = read_installinfo() 937 if ret: 938 allhw.append(ret) 939 except: 940 print(_("Error reading install method information:"), sys.exc_info()[0]) 941 942 if not cfg["skipNetwork"]: 943 try: 944 ret = read_network_interfaces() 945 if ret: 946 allhw.append(ret) 947 except: 948 print(_("Error reading network interface information:"), sys.exc_info()[0]) 949 950 # all Done. 951 return allhw
952 953 # XXX: Need more functions here: 954 # - filesystems layout (/proc.mounts and /proc/mdstat) 955 # - is the kudzu config enough or should we strat chasing lscpi and try to parse that 956 # piece of crap output? 957 958 # 959 # Main program 960 # 961 if __name__ == '__main__': 962 for hw in Hardware(): 963 for k in hw.keys(): 964 print("'%s' : '%s'" % (k, hw[k])) 965 print 966