mirror of https://gitee.com/openkylin/libvirt.git
* python/Makefile.am python/generator.py python/libvir.c
python/libvir.py python/libvirt_wrap.h python/types.c: adds support for events from the python bindings, also improves the generator allowing to embbed per function definition files, patch by Ben Guthro * examples/domain-events/events-python/event-test.py: also adds a programming example Daniel
This commit is contained in:
parent
c5ee075dd9
commit
7b716fce8e
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
Fri Oct 31 11:11:30 CET 2008 Daniel Veillard <veillard@redhat.com>
|
||||
|
||||
* python/Makefile.am python/generator.py python/libvir.c
|
||||
python/libvir.py python/libvirt_wrap.h python/types.c:
|
||||
adds support for events from the python bindings, also
|
||||
improves the generator allowing to embbed per function
|
||||
definition files, patch by Ben Guthro
|
||||
* examples/domain-events/events-python/event-test.py: also
|
||||
adds a programming example
|
||||
|
||||
Thu Oct 30 13:39:00 EST 2008 Cole Robinson <crobinso@redhat.com>
|
||||
|
||||
* src/test.c: Add a test storage driver.
|
||||
|
|
|
@ -0,0 +1,186 @@
|
|||
#!/usr/bin/python -u
|
||||
import sys,getopt,os
|
||||
import libvirt
|
||||
import select
|
||||
|
||||
mypoll = select.poll()
|
||||
TIMEOUT_MS = 1000
|
||||
|
||||
# handle globals
|
||||
h_fd = 0
|
||||
h_events = 0
|
||||
h_cb = None
|
||||
h_opaque = None
|
||||
|
||||
# timeout globals
|
||||
t_active = 0
|
||||
t_timeout = -1
|
||||
t_cb = None
|
||||
t_opaque = None
|
||||
|
||||
#####################################################
|
||||
# Callback Functions
|
||||
#####################################################
|
||||
def eventToString(event):
|
||||
eventStrings = ( "Added",
|
||||
"Removed",
|
||||
"Started",
|
||||
"Suspended",
|
||||
"Resumed",
|
||||
"Stopped",
|
||||
"Saved",
|
||||
"Restored" );
|
||||
return eventStrings[event];
|
||||
|
||||
def myDomainEventCallback1 (conn, dom, event, opaque):
|
||||
print "myDomainEventCallback1 EVENT: Domain %s(%s) %s" % (dom.name(), dom.ID(), eventToString(event))
|
||||
|
||||
def myDomainEventCallback2 (conn, dom, event, opaque):
|
||||
print "myDomainEventCallback2 EVENT: Domain %s(%s) %s" % (dom.name(), dom.ID(), eventToString(event))
|
||||
|
||||
#####################################################
|
||||
# EventImpl Functions
|
||||
#####################################################
|
||||
def myEventHandleTypeToPollEvent(events):
|
||||
ret = 0
|
||||
if events & libvirt.VIR_EVENT_HANDLE_READABLE:
|
||||
ret |= select.POLLIN
|
||||
if events & libvirt.VIR_EVENT_HANDLE_WRITABLE:
|
||||
ret |= select.POLLOUT
|
||||
if events & libvirt.VIR_EVENT_HANDLE_ERROR:
|
||||
ret |= select.POLLERR;
|
||||
if events & libvirt.VIR_EVENT_HANDLE_HANGUP:
|
||||
ret |= select.POLLHUP;
|
||||
return ret
|
||||
|
||||
def myPollEventToEventHandleType(events):
|
||||
ret = 0;
|
||||
if events & select.POLLIN:
|
||||
ret |= libvirt.VIR_EVENT_HANDLE_READABLE;
|
||||
if events & select.POLLOUT:
|
||||
ret |= libvirt.VIR_EVENT_HANDLE_WRITABLE;
|
||||
if events & select.POLLERR:
|
||||
ret |= libvirt.VIR_EVENT_HANDLE_ERROR;
|
||||
if events & select.POLLHUP:
|
||||
ret |= libvirt.VIR_EVENT_HANDLE_HANGUP;
|
||||
return ret;
|
||||
|
||||
def myAddHandle(fd, events, cb, opaque):
|
||||
global h_fd, h_events, h_cb, h_opaque
|
||||
#print "Adding Handle %s %s %s %s" % (str(fd), str(events), str(cb), str(opaque))
|
||||
h_fd = fd
|
||||
h_events = events
|
||||
h_cb = cb
|
||||
h_opaque = opaque
|
||||
|
||||
mypoll.register(fd, myEventHandleTypeToPollEvent(events))
|
||||
|
||||
def myUpdateHandle(fd, event):
|
||||
global h_fd, h_events
|
||||
#print "Updating Handle %s %s" % (str(fd), str(events))
|
||||
h_fd = fd
|
||||
h_events = event
|
||||
mypoll.unregister(fd)
|
||||
mypoll.register(fd, myEventHandleTypeToPollEvent(event))
|
||||
|
||||
def myRemoveHandle(fd):
|
||||
global h_fd
|
||||
#print "Removing Handle %s" % str(fd)
|
||||
h_fd = 0
|
||||
mypoll.unregister(fd)
|
||||
|
||||
def myAddTimeout(timeout, cb, opaque):
|
||||
global t_active, t_timeout, t_cb, t_opaque
|
||||
#print "Adding Timeout %s %s %s" % (str(timeout), str(cb), str(opaque))
|
||||
t_active = 1;
|
||||
t_timeout = timeout;
|
||||
t_cb = cb;
|
||||
t_opaque = opaque;
|
||||
|
||||
def myUpdateTimeout(timer, timeout):
|
||||
global t_timeout
|
||||
#print "Updating Timeout %s" % (str(timer), str(timeout))
|
||||
t_timeout = timeout;
|
||||
|
||||
def myRemoveTimeout(timer):
|
||||
global t_active
|
||||
#print "Removing Timeout %s" % str(timer)
|
||||
t_active = 0;
|
||||
|
||||
##########################################
|
||||
# Main
|
||||
##########################################
|
||||
|
||||
def usage():
|
||||
print "usage: "+os.path.basename(sys.argv[0])+" [uri]"
|
||||
print " uri will default to qemu:///system"
|
||||
|
||||
def main():
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "h", ["help"] )
|
||||
except getopt.GetoptError, err:
|
||||
# print help information and exit:
|
||||
print str(err) # will print something like "option -a not recognized"
|
||||
usage()
|
||||
sys.exit(2)
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
usage()
|
||||
sys.exit()
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
uri = sys.argv[1]
|
||||
else:
|
||||
uri = "qemu:///system"
|
||||
|
||||
print "Using uri:" + uri
|
||||
|
||||
libvirt.virEventRegisterImpl( myAddHandle,
|
||||
myUpdateHandle,
|
||||
myRemoveHandle,
|
||||
myAddTimeout,
|
||||
myUpdateTimeout,
|
||||
myRemoveTimeout );
|
||||
vc = libvirt.open(uri)
|
||||
|
||||
#Add 2 callbacks to prove this works with more than just one
|
||||
vc.domainEventRegister(myDomainEventCallback1,None)
|
||||
vc.domainEventRegister(myDomainEventCallback2,None)
|
||||
|
||||
while 1:
|
||||
try:
|
||||
sts = mypoll.poll(TIMEOUT_MS)
|
||||
except select.error, err:
|
||||
if err[0] == errno.EINTR:
|
||||
continue
|
||||
raise
|
||||
except KeyboardInterrupt:
|
||||
print "Keyboard Interrupt caught - exiting cleanly"
|
||||
break
|
||||
|
||||
if not sts:
|
||||
#print "Timed out"
|
||||
continue
|
||||
|
||||
rfd = sts[0][0]
|
||||
revents = sts[0][1]
|
||||
|
||||
if t_active:
|
||||
#print "Invoking Timeout CB"
|
||||
t_cb(t_timeout, t_opaque[0], t_opaque[1])
|
||||
|
||||
if revents & select.POLLHUP:
|
||||
print "Reset by peer";
|
||||
return -1;
|
||||
|
||||
if h_cb != None:
|
||||
#print "Invoking Handle CB"
|
||||
h_cb(h_fd, myPollEventToEventHandleType(revents & h_events),
|
||||
h_opaque[0], h_opaque[1])
|
||||
|
||||
#print "DEBUG EXIT"
|
||||
#break
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -13,6 +13,8 @@ DOCS_DIR = $(datadir)/doc/libvirt-python-$(LIBVIRT_VERSION)
|
|||
|
||||
DOCS = ${srcdir}/TODO
|
||||
|
||||
CLASSES_EXTRA = virConnect.py
|
||||
|
||||
EXTRA_DIST = \
|
||||
libvir.c \
|
||||
types.c \
|
||||
|
@ -21,6 +23,7 @@ EXTRA_DIST = \
|
|||
libvirt.py \
|
||||
libvir.py \
|
||||
libvirt-python-api.xml \
|
||||
$(CLASSES_EXTRA) \
|
||||
$(DOCS)
|
||||
|
||||
if WITH_PYTHON
|
||||
|
@ -50,7 +53,7 @@ GENERATED= libvirt-export.c \
|
|||
$(GENERATED): $(srcdir)/$(GENERATE) $(API_DESC)
|
||||
$(PYTHON) $(srcdir)/$(GENERATE) $(srcdir)
|
||||
|
||||
libvirt.py: $(srcdir)/libvir.py $(GENERATED)
|
||||
libvirt.py: $(srcdir)/libvir.py $(GENERATED) $(CLASSES_EXTRA)
|
||||
cat $(srcdir)/libvir.py libvirtclass.py > $@-t
|
||||
mv $@-t $@
|
||||
|
||||
|
|
|
@ -213,6 +213,8 @@ skipped_modules = {
|
|||
|
||||
skipped_types = {
|
||||
# 'int *': "usually a return type",
|
||||
'virConnectDomainEventCallback': "No function types in python",
|
||||
'virEventAddHandleFunc': "No function types in python",
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
@ -315,6 +317,7 @@ skip_impl = (
|
|||
'virStoragePoolListVolumes',
|
||||
'virDomainBlockPeek',
|
||||
'virDomainMemoryPeek',
|
||||
'virEventRegisterImpl',
|
||||
)
|
||||
|
||||
|
||||
|
@ -332,9 +335,8 @@ skip_function = (
|
|||
'virCopyLastError', # Python API is called virGetLastError instead
|
||||
'virConnectOpenAuth', # Python C code is manually written
|
||||
'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
|
||||
'virConnectDomainEventRegister', # TODO: generate python bindings for these below XXX
|
||||
'virConnectDomainEventDeregister',
|
||||
'virEventRegisterImpl',
|
||||
'virConnectDomainEventRegister', # overridden in virConnect.py
|
||||
'virConnectDomainEventDeregister', # overridden in virConnect.py
|
||||
)
|
||||
|
||||
|
||||
|
@ -615,7 +617,6 @@ classes_destructors = {
|
|||
"virNetwork": "virNetworkFree",
|
||||
"virStoragePool": "virStoragePoolFree",
|
||||
"virStorageVol": "virStorageVolFree",
|
||||
"virConnect": "virConnectClose",
|
||||
}
|
||||
|
||||
functions_noexcept = {
|
||||
|
@ -1210,6 +1211,16 @@ def buildWrappers():
|
|||
classes.write(" return ret\n");
|
||||
|
||||
classes.write("\n");
|
||||
# Append "<classname>.py" to class def, iff it exists
|
||||
try:
|
||||
extra = open(classname + ".py", "r")
|
||||
classes.write (" #\n")
|
||||
classes.write (" # %s methods from %s.py (hand coded)\n" % (classname,classname))
|
||||
classes.write (" #\n")
|
||||
classes.writelines(extra.readlines())
|
||||
extra.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
#
|
||||
# Generate enum constants
|
||||
|
|
441
python/libvir.c
441
python/libvir.c
|
@ -1466,7 +1466,443 @@ libvirt_virStoragePoolLookupByUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *ar
|
|||
return(py_retval);
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* Helper functions to avoid importing modules
|
||||
* for every callback
|
||||
*******************************************/
|
||||
static PyObject *libvirt_module = NULL;
|
||||
static PyObject *libvirt_dict = NULL;
|
||||
static PyObject *libvirt_dom_class = NULL;
|
||||
|
||||
static PyObject *
|
||||
getLibvirtModuleObject (void) {
|
||||
if(libvirt_module)
|
||||
return libvirt_module;
|
||||
|
||||
// PyImport_ImportModule returns a new reference
|
||||
libvirt_module = PyImport_ImportModule("libvirt");
|
||||
if(!libvirt_module) {
|
||||
printf("%s Error importing libvirt module\n", __FUNCTION__);
|
||||
PyErr_Print();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return libvirt_module;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
getLibvirtDictObject (void) {
|
||||
if(libvirt_dict)
|
||||
return libvirt_dict;
|
||||
|
||||
// PyModule_GetDict returns a borrowed reference
|
||||
libvirt_dict = PyModule_GetDict(getLibvirtModuleObject());
|
||||
if(!libvirt_dict) {
|
||||
printf("%s Error importing libvirt dictionary\n", __FUNCTION__);
|
||||
PyErr_Print();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(libvirt_dict);
|
||||
return libvirt_dict;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
getLibvirtDomainClassObject (void) {
|
||||
if(libvirt_dom_class)
|
||||
return libvirt_dom_class;
|
||||
|
||||
// PyDict_GetItemString returns a borrowed reference
|
||||
libvirt_dom_class = PyDict_GetItemString(getLibvirtDictObject(),
|
||||
"virDomain");
|
||||
if(!libvirt_dom_class) {
|
||||
printf("%s Error importing virDomain class\n", __FUNCTION__);
|
||||
PyErr_Print();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(libvirt_dom_class);
|
||||
return libvirt_dom_class;
|
||||
}
|
||||
/*******************************************
|
||||
* Domain Events
|
||||
*******************************************/
|
||||
|
||||
static int
|
||||
libvirt_virConnectDomainEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainPtr dom,
|
||||
int event,
|
||||
void *opaque)
|
||||
{
|
||||
PyObject *pyobj_ret;
|
||||
|
||||
PyObject *pyobj_conn_inst = (PyObject*)opaque;
|
||||
PyObject *pyobj_dom = libvirt_virDomainPtrWrap(dom);
|
||||
|
||||
PyObject *pyobj_dom_args;
|
||||
PyObject *pyobj_dom_inst;
|
||||
|
||||
PyObject *dom_class;
|
||||
|
||||
/* Create a python instance of this virDomainPtr */
|
||||
pyobj_dom_args = PyTuple_New(2);
|
||||
if(PyTuple_SetItem(pyobj_dom_args, 0, pyobj_conn_inst)!=0) {
|
||||
printf("%s error creating tuple",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
if(PyTuple_SetItem(pyobj_dom_args, 1, pyobj_dom)!=0) {
|
||||
printf("%s error creating tuple",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
Py_INCREF(pyobj_conn_inst);
|
||||
|
||||
dom_class = getLibvirtDomainClassObject();
|
||||
if(!PyClass_Check(dom_class)) {
|
||||
printf("%s dom_class is not a class!\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pyobj_dom_inst = PyInstance_New(dom_class,
|
||||
pyobj_dom_args,
|
||||
NULL);
|
||||
|
||||
Py_DECREF(pyobj_dom_args);
|
||||
|
||||
if(!pyobj_dom_inst) {
|
||||
printf("%s Error creating a python instance of virDomain\n", __FUNCTION__);
|
||||
PyErr_Print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Call the Callback Dispatcher */
|
||||
pyobj_ret = PyObject_CallMethod(pyobj_conn_inst,
|
||||
(char*)"dispatchDomainEventCallbacks",
|
||||
(char*)"Oi",
|
||||
pyobj_dom_inst,
|
||||
event);
|
||||
|
||||
Py_DECREF(pyobj_dom_inst);
|
||||
|
||||
if(!pyobj_ret) {
|
||||
printf("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
|
||||
PyErr_Print();
|
||||
return -1;
|
||||
} else {
|
||||
Py_DECREF(pyobj_ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
libvirt_virConnectDomainEventRegister(ATTRIBUTE_UNUSED PyObject * self,
|
||||
PyObject * args)
|
||||
{
|
||||
PyObject *py_retval; /* return value */
|
||||
PyObject *pyobj_conn; /* virConnectPtr */
|
||||
PyObject *pyobj_conn_inst; /* virConnect Python object */
|
||||
|
||||
virConnectPtr conn;
|
||||
int ret = 0;
|
||||
|
||||
if (!PyArg_ParseTuple
|
||||
(args, (char *) "OO:virConnectDomainEventRegister",
|
||||
&pyobj_conn, &pyobj_conn_inst)) {
|
||||
printf("%s failed parsing tuple\n", __FUNCTION__);
|
||||
return VIR_PY_INT_FAIL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ERROR
|
||||
printf("libvirt_virConnectDomainEventRegister(%p %p) called\n",
|
||||
pyobj_conn, pyobj_conn_inst);
|
||||
#endif
|
||||
conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
|
||||
|
||||
Py_INCREF(pyobj_conn_inst);
|
||||
|
||||
ret = virConnectDomainEventRegister(conn,
|
||||
libvirt_virConnectDomainEventCallback,
|
||||
(void *)pyobj_conn_inst);
|
||||
|
||||
py_retval = libvirt_intWrap(ret);
|
||||
return (py_retval);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
libvirt_virConnectDomainEventDeregister(ATTRIBUTE_UNUSED PyObject * self,
|
||||
PyObject * args)
|
||||
{
|
||||
PyObject *py_retval;
|
||||
PyObject *pyobj_conn;
|
||||
PyObject *pyobj_conn_inst;
|
||||
|
||||
virConnectPtr conn;
|
||||
int ret = 0;
|
||||
|
||||
if (!PyArg_ParseTuple
|
||||
(args, (char *) "OO:virConnectDomainEventDeregister",
|
||||
&pyobj_conn, &pyobj_conn_inst))
|
||||
return (NULL);
|
||||
|
||||
#ifdef DEBUG_ERROR
|
||||
printf("libvirt_virConnectDomainEventDeregister(%p) called\n", pyobj_conn);
|
||||
#endif
|
||||
|
||||
conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
|
||||
|
||||
ret = virConnectDomainEventDeregister(conn, libvirt_virConnectDomainEventCallback);
|
||||
|
||||
Py_DECREF(pyobj_conn_inst);
|
||||
py_retval = libvirt_intWrap(ret);
|
||||
return (py_retval);
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* Event Impl
|
||||
*******************************************/
|
||||
static PyObject *addHandleObj = NULL;
|
||||
static PyObject *updateHandleObj = NULL;
|
||||
static PyObject *removeHandleObj = NULL;
|
||||
static PyObject *addTimeoutObj = NULL;
|
||||
static PyObject *updateTimeoutObj = NULL;
|
||||
static PyObject *removeTimeoutObj = NULL;
|
||||
|
||||
|
||||
static int
|
||||
libvirt_virEventAddHandleFunc (int fd ATTRIBUTE_UNUSED, int event ATTRIBUTE_UNUSED,
|
||||
virEventHandleCallback cb, void *opaque)
|
||||
{
|
||||
PyObject *result = NULL;
|
||||
PyObject *python_cb;
|
||||
PyObject *cb_obj;
|
||||
PyObject *opaque_obj;
|
||||
PyObject *cb_args;
|
||||
PyObject *pyobj_args;
|
||||
|
||||
/* Lookup the python callback */
|
||||
python_cb = PyDict_GetItemString(getLibvirtDictObject(),
|
||||
"eventInvokeHandleCallback");
|
||||
if(!python_cb) {
|
||||
printf("%s Error finding eventInvokeHandleCallback\n", __FUNCTION__);
|
||||
PyErr_Print();
|
||||
return -1;
|
||||
}
|
||||
Py_INCREF(python_cb);
|
||||
|
||||
/* create tuple for cb */
|
||||
cb_obj = libvirt_virEventHandleCallbackWrap(cb);
|
||||
opaque_obj = libvirt_virVoidPtrWrap(opaque);
|
||||
|
||||
cb_args = PyTuple_New(2);
|
||||
PyTuple_SetItem(cb_args, 0, cb_obj);
|
||||
PyTuple_SetItem(cb_args, 1, opaque_obj);
|
||||
|
||||
pyobj_args = PyTuple_New(4);
|
||||
PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(fd));
|
||||
PyTuple_SetItem(pyobj_args, 1, libvirt_intWrap(event));
|
||||
PyTuple_SetItem(pyobj_args, 2, python_cb);
|
||||
PyTuple_SetItem(pyobj_args, 3, cb_args);
|
||||
|
||||
if(addHandleObj && PyCallable_Check(addHandleObj))
|
||||
result = PyEval_CallObject(addHandleObj, pyobj_args);
|
||||
|
||||
Py_XDECREF(result);
|
||||
Py_DECREF(pyobj_args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
libvirt_virEventUpdateHandleFunc(int fd, int event)
|
||||
{
|
||||
PyObject *result = NULL;
|
||||
PyObject *pyobj_args = PyTuple_New(2);
|
||||
PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(fd));
|
||||
PyTuple_SetItem(pyobj_args, 1, libvirt_intWrap(event));
|
||||
|
||||
if(updateHandleObj && PyCallable_Check(updateHandleObj))
|
||||
result = PyEval_CallObject(updateHandleObj, pyobj_args);
|
||||
|
||||
Py_XDECREF(result);
|
||||
Py_DECREF(pyobj_args);
|
||||
}
|
||||
|
||||
static int
|
||||
libvirt_virEventRemoveHandleFunc(int fd)
|
||||
{
|
||||
PyObject *result = NULL;
|
||||
PyObject *pyobj_args = PyTuple_New(1);
|
||||
PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(fd));
|
||||
|
||||
if(removeHandleObj && PyCallable_Check(removeHandleObj))
|
||||
result = PyEval_CallObject(removeHandleObj, pyobj_args);
|
||||
|
||||
Py_XDECREF(result);
|
||||
Py_DECREF(pyobj_args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
libvirt_virEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb,
|
||||
void *opaque)
|
||||
{
|
||||
PyObject *result = NULL;
|
||||
|
||||
PyObject *python_cb;
|
||||
|
||||
PyObject *cb_obj;
|
||||
PyObject *opaque_obj;
|
||||
PyObject *cb_args;
|
||||
PyObject *pyobj_args;
|
||||
|
||||
/* Lookup the python callback */
|
||||
python_cb = PyDict_GetItemString(getLibvirtDictObject(),
|
||||
"eventInvokeTimeoutCallback");
|
||||
if(!python_cb) {
|
||||
printf("%s Error finding eventInvokeTimeoutCallback\n", __FUNCTION__);
|
||||
PyErr_Print();
|
||||
return -1;
|
||||
}
|
||||
Py_INCREF(python_cb);
|
||||
|
||||
/* create tuple for cb */
|
||||
cb_obj = libvirt_virEventTimeoutCallbackWrap(cb);
|
||||
opaque_obj = libvirt_virVoidPtrWrap(opaque);
|
||||
|
||||
cb_args = PyTuple_New(2);
|
||||
PyTuple_SetItem(cb_args, 0, cb_obj);
|
||||
PyTuple_SetItem(cb_args, 1, opaque_obj);
|
||||
|
||||
pyobj_args = PyTuple_New(3);
|
||||
|
||||
PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(timeout));
|
||||
PyTuple_SetItem(pyobj_args, 1, python_cb);
|
||||
PyTuple_SetItem(pyobj_args, 2, cb_args);
|
||||
|
||||
if(addTimeoutObj && PyCallable_Check(addTimeoutObj))
|
||||
result = PyEval_CallObject(addTimeoutObj, pyobj_args);
|
||||
|
||||
Py_XDECREF(result);
|
||||
Py_DECREF(pyobj_args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
libvirt_virEventUpdateTimeoutFunc(int timer, int timeout)
|
||||
{
|
||||
PyObject *result = NULL;
|
||||
PyObject *pyobj_args = PyTuple_New(2);
|
||||
PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(timer));
|
||||
PyTuple_SetItem(pyobj_args, 1, libvirt_intWrap(timeout));
|
||||
|
||||
if(updateTimeoutObj && PyCallable_Check(updateTimeoutObj))
|
||||
result = PyEval_CallObject(updateTimeoutObj, pyobj_args);
|
||||
|
||||
Py_XDECREF(result);
|
||||
Py_DECREF(pyobj_args);
|
||||
}
|
||||
|
||||
static int
|
||||
libvirt_virEventRemoveTimeoutFunc(int timer)
|
||||
{
|
||||
PyObject *result = NULL;
|
||||
PyObject *pyobj_args = PyTuple_New(1);
|
||||
PyTuple_SetItem(pyobj_args, 0, libvirt_intWrap(timer));
|
||||
|
||||
if(updateTimeoutObj && PyCallable_Check(updateTimeoutObj))
|
||||
result = PyEval_CallObject(removeTimeoutObj, pyobj_args);
|
||||
|
||||
Py_XDECREF(result);
|
||||
Py_DECREF(pyobj_args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
libvirt_virEventRegisterImpl(ATTRIBUTE_UNUSED PyObject * self,
|
||||
PyObject * args)
|
||||
{
|
||||
Py_XDECREF(addHandleObj);
|
||||
Py_XDECREF(updateHandleObj);
|
||||
Py_XDECREF(removeHandleObj);
|
||||
Py_XDECREF(addTimeoutObj);
|
||||
Py_XDECREF(updateTimeoutObj);
|
||||
Py_XDECREF(removeTimeoutObj);
|
||||
|
||||
if (!PyArg_ParseTuple
|
||||
(args, (char *) "OOOOOO:virEventRegisterImpl",
|
||||
&addHandleObj,
|
||||
&updateHandleObj,
|
||||
&removeHandleObj,
|
||||
&addTimeoutObj,
|
||||
&updateTimeoutObj,
|
||||
&removeTimeoutObj
|
||||
))
|
||||
return VIR_PY_INT_FAIL;
|
||||
|
||||
Py_INCREF(addHandleObj);
|
||||
Py_INCREF(updateHandleObj);
|
||||
Py_INCREF(removeHandleObj);
|
||||
Py_INCREF(addTimeoutObj);
|
||||
Py_INCREF(updateTimeoutObj);
|
||||
Py_INCREF(removeTimeoutObj);
|
||||
|
||||
virEventRegisterImpl(libvirt_virEventAddHandleFunc,
|
||||
libvirt_virEventUpdateHandleFunc,
|
||||
libvirt_virEventRemoveHandleFunc,
|
||||
libvirt_virEventAddTimeoutFunc,
|
||||
libvirt_virEventUpdateTimeoutFunc,
|
||||
libvirt_virEventRemoveTimeoutFunc);
|
||||
|
||||
return VIR_PY_INT_SUCCESS;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
libvirt_virEventInvokeHandleCallback(PyObject *self ATTRIBUTE_UNUSED,
|
||||
PyObject *args)
|
||||
{
|
||||
int fd, event;
|
||||
PyObject *py_f;
|
||||
PyObject *py_opaque;
|
||||
virEventHandleCallback cb;
|
||||
void *opaque;
|
||||
|
||||
if (!PyArg_ParseTuple
|
||||
(args, (char *) "iiOO:virEventInvokeHandleCallback",
|
||||
&fd, &event, &py_f, &py_opaque
|
||||
))
|
||||
return VIR_PY_INT_FAIL;
|
||||
|
||||
cb = (virEventHandleCallback) PyvirEventHandleCallback_Get(py_f);
|
||||
opaque = (void *) PyvirVoidPtr_Get(py_opaque);
|
||||
|
||||
if(cb)
|
||||
cb (fd, event, opaque);
|
||||
|
||||
return VIR_PY_INT_SUCCESS;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
libvirt_virEventInvokeTimeoutCallback(PyObject *self ATTRIBUTE_UNUSED,
|
||||
PyObject *args)
|
||||
{
|
||||
int timer;
|
||||
PyObject *py_f;
|
||||
PyObject *py_opaque;
|
||||
virEventTimeoutCallback cb;
|
||||
void *opaque;
|
||||
|
||||
if (!PyArg_ParseTuple
|
||||
(args, (char *) "iOO:virEventInvokeTimeoutCallback",
|
||||
&timer, &py_f, &py_opaque
|
||||
))
|
||||
return VIR_PY_INT_FAIL;
|
||||
|
||||
cb = (virEventTimeoutCallback) PyvirEventTimeoutCallback_Get(py_f);
|
||||
opaque = (void *) PyvirVoidPtr_Get(py_opaque);
|
||||
if(cb)
|
||||
cb (timer, opaque);
|
||||
|
||||
return VIR_PY_INT_SUCCESS;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* *
|
||||
|
@ -1479,6 +1915,8 @@ static PyMethodDef libvirtMethods[] = {
|
|||
{(char *) "virConnectOpenAuth", libvirt_virConnectOpenAuth, METH_VARARGS, NULL},
|
||||
{(char *) "virConnectListDomainsID", libvirt_virConnectListDomainsID, METH_VARARGS, NULL},
|
||||
{(char *) "virConnectListDefinedDomains", libvirt_virConnectListDefinedDomains, METH_VARARGS, NULL},
|
||||
{(char *) "virConnectDomainEventRegister", libvirt_virConnectDomainEventRegister, METH_VARARGS, NULL},
|
||||
{(char *) "virConnectDomainEventDeregister", libvirt_virConnectDomainEventDeregister, METH_VARARGS, NULL},
|
||||
{(char *) "virDomainGetInfo", libvirt_virDomainGetInfo, METH_VARARGS, NULL},
|
||||
{(char *) "virNodeGetInfo", libvirt_virNodeGetInfo, METH_VARARGS, NULL},
|
||||
{(char *) "virDomainGetUUID", libvirt_virDomainGetUUID, METH_VARARGS, NULL},
|
||||
|
@ -1511,6 +1949,9 @@ static PyMethodDef libvirtMethods[] = {
|
|||
{(char *) "virStoragePoolGetUUID", libvirt_virStoragePoolGetUUID, METH_VARARGS, NULL},
|
||||
{(char *) "virStoragePoolGetUUIDString", libvirt_virStoragePoolGetUUIDString, METH_VARARGS, NULL},
|
||||
{(char *) "virStoragePoolLookupByUUID", libvirt_virStoragePoolLookupByUUID, METH_VARARGS, NULL},
|
||||
{(char *) "virEventRegisterImpl", libvirt_virEventRegisterImpl, METH_VARARGS, NULL},
|
||||
{(char *) "virEventInvokeHandleCallback", libvirt_virEventInvokeHandleCallback, METH_VARARGS, NULL},
|
||||
{(char *) "virEventInvokeTimeoutCallback", libvirt_virEventInvokeTimeoutCallback, METH_VARARGS, NULL},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -123,6 +123,26 @@ def getVersion (name = None):
|
|||
return ret
|
||||
|
||||
|
||||
#
|
||||
# Invoke an EventHandle callback
|
||||
#
|
||||
def eventInvokeHandleCallback (fd, event, callback, opaque):
|
||||
"""
|
||||
Invoke the Event Impl Handle Callback in C
|
||||
"""
|
||||
libvirtmod.virEventInvokeHandleCallback(fd, event, callback, opaque);
|
||||
|
||||
#
|
||||
# Invoke an EventTimeout callback
|
||||
#
|
||||
def eventInvokeTimeoutCallback (timer, callback, opaque):
|
||||
"""
|
||||
Invoke the Event Impl Timeout Callback in C
|
||||
"""
|
||||
libvirtmod.virEventInvokeTimeoutCallback(timer, callback, opaque);
|
||||
|
||||
|
||||
|
||||
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||
#
|
||||
# Everything before this line comes from libvir.py
|
||||
|
|
|
@ -65,6 +65,29 @@ typedef struct {
|
|||
virStorageVolPtr obj;
|
||||
} PyvirStorageVol_Object;
|
||||
|
||||
#define PyvirEventHandleCallback_Get(v) (((v) == Py_None) ? NULL : \
|
||||
(((PyvirEventHandleCallback_Object *)(v))->obj))
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
virEventHandleCallback obj;
|
||||
} PyvirEventHandleCallback_Object;
|
||||
|
||||
#define PyvirEventTimeoutCallback_Get(v) (((v) == Py_None) ? NULL : \
|
||||
(((PyvirEventTimeoutCallback_Object *)(v))->obj))
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
virEventTimeoutCallback obj;
|
||||
} PyvirEventTimeoutCallback_Object;
|
||||
|
||||
#define PyvirVoidPtr_Get(v) (((v) == Py_None) ? NULL : \
|
||||
(((PyvirVoidPtr_Object *)(v))->obj))
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
void* obj;
|
||||
} PyvirVoidPtr_Object;
|
||||
|
||||
PyObject * libvirt_intWrap(int val);
|
||||
PyObject * libvirt_longWrap(long val);
|
||||
|
@ -78,7 +101,9 @@ PyObject * libvirt_virDomainPtrWrap(virDomainPtr node);
|
|||
PyObject * libvirt_virNetworkPtrWrap(virNetworkPtr node);
|
||||
PyObject * libvirt_virStoragePoolPtrWrap(virStoragePoolPtr node);
|
||||
PyObject * libvirt_virStorageVolPtrWrap(virStorageVolPtr node);
|
||||
|
||||
PyObject * libvirt_virEventHandleCallbackWrap(virEventHandleCallback node);
|
||||
PyObject * libvirt_virEventTimeoutCallbackWrap(virEventTimeoutCallback node);
|
||||
PyObject * libvirt_virVoidPtrWrap(void* node);
|
||||
|
||||
/* Provide simple macro statement wrappers (adapted from GLib, in turn from Perl):
|
||||
* LIBVIRT_STMT_START { statements; } LIBVIRT_STMT_END;
|
||||
|
|
|
@ -162,3 +162,50 @@ libvirt_virConnectPtrWrap(virConnectPtr node)
|
|||
NULL);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
libvirt_virEventHandleCallbackWrap(virEventHandleCallback node)
|
||||
{
|
||||
PyObject *ret;
|
||||
|
||||
if (node == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
printf("%s: WARNING - Wrapping None\n", __FUNCTION__);
|
||||
return (Py_None);
|
||||
}
|
||||
ret =
|
||||
PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virEventHandleCallback",
|
||||
NULL);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
libvirt_virEventTimeoutCallbackWrap(virEventTimeoutCallback node)
|
||||
{
|
||||
PyObject *ret;
|
||||
|
||||
if (node == NULL) {
|
||||
printf("%s: WARNING - Wrapping None\n", __FUNCTION__);
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
ret =
|
||||
PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virEventTimeoutCallback",
|
||||
NULL);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
libvirt_virVoidPtrWrap(void* node)
|
||||
{
|
||||
PyObject *ret;
|
||||
|
||||
if (node == NULL) {
|
||||
Py_INCREF(Py_None);
|
||||
return (Py_None);
|
||||
}
|
||||
ret =
|
||||
PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "void*",
|
||||
NULL);
|
||||
return (ret);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue