#!/usr/bin/env python # # Examples which makes use of the different python-dmidecode features # This script should be run as root, or else expect permission warnings # # Copyright 2008-2009 Nima Talebi # Copyright 2010 David Sommerseth # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # For the avoidance of doubt the "preferred form" of this code is one which # is in an open unpatent encumbered format. Where cryptographic key signing # forms part of the process of creating an executable the information # including keys needed to generate an equivalently functional executable # are deemed to be part of the source code. # import dmidecode import sys, os from pprint import pprint def print_warnings(): "Simple function, dumping out warnings with a prefix if warnings are found and clearing warning buffer" warn = dmidecode.get_warnings() if warn: print "### WARNING: %s" % warn dmidecode.clear_warnings() # Check if running as root .... provide a warning if not root_user = (os.getuid() == 0 and True or False) if not root_user: print "####" print "#### NOT RUNNING AS ROOT" print "####" print "#### The first run must always be done as root for this example to work." print "#### When not run as root, quite some permission errors might appear" print "####" print "#### If this script is first run as root, it should be possible to run this script" print "#### as an unprivileged user afterwards, with less warnings." print "####" print print #. Test for presence of important functions using /dev/mem... Using the legacy API #. This does not print any decoded info. If the call fails, either a warning will #. be issued or an exception will be raised. This test is now only used to check #. for presence of the legacy API, which "under the hood" uses #. dmidecode.QuerySection(name), where name can be 'bios', 'system', etc. if root_user: print "*** bios ***\n"; dmidecode.bios() print_warnings() print "*** system ***\n"; dmidecode.system() print_warnings() print "*** baseboard ***\n"; dmidecode.baseboard() print_warnings() print "*** chassis ***\n"; dmidecode.chassis() print_warnings() print "*** processor ***\n"; dmidecode.processor() print_warnings() print "*** memory ***\n"; dmidecode.memory() print_warnings() print "*** cache ***\n"; dmidecode.cache() print_warnings() print "*** connector ***\n"; dmidecode.connector() print_warnings() print "*** slot ***\n"; dmidecode.slot() print_warnings() #. Now test get/set of memory device file... print "*** get_dev()" print dmidecode.get_dev() print_warnings() print "*** set_dev('dmidata.dump')" print dmidecode.set_dev("dmidata.dump"); print_warnings() print "*** get_dev()" print dmidecode.get_dev() print_warnings() #. Test taking a dump... if root_user: print "*** Dumping DMI data to dump file" print dmidecode.dump() print_warnings() #. Test reading the dump... Using the preferred API print "*** bios ***\n"; pprint(dmidecode.QuerySection('bios')) print_warnings() print "*** system ***\n"; pprint(dmidecode.QuerySection('system')) print_warnings() print "*** baseboard ***\n"; pprint(dmidecode.QuerySection('baseboard')) print_warnings() print "*** chassis ***\n"; pprint(dmidecode.QuerySection('chassis')) print_warnings() print "*** processor ***\n"; pprint(dmidecode.QuerySection('processor')) print_warnings() print "*** memory ***\n"; pprint(dmidecode.QuerySection('memory')) print_warnings() print "*** cache ***\n"; pprint(dmidecode.QuerySection('cache')) print_warnings() print "*** connector ***\n"; pprint(dmidecode.QuerySection('connector')) print_warnings() print "*** slot ***\n"; pprint(dmidecode.QuerySection('slot')) print_warnings() print "*** Extracting memory information" for v in dmidecode.memory().values(): if type(v) == dict and v['dmi_type'] == 17: pprint(v['data']['Size']), print "*** Querying for DMI type 3 and 7" pprint(dmidecode.type(3)) # <-- Legacy API pprint(dmidecode.QueryTypeId(7)) # <-- preferred API print_warnings() print "*** Querying for the BIOS section" pprint(dmidecode.QuerySection('bios')) print_warnings() # # Test XML stuff # print print print print "---------------------------------------" print "*** *** *** Testing XML API *** *** ***" print "---------------------------------------" print print dmixml = dmidecode.dmidecodeXML() # Fetch all DMI data into a libxml2.xmlDoc object print "*** Getting all DMI data into a XML document variable" dmixml.SetResultType(dmidecode.DMIXML_DOC) # Valid values: dmidecode.DMIXML_DOC, dmidecode.DMIXML_NODE xmldoc = dmixml.QuerySection('all') # Dump the XML to dmidump.xml - formated in UTF-8 decoding print "*** Dumping XML document to dmidump.xml" xmldoc.saveFormatFileEnc('dmidump.xml','UTF-8',1) # Do some XPath queries on the XML document print "*** Doing some XPath queries against the XML document" dmixp = xmldoc.xpathNewContext() # What to look for - XPath expressions keys = ['/dmidecode/SystemInfo/Manufacturer', '/dmidecode/SystemInfo/ProductName', '/dmidecode/SystemInfo/SerialNumber', '/dmidecode/SystemInfo/SystemUUID'] # Extract data and print it for k in keys: data = dmixp.xpathEval(k) for d in data: print "%s: %s" % (k, d.get_content()) del dmixp del xmldoc # Query for only a particular DMI TypeID - 0x04 - Processor print "*** Quering for Type ID 0x04 - Processor - dumping XML document to stdout" dmixml.QueryTypeId(0x04).saveFormatFileEnc('-','UTF-8',1) print_warnings()