[RFC PATCH] List IPs of VM Ifaces

Signed-off-by: Christy Perez <christy@linux.vnet.ibm.com> --- src/kimchi/model/vmifaces.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/kimchi/model/vmifaces.py b/src/kimchi/model/vmifaces.py index 8bf6b3d..0b1ffe3 100644 --- a/src/kimchi/model/vmifaces.py +++ b/src/kimchi/model/vmifaces.py @@ -25,6 +25,7 @@ from lxml import etree, objectify from kimchi.exception import InvalidParameter, MissingParameter, NotFoundError from kimchi.model.config import CapabilitiesModel from kimchi.model.vms import DOM_STATE_MAP, VMModel +from kimchi.utils import run_command from kimchi.xmlutils.interface import get_iface_xml @@ -122,9 +123,37 @@ class VMIfaceModel(object): info['network'] = iface.source.get('network') if info['type'] == 'bridge': info['bridge'] = iface.source.get('bridge') + info['ips'] = self._get_ips(info['mac'], info['network']) return info + def _get_ips(self, mac, network): + ips = [] + conn = self.conn.get() + # An iface may have multiple IPs + # An IP could have been assigned without libvirt. + # First check the ARP cache. + (stdout, stderr, returncode) = run_command(['arp', '-n']) + if returncode == 0: + ips = [line.split()[0] for line in stdout.splitlines() if mac in line] + # Some ifaces may be inactive, so if the ARP cache didn't have them, + # and they happen to be assigned via DHCP, we can check there too. + try: + net = conn.networkLookupByName(network) + leases = net.DHCPLeases(mac) + for lease in leases: + ip = lease.get('ipaddr') + if ip not in ips: + ips.append(ip) + except libvirt.libvirtError: + pass + + # @TODO: One other option is introspection. It is not, however, + # guaranteed that any host OS would have the same files & commands + # for storing and retreiving IPs. So, this may be as good as we can do. + + return ips + def delete(self, vm, mac): dom = VMModel.get_vm(vm, self.conn) iface = self._get_vmiface(vm, mac) -- 2.1.0

Also know, I do plan on adding doc and tests and test fixes of course. Just getting initial feedback here. Thanks! - Christy On 05/21/2015 12:04 PM, Christy Perez wrote:
Signed-off-by: Christy Perez <christy@linux.vnet.ibm.com> --- src/kimchi/model/vmifaces.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/src/kimchi/model/vmifaces.py b/src/kimchi/model/vmifaces.py index 8bf6b3d..0b1ffe3 100644 --- a/src/kimchi/model/vmifaces.py +++ b/src/kimchi/model/vmifaces.py @@ -25,6 +25,7 @@ from lxml import etree, objectify from kimchi.exception import InvalidParameter, MissingParameter, NotFoundError from kimchi.model.config import CapabilitiesModel from kimchi.model.vms import DOM_STATE_MAP, VMModel +from kimchi.utils import run_command from kimchi.xmlutils.interface import get_iface_xml
@@ -122,9 +123,37 @@ class VMIfaceModel(object): info['network'] = iface.source.get('network') if info['type'] == 'bridge': info['bridge'] = iface.source.get('bridge') + info['ips'] = self._get_ips(info['mac'], info['network'])
return info
+ def _get_ips(self, mac, network): + ips = [] + conn = self.conn.get() + # An iface may have multiple IPs + # An IP could have been assigned without libvirt. + # First check the ARP cache. + (stdout, stderr, returncode) = run_command(['arp', '-n']) + if returncode == 0: + ips = [line.split()[0] for line in stdout.splitlines() if mac in line] + # Some ifaces may be inactive, so if the ARP cache didn't have them, + # and they happen to be assigned via DHCP, we can check there too. + try: + net = conn.networkLookupByName(network) + leases = net.DHCPLeases(mac) + for lease in leases: + ip = lease.get('ipaddr') + if ip not in ips: + ips.append(ip) + except libvirt.libvirtError: + pass + + # @TODO: One other option is introspection. It is not, however, + # guaranteed that any host OS would have the same files & commands + # for storing and retreiving IPs. So, this may be as good as we can do. + + return ips + def delete(self, vm, mac): dom = VMModel.get_vm(vm, self.conn) iface = self._get_vmiface(vm, mac)

Hi Christy, Your patch looks good. I just have one suggestion. There is a python module name scapy that has some ARP methods. On Ubuntu the package is python-scapy. I am not sure it is available in all major Linux distribution, but I think we could take a look on it. Regards, Aline Manera On 21/05/2015 14:04, Christy Perez wrote:
Signed-off-by: Christy Perez <christy@linux.vnet.ibm.com> --- src/kimchi/model/vmifaces.py | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/src/kimchi/model/vmifaces.py b/src/kimchi/model/vmifaces.py index 8bf6b3d..0b1ffe3 100644 --- a/src/kimchi/model/vmifaces.py +++ b/src/kimchi/model/vmifaces.py @@ -25,6 +25,7 @@ from lxml import etree, objectify from kimchi.exception import InvalidParameter, MissingParameter, NotFoundError from kimchi.model.config import CapabilitiesModel from kimchi.model.vms import DOM_STATE_MAP, VMModel +from kimchi.utils import run_command from kimchi.xmlutils.interface import get_iface_xml
@@ -122,9 +123,37 @@ class VMIfaceModel(object): info['network'] = iface.source.get('network') if info['type'] == 'bridge': info['bridge'] = iface.source.get('bridge') + info['ips'] = self._get_ips(info['mac'], info['network'])
return info
+ def _get_ips(self, mac, network): + ips = [] + conn = self.conn.get() + # An iface may have multiple IPs + # An IP could have been assigned without libvirt. + # First check the ARP cache. + (stdout, stderr, returncode) = run_command(['arp', '-n']) + if returncode == 0: + ips = [line.split()[0] for line in stdout.splitlines() if mac in line] + # Some ifaces may be inactive, so if the ARP cache didn't have them, + # and they happen to be assigned via DHCP, we can check there too. + try: + net = conn.networkLookupByName(network) + leases = net.DHCPLeases(mac) + for lease in leases: + ip = lease.get('ipaddr') + if ip not in ips: + ips.append(ip) + except libvirt.libvirtError: + pass + + # @TODO: One other option is introspection. It is not, however, + # guaranteed that any host OS would have the same files & commands + # for storing and retreiving IPs. So, this may be as good as we can do. + + return ips + def delete(self, vm, mac): dom = VMModel.get_vm(vm, self.conn) iface = self._get_vmiface(vm, mac)

On 27-05-2015 13:19, Aline Manera wrote:
Hi Christy,
Your patch looks good.
I just have one suggestion. There is a python module name scapy that has some ARP methods. On Ubuntu the package is python-scapy. I am not sure it is available in all major Linux distribution, but I think we could take a look on it.
Or you could read the file /proc/net/arp. It's pretty much the same output of "arp -n" and it doesn't require new dependencies..

Thanks guys! I'll look into both those. On 05/27/2015 11:21 AM, Crístian Deives wrote:
On 27-05-2015 13:19, Aline Manera wrote:
Hi Christy,
Your patch looks good.
I just have one suggestion. There is a python module name scapy that has some ARP methods. On Ubuntu the package is python-scapy. I am not sure it is available in all major Linux distribution, but I think we could take a look on it.
Or you could read the file /proc/net/arp. It's pretty much the same output of "arp -n" and it doesn't require new dependencies..

On 05/27/2015 11:32 AM, Christy Perez wrote:
Thanks guys! I'll look into both those.
On 05/27/2015 11:21 AM, Crístian Deives wrote:
On 27-05-2015 13:19, Aline Manera wrote:
Hi Christy,
Your patch looks good.
I just have one suggestion. There is a python module name scapy that has some ARP methods. On Ubuntu the package is python-scapy. I am not sure it is available in all major Linux distribution, but I think we could take a look on it.
I looked into the scapy package, and it looks like a *lot* of overhead to get arp cache entries. The documentation's not that great (the scapy website search even hung), so I grepped the source and poked around in layers/l2.py. I couldn't find a straight-forward way to get ARP cache entries. There's a method called getmacbyip, but it looks like it requires some setup:
scapy.layers.l2.getmacbyip('192.168.0.1')
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/site-packages/scapy/layers/l2.py", line 57, in getmacbyip iff,a,gw = conf.route.route(ip) AttributeError: 'NoneType' object has no attribute 'route' So, unless you know there's a simple way to do this and I'm missing it, I don't think this package will actually beneficial to us.
Or you could read the file /proc/net/arp. It's pretty much the same output of "arp -n" and it doesn't require new dependencies..
Is it guaranteed that this file will exist on every distro? This seems to be the simplest way to go.

On 28-05-2015 11:55, Christy Perez wrote:
Or you could read the file /proc/net/arp. It's pretty much the same output of "arp -n" and it doesn't require new dependencies..
Is it guaranteed that this file will exist on every distro? This seems to be the simplest way to go.
AFAIK, yes.
participants (3)
-
Aline Manera
-
Christy Perez
-
Crístian Deives