diff options
Diffstat (limited to 'func/module_loader.py')
| -rwxr-xr-x | func/module_loader.py | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/func/module_loader.py b/func/module_loader.py new file mode 100755 index 0000000..2aa1378 --- /dev/null +++ b/func/module_loader.py @@ -0,0 +1,131 @@ +## func +## +## Copyright 2007, Red Hat, Inc +## See AUTHORS +## +## This software may be freely redistributed under the terms of the GNU +## general public license. +## +## 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., 675 Mass Ave, Cambridge, MA 02139, USA. +## +## + + +import distutils.sysconfig +import os +import sys +import inspect +from gettext import gettext +_ = gettext + +from func import logger +logger = logger.Logger().logger + +from inspect import isclass +from func.minion.modules import func_module +from func.utils import is_public_valid_method + +def module_walker(topdir): + module_files = [] + for root, dirs, files in os.walk(topdir): + # we should get here for each subdir + for filename in files: + # ASSUMPTION: all module files will end with .py, .pyc, .pyo + if filename[-3:] == ".py" or filename[-4:] == ".pyc" or filename[-4:] == ".pyo": + # the normpath is important, since we eventually replace /'s with .'s + # in the module name, and foo..bar doesnt work -akl + module_files.append(os.path.normpath("%s/%s" % (root, filename))) + + return module_files + +def load_methods(path, main_class, parent_class=None): + methods = {} + modules = load_modules(path, main_class, parent_class=parent_class) + for x in modules.keys(): + for method in dir(modules[x]): + if is_public_valid_method(modules[x], method): + methods["%s.%s" % (x,method)]=getattr(modules[x], method) + return methods + +def load_modules(path='func/minion/modules/', main_class=func_module.FuncModule, blacklist=None, parent_class=None): + python_path = distutils.sysconfig.get_python_lib() + module_file_path = "%s/%s" % (python_path, path) + (mod_path, mod_dir) = os.path.split(os.path.normpath(module_file_path)) + mod_dir = "func."+module_file_path[len(python_path+'/func/'):].replace("/",".") + + sys.path.insert(0, mod_path) + mods = {} + bad_mods = {} + + filenames = module_walker(module_file_path) + + # FIXME: this is probably more complicated than it needs to be -akl + for fn in filenames: + # aka, everything after the module_file_path + module_name_part = fn[len(module_file_path):] + dirname, basename = os.path.split(module_name_part) + + if basename[:8] == "__init__": + modname = dirname + dirname = "" + elif basename[-3:] == ".py": + modname = basename[:-3] + elif basename[-4:] in [".pyc", ".pyo"]: + modname = basename[:-4] + + pathname = modname + if dirname != "": + pathname = "%s/%s" % (dirname, modname) + + mod_imp_name = pathname.replace("/", ".") + + if mods.has_key(mod_imp_name): + # If we've already imported mod_imp_name, don't import it again + continue + + # ignore modules that we've already determined aren't valid modules + if bad_mods.has_key(mod_imp_name): + continue + + try: + # Auto-detect and load all FuncModules + blip = __import__("%s%s" % ( mod_dir,mod_imp_name), globals(), locals(), [mod_imp_name]) + for obj in dir(blip): + attr = getattr(blip, obj) + if isclass(attr) and issubclass(attr, main_class): + logger.debug("Loading %s module" % attr) + if parent_class: + mods[mod_imp_name] = attr(parent_class) + else: + mods[mod_imp_name] = attr() + + except ImportError, e: + # A module that raises an ImportError is (for now) simply not loaded. + errmsg = _("Could not load %s module: %s") + logger.warning(errmsg % (mod_imp_name, e)) + bad_mods[mod_imp_name] = True + continue + except: + errmsg = _("Could not load %s module") + logger.warning(errmsg % (mod_imp_name)) + bad_mods[mod_imp_name] = True + continue + + return mods + +if __name__ == "__main__": + + module_file_path = "/usr/lib/python2.5/site-packages/func/minion/modules/" + bar = module_walker(module_file_path) + print bar + for f in bar: + print f + print os.path.basename(f) + print os.path.split(f) + g = f[len(module_file_path):] + print g + print os.path.split(g) + + print load_modules() |
