[Libvir] Generate python binding for network APIs

Daniel P. Berrange berrange at redhat.com
Fri Mar 9 01:42:29 UTC 2007


I was about to make use of the new networking APIs in virt-manager/virt-install
when I discovered we don't have any python binding for it. Attached is the
quickest patch I could write to support it - I basically copied all the
virDomain related bits & s/Domain/Network/ throughout. A simple demo script
works:

#!/usr/bin/python

import libvirt

con = libvirt.open(None)

n = con.listNetworks()
print str(n)
for name in n:
    net = con.lookupByName(name)
    print net.XMLDesc(0)
    print net.bridgeName()

I think there are a couple more methods which need manual implementations
though - eg  UUIDString() is generated incorrectly - in fact the UUIDString()
impl for virDomains is already broken, and so is the binding for VCPU
pinning.

Regards,
Dan.
-- 
|=- Red Hat, Engineering, Emerging Technologies, Boston.  +1 978 392 2496 -=|
|=-           Perl modules: http://search.cpan.org/~danberr/              -=|
|=-               Projects: http://freshmeat.net/~danielpb/               -=|
|=-  GnuPG: 7D3B9505   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505  -=| 
-------------- next part --------------
? python/libvirt.pyc
Index: python/generator.py
===================================================================
RCS file: /data/cvs/libvirt/python/generator.py,v
retrieving revision 1.15
diff -u -p -r1.15 generator.py
--- python/generator.py	14 Feb 2007 17:20:27 -0000	1.15
+++ python/generator.py	9 Mar 2007 01:38:25 -0000
@@ -235,6 +235,10 @@ py_types = {
     'const virDomainPtr':  ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
     'virDomain *':  ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
     'const virDomain *':  ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
+    'virNetworkPtr':  ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
+    'const virNetworkPtr':  ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
+    'virNetwork *':  ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
+    'const virNetwork *':  ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
     'virConnectPtr':  ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
     'const virConnectPtr':  ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
     'virConnect *':  ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
@@ -261,12 +265,16 @@ foreign_encoding_args = (
 skip_impl = (
     'virConnectListDomainsID',
     'virConnectListDefinedDomains',
+    'virConnectListNetworks',
+    'virConnectListDefinedNetworks',
     'virConnGetLastError',
     'virGetLastError',
     'virDomainGetInfo',
     'virNodeGetInfo',
     'virDomainGetUUID',
     'virDomainLookupByUUID',
+    'virNetworkGetUUID',
+    'virNetworkLookupByUUID',
 )
 
 def skip_function(name):
@@ -274,6 +282,8 @@ def skip_function(name):
         return 1
     if name == "virDomainFree":
         return 1
+    if name == "virNetworkFree":
+        return 1
     if name == "vshRunConsole":
         return 1
     return 0
@@ -526,6 +536,8 @@ def buildStubs():
 classes_type = {
     "virDomainPtr": ("._o", "virDomain(_obj=%s)", "virDomain"),
     "virDomain *": ("._o", "virDomain(_obj=%s)", "virDomain"),
+    "virNetworkPtr": ("._o", "virNetwork(_obj=%s)", "virNetwork"),
+    "virNetwork *": ("._o", "virNetwork(_obj=%s)", "virNetwork"),
     "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
     "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
 }
@@ -533,17 +545,19 @@ classes_type = {
 converter_type = {
 }
 
-primary_classes = ["virDomain", "virConnect"]
+primary_classes = ["virDomain", "virNetwork", "virConnect"]
 
 classes_ancestor = {
 }
 classes_destructors = {
     "virDomain": "virDomainFree",
+    "virNetwork": "virNetworkFree",
     "virConnect": "virConnectClose",
 }
 
 classes_references = {
     "virDomain": "virConnect",
+    "virNetwork": "virConnect",
 }
 
 functions_noexcept = {
@@ -558,6 +572,7 @@ function_classes["None"] = []
 
 function_post = {
     'virDomainDestroy': "self._o = None",
+    'virNetworkDestroy': "self._o = None",
 }
 
 def nameFixup(name, classe, type, file):
@@ -573,6 +588,12 @@ def nameFixup(name, classe, type, file):
     elif name[0:9] == "virDomain":
         func = name[9:]
         func = string.lower(func[0:1]) + func[1:]
+    elif name[0:13] == "virNetworkGet":
+        func = name[13:]
+        func = string.lower(func[0:1]) + func[1:]
+    elif name[0:10] == "virNetwork":
+        func = name[10:]
+        func = string.lower(func[0:1]) + func[1:]
     elif name[0:7] == "virNode":
         func = name[7:]
         func = string.lower(func[0:1]) + func[1:]
@@ -588,6 +609,8 @@ def nameFixup(name, classe, type, file):
         func = "ID"
     if func == "uUID":
         func = "UUID"
+    if func == "uUIDString":
+        func = "UUIDString"
     if func == "oSType":
         func = "OSType"
     if func == "xMLDesc":
Index: python/libvir.c
===================================================================
RCS file: /data/cvs/libvirt/python/libvir.c,v
retrieving revision 1.19
diff -u -p -r1.19 libvir.c
--- python/libvir.c	6 Mar 2007 21:55:44 -0000	1.19
+++ python/libvir.c	9 Mar 2007 01:38:25 -0000
@@ -18,6 +18,7 @@
 extern void initlibvirtmod(void);
 
 PyObject *libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args);
+PyObject *libvirt_virNetworkGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args);
 PyObject *libvirt_virGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args);
 PyObject *libvirt_virConnGetLastError(PyObject *self ATTRIBUTE_UNUSED, PyObject *args);
 
@@ -250,7 +251,7 @@ libvirt_virConnectListDefinedDomains(PyO
     PyObject *pyobj_conn;
 
 
-    if (!PyArg_ParseTuple(args, (char *)"O:virConnectListDomains", &pyobj_conn))
+    if (!PyArg_ParseTuple(args, (char *)"O:virConnectListDefinedDomains", &pyobj_conn))
         return(NULL);
     conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
 
@@ -400,6 +401,176 @@ libvirt_virDomainLookupByUUID(PyObject *
     return(py_retval);
 }
 
+
+static PyObject *
+libvirt_virNetworkFree(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    int c_retval;
+    virNetworkPtr domain;
+    PyObject *pyobj_domain;
+
+    if (!PyArg_ParseTuple(args, (char *)"O:virNetworkFree", &pyobj_domain))
+        return(NULL);
+    domain = (virNetworkPtr) PyvirNetwork_Get(pyobj_domain);
+
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+    c_retval = virNetworkFree(domain);
+    LIBVIRT_END_ALLOW_THREADS;
+    py_retval = libvirt_intWrap((int) c_retval);
+    return(py_retval);
+}
+
+
+static PyObject *
+libvirt_virConnectListNetworks(PyObject *self ATTRIBUTE_UNUSED,
+			       PyObject *args) {
+    PyObject *py_retval;
+    char **names = NULL;
+    int c_retval, i;
+    virConnectPtr conn;
+    PyObject *pyobj_conn;
+
+
+    if (!PyArg_ParseTuple(args, (char *)"O:virConnectListNetworks", &pyobj_conn))
+        return(NULL);
+    conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
+
+    c_retval = virConnectNumOfNetworks(conn);
+    if (c_retval < 0) {
+        Py_INCREF(Py_None);
+        return (Py_None);
+    }
+    
+    if (c_retval) {
+        names = malloc(sizeof(char *) * c_retval);
+        if (!names) {
+            Py_INCREF(Py_None);
+            return (Py_None);
+        }
+        c_retval = virConnectListNetworks(conn, names, c_retval);
+        if (c_retval < 0) {
+            free(names);
+            Py_INCREF(Py_None);
+            return(Py_None);
+        }
+    }
+    py_retval = PyList_New(c_retval);
+
+    if (names) {
+        for (i = 0;i < c_retval;i++) {
+            PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i]));
+            free(names[i]);
+        }
+        free(names);
+    }
+
+    return(py_retval);
+}
+
+
+static PyObject *
+libvirt_virConnectListDefinedNetworks(PyObject *self ATTRIBUTE_UNUSED,
+				      PyObject *args) {
+    PyObject *py_retval;
+    char **names = NULL;
+    int c_retval, i;
+    virConnectPtr conn;
+    PyObject *pyobj_conn;
+
+
+    if (!PyArg_ParseTuple(args, (char *)"O:virConnectListDefinedNetworks", &pyobj_conn))
+        return(NULL);
+    conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
+
+    c_retval = virConnectNumOfDefinedNetworks(conn);
+    if (c_retval < 0) {
+        Py_INCREF(Py_None);
+        return (Py_None);
+    }
+    
+    if (c_retval) {
+        names = malloc(sizeof(char *) * c_retval);
+        if (!names) {
+            Py_INCREF(Py_None);
+            return (Py_None);
+        }
+        c_retval = virConnectListDefinedNetworks(conn, names, c_retval);
+        if (c_retval < 0) {
+            free(names);
+            Py_INCREF(Py_None);
+            return(Py_None);
+        }
+    }
+    py_retval = PyList_New(c_retval);
+
+    if (names) {
+        for (i = 0;i < c_retval;i++) {
+            PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(names[i]));
+            free(names[i]);
+        }
+        free(names);
+    }
+
+    return(py_retval);
+}
+
+
+PyObject *
+libvirt_virNetworkGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    unsigned char uuid[VIR_UUID_BUFLEN];
+    virNetworkPtr domain;
+    PyObject *pyobj_domain;
+    int c_retval;
+
+    if (!PyArg_ParseTuple(args, (char *)"O:virNetworkGetUUID", &pyobj_domain))
+        return(NULL);
+    domain = (virNetworkPtr) PyvirNetwork_Get(pyobj_domain);
+
+    if (domain == NULL) {
+        Py_INCREF(Py_None);
+	return(Py_None);
+    }
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+    c_retval = virNetworkGetUUID(domain, &uuid[0]);
+    LIBVIRT_END_ALLOW_THREADS;
+
+    if (c_retval < 0) {
+        Py_INCREF(Py_None);
+	return(Py_None);
+    }
+    py_retval = PyString_FromStringAndSize((char *) &uuid[0], VIR_UUID_BUFLEN);
+
+    return(py_retval);
+}
+
+static PyObject *
+libvirt_virNetworkLookupByUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+    PyObject *py_retval;
+    virNetworkPtr c_retval;
+    virConnectPtr conn;
+    PyObject *pyobj_conn;
+    unsigned char * uuid;
+    int len;
+
+    if (!PyArg_ParseTuple(args, (char *)"Oz#:virNetworkLookupByUUID", &pyobj_conn, &uuid, &len))
+        return(NULL);
+    conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
+
+    if ((uuid == NULL) || (len != VIR_UUID_BUFLEN)) {
+        Py_INCREF(Py_None);
+	return(Py_None);
+    }
+
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+    c_retval = virNetworkLookupByUUID(conn, uuid);
+    LIBVIRT_END_ALLOW_THREADS;
+    py_retval = libvirt_virNetworkPtrWrap((virNetworkPtr) c_retval);
+    return(py_retval);
+}
+
+
+
 /************************************************************************
  *									*
  *			The registration stuff				*
@@ -418,6 +589,11 @@ static PyMethodDef libvirtMethods[] = {
     {(char *) "virRegisterErrorHandler", libvirt_virRegisterErrorHandler, METH_VARARGS, NULL},
     {(char *) "virGetLastError", libvirt_virGetLastError, METH_VARARGS, NULL},
     {(char *) "virConnGetLastError", libvirt_virConnGetLastError, METH_VARARGS, NULL},
+    {(char *) "virNetworkFree", libvirt_virNetworkFree, METH_VARARGS, NULL},
+    {(char *) "virConnectListNetworks", libvirt_virConnectListNetworks, METH_VARARGS, NULL},
+    {(char *) "virConnectListDefinedNetworks", libvirt_virConnectListDefinedNetworks, METH_VARARGS, NULL},
+    {(char *) "virNetworkGetUUID", libvirt_virNetworkGetUUID, METH_VARARGS, NULL},
+    {(char *) "virNetworkLookupByUUID", libvirt_virNetworkLookupByUUID, METH_VARARGS, NULL},
     {NULL, NULL, 0, NULL}
 };
 
Index: python/libvirt-python-api.xml
===================================================================
RCS file: /data/cvs/libvirt/python/libvirt-python-api.xml,v
retrieving revision 1.5
diff -u -p -r1.5 libvirt-python-api.xml
--- python/libvirt-python-api.xml	16 Nov 2006 00:17:10 -0000	1.5
+++ python/libvirt-python-api.xml	9 Mar 2007 01:38:25 -0000
@@ -11,12 +11,28 @@
       <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
       <return type='str *' info='the list of Names of None in case of error'/>
     </function>
+    <function name='virConnectListNetworks' file='python'>
+      <info>list the networks, stores the pointers to the names in @names</info>
+      <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
+      <return type='str *' info='the list of Names of None in case of error'/>
+    </function>
+    <function name='virConnectListDefinedNetworks' file='python'>
+      <info>list the defined networks, stores the pointers to the names in @names</info>
+      <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
+      <return type='str *' info='the list of Names of None in case of error'/>
+    </function>
     <function name='virDomainLookupByUUID' file='python'>
       <info>Try to lookup a domain on the given hypervisor based on its UUID.</info>
       <return type='virDomainPtr' info='a new domain object or NULL in case of failure'/>
       <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
       <arg name='uuid' type='const unsigned char *' info='the UUID string for the domain, must be 16 bytes'/>
     </function>
+    <function name='virNetworkLookupByUUID' file='python'>
+      <info>Try to lookup a network on the given hypervisor based on its UUID.</info>
+      <return type='virNetworkPtr' info='a new network object or NULL in case of failure'/>
+      <arg name='conn' type='virNetworkPtr' info='pointer to the hypervisor connection'/>
+      <arg name='uuid' type='const unsigned char *' info='the UUID string for the network, must be 16 bytes'/>
+    </function>
     <function name='virDomainGetInfo' file='python'>
       <info>Extract informations about a domain. Note that if the connection used to get the domain is limited only a partial set of the informations can be extracted.</info>
       <return type='int *' info='the list of informations or None in case of error'/>
@@ -32,5 +48,10 @@
       <return type='char *' info='the 16 bytes string or None in case of error'/>
       <arg name='domain' type='virDomainPtr' info='a domain object'/>
     </function>
+    <function name='virNetworkGetUUID' file='python'>
+      <info>Extract the UUID unique Identifier of a network.</info>
+      <return type='char *' info='the 16 bytes string or None in case of error'/>
+      <arg name='domain' type='virNetworkPtr' info='a network object'/>
+    </function>
   </symbols>
 </api>
Index: python/libvirt_wrap.h
===================================================================
RCS file: /data/cvs/libvirt/python/libvirt_wrap.h,v
retrieving revision 1.6
diff -u -p -r1.6 libvirt_wrap.h
--- python/libvirt_wrap.h	6 Mar 2007 21:55:44 -0000	1.6
+++ python/libvirt_wrap.h	9 Mar 2007 01:38:25 -0000
@@ -39,6 +39,15 @@ typedef struct {
 } PyvirDomain_Object;
 
 
+#define PyvirNetwork_Get(v) (((v) == Py_None) ? NULL : \
+	(((PyvirNetwork_Object *)(v))->obj))
+
+typedef struct {
+    PyObject_HEAD
+    virNetworkPtr obj;
+} PyvirNetwork_Object;
+
+
 PyObject * libvirt_intWrap(int val);
 PyObject * libvirt_longWrap(long val);
 PyObject * libvirt_ulongWrap(unsigned long val);
@@ -48,6 +57,7 @@ PyObject * libvirt_constcharPtrWrap(cons
 PyObject * libvirt_charPtrConstWrap(const char *str);
 PyObject * libvirt_virConnectPtrWrap(virConnectPtr node);
 PyObject * libvirt_virDomainPtrWrap(virDomainPtr node);
+PyObject * libvirt_virNetworkPtrWrap(virNetworkPtr node);
 
 
 /* Provide simple macro statement wrappers (adapted from GLib, in turn from Perl):
Index: python/types.c
===================================================================
RCS file: /data/cvs/libvirt/python/types.c,v
retrieving revision 1.4
diff -u -p -r1.4 types.c
--- python/types.c	15 Nov 2006 19:40:00 -0000	1.4
+++ python/types.c	9 Mar 2007 01:38:25 -0000
@@ -125,6 +125,24 @@ libvirt_virDomainPtrWrap(virDomainPtr no
 }
 
 PyObject *
+libvirt_virNetworkPtrWrap(virNetworkPtr node)
+{
+    PyObject *ret;
+
+#ifdef DEBUG
+    printf("libvirt_virNetworkPtrWrap: node = %p\n", node);
+#endif
+    if (node == NULL) {
+        Py_INCREF(Py_None);
+        return (Py_None);
+    }
+    ret =
+        PyCObject_FromVoidPtrAndDesc((void *) node, (char *) "virNetworkPtr",
+                                     NULL);
+    return (ret);
+}
+
+PyObject *
 libvirt_virConnectPtrWrap(virConnectPtr node)
 {
     PyObject *ret;


More information about the libvir-list mailing list