rename util get_block_device_list into get_block_devices_dict and clean up its usage
[bootmanager.git] / source / systeminfo.py
index 23b4343..3140755 100755 (executable)
@@ -1,5 +1,5 @@
-#!/usr/bin/python2
-
+#!/usr/bin/python
+#
 # Copyright (c) 2003 Intel Corporation
 # All rights reserved.
 #
 # Copyright (c) 2003 Intel Corporation
 # All rights reserved.
 #
 #3     4   18804082 hda4
 #----------------------------------------------------
 
 #3     4   18804082 hda4
 #----------------------------------------------------
 
+from __future__ import print_function
 
 import string
 import sys
 import os
 import popen2
 
 import string
 import sys
 import os
 import popen2
-import merge_hw_tables
 import re
 import errno
 import ModelOptions
 import re
 import errno
 import ModelOptions
+from pypci import *
 from Exceptions import *
 
 from Exceptions import *
 
-hwdatapath = "usr/share/hwdata"
 """
 a utility class for finding and returning information about
 block devices, memory, and other hardware on the system
 """
 
 """
 a utility class for finding and returning information about
 block devices, memory, and other hardware on the system
 """
 
-PROC_MEMINFO_PATH= "/proc/meminfo"
-PROC_PARTITIONS_PATH= "/proc/partitions"
+PROC_MEMINFO_PATH = "/proc/meminfo"
+PROC_PARTITIONS_PATH = "/proc/partitions"
 
 # set when the sfdisk -l <dev> trick has been done to make
 # all devices show up
 
 # set when the sfdisk -l <dev> trick has been done to make
 # all devices show up
-DEVICES_SCANNED_FLAG= "/tmp/devices_scanned"
+DEVICES_SCANNED_FLAG = "/tmp/devices_scanned"
 
 # a /proc/partitions block is 1024 bytes
 # a GB to a HDD manufacturer is 10^9 bytes
 BLOCKS_PER_GB = pow(10, 9) / 1024.0;
 
 
 
 # a /proc/partitions block is 1024 bytes
 # a GB to a HDD manufacturer is 10^9 bytes
 BLOCKS_PER_GB = pow(10, 9) / 1024.0;
 
 
-# -n is numeric ids (no lookup), -m is machine readable
-LSPCI_CMD= "/sbin/lspci -nm"
-
-MODULE_CLASS_NETWORK= "network"
-MODULE_CLASS_SCSI= "scsi"
+MODULE_CLASS_NETWORK = "network"
+MODULE_CLASS_SCSI = "scsi"
 
 
-PCI_CLASS_NETWORK_ETHERNET=0x0200L
-PCI_CLASS_STORAGE_SCSI=0x0100L
-PCI_CLASS_STORAGE_SATA=0x0106L
-PCI_CLASS_STORAGE_IDE=0x0101L
-PCI_CLASS_STORAGE_FLOPPY=0x0102L
-PCI_CLASS_STORAGE_IPI=0x0103L
-PCI_CLASS_STORAGE_RAID=0x0104L
-PCI_CLASS_STORAGE_OTHER=0x0180L
-
-PCI_ANY=0xffffffffL
+#PCI_* is now defined in the pypci modules
+#PCI_BASE_CLASS_NETWORK = 0x02L
+#PCI_BASE_CLASS_STORAGE = 0x01L
 
 def get_total_phsyical_mem(vars = {}, log = sys.stderr):
     """
 
 def get_total_phsyical_mem(vars = {}, log = sys.stderr):
     """
@@ -72,28 +62,28 @@ def get_total_phsyical_mem(vars = {}, log = sys.stderr):
     """
 
     try:
     """
 
     try:
-        meminfo_file= file(PROC_MEMINFO_PATH,"r")
-    except IOError, e:
+        meminfo_file = file(PROC_MEMINFO_PATH, "r")
+    except IOError as e:
         return
 
         return
 
-    total_memory= None
+    total_memory = None
 
     for line in meminfo_file:
 
         try:
 
     for line in meminfo_file:
 
         try:
-            (fieldname,value)= string.split(line,":")
-        except ValueError, e:
+            fieldname, value = string.split(line, ":")
+        except ValueError as e:
             # this will happen for lines that don't have two values
             # (like the first line on 2.4 kernels)
             continue
 
             # this will happen for lines that don't have two values
             # (like the first line on 2.4 kernels)
             continue
 
-        fieldname= string.strip(fieldname)
-        value= string.strip(value)
+        fieldname = string.strip(fieldname)
+        value = string.strip(value)
         
         if fieldname == "MemTotal":
             try:
         
         if fieldname == "MemTotal":
             try:
-                (total_memory,units)= string.split(value)
-            except ValueError, e:
+                total_memory, units = string.split(value)
+            except ValueError as e:
                 return
 
             if total_memory == "" or total_memory == None or \
                 return
 
             if total_memory == "" or total_memory == None or \
@@ -104,8 +94,8 @@ def get_total_phsyical_mem(vars = {}, log = sys.stderr):
                 return
 
             try:
                 return
 
             try:
-                total_memory= int(total_memory)
-            except ValueError, e:
+                total_memory = int(total_memory)
+            except ValueError as e:
                 return
 
             break
                 return
 
             break
@@ -113,12 +103,12 @@ def get_total_phsyical_mem(vars = {}, log = sys.stderr):
     meminfo_file.close()
     return total_memory
 
     meminfo_file.close()
     return total_memory
 
-def get_block_device_list(vars = {}, log = sys.stderr):
+def get_block_devices_dict(vars = {}, log = sys.stderr):
     """
     get a list of block devices from this system.
     return an associative array, where the device name
     (full /dev/device path) is the key, and the value
     """
     get a list of block devices from this system.
     return an associative array, where the device name
     (full /dev/device path) is the key, and the value
-    is a tuple of (major,minor,numblocks,gb_size,readonly)
+    is a tuple of (major, minor, numblocks, gb_size, readonly)
     """
 
     # make sure we can access to the files/directories in /proc
     """
 
     # make sure we can access to the files/directories in /proc
@@ -128,17 +118,27 @@ def get_block_device_list(vars = {}, log = sys.stderr):
     # table with valid scsi/sata/ide/raid block device names
     valid_blk_names = {}
     # add in valid sd and hd block device names
     # table with valid scsi/sata/ide/raid block device names
     valid_blk_names = {}
     # add in valid sd and hd block device names
-    for blk_prefix in ('sd','hd'):
-        for blk_num in map ( \
-            lambda x: chr(x), range(ord('a'),ord('z')+1)):
-            devicename="%s%c" % (blk_prefix, blk_num)
-            valid_blk_names[devicename]=None
+    # also check for vd (virtio devices used with kvm)
+    for blk_prefix in ('sd', 'hd', 'vd'):
+        for blk_num in string.ascii_lowercase:
+            devicename = "{}{}".format(blk_prefix, blk_num)
+            valid_blk_names[devicename] = None
 
     # add in valid scsi raid block device names
 
     # add in valid scsi raid block device names
-    for M in range(0,1+1):
-        for N in range(0,7+1):
-            devicename = "cciss/c%dd%d" % (M,N)
-            valid_blk_names[devicename]=None
+    for M in range(0, 1+1):
+        for N in range(0, 7+1):
+            devicename = "cciss/c{}d{}".format(M, N)
+            valid_blk_names[devicename] = None
+
+    for devicename in valid_blk_names.keys():
+        # devfs under 2.4 (old boot cds) used to list partitions
+        # in a format such as scsi/host0/bus0/target0/lun0/disc
+        # and /dev/sda, etc. were just symlinks
+        try:
+            devfsname = os.readlink("/dev/{}".format(devicename))
+            valid_blk_names[devfsname] = None
+        except OSError:
+            pass
 
     # only do this once every system boot
     if not os.access(DEVICES_SCANNED_FLAG, os.R_OK):
 
     # only do this once every system boot
     if not os.access(DEVICES_SCANNED_FLAG, os.R_OK):
@@ -150,74 +150,76 @@ def get_block_device_list(vars = {}, log = sys.stderr):
         # so, lets run sfdisk -l (list partitions) against
         # most possible block devices, that way they show
         # up when it comes time to do the install.
         # so, lets run sfdisk -l (list partitions) against
         # most possible block devices, that way they show
         # up when it comes time to do the install.
+
+        # 27.6.2012 - Using parted instead of sfdisk, assuming
+        # that doing so respects the behavior mentioned above.
+
         devicenames = valid_blk_names.keys()
         devicenames.sort()
         for devicename in devicenames:
         devicenames = valid_blk_names.keys()
         devicenames.sort()
         for devicename in devicenames:
-            os.system( "sfdisk -l /dev/%s > /dev/null 2>&1" % devicename )
+            os.system("parted --script --list /dev/{} > /dev/null 2>&1".format(devicename))
 
         # touch file
 
         # touch file
-        fb = open(DEVICES_SCANNED_FLAG,"w")
+        fb = open(DEVICES_SCANNED_FLAG, "w")
         fb.close()
 
         fb.close()
 
-    devicelist= {}
+    devicelist = {}
 
 
-    partitions_file= file(PROC_PARTITIONS_PATH,"r")
-    line_count= 0
+    partitions_file = file(PROC_PARTITIONS_PATH, "r")
+    line_count = 0
     for line in partitions_file:
     for line in partitions_file:
-        line_count= line_count + 1
+        line_count = line_count + 1
 
         # skip the first two lines always
         if line_count < 2:
             continue
 
 
         # skip the first two lines always
         if line_count < 2:
             continue
 
-        parts= string.split(line)
+        parts = string.split(line)
 
         if len(parts) < 4:
             continue
 
 
         if len(parts) < 4:
             continue
 
-        device= parts[3]
+        device = parts[3]
 
         # skip and ignore any partitions
         if not valid_blk_names.has_key(device):
             continue
 
         try:
 
         # skip and ignore any partitions
         if not valid_blk_names.has_key(device):
             continue
 
         try:
-            major= int(parts[0])
-            minor= int(parts[1])
-            blocks= int(parts[2])
-        except ValueError, err:
+            major = int(parts[0])
+            minor = int(parts[1])
+            blocks = int(parts[2])
+        except ValueError as err:
             continue
 
             continue
 
-        gb_size= blocks/BLOCKS_PER_GB
+        gb_size = blocks/BLOCKS_PER_GB
 
         # check to see if the blk device is readonly
         try:
             # can we write to it?
 
         # check to see if the blk device is readonly
         try:
             # can we write to it?
-            dev_name= "/dev/%s" % device
-            fb = open(dev_name,"w")
+            dev_name = "/dev/{}".format(device)
+            fb = open(dev_name, "w")
             fb.close()
             fb.close()
-            readonly=False
-        except IOError, e:
+            readonly = False
+        except IOError as e:
             # check if EROFS errno
             # check if EROFS errno
-            if errno.errorcode.get(e.errno,None) == 'EROFS':
-                readonly=True
+            if errno.errorcode.get(e.errno, None) == 'EROFS':
+                readonly = True
             else:
                 # got some other errno, pretend device is readonly
             else:
                 # got some other errno, pretend device is readonly
-                readonly=True
+                readonly = True
 
 
-        devicelist[dev_name]= (major,minor,blocks,gb_size,readonly)
+        devicelist[dev_name] = (major, minor, blocks, gb_size, readonly)
 
     return devicelist
 
 
 
     return devicelist
 
 
-def get_system_modules( vars = {}, log = sys.stderr):
+def get_system_modules(vars = {}, log = sys.stderr):
     """
     Return a list of kernel modules that this system requires.
     This requires access to the installed system's root
     """
     Return a list of kernel modules that this system requires.
     This requires access to the installed system's root
-    directory, as the following files must exist and are used:
-    <install_root>/usr/share/hwdata/pcitable
+    directory, as the following file must exist and is used:
     <install_root>/lib/modules/(first entry if kernel_version unspecified)/modules.pcimap
     <install_root>/lib/modules/(first entry if kernel_version unspecified)/modules.pcimap
-    <install_root>/lib/modules/(first entry if kernel version unspecified)/modules.dep
 
     If there are more than one kernels installed, and the kernel
     version is not specified, then only the first one in
 
     If there are more than one kernels installed, and the kernel
     version is not specified, then only the first one in
@@ -236,8 +238,8 @@ def get_system_modules( vars = {}, log = sys.stderr):
     """
 
     if not vars.has_key("SYSIMG_PATH"):
     """
 
     if not vars.has_key("SYSIMG_PATH"):
-        vars["SYSIMG_PATH"]="/"
-    SYSIMG_PATH=vars["SYSIMG_PATH"]
+        vars["SYSIMG_PATH"] = "/"
+    SYSIMG_PATH = vars["SYSIMG_PATH"]
 
     if not vars.has_key("NODE_MODEL_OPTIONS"):
         vars["NODE_MODEL_OPTIONS"] = 0;
 
     if not vars.has_key("NODE_MODEL_OPTIONS"):
         vars["NODE_MODEL_OPTIONS"] = 0;
@@ -247,167 +249,98 @@ def get_system_modules( vars = {}, log = sys.stderr):
     # get the kernel version we are assuming
     if kernel_version is None:
         try:
     # get the kernel version we are assuming
     if kernel_version is None:
         try:
-            kernel_version= os.listdir( "%s/lib/modules/" % SYSIMG_PATH )
-        except OSError, e:
+            kernel_version = os.listdir("{}/lib/modules/".format(SYSIMG_PATH))
+        except OSError as e:
             return
 
         if len(kernel_version) == 0:
             return
 
         if len(kernel_version) > 1:
             return
 
         if len(kernel_version) == 0:
             return
 
         if len(kernel_version) > 1:
-            print( "WARNING: We may be returning modules for the wrong kernel." )
-
-        kernel_version= kernel_version[0]
+            print("WARNING: We may be returning modules for the wrong kernel.")
 
 
-    print( "Using kernel version %s" % kernel_version )
+        kernel_version = kernel_version[0]
 
 
-    # test to make sure the three files we need are present
-    pcitable_path = "%s/%s/pcitable" % (SYSIMG_PATH,hwdatapath)
-    modules_pcimap_path = "%s/lib/modules/%s/modules.pcimap" % \
-                          (SYSIMG_PATH,kernel_version)
-    modules_dep_path = "%s/lib/modules/%s/modules.dep" % \
-                       (SYSIMG_PATH,kernel_version)
+    print("Using kernel version {}".format(kernel_version))
 
 
-    for path in (pcitable_path,modules_pcimap_path,modules_dep_path):
-        if not os.access(path,os.R_OK):
-            print( "Unable to read %s" % path )
-            return
-
-    # now, with those three files, merge them all into one easy to
-    # use lookup table
-    (all_pci_ids, all_modules) = merge_hw_tables.merge_files( modules_dep_path,
-                                                              modules_pcimap_path,
-                                                              pcitable_path )
-    if all_modules is None:
-        print( "Unable to merge pci id tables." )
+    # test to make sure the file we need is present
+    modules_pcimap_path = "{}/lib/modules/{}/modules.pcimap"\
+        .format(SYSIMG_PATH, kernel_version)
+    if not os.access(modules_pcimap_path, os.R_OK):
+        print("WARNING: Unable to read {}".format(modules_pcimap_path))
         return
 
         return
 
+    pcimap = pypcimap.PCIMap(modules_pcimap_path)
+
     # this is the actual data structure we return
     # this is the actual data structure we return
-    system_mods= {}
+    system_mods = {}
 
     # these are the lists that will be in system_mods
 
     # these are the lists that will be in system_mods
-    network_mods= []
-    scsi_mods= []
-
-
-    # get all the system devices from lspci
-    lspci_prog= popen2.Popen3( LSPCI_CMD, 1 )
-    if lspci_prog is None:
-        print( "Unable to run %s with popen2.Popen3" % LSPCI_CMD )
-        return
-
-    returncode= lspci_prog.wait()
-    if returncode != 0:
-        print( "Running %s failed" % LSPCI_CMD )
-        return
-    else:
-        print( "Successfully ran %s" % LSPCI_CMD )
-
-    # for every lspci line, parse in the four tuple PCI id and the
-    # search for the corresponding driver from the dictionary
-    # generated by merge_hw_tables
-    for line in lspci_prog.fromchild:
-        # A sample line:
-        #
-        # 00:1f.1 "Class 0101" "8086" "2411" -r02 -p80 "8086" "2411"
-        #
-        # Remove '"', 'Class ', and anything beginning with '-'
-        # (usually revisions and prog-if flags) so that we can
-        # split on whitespace:
-        #
-        # 00:1f.1 0101 8086 2411 8086 2411
-        #
-        line = line.strip()
-        line = line.replace('"', '')
-        line = line.replace('Class ', '')
-        line = re.sub('-[^ ]*', '', line)
-
-        parts = line.split()
-        try:
-            if len(parts) < 4:
-                raise
-            classid = long(parts[1], 16)
-            vendorid = long(parts[2], 16)
-            deviceid = long(parts[3], 16)
-        except:
-            print "Invalid line:", line
-            continue
+    network_mods = []
+    scsi_mods = []
+
+    # XXX: this is really similar to what BootCD/conf_files/pl_hwinit does. merge?
+    pcidevs = get_devices()
+
+    devlist =pcidevs.keys()
+    devlist.sort()
+    for slot in devlist:
+        dev = pcidevs[slot]
+        base = (dev[4] & 0xff0000) >> 16
+        modules = pcimap.get(dev)
+        if base not in (PCI_BASE_CLASS_STORAGE,
+                        PCI_BASE_CLASS_NETWORK):
+            # special exception for forcedeth NICs whose base id
+            # claims to be a Bridge, even though it is clearly a
+            # network device
+            if "forcedeth" in modules: 
+                base = PCI_BASE_CLASS_NETWORK
+            else:
+                continue
 
 
-        if classid not in (PCI_CLASS_NETWORK_ETHERNET,
-                           PCI_CLASS_STORAGE_SCSI,
-                           PCI_CLASS_STORAGE_SATA,
-                           PCI_CLASS_STORAGE_RAID,
-                           PCI_CLASS_STORAGE_OTHER,
-                           PCI_CLASS_STORAGE_IDE):
-            continue
+        if len(modules) > 0:
+            if base == PCI_BASE_CLASS_NETWORK:
+                network_mods += modules
+            elif base == PCI_BASE_CLASS_STORAGE:
+                scsi_mods += modules
 
 
-        # Device may have a subvendorid and subdeviceid
-        try:
-            subvendorid = long(parts[4], 16)
-            subdeviceid = long(parts[5], 16)
-        except:
-            subvendorid = PCI_ANY
-            subdeviceid = PCI_ANY
-
-        # search for driver that most closely matches the full_id
-        # to drivers that can handle any subvendor/subdevice
-        # version of the hardware.
-        full_ids = ((vendorid,deviceid,subvendorid,subdeviceid),
-                    (vendorid,deviceid,subvendorid,PCI_ANY),
-                    (vendorid,deviceid,PCI_ANY,PCI_ANY))
-
-        for full_id in full_ids:
-            module = all_pci_ids.get(full_id, None)
-            if module is not None:
-                if classid == PCI_CLASS_NETWORK_ETHERNET:
-                    network_mods.append(module[0])
-                elif classid in (PCI_CLASS_STORAGE_SCSI,
-                                 PCI_CLASS_STORAGE_SATA,
-                                 PCI_CLASS_STORAGE_RAID,
-                                 PCI_CLASS_STORAGE_OTHER,
-                                 PCI_CLASS_STORAGE_IDE):
-                    scsi_mods.append(module[0])
-                else:
-                    print "not network or scsi: 0x%x" % classid
-                break
-
-    system_mods[MODULE_CLASS_SCSI]= scsi_mods
-    system_mods[MODULE_CLASS_NETWORK]= network_mods
+    system_mods[MODULE_CLASS_SCSI] = scsi_mods
+    system_mods[MODULE_CLASS_NETWORK] = network_mods
 
     return system_mods
 
 
 
     return system_mods
 
 
-def getKernelVersion( vars = {} , log = sys.stderr):
+def getKernelVersion(vars = {}, log = sys.stderr):
     # make sure we have the variables we need
     try:
     # make sure we have the variables we need
     try:
-        SYSIMG_PATH= vars["SYSIMG_PATH"]
+        SYSIMG_PATH = vars["SYSIMG_PATH"]
         if SYSIMG_PATH == "":
         if SYSIMG_PATH == "":
-            raise ValueError, "SYSIMG_PATH"
+            raise ValueError("SYSIMG_PATH")
 
 
-        NODE_MODEL_OPTIONS=vars["NODE_MODEL_OPTIONS"]
-    except KeyError, var:
-        raise BootManagerException, "Missing variable in vars: %s\n" % var
-    except ValueError, var:
-        raise BootManagerException, "Variable in vars, shouldn't be: %s\n" % var
+        NODE_MODEL_OPTIONS = vars["NODE_MODEL_OPTIONS"]
+    except KeyError as var:
+        raise BootManagerException("Missing variable in vars: {}\n".format(var))
+    except ValueError as var:
+        raise BootManagerException("Variable in vars, shouldn't be: {}\n".format(var))
 
     option = ''
     if NODE_MODEL_OPTIONS & ModelOptions.SMP:
         option = 'smp'
         try:
 
     option = ''
     if NODE_MODEL_OPTIONS & ModelOptions.SMP:
         option = 'smp'
         try:
-            os.stat("%s/boot/kernel-boot%s" % (SYSIMG_PATH,option))
-            os.stat("%s/boot/initrd-boot%s" % (SYSIMG_PATH,option))
-        except OSError, e:
+            os.stat("{}/boot/kernel-boot{}".format(SYSIMG_PATH, option))
+            os.stat("{}/boot/initrd-boot{}".format(SYSIMG_PATH, option))
+        except OSError as e:
             # smp kernel is not there; remove option from modeloptions
             # such that the rest of the code base thinks we are just
             # using the base kernel.
             NODE_MODEL_OPTIONS = NODE_MODEL_OPTIONS & ~ModelOptions.SMP
             vars["NODE_MODEL_OPTIONS"] = NODE_MODEL_OPTIONS
             # smp kernel is not there; remove option from modeloptions
             # such that the rest of the code base thinks we are just
             # using the base kernel.
             NODE_MODEL_OPTIONS = NODE_MODEL_OPTIONS & ~ModelOptions.SMP
             vars["NODE_MODEL_OPTIONS"] = NODE_MODEL_OPTIONS
-            log.write( "WARNING: Couldn't locate smp kernel.\n")
+            log.write("WARNING: Couldn't locate smp kernel.\n")
             option = ''
     try:
             option = ''
     try:
-        initrd= os.readlink( "%s/boot/initrd-boot%s" % (SYSIMG_PATH,option) )
-        kernel_version= initrd.replace("initrd-", "").replace(".img", "")    
-    except OSError, e:
+        initrd = os.readlink("{}/boot/initrd-boot{}".format(SYSIMG_PATH, option))
+        kernel_version = initrd.replace("initrd-", "").replace(".img", "")    
+    except OSError as e:
         initrd = None
         kernel_version = None
         
         initrd = None
         kernel_version = None
         
@@ -415,40 +348,37 @@ def getKernelVersion( vars = {} , log = sys.stderr):
 
 
 if __name__ == "__main__":
 
 
 if __name__ == "__main__":
-    devices= get_block_device_list()
-    print "block devices detected:"
+    devices = get_block_devices_dict()
+    print("block devices detected:")
     if not devices:
     if not devices:
-        print "no devices found!"
+        print("no devices found!")
     else:
         for dev in devices.keys():
     else:
         for dev in devices.keys():
-            print "%s %s" % (dev, repr(devices[dev]))
+            print("{} {}".format(dev, repr(devices[dev])))
             
 
             
 
-    print ""
-    memory= get_total_phsyical_mem()
+    print("")
+    memory = get_total_phsyical_mem()
     if not memory:
     if not memory:
-        print "unable to read /proc/meminfo for memory"
+        print("unable to read /proc/meminfo for memory")
     else:
     else:
-        print "total physical memory: %d kb" % memory
+        print("total physical memory: {} kb".format(memory))
         
 
         
 
-    print ""
+    print("")
 
     kernel_version = None
     if len(sys.argv) > 2:
         kernel_version = sys.argv[1]
         
 
     kernel_version = None
     if len(sys.argv) > 2:
         kernel_version = sys.argv[1]
         
-    modules= get_system_modules()
+    modules = get_system_modules()
     if not modules:
     if not modules:
-        print "unable to list system modules"
+        print("unable to list system modules")
     else:
     else:
-        for type in modules:
-            if type == MODULE_CLASS_SCSI:
-                print( "all scsi modules:" )
-                for a_mod in modules[type]:
-                    print a_mod
-            elif type == MODULE_CLASS_NETWORK:
-                print( "all network modules:" )
-                for a_mod in modules[type]:
-                    print a_mod
+        for module_class in (MODULE_CLASS_SCSI, MODULE_CLASS_NETWORK):
+            if len(modules[module_class]) > 0:
+                module_list = ""
+                for a_mod in modules[module_class]:
+                    module_list = module_list + "{} ".format(a_mod)
+                print("all {} modules: {}".format(module_class, module_list))