diff options
| author | Christian Berendt <berendt@betacloud-solutions.de> | 2016-10-14 12:55:26 +0200 |
|---|---|---|
| committer | Christian Berendt <berendt@betacloud-solutions.de> | 2016-10-14 12:57:49 +0200 |
| commit | b725bd09dd73edf22bdd67bd13359e2a7d8b0796 (patch) | |
| tree | b088b5f48a51df9dfb40938b1f573f0b6f1685d5 /contrib/dev/vagrant/newest_dhcp_lease.py | |
| parent | dbf05f076fb2394439afcee95de3922a83f92219 (diff) | |
| download | kolla-b725bd09dd73edf22bdd67bd13359e2a7d8b0796.tar.gz kolla-b725bd09dd73edf22bdd67bd13359e2a7d8b0796.zip | |
Move demos and dev directory into a new contrib directory
TrivialFix
Change-Id: Ifb8f19afa1514488bd288670d08b96f84982a4e1
Diffstat (limited to 'contrib/dev/vagrant/newest_dhcp_lease.py')
| -rw-r--r-- | contrib/dev/vagrant/newest_dhcp_lease.py | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/contrib/dev/vagrant/newest_dhcp_lease.py b/contrib/dev/vagrant/newest_dhcp_lease.py new file mode 100644 index 000000000..bb229af1d --- /dev/null +++ b/contrib/dev/vagrant/newest_dhcp_lease.py @@ -0,0 +1,134 @@ +#!/usr/bin/env python + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Command-line utility to get the IP address from the newest DHCP lease. + +It's written for using with vagrant-hostmanager and vagrant-libvirt plugins. +Vagrant-hostmanager by default fetches only IP addresses from eth0 interfaces +on VM-s. Therefore, the first purpose of this utility is to be able to fetch +the address also from the other interfaces. + +Libvirt/virsh only lists all DHCP leases for the given network with timestamps. +DHCP leases have their expiration time, but are not cleaned up after destroying +VM. If someone destroys and sets up the VM with the same hostname, we have +many DHCP leases for the same hostname and we have to look up for timestamp. +That's the second purpose of this script. +""" + +import argparse +import csv +import functools +import operator +import xml.etree.ElementTree as etree + +import libvirt + + +class NoPrivateDHCPInterfaceException(Exception): + pass + + +class NoDHCPLeaseException(Exception): + pass + + +def libvirt_conn(f): + @functools.wraps(f) + def wrapper(*args, **kwargs): + conn = libvirt.openReadOnly('qemu:///system') + return f(conn, *args, **kwargs) + return wrapper + + +@libvirt_conn +def get_vir_network_dhcp_lease(conn, vm_name): + """Libvirt since 1.2.6 version provides DHCPLeases method in virNetwork. + + That's the current official way for getting DHCP leases and this + information isn't stored anywhere else anymore. + """ + domain_name = 'vagrant_' + vm_name + mac_address = get_mac_address(conn, domain_name) + + network = conn.networkLookupByName('vagrant-private-dhcp') + dhcp_leases = libvirt.virNetwork.DHCPLeases(network) + + vm_dhcp_leases = [lease for lease in dhcp_leases + if lease['mac'] == mac_address] + + newest_vm_dhcp_lease = sorted(vm_dhcp_leases, + key=operator.itemgetter('expirytime'), + reverse=True)[0]['ipaddr'] + return newest_vm_dhcp_lease + + +def get_mac_address(conn, domain_name): + """Get MAC address from domain XML.""" + domain = conn.lookupByName(domain_name) + domain_xml = domain.XMLDesc() + domain_tree = etree.fromstring(domain_xml) + devices = domain_tree.find('devices') + interfaces = devices.iterfind('interface') + + for interface in interfaces: + source = interface.find('source') + if source is None or source.get('network') != 'vagrant-private-dhcp': + continue + mac_element = interface.find('mac') + mac_address = mac_element.get('address') + return mac_address + + raise NoPrivateDHCPInterfaceException() + + +@libvirt_conn +def get_dnsmasq_dhcp_lease(conn, vm_name): + """In libvirt under 1.2.6 DHCP leases are stored in file. + + There is no API for DHCP leases yet. + """ + domain_name = 'vagrant_' + vm_name + mac_address = get_mac_address(conn, domain_name) + + with open( + '/var/lib/libvirt/dnsmasq/vagrant-private-dhcp.leases' + ) as leases_file: + reader = csv.reader(leases_file, delimiter=' ') + for row in reader: + lease_mac, lease_ip, lease_vm_name = row[1:4] + if not (lease_mac == mac_address and lease_vm_name == vm_name): + continue + return lease_ip + + raise NoDHCPLeaseException() + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('vm_name', help='Name of the virtual machine') + + args = parser.parse_args() + vm_name = args.vm_name + + if libvirt.getVersion() >= 1002006: + newest_dhcp_lease = get_vir_network_dhcp_lease(vm_name) + else: + newest_dhcp_lease = get_dnsmasq_dhcp_lease(vm_name) + + print(newest_dhcp_lease) + + +if __name__ == '__main__': + main() |
