nixpkgs/pkgs/applications/virtualization/nova/fix-dhcpbridge-output.patch
Eelco Dolstra fbfb7714d0 * Apply an upstream patch to prevent dnsmasq from segfaulting due to
bad data from nova-dhcpbridge.

svn path=/nixpkgs/branches/modular-python/; revision=26661
2011-04-01 15:53:37 +00:00

125 lines
5 KiB
Diff

Prevent dnsmasq from segfaulting.
https://code.launchpad.net/~soren/nova/dnsmasq-leasesfile-init/+merge/52421
diff -ru nova-2011.1.1-orig//bin/nova-dhcpbridge nova-2011.1.1//bin/nova-dhcpbridge
--- nova-2011.1.1-orig//bin/nova-dhcpbridge 2011-02-24 19:51:54.000000000 +0100
+++ nova-2011.1.1//bin/nova-dhcpbridge 2011-04-01 17:49:53.848659259 +0200
@@ -94,7 +94,7 @@
"""Get the list of hosts for an interface."""
ctxt = context.get_admin_context()
network_ref = db.network_get_by_bridge(ctxt, interface)
- return linux_net.get_dhcp_hosts(ctxt, network_ref['id'])
+ return linux_net.get_dhcp_leases(ctxt, network_ref['id'])
def main():
diff -ru nova-2011.1.1-orig//nova/network/linux_net.py nova-2011.1.1//nova/network/linux_net.py
--- nova-2011.1.1-orig//nova/network/linux_net.py 2011-02-24 19:51:54.000000000 +0100
+++ nova-2011.1.1//nova/network/linux_net.py 2011-04-01 17:50:37.315585644 +0200
@@ -18,6 +18,7 @@
"""
import os
+import calendar
from nova import db
from nova import flags
@@ -48,6 +49,8 @@
'location of nova-dhcpbridge')
flags.DEFINE_string('routing_source_ip', '$my_ip',
'Public IP of network host')
+flags.DEFINE_integer('dhcp_lease_time', 120,
+ 'Lifetime of a DHCP lease')
flags.DEFINE_bool('use_nova_chains', False,
'use the nova_ routing chains instead of default')
@@ -218,8 +221,17 @@
_confirm_rule("FORWARD", "-j nova-local")
+def get_dhcp_leases(context, network_id):
+ """Return a network's hosts config in dnsmasq leasefile format"""
+ hosts = []
+ for fixed_ip_ref in db.network_get_associated_fixed_ips(context,
+ network_id):
+ hosts.append(_host_lease(fixed_ip_ref))
+ return '\n'.join(hosts)
+
+
def get_dhcp_hosts(context, network_id):
- """Get a string containing a network's hosts config in dnsmasq format"""
+ """Get a string containing a network's hosts config in dhcp-host format"""
hosts = []
for fixed_ip_ref in db.network_get_associated_fixed_ips(context,
network_id):
@@ -310,8 +322,24 @@
utils.get_my_linklocal(network_ref['bridge'])})
+def _host_lease(fixed_ip_ref):
+ """Return a host string for an address in leasefile format"""
+ instance_ref = fixed_ip_ref['instance']
+ if instance_ref['updated_at']:
+ timestamp = instance_ref['updated_at']
+ else:
+ timestamp = instance_ref['created_at']
+
+ seconds_since_epoch = calendar.timegm(timestamp.utctimetuple())
+
+ return "%d %s %s %s *" % (seconds_since_epoch + FLAGS.dhcp_lease_time,
+ instance_ref['mac_address'],
+ fixed_ip_ref['address'],
+ instance_ref['hostname'] or '*')
+
+
def _host_dhcp(fixed_ip_ref):
- """Return a host string for an address"""
+ """Return a host string for an address in dhcp-host format"""
instance_ref = fixed_ip_ref['instance']
return "%s,%s.novalocal,%s" % (instance_ref['mac_address'],
instance_ref['hostname'],
diff -ru nova-2011.1.1-orig//nova/tests/test_network.py nova-2011.1.1//nova/tests/test_network.py
--- nova-2011.1.1-orig//nova/tests/test_network.py 2011-02-24 19:51:54.000000000 +0100
+++ nova-2011.1.1//nova/tests/test_network.py 2011-04-01 17:49:53.849659365 +0200
@@ -20,6 +20,7 @@
"""
import IPy
import os
+import time
from nova import context
from nova import db
@@ -320,6 +321,31 @@
network['id'])
self.assertEqual(ip_count, num_available_ips)
+ def test_dhcp_lease_output(self):
+ admin_ctxt = context.get_admin_context()
+ address = self._create_address(0, self.instance_id)
+ lease_ip(address)
+ network_ref = db.network_get_by_instance(admin_ctxt, self.instance_id)
+ leases = linux_net.get_dhcp_leases(context.get_admin_context(),
+ network_ref['id'])
+ for line in leases.split('\n'):
+ seconds, mac, ip, hostname, client_id = line.split(' ')
+ self.assertTrue(int(seconds) > time.time(), 'Lease expires in '
+ 'the past')
+ octets = mac.split(':')
+ self.assertEqual(len(octets), 6, "Wrong number of octets "
+ "in %s" % (max,))
+ for octet in octets:
+ self.assertEqual(len(octet), 2, "Oddly sized octet: %s"
+ % (octet,))
+ # This will throw an exception if the octet is invalid
+ int(octet, 16)
+
+ # And this will raise an exception in case of an invalid IP
+ IPy.IP(ip)
+
+ release_ip(address)
+
def is_allocated_in_project(address, project_id):
"""Returns true if address is in specified project"""