summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--client/test_func.py23
-rwxr-xr-xmodules/func_module.py4
-rwxr-xr-xmodules/hardware.py100
-rwxr-xr-xmodules/process.py68
-rwxr-xr-xmodules/reboot.py2
-rwxr-xr-xmodules/service.py10
-rwxr-xr-xmodules/test.py2
-rwxr-xr-xmodules/virt.py28
-rw-r--r--modules/yum.py (renamed from modules/yummod.py)2
-rwxr-xr-xserver/module_loader.py53
-rwxr-xr-xserver/server.py4
12 files changed, 255 insertions, 42 deletions
diff --git a/.gitignore b/.gitignore
index f5f30f4..0fef094 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
*.pyc
*.pyo
*.swp
+build
MANIFEST
rpm-build
dist
diff --git a/client/test_func.py b/client/test_func.py
index 19ec3af..6362b85 100644
--- a/client/test_func.py
+++ b/client/test_func.py
@@ -5,34 +5,43 @@
import xmlrpclib
-TEST_VIRT = True
+TEST_PROCESS = True
+TEST_VIRT = False
TEST_SERVICES = True
+TEST_HARDWARE = True
# get a connecton (to be replaced by client lib logic)
s = xmlrpclib.ServerProxy("http://127.0.0.1:51234")
# here's the basic test...
-print s.test_add(1, 2)
+print s.test.add(1, 2)
+
+if TEST_PROCESS:
+ print s.process.info()
+ print s.process.pkill("thunderbird")
# here's the service module testing
if TEST_SERVICES:
- print s.service_restart("httpd")
+ print s.service.restart("httpd")
+
+if TEST_HARDWARE:
+ print s.hardware.info()
# this is so I can remember how the virt module works
if TEST_VIRT:
# example of using koan to install a virtual machine
- # s.virt_install("mdehaan.rdu.redhat.com","fc7webserver",False)
+ #s.virt_install("mdehaan.rdu.redhat.com","profileX")
# wait ...
- vms = s.virt_list_vms()
+ vms = s.virt.list_vms()
# example of stopping all stopped virtual machines
print "list of virtual instances = %s" % vms
for vm in vms:
- status = s.virt_status(vm)
+ status = s.virt.status(vm)
print status
if status == "shutdown":
- s.virt_start(vm)
+ s.virt.start(vm)
# add more tests here
diff --git a/modules/func_module.py b/modules/func_module.py
index ec587c1..4bb06d2 100755
--- a/modules/func_module.py
+++ b/modules/func_module.py
@@ -35,9 +35,9 @@ class FuncModule(object):
log = logger.Logger()
self.logger = log.logger
- def register_rpc(self, handlers):
+ def register_rpc(self, handlers, module_name):
for meth in self.methods:
- handlers[meth] = self.methods[meth]
+ handlers["%s.%s" % (module_name,meth)] = self.methods[meth]
diff --git a/modules/hardware.py b/modules/hardware.py
new file mode 100755
index 0000000..2c41b9f
--- /dev/null
+++ b/modules/hardware.py
@@ -0,0 +1,100 @@
+#!/usr/bin/python
+
+##
+## Hardware profiler plugin
+## requires the "smolt" client package be installed
+##
+## Copyright 2007, Red Hat, Inc
+## Michael DeHaan <mdehaan@redhat.com>
+##
+## 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.
+##
+
+
+# other modules
+import sys
+# hack: smolt is not installed in site-packages
+sys.path.append("/usr/share/smolt/client")
+import smolt
+
+# our modules
+from codes import *
+from modules import func_module
+
+# =================================
+
+class HardwareModule(func_module.FuncModule):
+ def __init__(self):
+ self.methods = {
+ "info": self.info
+ }
+ func_module.FuncModule.__init__(self)
+
+ def info(self,with_devices=True):
+ """
+ Returns a struct of hardware information. By default, this pulls down
+ all of the devices. If you don't care about them, set with_devices to
+ False.
+ """
+ return hw_info(with_devices)
+
+# =================================
+
+def hw_info(with_devices=True):
+
+ hardware = smolt.Hardware()
+ host = hardware.host
+
+ # NOTE: casting is needed because these are DBusStrings, not real strings
+ data = {
+ 'os' : str(host.os),
+ 'defaultRunlevel' : str(host.defaultRunlevel),
+ 'bogomips' : str(host.bogomips),
+ 'cpuVendor' : str(host.cpuVendor),
+ 'cpuModel' : str(host.cpuModel),
+ 'numCpus' : str(host.numCpus),
+ 'cpuSpeed' : str(host.cpuSpeed),
+ 'systemMemory' : str(host.systemMemory),
+ 'systemSwap' : str(host.systemSwap),
+ 'kernelVersion' : str(host.kernelVersion),
+ 'language' : str(host.language),
+ 'platform' : str(host.platform),
+ 'systemVendor' : str(host.systemVendor),
+ 'systemModel' : str(host.systemModel),
+ 'formfactor' : str(host.formfactor),
+ 'selinux_enabled' : str(host.selinux_enabled),
+ 'selinux_enforce' : str(host.selinux_enforce)
+ }
+
+ # if no hardware info requested, just return the above bits
+ if not with_devices:
+ return data
+
+ collection = data["devices"] = []
+
+ for item in hardware.deviceIter():
+
+ (VendorID,DeviceID,SubsysVendorID,SubsysDeviceID,Bus,Driver,Type,Description) = item
+
+ collection.append({
+ "VendorID" : str(VendorID),
+ "DeviceID" : str(DeviceID),
+ "SubsysVendorID" : str(SubsysVendorID),
+ "Bus" : str(Bus),
+ "Driver" : str(Driver),
+ "Type" : str(Type),
+ "Description" : str(Description)
+ })
+
+ return data
+
+methods = HardwareModule()
+register_rpc = methods.register_rpc
+
+
+
diff --git a/modules/process.py b/modules/process.py
new file mode 100755
index 0000000..064b1b3
--- /dev/null
+++ b/modules/process.py
@@ -0,0 +1,68 @@
+#!/usr/bin/python
+
+##
+## Process lister (control TBA)
+##
+## Copyright 2007, Red Hat, Inc
+## Michael DeHaan <mdehaan@redhat.com>
+##
+## 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.
+##
+
+# other modules
+import subprocess
+
+# our modules
+from codes import *
+from modules import func_module
+
+# =================================
+
+class ProcessModule(func_module.FuncModule):
+ def __init__(self):
+ self.methods = {
+ "info" : self.info,
+ "kill" : self.kill,
+ "pkill" : self.pkill
+ }
+ func_module.FuncModule.__init__(self)
+
+ def info(self,flags="-aux"):
+ """
+ Returns a struct of hardware information. By default, this pulls down
+ all of the devices. If you don't care about them, set with_devices to
+ False.
+ """
+
+ flags.replace(";","") # prevent stupidity
+
+ cmd = subprocess.Popen("ps %s" % flags,stdout=subprocess.PIPE,shell=True)
+ data = cmd.communicate()[0]
+
+ results = []
+
+ for x in data.split("\n"):
+ tokens = x.split()
+ results.append(tokens)
+
+ return results
+
+ def kill(self,pid,level=""):
+ rc = subprocess.call("/bin/kill %s %s" % (pid, level), shell=True)
+ return rc
+
+ def pkill(self,name,level=""):
+ # example killall("thunderbird","-9")
+ rc = subprocess.call("/usr/bin/pkill %s %s" % (name, level), shell=True)
+ return rc
+
+methods = ProcessModule()
+register_rpc = methods.register_rpc
+
+
+
diff --git a/modules/reboot.py b/modules/reboot.py
index c2f39ba..ddc7651 100755
--- a/modules/reboot.py
+++ b/modules/reboot.py
@@ -17,7 +17,7 @@ class Reboot(func_module.FuncModule):
def __init__(self):
self.methods = {
- "reboot_reboot" : self.reboot
+ "reboot" : self.reboot
}
func_module.FuncModule.__init__(self)
diff --git a/modules/service.py b/modules/service.py
index eaea16e..bbc51e1 100755
--- a/modules/service.py
+++ b/modules/service.py
@@ -25,11 +25,11 @@ class Service(func_module.FuncModule):
def __init__(self):
self.methods = {
- "service_start" : self.start,
- "service_stop" : self.stop,
- "service_restart" : self.restart,
- "service_reload" : self.reload,
- "service_status" : self.status
+ "start" : self.start,
+ "stop" : self.stop,
+ "restart" : self.restart,
+ "reload" : self.reload,
+ "status" : self.status
}
func_module.FuncModule.__init__(self)
diff --git a/modules/test.py b/modules/test.py
index b742e31..31f1e94 100755
--- a/modules/test.py
+++ b/modules/test.py
@@ -6,7 +6,7 @@ from modules import func_module
class Test(func_module.FuncModule):
def __init__(self):
self.methods = {
- "test_add": self.add
+ "add": self.add
}
func_module.FuncModule.__init__(self)
diff --git a/modules/virt.py b/modules/virt.py
index dc9a13a..d345d75 100755
--- a/modules/virt.py
+++ b/modules/virt.py
@@ -53,7 +53,7 @@ class FuncLibvirtConnection():
conn = libvirt.open("qemu:///system")
if not conn:
- raise FuncException(comment="hypervisor connection failure")
+ raise codes.FuncException("hypervisor connection failure")
self.conn = conn
@@ -84,7 +84,7 @@ class FuncLibvirtConnection():
if vm.name() == vmid:
return vm
- raise FuncException(comment="virtual machine %s not found" % needle)
+ raise codes.FuncException("virtual machine %s not found" % needle)
def shutdown(self, vmid):
return self.find_vm(vmid).shutdown()
@@ -131,15 +131,15 @@ class Virt(func_module.FuncModule):
"""
self.methods = {
- "virt_install" : self.install,
- "virt_shutdown" : self.shutdown,
- "virt_destroy" : self.destroy,
- "virt_start" : self.create,
- "virt_pause" : self.pause,
- "virt_unpause" : self.unpause,
- "virt_delete" : self.undefine,
- "virt_status" : self.get_status,
- "virt_list_vms" : self.list_vms,
+ "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,
+ "list_vms" : self.list_vms,
}
func_module.FuncModule.__init__(self)
@@ -171,10 +171,10 @@ class Virt(func_module.FuncModule):
conn = self.get_conn()
if conn is None:
- raise FuncException(comment="no connection")
+ raise codes.FuncException("no connection")
if not os.path.exists("/usr/bin/koan"):
- raise FuncException(comment="no /usr/bin/koan")
+ raise codes.FuncException("no /usr/bin/koan")
target = "profile"
if system:
target = "system"
@@ -192,7 +192,7 @@ class Virt(func_module.FuncModule):
if rc == 0:
return 0
else:
- raise FuncException(comment="koan returned %d" % rc)
+ raise codes.FuncException("koan returned %d" % rc)
def shutdown(self, vmid):
diff --git a/modules/yummod.py b/modules/yum.py
index 575b001..6600d47 100644
--- a/modules/yummod.py
+++ b/modules/yum.py
@@ -23,7 +23,7 @@ class Yum(func_module.FuncModule):
def __init__(self):
self.methods = {
- "yum_update" : self.update
+ "update" : self.update
}
func_module.FuncModule.__init__(self)
diff --git a/server/module_loader.py b/server/module_loader.py
index f189623..2b20429 100755
--- a/server/module_loader.py
+++ b/server/module_loader.py
@@ -22,6 +22,22 @@ import glob
from rhpl.translate import _, N_, textdomain, utf8
+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":
+ # we don't really care about __init__ files, though we do requure them
+ if filename[:8] == "__init__":
+ continue
+ # the normpath is important, since we
+ module_files.append(os.path.normpath("%s/%s" % (root, filename)))
+
+
+ return module_files
+
def load_modules(blacklist=None):
module_file_path="%s/func/server/modules/" % distutils.sysconfig.get_python_lib()
@@ -30,12 +46,14 @@ def load_modules(blacklist=None):
sys.path.insert(0, mod_path)
mods = {}
- filenames = glob.glob("%s/*.py" % module_file_path)
- filenames = filenames + glob.glob("%s/*.pyc" % module_file_path)
- filesnames = filenames + glob.glob("%s/*.pyo" % module_file_path)
+ filenames = module_walker(module_file_path)
+ # FIXME: this is probably more complicated than it needs to be -akl
for fn in filenames:
- basename = os.path.basename(fn)
+ # 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 == "__init__.py":
continue
if basename[-3:] == ".py":
@@ -43,14 +61,19 @@ def load_modules(blacklist=None):
elif basename[-4:] in [".pyc", ".pyo"]:
modname = basename[:-4]
-
+ pathname = modname
+ if dirname != "":
+ pathname = "%s/%s" % (dirname, modname)
+
+ mod_imp_name = pathname.replace("/", ".")
+
try:
- blip = __import__("modules.%s" % ( modname), globals(), locals(), [modname])
+ 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")
- print errmsg % {'module_path': module_file_path, 'modname':modname}
+ print errmsg % {'module_path': module_file_path, 'modname':mod_imp_name}
continue
- mods[modname] = blip
+ mods[mod_imp_name] = blip
except ImportError, e:
# shouldn't this be fatal?
print e
@@ -59,5 +82,17 @@ def load_modules(blacklist=None):
return mods
+if __name__ == "__main__":
+
+ module_file_path = "/usr/lib/python2.5/site-packages/func/server/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()
diff --git a/server/server.py b/server/server.py
index b167938..4e320e9 100755
--- a/server/server.py
+++ b/server/server.py
@@ -56,7 +56,7 @@ class XmlRpcInterface(object):
self.handlers = {}
for x in self.modules.keys():
try:
- self.modules[x].register_rpc(self.handlers)
+ self.modules[x].register_rpc(self.handlers, x)
self.logger.debug("adding %s" % x)
except AttributeError, e:
self.logger.warning("module %s not loaded, missing register_rpc method" % self.modules[x])
@@ -174,7 +174,7 @@ def main(argv):
try:
websvc = XmlRpcInterface(modules=modules)
- except FuncException, e:
+ except codes.FuncException, e:
print >> sys.stderr, 'error: %s' % e
sys.exit(1)