summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Hrdina <phrdina@redhat.com>2015-03-28 11:21:56 +0100
committerPavel Hrdina <phrdina@redhat.com>2015-03-28 11:21:56 +0100
commit0be1f5e31a06af9d93d5de73242de7f263cc5c3d (patch)
tree5f360af7781f543dbecc4f8047419d9d53033107
parente1e9b270965a94ce703d9cb2a458824877a77cf0 (diff)
downloadlibvirt-python-0be1f5e31a06af9d93d5de73242de7f263cc5c3d.tar.gz
Expose virDomainInterfacesAddresses to python bindingv1.2.14
examples/Makefile.am: * Add new file domipaddrs.py examples/README: * Add documentation for the python example libvirt-override-api.xml: * Add new symbol for virDomainInterfacesAddresses libvirt-override.c: * Hand written python api Example: $ python examples/domipaddrs.py qemu:///system f18 Interface MAC address Protocol Address vnet0 52:54:00:20:70:3d ipv4 192.168.105.240/16 Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
-rw-r--r--MANIFEST.in1
-rw-r--r--examples/README1
-rwxr-xr-xexamples/domipaddrs.py57
-rwxr-xr-xgenerator.py2
-rw-r--r--libvirt-override-api.xml7
-rw-r--r--libvirt-override.c128
-rw-r--r--sanitytest.py3
7 files changed, 199 insertions, 0 deletions
diff --git a/MANIFEST.in b/MANIFEST.in
index d7bc545..dd05221 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -4,6 +4,7 @@ include COPYING
include COPYING.LESSER
include ChangeLog
include examples/consolecallback.py
+include examples/domipaddrs.py
include examples/dominfo.py
include examples/domrestore.py
include examples/domsave.py
diff --git a/examples/README b/examples/README
index 5b5d405..1d4b425 100644
--- a/examples/README
+++ b/examples/README
@@ -11,6 +11,7 @@ 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
dhcpleases.py - list dhcp leases for a given virtual network
+domipaddrs.py - list IP addresses for guest domains
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/domipaddrs.py b/examples/domipaddrs.py
new file mode 100755
index 0000000..d6d5cac
--- /dev/null
+++ b/examples/domipaddrs.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# domipaddrs - 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.open(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(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE);
+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")
+
+def toIPAddrType(addrType):
+ if addrType == libvirt.VIR_IP_ADDR_TYPE_IPV4:
+ return "ipv4"
+ elif addrType == libvirt.VIR_IP_ADDR_TYPE_IPV6:
+ return "ipv6"
+
+for (name, val) in ifaces.iteritems():
+ if val['addrs']:
+ for addr in val['addrs']:
+ print " {0:10} {1:19}".format(name, val['hwaddr']),
+ print " {0:12} {1}/{2} ".format(toIPAddrType(addr['type']), addr['addr'], addr['prefix']),
+ print
+ else:
+ print " {0:10} {1:19}".format(name, val['hwaddr']),
+ print " {0:12} {1}".format("N/A", "N/A"),
+ print
diff --git a/generator.py b/generator.py
index 729daa2..78082e8 100755
--- a/generator.py
+++ b/generator.py
@@ -483,6 +483,7 @@ skip_impl = (
'virDomainBlockCopy',
'virNodeAllocPages',
'virDomainGetFSInfo',
+ 'virDomainInterfaceAddresses',
)
lxc_skip_impl = (
@@ -595,6 +596,7 @@ skip_function = (
'virDomainStatsRecordListFree', # only useful in C, python uses dict
'virDomainFSInfoFree', # only useful in C, python code uses list
'virDomainIOThreadInfoFree', # only useful in C, python code uses list
+ 'virDomainInterfaceFree', # only useful in C, python code uses list
)
lxc_skip_function = (
diff --git a/libvirt-override-api.xml b/libvirt-override-api.xml
index cf46090..d1a9c26 100644
--- a/libvirt-override-api.xml
+++ b/libvirt-override-api.xml
@@ -678,5 +678,12 @@
<arg name='flags' type='unsigned int' info='unused, pass 0'/>
<return type='char *' info="list of mounted filesystems information"/>
</function>
+ <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='source' type='unsigned int' info='the data source'/>
+ <arg name='flags' type='unsigned int' info='extra flags; not used yet, so callers should always pass 0'/>
+ <return type='char *' info="dictionary of domain interfaces along with their MAC and IP addresses"/>
+ </function>
</symbols>
</api>
diff --git a/libvirt-override.c b/libvirt-override.c
index 0699ae3..f770ffe 100644
--- a/libvirt-override.c
+++ b/libvirt-override.c
@@ -5120,6 +5120,131 @@ cleanup:
return py_retval;
}
+
+#if LIBVIR_CHECK_VERSION(1, 2, 14)
+static PyObject *
+libvirt_virDomainInterfaceAddresses(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args)
+{
+ PyObject *py_retval = VIR_PY_NONE;
+ PyObject *pyobj_domain;
+ virDomainPtr domain;
+ virDomainInterfacePtr *ifaces = NULL;
+ unsigned int source;
+ unsigned int flags;
+ int ifaces_count = 0;
+ size_t i, j;
+
+ if (!PyArg_ParseTuple(args, (char *) "Oii:virDomainInterfaceAddresses",
+ &pyobj_domain, &source, &flags))
+ goto error;
+
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ ifaces_count = virDomainInterfaceAddresses(domain, &ifaces, source, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (ifaces_count < 0)
+ goto cleanup;
+
+ if (!(py_retval = PyDict_New()))
+ goto error;
+
+ for (i = 0; i < ifaces_count; i++) {
+ virDomainInterfacePtr iface = ifaces[i];
+ PyObject *py_addrs = NULL;
+ PyObject *py_iface = NULL;
+ PyObject *py_iname = NULL;
+ PyObject *py_ivalue = NULL;
+
+ if (!(py_iface = PyDict_New()))
+ goto error;
+
+ if ((py_iname = libvirt_charPtrWrap(iface->name)) == NULL ||
+ PyDict_SetItem(py_retval, py_iname, py_iface) < 0) {
+ Py_XDECREF(py_iname);
+ Py_DECREF(py_iface);
+ goto error;
+ }
+
+ if (iface->naddrs) {
+ if (!(py_addrs = PyList_New(iface->naddrs))) {
+ goto error;
+ }
+ } else {
+ py_addrs = VIR_PY_NONE;
+ }
+
+ if ((py_iname = libvirt_constcharPtrWrap("addrs")) == NULL ||
+ PyDict_SetItem(py_iface, py_iname, py_addrs) < 0) {
+ Py_XDECREF(py_iname);
+ Py_DECREF(py_addrs);
+ goto error;
+ }
+
+ if ((py_iname = libvirt_constcharPtrWrap("hwaddr")) == NULL ||
+ (py_ivalue = libvirt_constcharPtrWrap(iface->hwaddr)) == NULL ||
+ PyDict_SetItem(py_iface, py_iname, py_ivalue) < 0) {
+ Py_XDECREF(py_iname);
+ Py_XDECREF(py_ivalue);
+ goto error;
+ }
+
+ for (j = 0; j < iface->naddrs; j++) {
+ virDomainIPAddressPtr addr = &(iface->addrs[j]);
+ PyObject *py_addr = PyDict_New();
+
+ if (!py_addr)
+ goto error;
+
+ if (PyList_SetItem(py_addrs, j, py_addr) < 0) {
+ Py_DECREF(py_addr);
+ goto error;
+ }
+
+ if ((py_iname = libvirt_constcharPtrWrap("addr")) == NULL ||
+ (py_ivalue = libvirt_constcharPtrWrap(addr->addr)) == NULL ||
+ PyDict_SetItem(py_addr, py_iname, py_ivalue) < 0) {
+ Py_XDECREF(py_iname);
+ Py_XDECREF(py_ivalue);
+ goto error;
+ }
+ if ((py_iname = libvirt_constcharPtrWrap("prefix")) == NULL ||
+ (py_ivalue = libvirt_intWrap(addr->prefix)) == NULL ||
+ PyDict_SetItem(py_addr, py_iname, py_ivalue) < 0) {
+ Py_XDECREF(py_iname);
+ Py_XDECREF(py_ivalue);
+ goto error;
+ }
+ if ((py_iname = libvirt_constcharPtrWrap("type")) == NULL ||
+ (py_ivalue = libvirt_intWrap(addr->type)) == NULL ||
+ PyDict_SetItem(py_addr, py_iname, py_ivalue) < 0) {
+ Py_XDECREF(py_iname);
+ Py_XDECREF(py_ivalue);
+ goto error;
+ }
+ }
+ }
+
+cleanup:
+ if (ifaces && ifaces_count > 0) {
+ for (i = 0; i < ifaces_count; i++) {
+ virDomainInterfaceFree(ifaces[i]);
+ }
+ }
+ VIR_FREE(ifaces);
+
+ return py_retval;
+
+error:
+ Py_XDECREF(py_retval);
+ py_retval = NULL;
+ goto cleanup;
+}
+#endif /* LIBVIR_CHECK_VERSION(1, 2, 14) */
+
+
/*******************************************
* Helper functions to avoid importing modules
* for every callback
@@ -8750,6 +8875,9 @@ static PyMethodDef libvirtMethods[] = {
#if LIBVIR_CHECK_VERSION(1, 2, 11)
{(char *) "virDomainGetFSInfo", libvirt_virDomainGetFSInfo, METH_VARARGS, NULL},
#endif /* LIBVIR_CHECK_VERSION(1, 2, 11) */
+#if LIBVIR_CHECK_VERSION(1, 2, 14)
+ {(char *) "virDomainInterfaceAddresses", libvirt_virDomainInterfaceAddresses, METH_VARARGS, NULL},
+#endif /* LIBVIR_CHECK_VERSION(1, 2, 14) */
{NULL, NULL, 0, NULL}
};
diff --git a/sanitytest.py b/sanitytest.py
index db65a6d..eb44cdb 100644
--- a/sanitytest.py
+++ b/sanitytest.py
@@ -145,6 +145,9 @@ for cname in wantfunctions:
if name[0:25] == "virDomainIOThreadInfoFree":
continue
+ if name[0:22] == "virDomainInterfaceFree":
+ continue
+
if name[0:21] == "virDomainListGetStats":
name = "virConnectDomainListGetStats"