On 05/20/2010 12:34 PM, Cole Robinson wrote: > On 05/20/2010 11:14 AM, Chris Lalancette wrote: >> This involved a few fixes. To start with, >> an virDomainSnapshot object is really tied to a >> domain, not a connection, so we have to generate >> a slightly different object so that we can get >> at self._dom for the object. >> >> Next, we had to "dummy" up an override piece of >> XML with a bogus argument that the function doesn't >> actually take. That's so that the generator places >> virDomainRevertToSnapshot underneath the correct >> class (namely, the virDomain class). >> >> Finally, we had to hand-implement the >> virDomainRevertToSnapshot implementation, ignoring the >> bogus pointer we are being passed. >> >> With all of this in place, I was able to successfully >> take a snapshot and revert to it using only the >> Python bindings. >> >> Signed-off-by: Chris Lalancette <clalance@xxxxxxxxxx> >> --- >> python/generator.py | 26 +++++++++++++++++++++++--- >> python/libvirt-override-api.xml | 7 +++++++ >> python/libvirt-override.c | 23 +++++++++++++++++++++++ >> 3 files changed, 53 insertions(+), 3 deletions(-) >> >> diff --git a/python/generator.py b/python/generator.py >> index a243c82..d876df6 100755 >> --- a/python/generator.py >> +++ b/python/generator.py >> @@ -331,7 +331,7 @@ skip_impl = ( >> 'virNodeListDevices', >> 'virNodeDeviceListCaps', >> 'virConnectBaselineCPU', >> - 'virDomainSnapshotListNames', >> + 'virDomainRevertToSnapshot', >> ) >> >> >> @@ -385,6 +385,10 @@ skip_function = ( >> "virStorageVolGetConnect", >> ) >> >> +function_skip_index_one = ( >> + "virDomainRevertToSnapshot", >> +) >> + >> >> def print_function_wrapper(name, output, export, include): >> global py_types >> @@ -688,9 +692,13 @@ classes_destructors = { >> } >> >> class_skip_connect_impl = { >> - "virConnect" : True >> + "virConnect" : True, >> + "virDomainSnapshot": True, >> } >> >> +class_domain_impl = { >> + "virDomainSnapshot": True, >> +} >> >> functions_noexcept = { >> 'virDomainGetID': True, >> @@ -986,7 +994,7 @@ def buildWrappers(): >> info = (0, func, name, ret, args, file) >> function_classes[classe].append(info) >> elif name[0:3] == "vir" and len(args) >= 2 and args[1][1] == type \ >> - and file != "python_accessor": >> + and file != "python_accessor" and not name in function_skip_index_one: >> found = 1 >> func = nameFixup(name, classe, type, file) >> info = (1, func, name, ret, args, file) >> @@ -1128,6 +1136,8 @@ def buildWrappers(): >> "virStorageVol", "virNodeDevice", "virSecret","virStream", >> "virNWFilter" ]: >> classes.write(" def __init__(self, conn, _obj=None):\n") >> + elif classname in [ 'virDomainSnapshot' ]: >> + classes.write(" def __init__(self, dom, _obj=None):\n") >> else: >> classes.write(" def __init__(self, _obj=None):\n") >> if reference_keepers.has_key(classname): >> @@ -1142,6 +1152,8 @@ def buildWrappers(): >> classes.write(" self._conn = conn\n" + \ >> " if not isinstance(conn, virConnect):\n" + \ >> " self._conn = conn._conn\n") >> + elif classname in [ "virDomainSnapshot" ]: >> + classes.write(" self._dom = dom\n") >> classes.write(" if _obj != None:self._o = _obj;return\n") >> classes.write(" self._o = None\n\n"); >> destruct=None >> @@ -1158,6 +1170,10 @@ def buildWrappers(): >> classes.write(" def connect(self):\n") >> classes.write(" return self._conn\n\n") >> >> + if class_domain_impl.has_key(classname): >> + classes.write(" def domain(self):\n") >> + classes.write(" return self._dom\n\n") >> + >> flist = function_classes[classname] >> flist.sort(functionCompare) >> oldfile = "" >> @@ -1252,6 +1268,10 @@ def buildWrappers(): >> classes.write( >> " if ret is None:raise libvirtError('%s() failed', vol=self)\n" % >> (name)) >> + elif classname == "virDomainSnapshot": >> + classes.write( >> + " if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" % >> + (name)) >> else: >> classes.write( >> " if ret is None:raise libvirtError('%s() failed')\n" % >> diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml >> index 9ba8e4e..be28b40 100644 >> --- a/python/libvirt-override-api.xml >> +++ b/python/libvirt-override-api.xml >> @@ -277,5 +277,12 @@ >> <arg name='flags' type='unsigned int' info='flags, curently unused'/> >> <return type='str *' info='the list of Names of None in case of error'/> >> </function> >> + <function name='virDomainRevertToSnapshot' file='python'> >> + <info>revert the domain to the given snapshot</info> >> + <arg name='dom' type='virDomainPtr' info='dummy domain pointer'/> >> + <arg name='snap' type='virDomainSnapshotPtr' info='pointer to the snapshot'/> >> + <arg name='flags' type='unsigned int' info='flags, curently unused'/> >> + <return type='int' info="0 on success, -1 on error"/> >> + </function> >> </symbols> >> </api> >> diff --git a/python/libvirt-override.c b/python/libvirt-override.c >> index c9721f7..ad55940 100644 >> --- a/python/libvirt-override.c >> +++ b/python/libvirt-override.c >> @@ -988,6 +988,28 @@ libvirt_virDomainSnapshotListNames(PyObject *self ATTRIBUTE_UNUSED, >> } >> >> static PyObject * >> +libvirt_virDomainRevertToSnapshot(PyObject *self ATTRIBUTE_UNUSED, >> + PyObject *args) { >> + int c_retval; >> + virDomainSnapshotPtr snap; >> + PyObject *pyobj_snap; >> + PyObject *pyobj_dom; >> + int flags; >> + >> + if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainRevertToSnapshot", &pyobj_dom, &pyobj_snap, &flags)) >> + return(NULL); >> + snap = (virDomainSnapshotPtr) PyvirDomainSnapshot_Get(pyobj_snap); >> + >> + LIBVIRT_BEGIN_ALLOW_THREADS; >> + c_retval = virDomainRevertToSnapshot(snap, flags); >> + LIBVIRT_END_ALLOW_THREADS; >> + if (c_retval < 0) >> + return VIR_PY_INT_FAIL; >> + >> + return PyInt_FromLong(c_retval); >> +} >> + >> +static PyObject * >> libvirt_virDomainGetInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { >> PyObject *py_retval; >> int c_retval; >> @@ -3527,6 +3549,7 @@ static PyMethodDef libvirtMethods[] = { >> {(char *) "virConnectBaselineCPU", libvirt_virConnectBaselineCPU, METH_VARARGS, NULL}, >> {(char *) "virDomainGetJobInfo", libvirt_virDomainGetJobInfo, METH_VARARGS, NULL}, >> {(char *) "virDomainSnapshotListNames", libvirt_virDomainSnapshotListNames, METH_VARARGS, NULL}, >> + {(char *) "virDomainRevertToSnapshot", libvirt_virDomainRevertToSnapshot, METH_VARARGS, NULL}, >> {NULL, NULL, 0, NULL} >> }; >> > > ACK, change looks fine. Might be worth checking the python bindings diff > though, the generator is fragile and changes can sometimes muck up > existing APIs. Excellent thought. I did that across libvirt.c, libvirt-export.c, libvirt.h and libvirt.py, and the only changes were the ones I expected. Thanks for the heads up. I've now pushed this patch. -- Chris Lalancette -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list