[Libvir] PATCH: Fix exception reporting for virNetwork / virDomain python methods

Daniel P. Berrange berrange at redhat.com
Sun Apr 15 21:07:01 UTC 2007


The virError() class in the python bindings will either pick up the global
error details, or will extract them from the virConnect private error
details. For the latter to work, you must pass in a virConnect object
when creating the virError. I'd previously fixed up the generator so that
was done correctly for any method on virConnectPtr, however, I forgot that
a similar fix was needed for the virDomainPtr / virNetworkPtr related
methods. Currently we're getting back zero useful information in the python
layer with a virDomain* or virNetwork* method fails.

Unfortunately, given a virDomainPtr / virNetworkPtr object in python, there
is no easy way to get back the virConnectPtr object. So this patch does
two things - it passes the virConnect python object into the constructor
of the virDomain / virNetwork python objects, and then stores it in a
private _conn attribute. Then, the virNetwork/virDomain objects are passed
into the virError() classes when needeed so it can get hold of the private
error details.  

So with this patch, virt-manager will get sensible error information when
attempting to start an inactive guest, or when doing device hot-add/remove.

BTW, since we now store an explicit reference to the virConnect object,
I removed the generic 'self.ref' back-reference.

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
Index: generator.py
===================================================================
RCS file: /data/cvs/libvirt/python/generator.py,v
retrieving revision 1.19
diff -u -p -r1.19 generator.py
--- generator.py	28 Mar 2007 11:24:14 -0000	1.19
+++ generator.py	15 Apr 2007 21:06:16 -0000
@@ -535,10 +535,10 @@ def buildStubs():
 # The type automatically remapped to generated classes
 #
 classes_type = {
-    "virDomainPtr": ("._o", "virDomain(_obj=%s)", "virDomain"),
-    "virDomain *": ("._o", "virDomain(_obj=%s)", "virDomain"),
-    "virNetworkPtr": ("._o", "virNetwork(_obj=%s)", "virNetwork"),
-    "virNetwork *": ("._o", "virNetwork(_obj=%s)", "virNetwork"),
+    "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"),
+    "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"),
+    "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
+    "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
     "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
     "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
 }
@@ -556,11 +556,6 @@ classes_destructors = {
     "virConnect": "virConnectClose",
 }
 
-classes_references = {
-    "virDomain": "virConnect",
-    "virNetwork": "virConnect",
-}
-
 functions_noexcept = {
     'virDomainGetID': True,
     'virDomainGetName': True,
@@ -872,11 +867,16 @@ def buildWrappers():
 	    else:
 		txt.write("Class %s()\n" % (classname))
 		classes.write("class %s:\n" % (classname))
-		classes.write("    def __init__(self, _obj=None):\n")
+                if classname == "virDomain" or classname == "virNetwork":
+                    classes.write("    def __init__(self, conn, _obj=None):\n")
+                else:
+                    classes.write("    def __init__(self, _obj=None):\n")
 		if reference_keepers.has_key(classname):
 		    list = reference_keepers[classname]
 		    for ref in list:
 		        classes.write("        self.%s = None\n" % ref[1])
+                if classname == "virDomain" or classname == "virNetwork":
+                    classes.write("        self._conn = conn\n")
 		classes.write("        if _obj != None:self._o = _obj;return\n")
 		classes.write("        self._o = None\n\n");
 	    destruct=None
@@ -961,6 +961,14 @@ def buildWrappers():
                                 classes.write(
 		     "        if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
                                               (name))
+                            elif classname == "virDomain":
+                                classes.write(
+		     "        if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
+                                              (name))
+                            elif classname == "virNetwork":
+                                classes.write(
+		     "        if ret is None:raise libvirtError('%s() failed', net=self)\n" %
+                                              (name))
                             else:
                                 classes.write(
 		     "        if ret is None:raise libvirtError('%s() failed')\n" %
@@ -973,12 +981,6 @@ def buildWrappers():
 			classes.write(classes_type[ret[0]][1] % ("ret"));
 			classes.write("\n");
 
-			#
-			# hook up a reference if needed
-			#
-			if classes_references.has_key(classes_type[ret[0]][2]):
-			    classes.write("        __tmp.ref = self\n");
-
                         #
 			# Sometime one need to keep references of the source
 			# class in the returned class object.
@@ -1031,6 +1033,14 @@ def buildWrappers():
                                 classes.write (("        if " + test +
                                                 ": raise libvirtError ('%s() failed', conn=self)\n") %
                                                ("ret", name))
+                            elif classname == "virDomain":
+                                classes.write (("        if " + test +
+                                                ": raise libvirtError ('%s() failed', dom=self)\n") %
+                                               ("ret", name))
+                            elif classname == "virNetwork":
+                                classes.write (("        if " + test +
+                                                ": raise libvirtError ('%s() failed', net=self)\n") %
+                                               ("ret", name))
                             else:
                                 classes.write (("        if " + test +
                                                 ": raise libvirtError ('%s() failed')\n") %
@@ -1053,6 +1063,14 @@ def buildWrappers():
                                 classes.write (("        if " + test +
                                                 ": raise libvirtError ('%s() failed', conn=self)\n") %
                                                ("ret", name))
+                            elif classname == "virDomain":
+                                classes.write (("        if " + test +
+                                                ": raise libvirtError ('%s() failed', dom=self)\n") %
+                                               ("ret", name))
+                            elif classname == "virNetwork":
+                                classes.write (("        if " + test +
+                                                ": raise libvirtError ('%s() failed', net=self)\n") %
+                                               ("ret", name))
                             else:
                                 classes.write (("        if " + test +
                                                 ": raise libvirtError ('%s() failed')\n") %
Index: libvir.py
===================================================================
RCS file: /data/cvs/libvirt/python/libvir.py,v
retrieving revision 1.3
diff -u -p -r1.3 libvir.py
--- libvir.py	10 Nov 2006 19:55:27 -0000	1.3
+++ libvir.py	15 Apr 2007 21:06:16 -0000
@@ -9,9 +9,14 @@ import types
 
 # The root of all libvirt errors.
 class libvirtError(Exception):
-    def __init__(self, msg, conn=None):
+    def __init__(self, msg, conn=None, dom=None, net=None):
         Exception.__init__(self, msg)
 
+        if dom is not None:
+            conn = dom._conn
+        elif net is not None:
+            conn = net._conn
+
         if conn is None:
             self.err = virGetLastError()
         else:


More information about the libvir-list mailing list