summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/Client/Proxy.py92
-rw-r--r--src/lib/Client/__init__.py2
-rwxr-xr-xsrc/sbin/bcfg256
3 files changed, 98 insertions, 52 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"]
diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2
index fcc3a757c..842c5666b 100755
--- a/src/sbin/bcfg2
+++ b/src/sbin/bcfg2
@@ -9,12 +9,13 @@ from signal import signal, SIGINT
from sys import argv
from tempfile import mktemp
from ConfigParser import ConfigParser, NoSectionError, NoOptionError
-from xmlrpclib import ServerProxy, Fault
from lxml.etree import Element, XML, tostring, XMLSyntaxError
-from time import sleep, time
+from time import time
from sys import exc_info
from traceback import extract_tb
-import socket
+
+import xmlrpclib
+import Bcfg2.Client.Proxy
def cb_sigint_handler(signum, frame):
'''Exit upon CTRL-C'''
@@ -27,53 +28,6 @@ def if_then(cond, value_if, value_else):
else:
return value_else
-class SafeProxy:
- '''Wrapper for proxy'''
- def __init__(self, setup, client):
- self.retryCount = 0
- self.client = client
- self.setup = setup
- try:
- self.proxy = ServerProxy(self.setup["server"])
- except IOError, io_error:
- self.client.fatal_error("Invalid server URL %s: %s" %
- (self.setup["server"], io_error))
- except:
- self.client.critical_error("initialising XML-RPC")
-
- def run_method(self, operation_desc, method_name, method_args):
- ''' Perform an XMLRPC invocation against the server'''
- method = getattr(self.proxy, method_name)
- instance_retries = 0
- for i in xrange(int(self.setup["retries"])):
- try:
- self.client.cond_print("debug", "Attempting %s (%d of %d)" %
- (operation_desc,(i+1),
- int(self.setup["retries"])))
- ret = apply(method, (self.setup['user'],
- self.setup['password']) + method_args)
- if instance_retries > 0:
- self.client.warning_error(
- "during %s:\nRequired %d attempts to contact server (%s)"
- % (operation_desc, instance_retries,
- self.setup["server"]))
- self.client.cond_print("debug", "%s completed successfully" %
- (operation_desc))
- return ret
- except Fault, fault:
- self.client.fatal_error("%s encountered a server error:\n%s" %
- (operation_desc, fault))
- except socket.error:
- instance_retries += 1
- self.retryCount += 1
- sleep(1.0)
- except:
- self.client.critical_error(operation_desc)
-
- self.client.fatal_error("%s failed:\nCould not connect to server (%s)" %
- (operation_desc, self.setup["server"]))
-
-
class Client:
''' The main bcfg2 client class '''
def __init__(self, args):
@@ -354,7 +308,7 @@ class Client:
% (self.setup['file']))
else:
# retrieve config from server
- proxy = SafeProxy(self.setup, self)
+ proxy = Bcfg2.Client.Proxy.SafeProxy(self.setup, self)
probe_data = proxy.run_method("probe download", "GetProbes", ())