[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCHv5 5/5] domifaddr: Expose python binding



On 02/09/13 18:01, Nehal J Wani wrote:
On Sun, Sep 1, 2013 at 7:13 PM, Nehal J Wani <nehaljw kkd1 gmail com> wrote:
Expose virDomainInterfaceAddresses to python binding

examples/python/Makefile.am:
   * Add new file domipaddrs.py

examples/python/README:
   * Add documentation for the python example

python/libvirt-override-api.xml:
   * Add new symbol for virDomainInterfaceAddresses

python/libvirt-override.c:
   * Hand written python api

Example:
   $ ./run python ./examples/python/domipaddrs.py f18
   Interface  MAC address          Protocol     Address
   lo         00:00:00:00:00:00    ipv4         127.0.0.1/8
   lo         00:00:00:00:00:00    ipv6         ::1/128
   eth2       52:54:00:36:2a:e5
   eth1       52:54:00:b1:70:19    ipv4         192.168.105.201/16
   eth1       52:54:00:b1:70:19    ipv4         192.168.201.195/16
   eth1       52:54:00:b1:70:19    ipv6         fe80::5054:ff:feb1:7019/64
   eth0       52:54:00:2e:45:ce    ipv4         10.1.33.188/24
   eth0       52:54:00:2e:45:ce    ipv6         2001:db8:0:f101::2/64
   eth0       52:54:00:2e:45:ce    ipv6         fe80::5054:ff:fe2e:45ce/64

---
  examples/python/Makefile.am     |   2 +-
  examples/python/README          |   1 +
  examples/python/domipaddrs.py   |  50 ++++++++++++++++++
  python/libvirt-override-api.xml |   8 ++-
  python/libvirt-override.c       | 111 ++++++++++++++++++++++++++++++++++++++++
  5 files changed, 170 insertions(+), 2 deletions(-)
  create mode 100755 examples/python/domipaddrs.py

diff --git a/examples/python/Makefile.am b/examples/python/Makefile.am
index 2cacfa1..d33ee17 100644
--- a/examples/python/Makefile.am
+++ b/examples/python/Makefile.am
@@ -17,4 +17,4 @@
  EXTRA_DIST=                                            \
         README                                          \
         consolecallback.py                              \
-       dominfo.py domrestore.py domsave.py domstart.py esxlist.py
+       dominfo.py domrestore.py domsave.py domstart.py esxlist.py domipaddrs.py
diff --git a/examples/python/README b/examples/python/README
index f4db76c..1285d52 100644
--- a/examples/python/README
+++ b/examples/python/README
@@ -10,6 +10,7 @@ domsave.py  - save all running domU's into a directory
  domrestore.py - restore domU's from their saved files in a directory
  esxlist.py  - list active domains of an VMware ESX host and print some info.
                also demonstrates how to use the libvirt.openAuth() method
+domipaddrs.py - print domain interfaces along with their MAC and IP addresses

  The XML files in this directory are examples of the XML format that libvirt
  expects, and will have to be adapted for your setup. They are only needed
diff --git a/examples/python/domipaddrs.py b/examples/python/domipaddrs.py
new file mode 100755
index 0000000..679e0bf
--- /dev/null
+++ b/examples/python/domipaddrs.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python
+# domipaddrds - print domain interfaces along with their MAC and IP addresses
+
+import libvirt
+import sys
+
+def usage():
+    print "Usage: %s [URI] DOMAIN" % sys.argv[0]
+    print "        Print domain interfaces along with their MAC and IP addresses"
+
+uri = None
+name = None
+args = len(sys.argv)
+
+if args == 2:
+    name = sys.argv[1]
+elif args == 3:
+    uri = sys.argv[1]
+    name = sys.argv[2]
+else:
+    usage()
+    sys.exit(2)
+
+conn = libvirt.openReadOnly(uri)
+if conn == None:
+    print "Unable to open connection to libvirt"
+    sys.exit(1)
+
+try:
+    dom = conn.lookupByName(name)
+except libvirt.libvirtError:
+    print "Domain %s not found" % name
+    sys.exit(0)
+
+ifaces = dom.interfaceAddresses(0)
+if (ifaces == None):
+    print "Failed to get domain interfaces"
+    sys.exit(0)
+
+print " {0:10} {1:20} {2:12} {3}".format("Interface", "MAC address", "Protocol", "Address")
+
+for (name, val) in ifaces.iteritems():
+    if val['ip_addrs']:
+        for addr in val['ip_addrs']:
+           print " {0:10} {1:19}".format(name, val['hwaddr']),
+           print " {0:12} {1}/{2} ".format(addr['type'], addr['addr'], addr['prefix']),
+           print
+    else:
+        print " {0:10} {1:19}".format(name, val['hwaddr']),
+        print
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 9a88215..60491de 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -602,5 +602,11 @@
        <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
        <arg name='flags' type='int' info='unused, pass 0'/>
      </function>
-  </symbols>
+    <function name='virDomainInterfaceAddresses' file='python'>
+      <info>returns a dictionary of domain interfaces along with their MAC and IP addresses</info>
+      <arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
+      <arg name='flags' type='unsigned int' info='extra flags; not used yet, so callers should always pass 0'/>
+      <return type='virDomainInterfacePtr' info="dictionary of domain interfaces along with their MAC and IP addresses"/>
+    </function>
+</symbols>
  </api>
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index d16b9a2..67e0cb8 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -4761,6 +4761,116 @@ cleanup:
      return py_retval;
  }

+
+static PyObject *
+libvirt_virDomainInterfaceAddresses(PyObject *self ATTRIBUTE_UNUSED,
+                                    PyObject *args)
+{
+    PyObject *py_retval = VIR_PY_NONE;
+    virDomainPtr domain;
+    PyObject *pyobj_domain;
+    unsigned int flags;
+    virDomainInterfacePtr *ifaces = NULL;
+    int ifaces_count = 0;
+    size_t i, j;
+    int ret;
+    bool full_free = true;
+
+    if (!PyArg_ParseTuple(args, (char *) "Oi:virDomainInterfacePtr",
+                          &pyobj_domain, &flags))
+        return NULL;
+
+    domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+    LIBVIRT_BEGIN_ALLOW_THREADS;
+    ifaces_count = virDomainInterfaceAddresses(domain, &ifaces, flags);
+    ret = ifaces_count;
+    LIBVIRT_END_ALLOW_THREADS;
+    if (ret < 0)
+        goto cleanup;
+
+    if (!(py_retval = PyDict_New()))
+        goto no_memory;
+
+    for (i = 0; i < ifaces_count; i++) {
+        virDomainInterfacePtr iface = ifaces[i];
+        PyObject *py_ip_addrs = NULL;
+        PyObject *py_iface = NULL;
+
+        if (!(py_iface = PyDict_New()))
+            goto no_memory;
+
+        if (iface->naddrs) {
+            if (!(py_ip_addrs = PyList_New(iface->naddrs))) {
+                Py_DECREF(py_iface);
+                goto no_memory;
+            }
+        } else {
+            py_ip_addrs = VIR_PY_NONE;
+        }
+
+        for (j = 0; j < iface->naddrs; j++) {
+            virDomainIPAddressPtr ip_addr = &(iface->addrs[j]);
+            PyObject *py_addr = PyDict_New();
+            const char *type = NULL;
+
+            if (!py_addr) {
+                Py_DECREF(py_iface);
+                Py_DECREF(py_ip_addrs);
+                goto no_memory;
+            }
+
+            switch (ip_addr->type) {
+            case VIR_IP_ADDR_TYPE_IPV4:
+                type = "ipv4";
+                break;
+            case VIR_IP_ADDR_TYPE_IPV6:
+                type = "ipv6";
+                break;
+            }
+
+            PyDict_SetItem(py_addr, libvirt_constcharPtrWrap("addr"),
+                           PyString_FromString(ip_addr->addr));
+            PyDict_SetItem(py_addr, libvirt_constcharPtrWrap("prefix"),
+                           libvirt_intWrap(ip_addr->prefix));
+            PyDict_SetItem(py_addr, libvirt_constcharPtrWrap("type"),
+                           PyString_FromString(type));
+
+            PyList_SetItem(py_ip_addrs, j, py_addr);
+        }
+
+        PyDict_SetItem(py_iface, libvirt_constcharPtrWrap("ip_addrs"),
+                       py_ip_addrs);
+        PyDict_SetItem(py_iface, libvirt_constcharPtrWrap("hwaddr"),
+                       libvirt_charPtrWrap(iface->hwaddr));
+
+        PyDict_SetItem(py_retval, libvirt_charPtrWrap(iface->name),
+                       py_iface);
+    }
+
+    full_free = false;
+
+cleanup:
+    if (ifaces) {
+        for (i = 0; full_free && i < ifaces_count; i++) {
+            /*
+             * We don't want to free values we've just shared with python variables unless
+             * there was an error and hence we are returning PY_NONE or equivalent
+             */
+            virDomainInterfaceFree(ifaces[i]);
+        }
+    }
+    VIR_FREE(ifaces);
+
+    return py_retval;
+
+no_memory:
+    Py_XDECREF(py_retval);
+    py_retval = PyErr_NoMemory();
+    goto cleanup;
+}
+
+
  /*******************************************
   * Helper functions to avoid importing modules
   * for every callback
@@ -7284,6 +7394,7 @@ static PyMethodDef libvirtMethods[] = {
      {(char *) "virDomainBlockPeek", libvirt_virDomainBlockPeek, METH_VARARGS, NULL},
      {(char *) "virDomainMemoryPeek", libvirt_virDomainMemoryPeek, METH_VARARGS, NULL},
      {(char *) "virDomainGetDiskErrors", libvirt_virDomainGetDiskErrors, METH_VARARGS, NULL},
+    {(char *) "virDomainInterfaceAddresses", libvirt_virDomainInterfaceAddresses, METH_VARARGS, NULL},
      {(char *) "virNodeGetMemoryParameters", libvirt_virNodeGetMemoryParameters, METH_VARARGS, NULL},
      {(char *) "virNodeSetMemoryParameters", libvirt_virNodeSetMemoryParameters, METH_VARARGS, NULL},
      {(char *) "virNodeGetCPUMap", libvirt_virNodeGetCPUMap, METH_VARARGS, NULL},
--
1.7.11.7

In agreement with Guido's suggestion on 5/5 of the previous version
(https://www.redhat.com/archives/libvir-list/2013-August/msg01271.html),
instead of string, the enum virIPAddrType is to be used in python, for which
examples/python/domipaddrs.py and python/libvirt-override.c are to be
modified a bit. Diff has been attached.


ACK with the diff applied.

Osier


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]