[libvirt] [PATCH] Fix up the python bindings for snapshotting.
Chris Lalancette
clalance at redhat.com
Thu May 20 17:49:46 UTC 2010
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 at redhat.com>
>> ---
>> 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
More information about the libvir-list
mailing list