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 -=|
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:
-- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list