mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +00:00
* 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:
parent
9aba17bd6c
commit
65bace1765
10
ChangeLog
10
ChangeLog
@ -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
1
TODO
@ -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 ?
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
30
python/libvir.py
Normal 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
|
@ -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
41
python/tests/error.py
Executable 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)
|
Loading…
Reference in New Issue
Block a user