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 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 eth3 52:54:00:20:70:3d ipv4 192.168.105.240/16 eth3 52:54:00:20:70:3d ipv6 fe80::5054:ff:fe20:703d/64 eth2 52:54:00:36:2a:e5 N/A N/A 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 | 57 ++++++++++++++++++++++ python/libvirt-override-api.xml | 8 +++- python/libvirt-override.c | 102 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 168 insertions(+), 2 deletions(-) create mode 100755 examples/python/domipaddrs.py diff --git a/examples/python/Makefile.am b/examples/python/Makefile.am index 7823c20..b77154f 100644 --- a/examples/python/Makefile.am +++ b/examples/python/Makefile.am @@ -18,4 +18,4 @@ EXTRA_DIST= \ README \ consolecallback.py \ topology.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..4430f59 --- /dev/null +++ b/examples/python/domipaddrs.py @@ -0,0 +1,57 @@ +#!/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.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_AGENT); +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['ip_addrs']: + for addr in val['ip_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/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..f288587 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -4761,6 +4761,107 @@ 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(); + int type = ip_addr->type; + + if (!py_addr) { + Py_DECREF(py_iface); + Py_DECREF(py_ip_addrs); + goto no_memory; + } + + 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"), + libvirt_intWrap(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 +7385,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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list