* TODO: updated

* python/Makefile.am python/generator.py python/libvir.c
  python/libvir.py: improved python binding, raise exception
  when an instance creation or lookup fails, and add support
  for the global error handler, per conn handler still needed
* python/tests/error.py python/tests/Makefile.am: adding a
  regression test
Daniel
This commit is contained in:
Daniel Veillard 2006-02-28 12:17:00 +00:00
parent 9aba17bd6c
commit 65bace1765
8 changed files with 197 additions and 15 deletions

View File

@ -1,3 +1,13 @@
Tue Feb 28 13:12:50 CET 2006 Daniel Veillard <veillard@redhat.com>
* TODO: updated
* python/Makefile.am python/generator.py python/libvir.c
python/libvir.py: improved python binding, raise exception
when an instance creation or lookup fails, and add support
for the global error handler, per conn handler still needed
* python/tests/error.py python/tests/Makefile.am: adding a
regression test
Mon Feb 27 17:36:29 EST 2006 Daniel Veillard <veillard@redhat.com>
* doc//*: rebuilt

1
TODO
View File

@ -32,6 +32,7 @@ Would-be-nice TODO:
- man page for virsh and the libraries entry points
- support for QEmu and other virtualization engines
- more documentation and examples on using the toolkit
- examples and docs for the principle in the error handling code
Cleanup:
- now that libxml2 is linked in, drop hash.[ch] and get back to libxml2 ones ?

View File

@ -18,6 +18,7 @@ EXTRA_DIST = \
generator.py \
libvirt_wrap.h \
libvirt.py \
libvir.py \
libvirt-python-api.xml \
$(DOCS)
@ -33,6 +34,8 @@ python_LTLIBRARIES = libvirtmod.la
libvirtmod_la_SOURCES = libvir.c types.c libvirt-py.c libvirt-py.h
libvirtmod_la_LIBADD = $(mylibs)
libvirt.py: $(srcdir)/libvir.py libvirtclass.py
cat $(srcdir)/libvir.py libvirtclass.py > libvirt.py
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(pythondir)

View File

@ -251,7 +251,7 @@ foreign_encoding_args = (
#######################################################################
#
# This part writes the C <-> Python stubs libxml2-py.[ch] and
# This part writes the C <-> Python stubs libvirt2-py.[ch] and
# the table libxml2-export.c to add when registrering the Python module
#
#######################################################################
@ -691,17 +691,7 @@ def buildWrappers():
info = (0, func, name, ret, args, file)
function_classes['None'].append(info)
classes = open("libvirt.py", "w")
classes.write("""#!/usr/bin/python -u
#
# Those are the autogenerated Python bindings for libvirt.
# Check python/generator.py in the source distribution of libvirt
# to find out more about the generation process
#
""")
classes.write("import libvirtmod\n")
classes.write("import types\n\n")
classes = open("libvirtclass.py", "w")
txt = open("libvirtclass.txt", "w")
txt.write(" Generated Classes for libvir-python\n\n")
@ -754,7 +744,12 @@ def buildWrappers():
# Raise an exception
#
if functions_noexcept.has_key(name):
classes.write(" if ret is None:return None\n");
classes.write(" if ret is None:return None\n");
else:
classes.write(
" if ret is None:raise libvirtError('%s() failed')\n" %
(name))
classes.write(" return ");
classes.write(classes_type[ret[0]][1] % ("ret"));
classes.write("\n");
@ -867,6 +862,10 @@ def buildWrappers():
if functions_noexcept.has_key(name):
classes.write(
" if ret is None:return None\n");
else:
classes.write(
" if ret is None:raise libvirtError('%s() failed')\n" %
(name))
#
# generate the returned class wrapper for the object

View File

@ -11,11 +11,108 @@
#include <Python.h>
#include <libvirt.h>
#include <virterror.h>
#include "libvirt_wrap.h"
#include "libvirt-py.h"
void initlibvirmod(void);
PyObject *libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args);
/************************************************************************
* *
* Global error handler at the Python level *
* *
************************************************************************/
static PyObject *libvirt_virPythonErrorFuncHandler = NULL;
static PyObject *libvirt_virPythonErrorFuncCtxt = NULL;
static void
libvirt_virErrorFuncHandler(ATTRIBUTE_UNUSED void *ctx, virErrorPtr err)
{
PyObject *list, *info;
PyObject *result;
#ifdef DEBUG_ERROR
printf("libvirt_virErrorFuncHandler(%p, %s, ...) called\n", ctx, msg);
#endif
if ((err == NULL) || (err->code == VIR_ERR_OK))
return;
if ((libvirt_virPythonErrorFuncHandler == NULL) ||
(libvirt_virPythonErrorFuncHandler == Py_None)) {
virDefaultErrorFunc(err);
} else {
list = PyTuple_New(2);
info = PyTuple_New(9);
PyTuple_SetItem(list, 0, libvirt_virPythonErrorFuncCtxt);
PyTuple_SetItem(list, 1, info);
Py_XINCREF(libvirt_virPythonErrorFuncCtxt);
PyTuple_SetItem(info, 0, PyInt_FromLong((long) err->code));
PyTuple_SetItem(info, 1, PyInt_FromLong((long) err->domain));
PyTuple_SetItem(info, 2, libvirt_charPtrWrap(err->message));
PyTuple_SetItem(info, 3, PyInt_FromLong((long) err->level));
PyTuple_SetItem(info, 4, libvirt_charPtrWrap(err->str1));
PyTuple_SetItem(info, 5, libvirt_charPtrWrap(err->str2));
PyTuple_SetItem(info, 6, libvirt_charPtrWrap(err->str3));
PyTuple_SetItem(info, 7, PyInt_FromLong((long) err->int1));
PyTuple_SetItem(info, 8, PyInt_FromLong((long) err->int2));
/* TODO pass conn and dom if available */
result = PyEval_CallObject(libvirt_virPythonErrorFuncHandler, list);
Py_XDECREF(list);
Py_XDECREF(result);
}
}
static PyObject *
libvirt_virRegisterErrorHandler(ATTRIBUTE_UNUSED PyObject * self,
PyObject * args)
{
PyObject *py_retval;
PyObject *pyobj_f;
PyObject *pyobj_ctx;
if (!PyArg_ParseTuple
(args, (char *) "OO:xmlRegisterErrorHandler", &pyobj_f,
&pyobj_ctx))
return (NULL);
#ifdef DEBUG_ERROR
printf("libvirt_virRegisterErrorHandler(%p, %p) called\n", pyobj_ctx,
pyobj_f);
#endif
virSetErrorFunc(NULL, libvirt_virErrorFuncHandler);
if (libvirt_virPythonErrorFuncHandler != NULL) {
Py_XDECREF(libvirt_virPythonErrorFuncHandler);
}
if (libvirt_virPythonErrorFuncCtxt != NULL) {
Py_XDECREF(libvirt_virPythonErrorFuncCtxt);
}
if ((pyobj_f == Py_None) && (pyobj_ctx == Py_None)) {
libvirt_virPythonErrorFuncHandler = NULL;
libvirt_virPythonErrorFuncCtxt = NULL;
} else {
Py_XINCREF(pyobj_ctx);
Py_XINCREF(pyobj_f);
/* TODO: check f is a function ! */
libvirt_virPythonErrorFuncHandler = pyobj_f;
libvirt_virPythonErrorFuncCtxt = pyobj_ctx;
}
py_retval = libvirt_intWrap(1);
return (py_retval);
}
/************************************************************************
* *
* Wrappers for functions where generator fails *
* *
************************************************************************/
static PyObject *
libvirt_virDomainFree(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_retval;
@ -106,7 +203,6 @@ libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
unsigned char uuid[16];
virDomainPtr domain;
PyObject *pyobj_domain;
virDomainInfo info;
if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetUUID", &pyobj_domain))
return(NULL);
@ -161,6 +257,7 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virDomainGetInfo", libvirt_virDomainGetInfo, METH_VARARGS, NULL},
{(char *) "virDomainGetUUID", libvirt_virDomainGetUUID, METH_VARARGS, NULL},
{(char *) "virDomainLookupByUUID", libvirt_virDomainLookupByUUID, METH_VARARGS, NULL},
{(char *) "virRegisterErrorHandler", libvirt_virRegisterErrorHandler, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
};

30
python/libvir.py Normal file
View File

@ -0,0 +1,30 @@
#!/usr/bin/python -u
#
# Those are the autogenerated Python bindings for libvirt.
# Check python/generator.py in the source distribution of libvir
# to find out more about the generation process
#
import libvirtmod
import types
# The root of all libxml2 errors.
class libvirtError(Exception):
pass
#
# register the libvirt global error handler
#
def registerErrorHandler(f, ctx):
"""Register a Python written function to for error reporting.
The function is called back as f(ctx, error), with error
being a list of informations about the error being raised.
Returns 1 in case of success."""
return libvirtmod.virRegisterErrorHandler(f,ctx)
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
#
# Everything before this line comes from libvir.py
# Everything after this line is automatically generated
#
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING

View File

@ -3,7 +3,8 @@ EXAMPLE_DIR = $(datadir)/doc/libvirt-python-$(LIBVIRT_VERSION)/examples
PYTESTS= \
basic.py \
create.py \
uuid.py
uuid.py \
error.py
EXTRA_DIST = $(PYTESTS)

41
python/tests/error.py Executable file
View File

@ -0,0 +1,41 @@
#!/usr/bin/python -u
#
# Tests global error handlers at the python level.
#
import libvirt
import sys
import os
errno = None
def handler(ctxt, err):
global errno
#print "handler(%s, %s)" % (ctxt, err)
errno = err
libvirt.registerErrorHandler(handler, 'context')
conn = libvirt.openReadOnly(None)
if conn == None:
print 'Failed to open connection to the hypervisor'
sys.exit(1)
try:
dom0 = conn.lookupByName("Does_not_exist")
print 'strange found a Does_not_exist domain'
sys.exit(1)
except:
pass
del conn
if errno == None:
print 'failed to get an error'
elif errno[0] == libvirt.VIR_ERR_NO_CONNECT or \
errno[0] == libvirt.VIR_ERR_INVALID_DOMAIN:
print "OK"
else:
print 'got unexpected error %s' % (errno)
sys.exit(0)