This patch was extracted from the network events feature patch to fit the new libvirt-python repository. --- generator.py | 2 + libvirt-override-virConnect.py | 34 +++++++++ libvirt-override.c | 154 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) diff --git a/generator.py b/generator.py index a9f98ab..02ea821 100755 --- a/generator.py +++ b/generator.py @@ -491,6 +491,8 @@ skip_function = ( 'virConnectDomainEventDeregister', # overridden in virConnect.py 'virConnectDomainEventRegisterAny', # overridden in virConnect.py 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py + 'virConnectNetworkEventRegisterAny', # overridden in virConnect.py + 'virConnectNetworkEventDeregisterAny', # overridden in virConnect.py 'virSaveLastError', # We have our own python error wrapper 'virFreeError', # Only needed if we use virSaveLastError 'virConnectListAllDomains', # overridden in virConnect.py diff --git a/libvirt-override-virConnect.py b/libvirt-override-virConnect.py index 23fadfd..15e9c54 100644 --- a/libvirt-override-virConnect.py +++ b/libvirt-override-virConnect.py @@ -198,6 +198,40 @@ except AttributeError: pass + def _dispatchNetworkEventLifecycleCallback(self, net, event, cbData): + """Dispatches events to python user network lifecycle event callbacks + """ + cb = cbData["cb"] + opaque = cbData["opaque"] + + cb(self, virNetwork(self, _obj=net), event, opaque) + return 0 + + def networkEventDeregisterAny(self, callbackID): + """Removes a Network Event Callback. De-registering for a + network callback will disable delivery of this event type """ + try: + ret = libvirtmod.virConnectNetworkEventDeregisterAny(self._o, callbackID) + if ret == -1: raise libvirtError ('virConnectNetworkEventDeregisterAny() failed', conn=self) + del self.networkEventCallbackID[callbackID] + except AttributeError: + pass + + def networkEventRegisterAny(self, net, eventID, cb, opaque): + """Adds a Network Event Callback. Registering for a network + callback will enable delivery of the events """ + if not hasattr(self, 'networkEventCallbackID'): + self.networkEventCallbackID = {} + cbData = { "cb": cb, "conn": self, "opaque": opaque } + if net is None: + ret = libvirtmod.virConnectNetworkEventRegisterAny(self._o, None, eventID, cbData) + else: + ret = libvirtmod.virConnectNetworkEventRegisterAny(self._o, net._o, eventID, cbData) + if ret == -1: + raise libvirtError ('virConnectNetworkEventRegisterAny() failed', conn=self) + self.networkEventCallbackID[ret] = opaque + return ret + def domainEventRegisterAny(self, dom, eventID, cb, opaque): """Adds a Domain Event Callback. Registering for a domain callback will enable delivery of the events """ diff --git a/libvirt-override.c b/libvirt-override.c index 93b9c5f..d613b0d 100644 --- a/libvirt-override.c +++ b/libvirt-override.c @@ -6569,6 +6569,156 @@ libvirt_virConnectDomainEventDeregisterAny(ATTRIBUTE_UNUSED PyObject * self, return py_retval; } +#if LIBVIR_CHECK_VERSION(1, 2, 1) +static void +libvirt_virConnectNetworkEventFreeFunc(void *opaque) +{ + PyObject *pyobj_conn = (PyObject*)opaque; + LIBVIRT_ENSURE_THREAD_STATE; + Py_DECREF(pyobj_conn); + LIBVIRT_RELEASE_THREAD_STATE; +} + +static int +libvirt_virConnectNetworkEventLifecycleCallback(virConnectPtr conn ATTRIBUTE_UNUSED, + virNetworkPtr net, + int event, + void *opaque) +{ + PyObject *pyobj_cbData = (PyObject*)opaque; + PyObject *pyobj_net; + PyObject *pyobj_ret; + PyObject *pyobj_conn; + PyObject *dictKey; + int ret = -1; + + LIBVIRT_ENSURE_THREAD_STATE; + + /* Create a python instance of this virNetworkPtr */ + virNetworkRef(net); + pyobj_net = libvirt_virNetworkPtrWrap(net); + Py_INCREF(pyobj_cbData); + + dictKey = libvirt_constcharPtrWrap("conn"); + pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey); + Py_DECREF(dictKey); + + /* Call the Callback Dispatcher */ + pyobj_ret = PyObject_CallMethod(pyobj_conn, + (char*)"_dispatchNetworkEventLifecycleCallback", + (char*)"OiO", + pyobj_net, + event, + pyobj_cbData); + + Py_DECREF(pyobj_cbData); + Py_DECREF(pyobj_net); + + if (!pyobj_ret) { + DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); + PyErr_Print(); + } else { + Py_DECREF(pyobj_ret); + ret = 0; + } + + LIBVIRT_RELEASE_THREAD_STATE; + return ret; +} + +static PyObject * +libvirt_virConnectNetworkEventRegisterAny(ATTRIBUTE_UNUSED PyObject * self, + PyObject * args) +{ + PyObject *py_retval; /* return value */ + PyObject *pyobj_conn; /* virConnectPtr */ + PyObject *pyobj_net; + PyObject *pyobj_cbData; /* hash of callback data */ + int eventID; + virConnectPtr conn; + int ret = 0; + virConnectNetworkEventGenericCallback cb = NULL; + virNetworkPtr net; + virNetworkEventID eventId = VIR_NETWORK_EVENT_ID_LAST; + + if (!PyArg_ParseTuple + (args, (char *) "OOiO:virConnectNetworkEventRegisterAny", + &pyobj_conn, &pyobj_net, &eventID, &pyobj_cbData)) { + DEBUG("%s failed parsing tuple\n", __FUNCTION__); + return VIR_PY_INT_FAIL; + } + + DEBUG("libvirt_virConnectNetworkEventRegister(%p %p %d %p) called\n", + pyobj_conn, pyobj_net, eventID, pyobj_cbData); + conn = PyvirConnect_Get(pyobj_conn); + if (pyobj_net == Py_None) + net = NULL; + else + net = PyvirNetwork_Get(pyobj_net); + + if ( ((eventID & 0xFF00) >> 8) != VIR_EVENT_NAMESPACE_NETWORK) { + return VIR_PY_INT_FAIL; + } + + eventId = (virNetworkEventID) (eventID & 0xFF); + switch (eventId) { + case VIR_NETWORK_EVENT_ID_LIFECYCLE: + cb = VIR_NETWORK_EVENT_CALLBACK(libvirt_virConnectNetworkEventLifecycleCallback); + break; + + case VIR_NETWORK_EVENT_ID_LAST: + break; + } + + if (!cb) { + return VIR_PY_INT_FAIL; + } + + Py_INCREF(pyobj_cbData); + + LIBVIRT_BEGIN_ALLOW_THREADS; + ret = virConnectNetworkEventRegisterAny(conn, net, eventID, + cb, pyobj_cbData, + libvirt_virConnectNetworkEventFreeFunc); + LIBVIRT_END_ALLOW_THREADS; + + if (ret < 0) { + Py_DECREF(pyobj_cbData); + } + + py_retval = libvirt_intWrap(ret); + return py_retval; +} + +static PyObject * +libvirt_virConnectNetworkEventDeregisterAny(ATTRIBUTE_UNUSED PyObject * self, + PyObject * args) +{ + PyObject *py_retval; + PyObject *pyobj_conn; + int callbackID; + virConnectPtr conn; + int ret = 0; + + if (!PyArg_ParseTuple + (args, (char *) "Oi:virConnectNetworkEventDeregister", + &pyobj_conn, &callbackID)) + return NULL; + + DEBUG("libvirt_virConnectNetworkEventDeregister(%p) called\n", pyobj_conn); + + conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); + + LIBVIRT_BEGIN_ALLOW_THREADS; + + ret = virConnectNetworkEventDeregisterAny(conn, callbackID); + + LIBVIRT_END_ALLOW_THREADS; + py_retval = libvirt_intWrap(ret); + return py_retval; +} +#endif /* LIBVIR_CHECK_VERSION(1, 2, 1)*/ + #if LIBVIR_CHECK_VERSION(0, 10, 0) static void libvirt_virConnectCloseCallbackDispatch(virConnectPtr conn ATTRIBUTE_UNUSED, @@ -7369,6 +7519,10 @@ static PyMethodDef libvirtMethods[] = { {(char *) "virConnectDomainEventDeregister", libvirt_virConnectDomainEventDeregister, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventRegisterAny", libvirt_virConnectDomainEventRegisterAny, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventDeregisterAny", libvirt_virConnectDomainEventDeregisterAny, METH_VARARGS, NULL}, +#if LIBVIR_CHECK_VERSION(1, 2, 1) + {(char *) "virConnectNetworkEventRegisterAny", libvirt_virConnectNetworkEventRegisterAny, METH_VARARGS, NULL}, + {(char *) "virConnectNetworkEventDeregisterAny", libvirt_virConnectNetworkEventDeregisterAny, METH_VARARGS, NULL}, +#endif /* LIBVIR_CHECK_VERSION(1, 2, 1) */ #if LIBVIR_CHECK_VERSION(0, 10, 0) {(char *) "virConnectRegisterCloseCallback", libvirt_virConnectRegisterCloseCallback, METH_VARARGS, NULL}, {(char *) "virConnectUnregisterCloseCallback", libvirt_virConnectUnregisterCloseCallback, METH_VARARGS, NULL}, -- 1.8.4.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list