Browse Source

[libvirt cluster] Use net-dhcp-leases to find VMs’ IPs

Query libvirt’s DHCP leases rather than inspecting the host’s ARP cache
to find the VMs’ IPs.
Lénaïc Huard 10 years ago
parent
commit
4e8f6d1923

+ 7 - 19
inventory/libvirt/hosts/libvirt_generic.py

@@ -113,8 +113,6 @@ class LibvirtInventory(object):
             print "Failed to list domains for connection %s" % libvirt_uri
             sys.exit(1)
 
-        arp_entries = self.parse_arp_entries()
-
         for domain in domains:
             hostvars = dict(libvirt_name=domain.name(),
                             libvirt_id=domain.ID(),
@@ -140,11 +138,13 @@ class LibvirtInventory(object):
             # interface types other than 'network'
             interface = root.find("./devices/interface[@type='network']")
             if interface is not None:
-                mac_elem = interface.find('mac')
-                if mac_elem is not None:
-                    mac = mac_elem.get('address')
-                    if mac in arp_entries:
-                        ip_address = arp_entries[mac]['ip_address']
+                source_elem = interface.find('source')
+                mac_elem    = interface.find('mac')
+                if source_elem is not None and \
+                   mac_elem    is not None:
+                    dhcp_leases = conn.networkLookupByName(source_elem.get('network')).DHCPLeases(mac_elem.get('address'))
+                    if len(dhcp_leases) > 0:
+                        ip_address = dhcp_leases[0]['ipaddr']
                         hostvars['ansible_ssh_host'] = ip_address
                         hostvars['libvirt_ip_address'] = ip_address
 
@@ -152,18 +152,6 @@ class LibvirtInventory(object):
 
         return inventory
 
-    def parse_arp_entries(self):
-        arp_entries = dict()
-        with open('/proc/net/arp', 'r') as f:
-            # throw away the header
-            f.readline()
-
-            for line in f:
-                ip_address, _, _, mac, _, device = line.strip().split()
-                arp_entries[mac] = dict(ip_address=ip_address, device=device)
-
-        return arp_entries
-
     def push(self, my_dict, key, element):
         if key in my_dict:
             my_dict[key].append(element)

+ 3 - 9
playbooks/libvirt/openshift-cluster/tasks/launch_instances.yml

@@ -58,23 +58,17 @@
     uri: '{{ libvirt_uri }}'
   with_items: instances
 
-- name: Collect MAC addresses of the VMs
-  shell: 'virsh -c {{ libvirt_uri }} dumpxml {{ item }} | xmllint --xpath "string(//domain/devices/interface/mac/@address)" -'
-  register: scratch_mac
-  with_items: instances
-
 - name: Wait for the VMs to get an IP
-  command: "egrep -c '{{ scratch_mac.results | oo_collect('stdout') | join('|') }}' /proc/net/arp"
-  ignore_errors: yes
+  shell: 'virsh net-dhcp-leases openshift-ansible | egrep -c ''{{ instances | join("|") }}'''
   register: nb_allocated_ips
   until: nb_allocated_ips.stdout == '{{ instances | length }}'
   retries: 30
   delay: 1
 
 - name: Collect IP addresses of the VMs
-  shell: "awk '/{{ item.stdout }}/ {print $1}' /proc/net/arp"
+  shell: 'virsh net-dhcp-leases openshift-ansible | awk ''$6 == "{{ item }}" {gsub(/\/.*/, "", $5); print $5}'''
   register: scratch_ip
-  with_items: scratch_mac.results
+  with_items: instances
 
 - set_fact:
     ips: "{{ scratch_ip.results | oo_collect('stdout') }}"