summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am35
-rwxr-xr-xgenerator.py172
-rw-r--r--libvirt-lxc-override-api.xml19
-rw-r--r--libvirt-lxc-override.c141
4 files changed, 361 insertions, 6 deletions
diff --git a/Makefile.am b/Makefile.am
index 97f21c3..dd69600 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,6 +35,8 @@ EXTRA_DIST = \
libvirt-override.c \
libvirt-override.py \
libvirt-override-api.xml \
+ libvirt-lxc-override.c \
+ libvirt-lxc-override-api.xml \
libvirt-qemu-override.c \
libvirt-qemu-override-api.xml \
$(CLASSES_EXTRA) \
@@ -47,10 +49,13 @@ mylibs = \
myqemulibs = \
$(top_builddir)/src/libvirt-qemu.la \
$(top_builddir)/gnulib/lib/libgnu.la
+mylxclibs = \
+ $(top_builddir)/src/libvirt-lxc.la \
+ $(top_builddir)/gnulib/lib/libgnu.la
-all-local: libvirt.py libvirt_qemu.py
+all-local: libvirt.py libvirt_qemu.py libvirt_lxc.py
-pyexec_LTLIBRARIES = libvirtmod.la libvirtmod_qemu.la
+pyexec_LTLIBRARIES = libvirtmod.la libvirtmod_qemu.la libvirtmod_lxc.la
libvirtmod_la_SOURCES = libvirt-override.c typewrappers.c
nodist_libvirtmod_la_SOURCES = libvirt.c libvirt.h
@@ -74,6 +79,17 @@ libvirtmod_qemu_la_LDFLAGS = -module -avoid-version -shared -L$(top_builddir)/sr
libvirtmod_qemu_la_LIBADD = $(myqemulibs) \
$(CYGWIN_EXTRA_LIBADD) $(CYGWIN_EXTRA_PYTHON_LIBADD)
+libvirtmod_lxc_la_SOURCES = libvirt-lxc-override.c typewrappers.c
+nodist_libvirtmod_lxc_la_SOURCES = libvirt-lxc.c libvirt-lxc.h
+# Python <= 2.4 header files contain a redundant decl, hence we
+# need extra flags here
+libvirtmod_lxc_la_CFLAGS = $(WARN_PYTHON_CFLAGS)
+
+libvirtmod_lxc_la_LDFLAGS = -module -avoid-version -shared -L$(top_builddir)/src/.libs \
+ $(CYGWIN_EXTRA_LDFLAGS)
+libvirtmod_lxc_la_LIBADD = $(mylxclibs) \
+ $(CYGWIN_EXTRA_LIBADD) $(CYGWIN_EXTRA_PYTHON_LIBADD)
+
GENERATE = generator.py
API_DESC = $(top_srcdir)/docs/libvirt-api.xml $(srcdir)/libvirt-override-api.xml
GENERATED= libvirt-export.c \
@@ -87,18 +103,26 @@ QEMU_GENERATED= libvirt-qemu-export.c \
libvirt-qemu.h \
libvirt_qemu.py
-$(GENERATE).stamp: $(srcdir)/$(GENERATE) $(API_DESC) $(QEMU_API_DESC)
+LXC_API_DESC = $(top_srcdir)/docs/libvirt-lxc-api.xml $(srcdir)/libvirt-lxc-override-api.xml
+LXC_GENERATED= libvirt-lxc-export.c \
+ libvirt-lxc.c \
+ libvirt-lxc.h \
+ libvirt_lxc.py
+
+$(GENERATE).stamp: $(srcdir)/$(GENERATE) $(API_DESC) $(QEMU_API_DESC) $(LXC_API_DESC)
$(AM_V_GEN)$(PYTHON) $(srcdir)/$(GENERATE) $(PYTHON) && \
touch $@
-$(GENERATED) $(QEMU_GENERATED): $(GENERATE).stamp
+$(GENERATED) $(QEMU_GENERATED) $(LXC_GENERATED): $(GENERATE).stamp
$(libvirtmod_la_OBJECTS): $(GENERATED)
$(libvirtmod_qemu_la_OBJECTS): $(QEMU_GENERATED)
+$(libvirtmod_lxc_la_OBJECTS): $(LXC_GENERATED)
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(pyexecdir)
$(INSTALL) -m 0644 libvirt.py $(DESTDIR)$(pyexecdir)
+ $(INSTALL) -m 0644 libvirt_lxc.py $(DESTDIR)$(pyexecdir)
$(INSTALL) -m 0644 libvirt_qemu.py $(DESTDIR)$(pyexecdir)
$(mkinstalldirs) $(DESTDIR)$(DOCS_DIR)
@(for doc in $(DOCS) ; \
@@ -106,9 +130,10 @@ install-data-local:
uninstall-local:
rm -f $(DESTDIR)$(pyexecdir)/libvirt.py
+ rm -f $(DESTDIR)$(pyexecdir)/libvirt_lxc.py
rm -f $(DESTDIR)$(pyexecdir)/libvirt_qemu.py
-CLEANFILES= $(GENERATED) $(QEMU_GENERATED) $(GENERATE).stamp
+CLEANFILES= $(GENERATED) $(QEMU_GENERATED) $(LXC_GENERATED) $(GENERATE).stamp
else
all:
diff --git a/generator.py b/generator.py
index bae4edc..f984dfa 100755
--- a/generator.py
+++ b/generator.py
@@ -4,8 +4,10 @@
#
functions = {}
+lxc_functions = {}
qemu_functions = {}
enums = {} # { enumType: { enumConstant: enumValue } }
+lxc_enums = {} # { enumType: { enumConstant: enumValue } }
qemu_enums = {} # { enumType: { enumConstant: enumValue } }
import os
@@ -123,6 +125,8 @@ class docParser(xml.sax.handler.ContentHandler):
if (attrs['file'] == "libvirt" or
attrs['file'] == "virterror"):
enum(attrs['type'],attrs['name'],attrs['value'])
+ elif attrs['file'] == "libvirt-lxc":
+ lxc_enum(attrs['type'],attrs['name'],attrs['value'])
elif attrs['file'] == "libvirt-qemu":
qemu_enum(attrs['type'],attrs['name'],attrs['value'])
@@ -138,6 +142,11 @@ class docParser(xml.sax.handler.ContentHandler):
self.function_return, self.function_args,
self.function_file, self.function_module,
self.function_cond)
+ elif self.function_module == "libvirt-lxc":
+ lxc_function(self.function, self.function_descr,
+ self.function_return, self.function_args,
+ self.function_file, self.function_module,
+ self.function_cond)
elif self.function_module == "libvirt-qemu":
qemu_function(self.function, self.function_descr,
self.function_return, self.function_args,
@@ -148,6 +157,11 @@ class docParser(xml.sax.handler.ContentHandler):
self.function_return, self.function_args,
self.function_file, self.function_module,
self.function_cond)
+ elif self.function_file == "python-lxc":
+ lxc_function(self.function, self.function_descr,
+ self.function_return, self.function_args,
+ self.function_file, self.function_module,
+ self.function_cond)
elif self.function_file == "python-qemu":
qemu_function(self.function, self.function_descr,
self.function_return, self.function_args,
@@ -184,6 +198,9 @@ def function(name, desc, ret, args, file, module, cond):
def qemu_function(name, desc, ret, args, file, module, cond):
qemu_functions[name] = (desc, ret, args, file, module, cond)
+def lxc_function(name, desc, ret, args, file, module, cond):
+ lxc_functions[name] = (desc, ret, args, file, module, cond)
+
def enum(type, name, value):
if not enums.has_key(type):
enums[type] = {}
@@ -208,6 +225,11 @@ def enum(type, name, value):
if name[-5:] != '_LAST':
enums[type][name] = value
+def lxc_enum(type, name, value):
+ if not lxc_enums.has_key(type):
+ lxc_enums[type] = {}
+ lxc_enums[type][name] = value
+
def qemu_enum(type, name, value):
if not qemu_enums.has_key(type):
qemu_enums[type] = {}
@@ -222,10 +244,12 @@ def qemu_enum(type, name, value):
#######################################################################
functions_failed = []
+lxc_functions_failed = []
qemu_functions_failed = []
functions_skipped = [
"virConnectListDomains",
]
+lxc_functions_skipped = []
qemu_functions_skipped = []
skipped_modules = {
@@ -430,6 +454,10 @@ skip_impl = (
'virNodeGetCPUMap',
)
+lxc_skip_impl = (
+ 'virDomainLxcOpenNamespace',
+)
+
qemu_skip_impl = (
'virDomainQemuMonitorCommand',
'virDomainQemuAgentCommand',
@@ -501,6 +529,8 @@ skip_function = (
"virStorageVolGetConnect",
)
+lxc_skip_function = (
+)
qemu_skip_function = (
#"virDomainQemuAttach",
)
@@ -511,6 +541,7 @@ function_skip_python_impl = (
# be exposed in bindings
)
+lxc_function_skip_python_impl = ()
qemu_function_skip_python_impl = ()
function_skip_index_one = (
@@ -521,6 +552,7 @@ def print_function_wrapper(module, name, output, export, include):
global py_types
global unknown_types
global functions
+ global lxc_functions
global qemu_functions
global skipped_modules
global function_skip_python_impl
@@ -528,6 +560,8 @@ def print_function_wrapper(module, name, output, export, include):
try:
if module == "libvirt":
(desc, ret, args, file, mod, cond) = functions[name]
+ if module == "libvirt-lxc":
+ (desc, ret, args, file, mod, cond) = lxc_functions[name]
if module == "libvirt-qemu":
(desc, ret, args, file, mod, cond) = qemu_functions[name]
except:
@@ -543,6 +577,12 @@ def print_function_wrapper(module, name, output, export, include):
if name in skip_impl:
# Don't delete the function entry in the caller.
return 1
+ elif module == "libvirt-lxc":
+ if name in lxc_skip_function:
+ return 0
+ if name in lxc_skip_impl:
+ # Don't delete the function entry in the caller.
+ return 1
elif module == "libvirt-qemu":
if name in qemu_skip_function:
return 0
@@ -643,6 +683,10 @@ def print_function_wrapper(module, name, output, export, include):
include.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name));
export.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
(name, name))
+ elif module == "libvirt-lxc":
+ include.write("libvirt_lxc_%s(PyObject *self, PyObject *args);\n" % (name));
+ export.write(" { (char *)\"%s\", libvirt_lxc_%s, METH_VARARGS, NULL },\n" %
+ (name, name))
elif module == "libvirt-qemu":
include.write("libvirt_qemu_%s(PyObject *self, PyObject *args);\n" % (name));
export.write(" { (char *)\"%s\", libvirt_qemu_%s, METH_VARARGS, NULL },\n" %
@@ -666,6 +710,8 @@ def print_function_wrapper(module, name, output, export, include):
output.write("PyObject *\n")
if module == "libvirt":
output.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
+ elif module == "libvirt-lxc":
+ output.write("libvirt_lxc_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
elif module == "libvirt-qemu":
output.write("libvirt_qemu_%s(PyObject *self ATTRIBUTE_UNUSED," % (name))
output.write(" PyObject *args")
@@ -698,6 +744,9 @@ def print_function_wrapper(module, name, output, export, include):
if module == "libvirt":
if name in function_skip_python_impl:
return 0
+ elif module == "libvirt-lxc":
+ if name in lxc_function_skip_python_impl:
+ return 0
elif module == "libvirt-qemu":
if name in qemu_function_skip_python_impl:
return 0
@@ -708,7 +757,7 @@ def buildStubs(module):
global py_return_types
global unknown_types
- if module not in ["libvirt", "libvirt-qemu"]:
+ if module not in ["libvirt", "libvirt-qemu", "libvirt-lxc"]:
print "ERROR: Unknown module type: %s" % module
return None
@@ -716,6 +765,10 @@ def buildStubs(module):
funcs = functions
funcs_failed = functions_failed
funcs_skipped = functions_skipped
+ elif module == "libvirt-lxc":
+ funcs = lxc_functions
+ funcs_failed = lxc_functions_failed
+ funcs_skipped = functions_skipped
elif module == "libvirt-qemu":
funcs = qemu_functions
funcs_failed = qemu_functions_failed
@@ -1111,6 +1164,8 @@ def functionCompare(info1, info2):
def writeDoc(module, name, args, indent, output):
if module == "libvirt":
funcs = functions
+ elif module == "libvirt-lxc":
+ funcs = lxc_functions
elif module == "libvirt-qemu":
funcs = qemu_functions
if funcs[name][0] is None or funcs[name][0] == "":
@@ -1762,11 +1817,126 @@ def qemuBuildWrappers(module):
fd.close()
+def lxcBuildWrappers(module):
+ global lxc_functions
+
+ if not module == "libvirt-lxc":
+ print "ERROR: only libvirt-lxc is supported"
+ return None
+
+ extra_file = os.path.join(srcPref, "%s-override.py" % module)
+ extra = None
+
+ fd = open("libvirt_lxc.py", "w")
+
+ if os.path.exists(extra_file):
+ extra = open(extra_file, "r")
+ fd.write("#! " + python + " -i\n")
+ fd.write("#\n")
+ fd.write("# WARNING WARNING WARNING WARNING\n")
+ fd.write("#\n")
+ fd.write("# This file is automatically written by generator.py. Any changes\n")
+ fd.write("# made here will be lost.\n")
+ fd.write("#\n")
+ fd.write("# To change the manually written methods edit " + module + "-override.py\n")
+ fd.write("# To change the automatically written methods edit generator.py\n")
+ fd.write("#\n")
+ fd.write("# WARNING WARNING WARNING WARNING\n")
+ fd.write("#\n")
+ if extra != None:
+ fd.writelines(extra.readlines())
+ fd.write("#\n")
+ fd.write("# WARNING WARNING WARNING WARNING\n")
+ fd.write("#\n")
+ fd.write("# Automatically written part of python bindings for libvirt\n")
+ fd.write("#\n")
+ fd.write("# WARNING WARNING WARNING WARNING\n")
+ if extra != None:
+ extra.close()
+
+ fd.write("try:\n")
+ fd.write(" import libvirtmod_lxc\n")
+ fd.write("except ImportError, lib_e:\n")
+ fd.write(" try:\n")
+ fd.write(" import cygvirtmod_lxc as libvirtmod_lxc\n")
+ fd.write(" except ImportError, cyg_e:\n")
+ fd.write(" if str(cyg_e).count(\"No module named\"):\n")
+ fd.write(" raise lib_e\n\n")
+
+ fd.write("import libvirt\n\n");
+ fd.write("#\n# Functions from module %s\n#\n\n" % module)
+ #
+ # Generate functions directly, no classes
+ #
+ for name in lxc_functions.keys():
+ func = nameFixup(name, 'None', None, None)
+ (desc, ret, args, file, mod, cond) = lxc_functions[name]
+ fd.write("def %s(" % func)
+ n = 0
+ for arg in args:
+ if n != 0:
+ fd.write(", ")
+ fd.write("%s" % arg[0])
+ n = n + 1
+ fd.write("):\n")
+ writeDoc(module, name, args, ' ', fd);
+
+ if ret[0] != "void":
+ fd.write(" ret = ");
+ else:
+ fd.write(" ");
+ fd.write("libvirtmod_lxc.%s(" % name)
+ n = 0
+
+ conn = None
+
+ for arg in args:
+ if arg[1] == "virConnectPtr":
+ conn = arg[0]
+
+ if n != 0:
+ fd.write(", ");
+ if arg[1] in ["virDomainPtr", "virConnectPtr"]:
+ # FIXME: This might have problem if the function
+ # has multiple args which are objects.
+ fd.write("%s.%s" % (arg[0], "_o"))
+ else:
+ fd.write("%s" % arg[0])
+ n = n + 1
+ fd.write(")\n");
+
+ if ret[0] != "void":
+ fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n")
+ if ret[0] == "virDomainPtr":
+ fd.write(" __tmp = virDomain(" + conn + ",_obj=ret)\n")
+ fd.write(" return __tmp\n")
+ else:
+ fd.write(" return ret\n")
+
+ fd.write("\n")
+
+ #
+ # Generate enum constants
+ #
+ for type,enum in lxc_enums.items():
+ fd.write("# %s\n" % type)
+ items = enum.items()
+ items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1])))
+ for name,value in items:
+ fd.write("%s = %s\n" % (name,value))
+ fd.write("\n");
+
+ fd.close()
+
+
quiet = 0
if buildStubs("libvirt") < 0:
sys.exit(1)
+if buildStubs("libvirt-lxc") < 0:
+ sys.exit(1)
if buildStubs("libvirt-qemu") < 0:
sys.exit(1)
buildWrappers("libvirt")
+lxcBuildWrappers("libvirt-lxc")
qemuBuildWrappers("libvirt-qemu")
sys.exit(0)
diff --git a/libvirt-lxc-override-api.xml b/libvirt-lxc-override-api.xml
new file mode 100644
index 0000000..db0d45d
--- /dev/null
+++ b/libvirt-lxc-override-api.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0"?>
+<api name='libvir-lxc-python'>
+ <symbols>
+ <function name='virDomainLxcOpenNamespace' file='python-lxc'>
+ <info><![CDATA[This API is LXC specific, so it will only work with hypervisor
+connections to the LXC driver.
+
+Open the namespaces associated with the container @domain
+and return a list of file descriptors associated with the
+container.
+
+The returned file descriptors are intended to be used with
+the setns() system call.]]></info>
+ <return type='int' info='the list of open file descriptors, or -1 on error'/>
+ <arg name='domain' type='virDomainPtr' info='a domain object'/>
+ <arg name='flags' type='unsigned int' info='currently unused, pass 0'/>
+ </function>
+ </symbols>
+</api>
diff --git a/libvirt-lxc-override.c b/libvirt-lxc-override.c
new file mode 100644
index 0000000..c80668e
--- /dev/null
+++ b/libvirt-lxc-override.c
@@ -0,0 +1,141 @@
+/*
+ * libvir.c: this modules implements the main part of the glue of the
+ * libvir library and the Python interpreter. It provides the
+ * entry points where an automatically generated stub is
+ * unpractical
+ *
+ * Copyright (C) 2012-2013 Red Hat, Inc.
+ *
+ * Daniel Veillard <veillard@redhat.com>
+ */
+
+#include <config.h>
+
+/* Horrible kludge to work around even more horrible name-space pollution
+ via Python.h. That file includes /usr/include/python2.5/pyconfig*.h,
+ which has over 180 autoconf-style HAVE_* definitions. Shame on them. */
+#undef HAVE_PTHREAD_H
+
+#include <Python.h>
+#include "libvirt/libvirt-lxc.h"
+#include "libvirt/virterror.h"
+#include "typewrappers.h"
+#include "libvirt-lxc.h"
+#include "viralloc.h"
+#include "virfile.h"
+
+#ifndef __CYGWIN__
+extern void initlibvirtmod_lxc(void);
+#else
+extern void initcygvirtmod_lxc(void);
+#endif
+
+#if 0
+# define DEBUG_ERROR 1
+#endif
+
+#if DEBUG_ERROR
+# define DEBUG(fmt, ...) \
+ printf(fmt, __VA_ARGS__)
+#else
+# define DEBUG(fmt, ...) \
+ do {} while (0)
+#endif
+
+/* The two-statement sequence "Py_INCREF(Py_None); return Py_None;"
+ is so common that we encapsulate it here. Now, each use is simply
+ return VIR_PY_NONE; */
+#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None)
+#define VIR_PY_INT_FAIL (libvirt_intWrap(-1))
+#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0))
+
+/************************************************************************
+ * *
+ * Statistics *
+ * *
+ ************************************************************************/
+
+static PyObject *
+libvirt_lxc_virDomainLxcOpenNamespace(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args) {
+ PyObject *py_retval;
+ virDomainPtr domain;
+ PyObject *pyobj_domain;
+ unsigned int flags;
+ int c_retval;
+ int *fdlist = NULL;
+ int i;
+
+ if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainLxcOpenNamespace",
+ &pyobj_domain, &flags))
+ return NULL;
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ if (domain == NULL)
+ return VIR_PY_NONE;
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ c_retval = virDomainLxcOpenNamespace(domain, &fdlist, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (c_retval < 0)
+ return VIR_PY_NONE;
+
+ py_retval = PyList_New(c_retval);
+ for (i = 0 ; i < c_retval ; i++) {
+ PyObject *item = NULL;
+
+ if ((item = PyInt_FromLong(fdlist[i])) == NULL)
+ goto error;
+
+ if (PyList_Append(py_retval, item) < 0) {
+ Py_DECREF(item);
+ goto error;
+ }
+ }
+ return py_retval;
+
+error:
+ for (i = 0 ; i < c_retval ; i++) {
+ VIR_FORCE_CLOSE(fdlist[i]);
+ }
+ VIR_FREE(fdlist);
+ return VIR_PY_NONE;
+}
+/************************************************************************
+ * *
+ * The registration stuff *
+ * *
+ ************************************************************************/
+static PyMethodDef libvirtLxcMethods[] = {
+#include "libvirt-lxc-export.c"
+ {(char *) "virDomainLxcOpenNamespace", libvirt_lxc_virDomainLxcOpenNamespace, METH_VARARGS, NULL},
+ {NULL, NULL, 0, NULL}
+};
+
+void
+#ifndef __CYGWIN__
+initlibvirtmod_lxc
+#else
+initcygvirtmod_lxc
+#endif
+ (void)
+{
+ static int initialized = 0;
+
+ if (initialized != 0)
+ return;
+
+ if (virInitialize() < 0)
+ return;
+
+ /* initialize the python extension module */
+ Py_InitModule((char *)
+#ifndef __CYGWIN__
+ "libvirtmod_lxc"
+#else
+ "cygvirtmod_lxc"
+#endif
+ , libvirtLxcMethods);
+
+ initialized = 1;
+}