[Cluster-devel] conga/luci/site/luci/Extensions LuciSyslog.py ...

rmccabe at sourceware.org rmccabe at sourceware.org
Wed Oct 18 21:59:48 UTC 2006


CVSROOT:	/cvs/cluster
Module name:	conga
Changes by:	rmccabe at sourceware.org	2006-10-18 21:59:47

Modified files:
	luci/site/luci/Extensions: LuciSyslog.py ricci_communicator.py 

Log message:
	improved error handling and debug logging

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciSyslog.py.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_communicator.py.diff?cvsroot=cluster&r1=1.9&r2=1.10

--- conga/luci/site/luci/Extensions/LuciSyslog.py	2006/10/16 04:59:52	1.2
+++ conga/luci/site/luci/Extensions/LuciSyslog.py	2006/10/18 21:59:47	1.3
@@ -12,34 +12,47 @@
 """
 class LuciSyslog:
 	def __init__(self):
+		self.__init = 0
 		try:
 			openlog('luci', LOG_DAEMON, LOG_PID | LOG_NDELAY)
+			self.__init = 1
 		except:
 			raise LuciSyslogError, 'unable to setup syslog functionality.'
 
 	def info(self, msg):
+		if not self.__init:
+			return
 		try:
 			syslog(LOG_INFO, msg)
 		except:
 			raise LuciSyslogError, 'syslog info call failed'
 
 	def warn(self, msg):
+		if not self.__init:
+			return
 		try:
 			syslog(LOG_WARNING, msg)
 		except:
 			raise LuciSyslogError, 'syslog warn call failed'
 
 	def private(self, msg):
+		if not self.__init:
+			return
 		try:
 			syslog(LOG_AUTH, msg)
 		except:
 			raise LuciSyslogError, 'syslog private call failed'
 
 	def debug(self, msg):
+		if not self.__init:
+			return
 		try:
 			syslog(LOG_DEBUG, msg)
 		except:
 			raise LuciSyslogError, 'syslog debug calle failed'
 
 	def close(self):
-		closelog()
+		try:
+			closelog()
+		except:
+			pass
--- conga/luci/site/luci/Extensions/ricci_communicator.py	2006/10/16 07:39:27	1.9
+++ conga/luci/site/luci/Extensions/ricci_communicator.py	2006/10/18 21:59:47	1.10
@@ -1,17 +1,24 @@
-
-
 from time import *
 from socket import *
 import xml
 import xml.dom
 from xml.dom import minidom
-
+from LuciSyslog import LuciSyslog
 
 from HelperFunctions import access_to_host_allowed
 
 
 CERTS_DIR_PATH = '/var/lib/luci/var/certs/'
 
+try:
+    luci_log = LuciSyslog()
+except:
+    pass
+
+class RicciError(Exception):
+    def __init__(self, e):
+        pass
+
 class RicciCommunicator:
     def __init__(self, hostname, port=11111):
         self.__hostname = hostname
@@ -21,13 +28,21 @@
         self.__cert_file = CERTS_DIR_PATH + 'cacert.pem'
         
         # socket
-        sock = socket(AF_INET, SOCK_STREAM)
-        sock.settimeout(2.0)
-        sock.connect((self.__hostname, self.__port))
-        self.ss = ssl(sock, self.__privkey_file, self.__cert_file)
-        sock.settimeout(600.0) # 10 minutes
-        # TODO: data transfer timeout should be much less, 
-        # leave until all calls are async ricci calls
+        try:
+            sock = socket(AF_INET, SOCK_STREAM)
+            sock.settimeout(2.0)
+            sock.connect((self.__hostname, self.__port))
+        except Exception, e:
+            raise RicciError, 'Error connecting to %s:%d: %s' \
+                    % (self.__hostname, self.__port, str(e))
+        try:
+            self.ss = ssl(sock, self.__privkey_file, self.__cert_file)
+            # TODO: data transfer timeout should be much less, 
+            # leave until all calls are async ricci calls
+            sock.settimeout(600.0) # 10 minutes
+        except Exception, e:
+            raise RicciError, 'Error setting up SSL for connection to %s: %s' \
+                % (self.__hostname, str(e))
         
         # receive ricci header
         hello = self.__receive()
@@ -83,15 +98,22 @@
         doc.appendChild(ricci)
         self.__send(doc)
         resp = self.__receive()
-        ret = resp.firstChild.getAttribute('success')
-        if ret != '0':
-            raise Exception(str(ret))
+
+        try:
+            ret = resp.firstChild.getAttribute('success')
+            if ret != '0':
+                raise Exception, 'Invalid response'
+        except:
+            errstr = 'Error authenticating to host %s: %s' \
+                        % (self.__hostname, str(ret))
+            luci_log.debug(errstr)
+            raise RicciError, errstr
         return True
 
 
     def process_batch(self, batch_xml, async=False):
         if not self.authed():
-            raise 'not authenticated'
+            raise RicciError, 'not authenticated to host %s', self.__hostname
         
         # construct request
         doc = minidom.Document()
@@ -108,13 +130,19 @@
         ricci.appendChild(batch_xml.cloneNode(True))
         
         # send request
-        self.__send(doc)
-        
+        try:
+            self.__send(doc)
+        except Exception, e:
+            luci_log.debug('Error sending XML \"%s\" to host %s' \
+                % (doc.toxml(), self.__hostname))
+            raise RicciError, 'Error sending XML to host %s: %s' \
+                    % (self.__hostname, str(e))
         
         # receive response
         doc = self.__receive()
         if doc.firstChild.getAttribute('success') != '0':
-            raise 'ricci reported error'
+            raise RicciError, 'The last ricci command to host %s failed' \
+                    % self.__hostname
         
         batch_node = None
         for node in doc.firstChild.childNodes:
@@ -122,7 +150,8 @@
                 if node.nodeName == 'batch':
                     batch_node = node.cloneNode(True)
         if batch_node == None:
-            raise 'missing <batch/> in ricci\'s response'
+            raise RicciError, 'missing <batch/> in ricci\'s response from %s' \
+                    % self.__hostname
 
         return batch_node
     
@@ -130,18 +159,22 @@
         try:
             batch_xml_str = '<?xml version="1.0" ?><batch>' + batch_str + '</batch>'
             batch_xml = minidom.parseString(batch_xml_str).firstChild
-        except:
-            return None
+        except Exception, e:
+            luci_log.debug('received invalid batch XML for %s: \"%s\"' \
+                % (self.__hostname, batch_xml_str))
+            raise RicciError, 'batch XML is malformed'
 
         try:
             ricci_xml = self.process_batch(batch_xml, async)
         except:
+            luci_log.debug('An error occurred while trying to process the batch job: %s' % batch_xml_str)
             return None
+
         return ricci_xml
 
     def batch_report(self, batch_id):
         if not self.authed():
-            raise 'not authenticated'
+            raise RicciError, 'Not authenticated to host %s' % self.__hostname
         
         # construct request
         doc = minidom.Document()
@@ -153,22 +186,21 @@
         
         # send request
         self.__send(doc)
-        
-        
+ 
+       
         # receive response
         doc = self.__receive()
         if doc.firstChild.getAttribute('success') == '12':
             return None
         if doc.firstChild.getAttribute('success') != '0':
-            raise 'ricci reported error'
-        
+            raise RicciError, 'Error while retrieving batch report for batch #%s from host %s' % (batch_id, self.__hostname)
         batch_node = None
         for node in doc.firstChild.childNodes:
             if node.nodeType == xml.dom.Node.ELEMENT_NODE:
                 if node.nodeName == 'batch':
                     batch_node = node.cloneNode(True)
         if batch_node == None:
-            raise 'missing <batch/> in ricci\'s response'
+            raise RicciError, 'Missing <batch/> in ricci\'s response from host %s' % self.__hostname
         return batch_node
     
     
@@ -177,13 +209,17 @@
     
     def __send(self, xml_doc):
         buff = xml_doc.toxml() + '\n'
-        #print buff
         while len(buff) != 0:
-            pos = self.ss.write(buff)
+            try:
+                pos = self.ss.write(buff)
+            except Exception, e:
+                luci_log.debug('Error sending XML \"%s\" to %s' \
+                    % (buff, self.__hostname))
+                raise RicciError, 'write error while sending XML to host %s' \
+                        % self.__hostname
             buff = buff[pos:]
         return
     
-    
     def __receive(self):
         doc = None
         xml_in = ''
@@ -197,18 +233,36 @@
                     doc = minidom.parseString(xml_in)
                     break
                 except:
-                    pass
-        except:
-            pass
+                    # we haven't received all of the XML data yet.
+                    continue
+        except Exception, e:
+            luci_log.debug('Error reading data from %s: %s' \
+                % (self.__hostname, str(e)))
+            raise RicciError, 'Error reading data from host %s' \
+                    % self.__hostname
+
         try:
             if doc == None:
                 doc = minidom.parseString(xml_in)
-            if doc.firstChild.nodeName != 'ricci':
-                raise ''
-        except:
-            raise 'invalid ricci response'
+        except Exception, e:
+            luci_log.debug('Error parsing XML \"%s" from %s' \
+                % (xml_in, str(e)))
+            raise RicciError, 'Error parsing XML from host %s: %s' \
+                    % (self.__hostname, str(e))
+
+        if not doc or not doc.firstChild:
+            raise RicciError, \
+                    'Error an empty response was received from host %s' \
+                    % self.__hostname
         
-        #print doc.toxml()
+        try:        
+            if doc.firstChild.nodeName != 'ricci':
+                luci_log.debug('Expecting \"ricci\" got XML \"%s\" from %s' %
+                    (xml_in, self.__hostname))
+                raise Exception, 'Expecting first XML child node to be \"ricci\"'
+        except Exception, e:
+            raise RicciError, 'Invalid XML ricci response from host %s' \
+                    % self.__hostname
         
         return doc
     
@@ -220,7 +274,9 @@
     
     try:
         return RicciCommunicator(hostname)
-    except:
+    except Exception, e:
+        luci_log.debug('Error creating a ricci connection to %s: %s' \
+            % (hostname, str(e)))
         return None
     pass
 
@@ -307,7 +363,9 @@
 # * error_msg:  error message
 def extract_module_status(batch_xml, module_num=1):
     if batch_xml.nodeName != 'batch':
-        raise 'not a batch'
+        luci_log.debug('Expecting \"batch\" got \"%s\"' % batch_xml.toxml())
+        raise RicciError, 'Invalid XML node; expecting a batch node'
+
     c = 0
     for node in batch_xml.childNodes:
         if node.nodeType == xml.dom.Node.ELEMENT_NODE:
@@ -349,5 +407,5 @@
                     elif status == '5':
                         return -103, 'module removed from schedule'
     
-    raise Exception, str('no ' + str(module_num) + 'th module in the batch, or malformed response')
+    raise RicciError, str('no ' + str(module_num) + 'th module in the batch, or malformed response')
 




More information about the Cluster-devel mailing list