summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorNarayan Desai <desai@mcs.anl.gov>2006-02-09 20:02:19 +0000
committerNarayan Desai <desai@mcs.anl.gov>2006-02-09 20:02:19 +0000
commitdfcd59780e947e448b2a51647fc01b72c8c9eabd (patch)
tree901b79da15642dc0d3375be877beb020e7e451f4 /src/lib
parent1d486f8ec85597c88a2f46acaf21a379ba80aaab (diff)
downloadbcfg2-dfcd59780e947e448b2a51647fc01b72c8c9eabd.tar.gz
bcfg2-dfcd59780e947e448b2a51647fc01b72c8c9eabd.tar.bz2
bcfg2-dfcd59780e947e448b2a51647fc01b72c8c9eabd.zip
Switch to cobalt xmlrpc proxy code; should allow easier sync between bcfg and cobalt
git-svn-id: https://svn.mcs.anl.gov/repos/bcfg/trunk/bcfg2@1725 ce84e21b-d406-0410-9b95-82705330c041
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/Client/Proxy.py92
-rw-r--r--src/lib/Client/__init__.py2
2 files changed, 93 insertions, 1 deletions
diff --git a/src/lib/Client/Proxy.py b/src/lib/Client/Proxy.py
new file mode 100644
index 000000000..d300eac72
--- /dev/null
+++ b/src/lib/Client/Proxy.py
@@ -0,0 +1,92 @@
+'''Cobalt proxy provides client access to cobalt components'''
+__revision__ = '$Revision:$'
+
+import logging, socket, time, xmlrpclib, ConfigParser
+
+class CobaltComponentError(Exception):
+ '''This error signals component connection errors'''
+ pass
+
+class SafeProxy:
+ '''Wrapper for proxy'''
+ _cfile = ConfigParser.ConfigParser()
+ _cfile.read(['/etc/cobalt.conf'])
+ _components = _cfile._sections['components']
+ _authinfo = ('root', _cfile.get('communication', 'password'))
+ _retries = 4
+
+ def __init__(self, component, url=None):
+ self.component = component
+ self.log = logging.getLogger(component)
+ if url != None:
+ address = url
+ else:
+ address = self.__get_location(component)
+ try:
+ self.proxy = xmlrpclib.ServerProxy(address)
+ except IOError, io_error:
+ self.log.error("Invalid server URL %s: %s" % (address, io_error))
+ raise CobaltComponentError
+ except:
+ self.log.error("Failed to initialize xml-rpc", exc_info=1)
+
+ def run_method(self, method_name, method_args):
+ ''' Perform an XMLRPC invocation against the server'''
+ method = getattr(self.proxy, method_name)
+ for irs in range(self._retries):
+ try:
+ ret = apply(method, self._authinfo + method_args)
+ if irs > 0:
+ self.log.warning("Required %d attempts to contact %s for operation %s" %
+ (irs, self.component, method_name))
+ self.log.debug("%s completed successfully" % (method_name))
+ return ret
+ except xmlrpclib.ProtocolError:
+ self.log.error("Server failure: Protocol Error")
+ raise xmlrpclib.Fault(20, "Server Failure")
+ except xmlrpclib.Fault:
+ self.log.debug("Operation %s completed with fault" % (method_name))
+ raise
+ except socket.error:
+ self.log.debug("Attempting %s (%d of %d) failed" % (method_name, (irs+1), self._retries))
+ time.sleep(0.5)
+ except:
+ break
+ self.log.error("%s failed:\nCould not connect to %s" % (method_name, self.component))
+
+ def __get_location(self, name):
+ '''Perform component location lookups if needed'''
+ if self._components.has_key(name):
+ return self._components[name]
+ slp = SafeProxy('service-location', url=self._cfile.get('components', 'service-location'))
+ try:
+ sdata = slp.run_method('LookupService',
+ ([{'tag':'location', 'name':name, 'url':'*'}],))
+ except xmlrpclib.Fault:
+ raise CobaltComponentError, "No Such Component"
+ if sdata:
+ curl = sdata[0]['url']
+ self._components[name] = curl
+ return curl
+
+class ComponentProxy(SafeProxy):
+ '''Component Proxy instantiates a SafeProxy to a component and registers local functions
+ based on its definition'''
+ name = 'dummy'
+ methods = []
+
+ def __init__(self, url=None):
+ SafeProxy.__init__(self, self.name, url)
+ for method in self.methods:
+ setattr(self, method, eval('lambda *x:self.run_method(method, x)',
+ {'self':self, 'method':method}))
+
+class service_location(ComponentProxy):
+ '''service-location component-specific proxy'''
+ name = 'service-location'
+ methods = ['AssertService', 'LookupService', 'DeassertService']
+
+class process_manager(ComponentProxy):
+ '''process manager specific component proxy'''
+ name = 'process-manager'
+ methods = ['CreateProcessGroup', 'GetProcessGroup']
diff --git a/src/lib/Client/__init__.py b/src/lib/Client/__init__.py
index 0435249f7..bfdbc0e98 100644
--- a/src/lib/Client/__init__.py
+++ b/src/lib/Client/__init__.py
@@ -1,4 +1,4 @@
'''This contains all Bcfg2 Client modules'''
__revision__ = '$Revision$'
-__all__ = ["Toolset", "Debian", "Solaris", "Redhat", "Gentoo"]
+__all__ = ["Proxy", "Toolset", "Debian", "Solaris", "Redhat", "Gentoo"]