diff options
author | David Sommerseth <davids@redhat.com> | 2012-12-18 22:27:51 +0100 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2012-12-18 22:27:51 +0100 |
commit | fa6ff23d9c10e8f94b0d9ed85f4723f4646d0ad3 (patch) | |
tree | e9d158718812fa322932c5500bea14a77314955e /rteval/modules | |
parent | d3976bd04b251dfdb6a2823326acbdfbfa57c1e6 (diff) | |
download | rteval-fa6ff23d9c10e8f94b0d9ed85f4723f4646d0ad3.tar.gz rteval-fa6ff23d9c10e8f94b0d9ed85f4723f4646d0ad3.tar.xz rteval-fa6ff23d9c10e8f94b0d9ed85f4723f4646d0ad3.zip |
Added infrastructure to add command line arguments from modules
All rteval modules must now provide a ModuleParameters() function
which returns a dictionary containing the option setup it expects.
Each module will get a separate option group, and all its options
will be prefixed with the module name. These option variables will
be stored as well, prefixed with the module name. So if the a module
'dummy' configures an option 'value1', it will be stored as
'dummy_value1' in the option container. To set this option, you
will need to use --dummy-value1 from the command line.
Signed-off-by: David Sommerseth <davids@redhat.com>
Diffstat (limited to 'rteval/modules')
-rw-r--r-- | rteval/modules/__init__.py | 40 | ||||
-rw-r--r-- | rteval/modules/loads/__init__.py | 11 | ||||
-rw-r--r-- | rteval/modules/measurement/__init__.py | 29 |
3 files changed, 70 insertions, 10 deletions
diff --git a/rteval/modules/__init__.py b/rteval/modules/__init__.py index 153d854..ea5a0a2 100644 --- a/rteval/modules/__init__.py +++ b/rteval/modules/__init__.py @@ -24,7 +24,7 @@ from rteval.Log import Log from rteval.rtevalConfig import rtevalCfgSection -import time, libxml2, threading +import time, libxml2, threading, optparse __all__ = ["rtevalModulePrototype", "ModuleContainer", "RtEvalModules"] @@ -187,7 +187,7 @@ objects during module import.""" self.__iter_list = None - def __importmod(self, modname, modroot=None): + def LoadModule(self, modname, modroot=None): """Imports a module and saves references to the imported module. If the same module is tried imported more times, it will return the module reference from the first import""" @@ -212,10 +212,34 @@ reference from the first import""" """Imports a module and calls the modules' ModuleInfo() function and returns the information provided by the module""" - mod = self.__importmod(modname, modroot) + mod = self.LoadModule(modname, modroot) return mod.ModuleInfo() + def SetupModuleOptions(self, parser): + """Sets up a separate optptarse OptionGroup per module with its supported parameters""" + + for (modname, mod) in self.__modsloaded.items(): + opts = mod.ModuleParameters() + if len(opts) == 0: + continue + + shortmod = modname.split('.')[-1] + grparser = optparse.OptionGroup(parser, "Options for the %s module" % shortmod) + for (o, s) in opts.items(): + descr = s.has_key('descr') and s['descr'] or "" + default = s.has_key('default') and s['default'] or None + metavar = s.has_key('metavar') and s['metavar'] or None + grparser.add_option('--%s-%s' % (shortmod, o), + dest="%s_%s" % (shortmod, o), + action='store', + help='%s%s' % (descr, + default and '(default: %s)' % default or ''), + default=default, + metavar=metavar) + parser.add_option_group(grparser) + + def InstantiateModule(self, modname, modcfg, modroot = None): """Imports a module and instantiates an object from the modules create() function. The instantiated object is returned in this call""" @@ -223,7 +247,7 @@ The instantiated object is returned in this call""" if modcfg and not isinstance(modcfg, rtevalCfgSection): raise TypeError("modcfg attribute is not a rtevalCfgSection() object") - mod = self.__importmod(modname, modroot) + mod = self.LoadModule(modname, modroot) return mod.create(modcfg, self.__logger) @@ -313,6 +337,10 @@ and will also be given to the instantiated objects during module import.""" "Registers an instantiated module object which RtEvalModules will control" return self.__modules.RegisterModuleObject(modname, modobj) + def _LoadModule(self, modname, modroot=None): + "Loads and imports a module" + return self.__modules.LoadModule(modname, modroot) + def ModulesLoaded(self): "Returns number of imported modules" return self.__modules.ModulesLoaded() @@ -321,6 +349,10 @@ and will also be given to the instantiated objects during module import.""" "Returns a list of module names" return self.__modules.GetModulesList() + def SetupModuleOptions(self, parser): + "Sets up optparse based option groups for the loaded modules" + return self.__modules.SetupModuleOptions(parser) + def GetNamedModuleObject(self, modname): "Returns a list of module names" return self.__modules.GetNamedModuleObject(modname) diff --git a/rteval/modules/loads/__init__.py b/rteval/modules/loads/__init__.py index f4d4de4..3c897b8 100644 --- a/rteval/modules/loads/__init__.py +++ b/rteval/modules/loads/__init__.py @@ -95,6 +95,17 @@ class LoadModules(RtEvalModules): self.__loadavg_samples = 0 self.__cfg = config RtEvalModules.__init__(self, "modules.loads", logger) + self.__LoadModules(self.__cfg.GetSection(self._module_config)) + + + def __LoadModules(self, modcfg): + "Loads and imports all the configured modules" + + for m in modcfg: + # hope to eventually have different kinds but module is only on + # for now (jcw) + if m[1].lower() == 'module': + self._LoadModule(m[0]) def Setup(self, modparams): diff --git a/rteval/modules/measurement/__init__.py b/rteval/modules/measurement/__init__.py index a12eba2..1298932 100644 --- a/rteval/modules/measurement/__init__.py +++ b/rteval/modules/measurement/__init__.py @@ -118,6 +118,21 @@ measurement profiles, based on their characteristics""" self.__modules_root = "modules.measurement" self.__iter_item = None + # Temporary module container, which is used to evalute measurement modules. + # This will container will be destroyed after Setup() has been called + self.__container = ModuleContainer(self.__modules_root, self.__logger) + self.__LoadModules(self.__cfg.GetSection("measurement")) + + + def __LoadModules(self, modcfg): + "Loads and imports all the configured modules" + + for m in modcfg: + # hope to eventually have different kinds but module is only on + # for now (jcw) + if m[1].lower() == 'module': + self.__container.LoadModule(m[0]) + def GetProfile(self, with_load, run_parallel): "Returns the appropriate MeasurementProfile object, based on the profile type" @@ -129,20 +144,22 @@ measurement profiles, based on their characteristics""" return None + def SetupModuleOptions(self, parser): + "Sets up all the measurement modules' parameters for the option parser" + self.__container.SetupModuleOptions(parser) + + def Setup(self, modparams): "Loads all measurement modules and group them into different measurement profiles" if not isinstance(modparams, dict): raise TypeError("modparams attribute is not of a dictionary type") - # Temporary module container, which is used to evalute measurement modules - container = ModuleContainer(self.__modules_root, self.__logger) - modcfg = self.__cfg.GetSection("measurement") for (modname, modtype) in modcfg: if modtype.lower() == 'module': # Only 'module' will be supported (ds) # Extract the measurement modules info - modinfo = container.ModuleInfo(modname) + modinfo = self.__container.ModuleInfo(modname) # Get the correct measurement profile container for this module mp = self.GetProfile(modinfo["loads"], modinfo["parallel"]) @@ -154,13 +171,13 @@ measurement profiles, based on their characteristics""" # Export the module imported here and transfer it to the # measurement profile - mp.ImportModule(container.ExportModule(modname)) + mp.ImportModule(self.__container.ExportModule(modname)) # Setup this imported module inside the appropriate measurement profile self.__cfg.AppendConfig(modname, modparams) mp.Setup(modname, self.__cfg.GetSection(modname)) - del container + del self.__container def MakeReport(self): |