On Sun, Aug 25, 2013 at 04:45:45AM +0530, Nehal J Wani wrote:
Expose virDomainInterfacesAddresses 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 virDomainInterfacesAddresses
python/libvirt-override.c:
* Hand written python api
Example:
$ ./run ./examples/python/domipaddrs.py qemu:///system f18
Interface MAC address IPv4 Address IPv6 Address
eth3:1 52:54:00:fe:4c:4f 192.168.101.198/24
eth2:1 52:54:00:d3:39:ee 192.168.103.185/24
eth2:0 52:54:00:d3:39:ee 192.168.103.184/24
eth1:2 52:54:00:89:ad:35 192.168.102.143/24
lo 00:00:00:00:00:00 127.0.0.1/8 ::1/128
eth0:2 52:54:00:89:4e:97 192.168.101.132/24
eth0:1 52:54:00:89:4e:97 192.168.101.133/24
eth3 52:54:00:fe:4c:4f 192.168.101.197/24 fe80::5054:ff:fefe:4c4f/64
eth2 52:54:00:d3:39:ee 192.168.103.183/24 fe80::5054:ff:fed3:39ee/64
eth1 52:54:00:89:ad:35 192.168.102.142/24 fe80::5054:ff:fe89:ad35/64
eth0 52:54:00:89:4e:97 192.168.101.130/24 fe80::5054:ff:fe89:4e97/64
---
examples/python/Makefile.am | 2 +-
examples/python/README | 1 +
examples/python/domipaddrs.py | 49 +++++++++++++++++
python/libvirt-override-api.xml | 8 ++-
python/libvirt-override.c | 113 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 171 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..e71e8f6
--- /dev/null
+++ b/examples/python/domipaddrs.py
@@ -0,0 +1,49 @@
+#!/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.interfacesAddresses(0)
+if (ifaces == None):
+ print "Failed to get domain interfaces"
+ sys.exit(0)
+
+print " {0:10} {1:20} {2:15} {3}".format("Interface", "MAC
address", "IPv4 Address", "IPv6 Address")
+
+for (name, val) in ifaces.iteritems():
+ print " {0:10} {1:17}".format(name, val['hwaddr']),
+
+ if (val['ip_addrs'] <> None):
+ print " ",
+ for addr in val['ip_addrs']:
+ print "{0}/{1} ".format(addr['addr'],
addr['prefix']),
+ print
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 9a88215..f5c6e83 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='virDomainInterfacesAddresses' 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..9eae9fb 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -4761,6 +4761,118 @@ cleanup:
return py_retval;
}
+
+static PyObject *
+libvirt_virDomainInterfacesAddresses(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 = virDomainInterfacesAddresses(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;
+
+ 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";
I'd prefer to have libvirt.VIR_IP_ADDR_TYPE_IPV4 instead of a text
representation here but that's probably a matter of taste.
+ break;
+ case VIR_IP_ADDR_TYPE_IPV6:
+ type = "ipv6";
+ break
Same here.
+ default:
+ type = "unknown";
+ break;
Same here.
+ }
+
+ 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:
+ for (i = 0; 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
+ */
+ if (full_free)
+ virDomainInterfaceFree(ifaces[i]);
Wouldn't it be nicer to move the conditional outside the loop or even:
for (i = 0; full_free && i < ifaces_count; i++) {
Cheers,
-- Guido
+ }
+ 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 +7396,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 *) "virDomainInterfacesAddresses",
libvirt_virDomainInterfacesAddresses, 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
--
libvir-list mailing list
libvir-list(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list