[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