summaryrefslogtreecommitdiffstats
path: root/func/minion
diff options
context:
space:
mode:
authorLuke Macken <lmacken@redhat.com>2008-01-15 17:42:05 -0500
committerLuke Macken <lmacken@redhat.com>2008-01-15 17:42:05 -0500
commit23c9c26d270ff766133e7aeebffc99a35633ef41 (patch)
treed68c5030efd41b5de10dcf7d92b1fa2c0c86b445 /func/minion
parentc4371ce647118902dd7574394d86c690c9be686e (diff)
downloadfunc-23c9c26d270ff766133e7aeebffc99a35633ef41.tar.gz
func-23c9c26d270ff766133e7aeebffc99a35633ef41.tar.xz
func-23c9c26d270ff766133e7aeebffc99a35633ef41.zip
Simplify our modules by auto-detecting them and registering their handlers
- Auto-detect and load all FuncModules. This obsoletes the need to have our modules define a register_rpc method. - Use introspection in our FuncModule to auto-register all method handlers that do not being with an underscore. This obsoletes the need to hardcode methods in our modules. - Remove all __init__ methods from our modules, along with register_rpc - Modify the func-create-module script to reflect these changes. Note that doing 'from modules import func_module' is no longer supported in our modules, do to some interesting path issues with our auto-detection code. Supported methods are now: 'import func_module' or 'from func.minion.modules import func_module'
Diffstat (limited to 'func/minion')
-rwxr-xr-xfunc/minion/module_loader.py17
-rw-r--r--func/minion/modules/command.py14
-rw-r--r--func/minion/modules/copyfile.py16
-rw-r--r--func/minion/modules/filetracker.py20
-rw-r--r--func/minion/modules/func_module.py14
-rw-r--r--func/minion/modules/hardware.py12
-rw-r--r--func/minion/modules/mount.py14
-rw-r--r--func/minion/modules/nagios-check.py14
-rw-r--r--func/minion/modules/process.py13
-rw-r--r--func/minion/modules/reboot.py14
-rw-r--r--func/minion/modules/rpms.py12
-rw-r--r--func/minion/modules/service.py18
-rw-r--r--func/minion/modules/smart.py11
-rw-r--r--func/minion/modules/snmp.py14
-rw-r--r--func/minion/modules/test.py12
-rw-r--r--func/minion/modules/virt.py49
-rw-r--r--func/minion/modules/yumcmd.py14
17 files changed, 44 insertions, 234 deletions
diff --git a/func/minion/module_loader.py b/func/minion/module_loader.py
index 6fb2a6b..f8f8f42 100755
--- a/func/minion/module_loader.py
+++ b/func/minion/module_loader.py
@@ -19,10 +19,11 @@ import sys
from gettext import gettext
_ = gettext
-
from func import logger
logger = logger.Logger().logger
+from inspect import isclass
+from func.minion.modules import func_module
def module_walker(topdir):
module_files = []
@@ -80,13 +81,15 @@ def load_modules(blacklist=None):
continue
try:
+ # Auto-detect and load all FuncModules
blip = __import__("modules.%s" % ( mod_imp_name), globals(), locals(), [mod_imp_name])
- if not hasattr(blip, "register_rpc"):
- errmsg = _("%(module_path)s%(modname)s module not a proper module")
- logger.warning(errmsg % {'module_path': module_file_path, 'modname':mod_imp_name})
- bad_mods[mod_imp_name] = True
- continue
- mods[mod_imp_name] = blip
+ for obj in dir(blip):
+ attr = getattr(blip, obj)
+ if isclass(attr):
+ if issubclass(attr, func_module.FuncModule):
+ logger.debug("Loading %s module" % attr)
+ 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")
diff --git a/func/minion/modules/command.py b/func/minion/modules/command.py
index 3329927..9b93de5 100644
--- a/func/minion/modules/command.py
+++ b/func/minion/modules/command.py
@@ -13,19 +13,11 @@
Abitrary command execution module for func.
"""
-from modules import func_module
-
+import func_module
import sub_process
class Command(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "run" : self.run,
- "exists" : self.exists,
- }
- func_module.FuncModule.__init__(self)
-
def run(self, command):
"""
Runs a command, returning the return code, stdout, and stderr as a tuple.
@@ -46,7 +38,3 @@ class Command(func_module.FuncModule):
if os.access(command, os.X_OK):
return True
return False
-
-
-methods = Command()
-register_rpc = methods.register_rpc \ No newline at end of file
diff --git a/func/minion/modules/copyfile.py b/func/minion/modules/copyfile.py
index 6c81098..85001f8 100644
--- a/func/minion/modules/copyfile.py
+++ b/func/minion/modules/copyfile.py
@@ -14,7 +14,7 @@ import os
import time
import shutil
-from modules import func_module
+import func_module
@@ -22,15 +22,6 @@ from modules import func_module
class CopyFile(func_module.FuncModule):
version = "0.0.1"
api_version = "0.0.2"
-
-
-
- def __init__(self):
- self.methods = {
- "copyfile" : self.copyfile,
- "checksum" : self.checksum
- }
- func_module.FuncModule.__init__(self)
def _checksum_blob(self, blob):
CHUNK=2**16
@@ -118,8 +109,3 @@ class CopyFile(func_module.FuncModule):
#XXX logger output here
return False
return True
-
-
-
-methods = CopyFile()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/filetracker.py b/func/minion/modules/filetracker.py
index 0aa4a49..8deb382 100644
--- a/func/minion/modules/filetracker.py
+++ b/func/minion/modules/filetracker.py
@@ -16,7 +16,7 @@
##
# func modules
-from modules import func_module
+import func_module
# other modules
from stat import *
@@ -30,17 +30,6 @@ CONFIG_FILE='/etc/func/modules/filetracker.conf'
class FileTracker(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "track" : self.track,
- "untrack" : self.untrack,
- "info" : self.inventory,
- "inventory" : self.inventory,
- }
- func_module.FuncModule.__init__(self)
-
- #==========================================================
-
def __load(self):
"""
Parse file and return data structure.
@@ -145,7 +134,7 @@ class FileTracker(func_module.FuncModule):
gid = filestat[ST_GID]
if not os.path.isdir(file_name) and checksum_enabled:
sum_handle = open(file_name)
- hash = self.sumfile(sum_handle)
+ hash = self.__sumfile(sum_handle)
sum_handle.close()
else:
hash = "N/A"
@@ -185,7 +174,7 @@ class FileTracker(func_module.FuncModule):
#==========================================================
- def sumfile(self, fobj):
+ def __sumfile(self, fobj):
"""
Returns an md5 hash for an object with read() method.
credit: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/266486
@@ -198,6 +187,3 @@ class FileTracker(func_module.FuncModule):
break
m.update(d)
return m.hexdigest()
-
-methods = FileTracker()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/func_module.py b/func/minion/modules/func_module.py
index 5965e24..c911b91 100644
--- a/func/minion/modules/func_module.py
+++ b/func/minion/modules/func_module.py
@@ -10,6 +10,7 @@
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
+import inspect
from func import logger
from func.config import read_config
@@ -34,7 +35,7 @@ class FuncModule(object):
"module_api_version" : self.__module_api_version,
"module_description" : self.__module_description,
"list_methods" : self.__list_methods
- }
+ }
def __init_log(self):
log = logger.Logger()
@@ -45,8 +46,11 @@ class FuncModule(object):
# can get clobbbered by subclass versions
for meth in self.__base_methods:
handlers["%s.%s" % (module_name, meth)] = self.__base_methods[meth]
- for meth in self.methods:
- handlers["%s.%s" % (module_name,meth)] = self.methods[meth]
+
+ # register all methods that don't start with an underscore
+ for attr in dir(self):
+ if inspect.ismethod(getattr(self, attr)) and attr[0] != '_':
+ handlers["%s.%s" % (module_name, attr)] = getattr(self, attr)
def __list_methods(self):
return self.methods.keys() + self.__base_methods.keys()
@@ -59,7 +63,3 @@ class FuncModule(object):
def __module_description(self):
return self.description
-
-
-methods = FuncModule()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/hardware.py b/func/minion/modules/hardware.py
index acf5988..5136228 100644
--- a/func/minion/modules/hardware.py
+++ b/func/minion/modules/hardware.py
@@ -20,18 +20,11 @@ import sys
# our modules
import sub_process
-from modules import func_module
+import func_module
# =================================
class HardwareModule(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "info" : self.info,
- "inventory" : self.inventory, # for func-inventory
- "hal_info" : self.hal_info
- }
- func_module.FuncModule.__init__(self)
def hal_info(self):
"""
@@ -131,6 +124,3 @@ def hw_info(with_devices=True):
})
return data
-
-methods = HardwareModule()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/mount.py b/func/minion/modules/mount.py
index e8e41ce..1b4671d 100644
--- a/func/minion/modules/mount.py
+++ b/func/minion/modules/mount.py
@@ -13,18 +13,10 @@
##
import sub_process, os
-from modules import func_module
+import func_module
class MountModule(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "list": self.list,
- "mount": self.mount,
- "umount": self.umount,
- "inventory": self.inventory,
- }
- func_module.FuncModule.__init__(self)
def list(self):
cmd = sub_process.Popen(["/bin/cat", "/proc/mounts"], executable="/bin/cat", stdout=sub_process.PIPE, shell=False)
@@ -86,7 +78,3 @@ class MountModule(func_module.FuncModule):
def inventory(self, flatten=True):
return self.list()
-
-
-methods = MountModule()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/nagios-check.py b/func/minion/modules/nagios-check.py
index a902762..80889ce 100644
--- a/func/minion/modules/nagios-check.py
+++ b/func/minion/modules/nagios-check.py
@@ -13,18 +13,11 @@
Abitrary command execution module for func.
"""
-from modules import func_module
-
+import func_module
import sub_process
class Nagios(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "run" : self.run
- }
- func_module.FuncModule.__init__(self)
-
def run(self, check_command):
"""
Runs a nagios check returning the return code, stdout, and stderr as a tuple.
@@ -35,8 +28,3 @@ class Nagios(func_module.FuncModule):
cmdref = sub_process.Popen(command.split(),stdout=sub_process.PIPE,stderr=sub_process.PIPE, shell=False)
data = cmdref.communicate()
return (cmdref.returncode, data[0], data[1])
-
-methods = Nagios()
-register_rpc = methods.register_rpc
-
-
diff --git a/func/minion/modules/process.py b/func/minion/modules/process.py
index 92c6d6a..18b5abe 100644
--- a/func/minion/modules/process.py
+++ b/func/minion/modules/process.py
@@ -18,19 +18,11 @@ import sub_process
import codes
# our modules
-from modules import func_module
+import func_module
# =================================
class ProcessModule(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "info" : self.info,
- "kill" : self.kill,
- "pkill" : self.pkill,
- "mem" : self.mem
- }
- func_module.FuncModule.__init__(self)
def info(self,flags="-auxh"):
"""
@@ -208,6 +200,3 @@ class ProcessModule(func_module.FuncModule):
# example killall("thunderbird","-9")
rc = sub_process.call(["/usr/bin/pkill", name, level], executable="/usr/bin/pkill", shell=False)
return rc
-
-methods = ProcessModule()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/reboot.py b/func/minion/modules/reboot.py
index 8772b8f..0af78f9 100644
--- a/func/minion/modules/reboot.py
+++ b/func/minion/modules/reboot.py
@@ -8,22 +8,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-from modules import func_module
-
+import func_module
import sub_process
class Reboot(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "reboot" : self.reboot
- }
- func_module.FuncModule.__init__(self)
-
def reboot(self, when='now', message=''):
return sub_process.call(["/sbin/shutdown", '-r', when, message])
-
-
-methods = Reboot()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/rpms.py b/func/minion/modules/rpms.py
index 901a9d6..f73e9db 100644
--- a/func/minion/modules/rpms.py
+++ b/func/minion/modules/rpms.py
@@ -8,18 +8,11 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-from modules import func_module
+import func_module
import rpm
class RpmModule(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "inventory" : self.inventory,
- "info" : self.inventory
- }
- func_module.FuncModule.__init__(self)
-
def inventory(self, flatten=True):
"""
Returns information on all installed packages.
@@ -43,6 +36,3 @@ class RpmModule(func_module.FuncModule):
else:
results.append([name,epoch,version,release,arch])
return results
-
-methods = RpmModule()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/service.py b/func/minion/modules/service.py
index d088907..d1170a8 100644
--- a/func/minion/modules/service.py
+++ b/func/minion/modules/service.py
@@ -13,26 +13,13 @@
##
import codes
-from modules import func_module
+import func_module
import sub_process
import os
class Service(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "start" : self.start,
- "stop" : self.stop,
- "restart" : self.restart,
- "reload" : self.reload,
- "status" : self.status,
- "get_enabled" : self.get_enabled,
- "get_running" : self.get_running,
- "inventory" : self.inventory,
- }
- func_module.FuncModule.__init__(self)
-
def __command(self, service_name, command):
filename = os.path.join("/etc/rc.d/init.d/",service_name)
@@ -95,6 +82,3 @@ class Service(func_module.FuncModule):
tokens = line.split()
results.append((tokens[0], tokens[-1].replace("...","")))
return results
-
-methods = Service()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/smart.py b/func/minion/modules/smart.py
index e85b90c..ff7afd9 100644
--- a/func/minion/modules/smart.py
+++ b/func/minion/modules/smart.py
@@ -17,17 +17,11 @@
import sub_process
# our modules
-from modules import func_module
+import func_module
# =================================
class SmartModule(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "info" : self.info,
- "inventory" : self.info, # for func-inventory
- }
- func_module.FuncModule.__init__(self)
def info(self,flags="-q onecheck"):
"""
@@ -47,6 +41,3 @@ class SmartModule(func_module.FuncModule):
results.append(x)
return (cmd.returncode, results)
-
-methods = SmartModule()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/snmp.py b/func/minion/modules/snmp.py
index 3144144..374821c 100644
--- a/func/minion/modules/snmp.py
+++ b/func/minion/modules/snmp.py
@@ -13,19 +13,12 @@
Abitrary command execution module for func.
"""
-from modules import func_module
-
+import func_module
import sub_process
base_snmp_command = '/usr/bin/snmpget -v2c -Ov -OQ'
class Snmp(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "get" : self.get
- }
- func_module.FuncModule.__init__(self)
-
def get(self, oid, rocommunity, hostname='localhost'):
"""
Runs an snmpget on a specific oid returns the output of the call.
@@ -39,8 +32,3 @@ class Snmp(func_module.FuncModule):
#def walk(self, oid, rocommunity):
#def table(self, oid, rocommunity):
-
-methods = Snmp()
-register_rpc = methods.register_rpc
-
-
diff --git a/func/minion/modules/test.py b/func/minion/modules/test.py
index 24af03e..6718fed 100644
--- a/func/minion/modules/test.py
+++ b/func/minion/modules/test.py
@@ -1,17 +1,10 @@
-from modules import func_module
+import func_module
import time
class Test(func_module.FuncModule):
version = "11.11.11"
api_version = "0.0.1"
description = "Just a very simple example module"
- def __init__(self):
- self.methods = {
- "add": self.add,
- "ping": self.ping,
- "sleep": self.sleep
- }
- func_module.FuncModule.__init__(self)
def add(self, numb1, numb2):
return numb1 + numb2
@@ -27,6 +20,3 @@ class Test(func_module.FuncModule):
t = int(t)
time.sleep(t)
return time.time()
-
-methods = Test()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/virt.py b/func/minion/modules/virt.py
index ba888ec..3671172 100644
--- a/func/minion/modules/virt.py
+++ b/func/minion/modules/virt.py
@@ -119,31 +119,8 @@ class FuncLibvirtConnection(object):
class Virt(func_module.FuncModule):
-
- def __init__(self):
-
- """
- Constructor. Register methods and make them available.
- """
-
- self.methods = {
- "install" : self.install,
- "shutdown" : self.shutdown,
- "destroy" : self.destroy,
- "start" : self.create,
- "pause" : self.pause,
- "unpause" : self.unpause,
- "delete" : self.undefine,
- "status" : self.get_status,
- "info" : self.info,
- "inventory" : self.info, # for func-inventory
- "list_vms" : self.list_vms,
- }
-
- func_module.FuncModule.__init__(self)
-
- def get_conn(self):
- self.conn = FuncLibvirtConnection()
+ def __get_conn(self):
+ self.conn = FuncLibvirtConnection()
return self.conn
def state(self):
@@ -176,7 +153,7 @@ class Virt(func_module.FuncModule):
def list_vms(self):
- self.conn = self.get_conn()
+ self.conn = self.__get_conn()
vms = self.conn.find_vm(-1)
results = []
for x in vms:
@@ -195,7 +172,7 @@ class Virt(func_module.FuncModule):
# Example:
# install("bootserver.example.org", "fc7webserver", True)
- conn = self.get_conn()
+ conn = self.__get_conn()
if conn is None:
raise codes.FuncException("no connection")
@@ -227,7 +204,7 @@ class Virt(func_module.FuncModule):
Make the machine with the given vmid stop running.
Whatever that takes.
"""
- self.get_conn()
+ self.__get_conn()
self.conn.shutdown(vmid)
return 0
@@ -237,7 +214,7 @@ class Virt(func_module.FuncModule):
"""
Pause the machine with the given vmid.
"""
- self.get_conn()
+ self.__get_conn()
self.conn.suspend(vmid)
return 0
@@ -248,7 +225,7 @@ class Virt(func_module.FuncModule):
Unpause the machine with the given vmid.
"""
- self.get_conn()
+ self.__get_conn()
self.conn.resume(vmid)
return 0
@@ -258,7 +235,7 @@ class Virt(func_module.FuncModule):
"""
Start the machine via the given mac address.
"""
- self.get_conn()
+ self.__get_conn()
self.conn.create(vmid)
return 0
@@ -269,7 +246,7 @@ class Virt(func_module.FuncModule):
Pull the virtual power from the virtual domain, giving it virtually no
time to virtually shut down.
"""
- self.get_conn()
+ self.__get_conn()
self.conn.destroy(vmid)
return 0
@@ -281,7 +258,7 @@ class Virt(func_module.FuncModule):
by deleting the disk image and it's configuration file.
"""
- self.get_conn()
+ self.__get_conn()
self.conn.undefine(vmid)
return 0
@@ -292,9 +269,5 @@ class Virt(func_module.FuncModule):
Return a state suitable for server consumption. Aka, codes.py values, not XM output.
"""
- self.get_conn()
+ self.__get_conn()
return self.conn.get_status(vmid)
-
-
-methods = Virt()
-register_rpc = methods.register_rpc
diff --git a/func/minion/modules/yumcmd.py b/func/minion/modules/yumcmd.py
index b3976fb..8bf760c 100644
--- a/func/minion/modules/yumcmd.py
+++ b/func/minion/modules/yumcmd.py
@@ -8,8 +8,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-from modules import func_module
+import func_module
import yum
from yum import repos
@@ -22,13 +21,6 @@ class DummyCallback(object):
class Yum(func_module.FuncModule):
- def __init__(self):
- self.methods = {
- "update" : self.update,
- "check_update" : self.check_update
- }
- func_module.FuncModule.__init__(self)
-
def update(self):
# XXX support updating specific rpms
ayum = yum.YumBase()
@@ -52,7 +44,3 @@ class Yum(func_module.FuncModule):
ayum.doTsSetup()
ayum.repos.enableRepo(repo)
return map(str, ayum.doPackageLists('updates').updates)
-
-
-methods = Yum()
-register_rpc = methods.register_rpc