1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
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()
|