Merge lp:~soren/nova/dnsmasq-leasesfile-init into lp:~hudson-openstack/nova/trunk

Proposed by Soren Hansen
Status: Merged
Approved by: Devin Carlen
Approved revision: 764
Merged at revision: 797
Proposed branch: lp:~soren/nova/dnsmasq-leasesfile-init
Merge into: lp:~hudson-openstack/nova/trunk
Diff against target: 122 lines (+57/-3)
3 files modified
bin/nova-dhcpbridge (+1/-1)
nova/network/linux_net.py (+30/-2)
nova/tests/test_network.py (+26/-0)
To merge this branch: bzr merge lp:~soren/nova/dnsmasq-leasesfile-init
Reviewer Review Type Date Requested Status
Devin Carlen (community) Approve
Jay Pipes (community) Approve
Rick Harris (community) Approve
Josh Kearney (community) Approve
Review via email: mp+52421@code.launchpad.net

Commit message

Make nova-dhcpbridge output lease information in dnsmasq's leasesfile format.

Description of the change

The output from nova-dhcpbridge has been wrong all along, but recently it caused dnsmasq to segfault. It's supposed to be in the format of dnsmasq's leases file, but it's currently in the format of dhcp-hosts.

To post a comment you must log in.
Revision history for this message
Josh Kearney (jk0) wrote :

Looks great!

review: Approve
Revision history for this message
Rick Harris (rconradharris) wrote :

Think we could include a small test with this?

Other than that, looks great.

review: Approve
Revision history for this message
Jay Pipes (jaypipes) wrote :

lgtm.

review: Approve
Revision history for this message
Devin Carlen (devcamcar) wrote :

Agree with Rick. Let's add a test for this so we don't break it again in the future. :)

review: Needs Fixing
763. By Soren Hansen

Add a unit test

Revision history for this message
Soren Hansen (soren) wrote :

Unit test added.

764. By Soren Hansen

Merge trunk

Revision history for this message
Devin Carlen (devcamcar) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bin/nova-dhcpbridge'
--- bin/nova-dhcpbridge 2011-02-23 19:20:52 +0000
+++ bin/nova-dhcpbridge 2011-03-14 13:45:28 +0000
@@ -94,7 +94,7 @@
94 """Get the list of hosts for an interface."""94 """Get the list of hosts for an interface."""
95 ctxt = context.get_admin_context()95 ctxt = context.get_admin_context()
96 network_ref = db.network_get_by_bridge(ctxt, interface)96 network_ref = db.network_get_by_bridge(ctxt, interface)
97 return linux_net.get_dhcp_hosts(ctxt, network_ref['id'])97 return linux_net.get_dhcp_leases(ctxt, network_ref['id'])
9898
9999
100def main():100def main():
101101
=== modified file 'nova/network/linux_net.py'
--- nova/network/linux_net.py 2011-03-11 02:44:01 +0000
+++ nova/network/linux_net.py 2011-03-14 13:45:28 +0000
@@ -19,6 +19,7 @@
1919
20import inspect20import inspect
21import os21import os
22import calendar
2223
23from eventlet import semaphore24from eventlet import semaphore
2425
@@ -56,6 +57,8 @@
56 'Public IP of network host')57 'Public IP of network host')
57flags.DEFINE_string('input_chain', 'INPUT',58flags.DEFINE_string('input_chain', 'INPUT',
58 'chain to add nova_input to')59 'chain to add nova_input to')
60flags.DEFINE_integer('dhcp_lease_time', 120,
61 'Lifetime of a DHCP lease')
5962
60flags.DEFINE_string('dns_server', None,63flags.DEFINE_string('dns_server', None,
61 'if set, uses specific dns server for dnsmasq')64 'if set, uses specific dns server for dnsmasq')
@@ -533,8 +536,17 @@
533 bridge)536 bridge)
534537
535538
539def get_dhcp_leases(context, network_id):
540 """Return a network's hosts config in dnsmasq leasefile format"""
541 hosts = []
542 for fixed_ip_ref in db.network_get_associated_fixed_ips(context,
543 network_id):
544 hosts.append(_host_lease(fixed_ip_ref))
545 return '\n'.join(hosts)
546
547
536def get_dhcp_hosts(context, network_id):548def get_dhcp_hosts(context, network_id):
537 """Get a string containing a network's hosts config in dnsmasq format"""549 """Get a string containing a network's hosts config in dhcp-host format"""
538 hosts = []550 hosts = []
539 for fixed_ip_ref in db.network_get_associated_fixed_ips(context,551 for fixed_ip_ref in db.network_get_associated_fixed_ips(context,
540 network_id):552 network_id):
@@ -625,8 +637,24 @@
625 utils.get_my_linklocal(network_ref['bridge'])})637 utils.get_my_linklocal(network_ref['bridge'])})
626638
627639
640def _host_lease(fixed_ip_ref):
641 """Return a host string for an address in leasefile format"""
642 instance_ref = fixed_ip_ref['instance']
643 if instance_ref['updated_at']:
644 timestamp = instance_ref['updated_at']
645 else:
646 timestamp = instance_ref['created_at']
647
648 seconds_since_epoch = calendar.timegm(timestamp.utctimetuple())
649
650 return "%d %s %s %s *" % (seconds_since_epoch + FLAGS.dhcp_lease_time,
651 instance_ref['mac_address'],
652 fixed_ip_ref['address'],
653 instance_ref['hostname'] or '*')
654
655
628def _host_dhcp(fixed_ip_ref):656def _host_dhcp(fixed_ip_ref):
629 """Return a host string for an address"""657 """Return a host string for an address in dhcp-host format"""
630 instance_ref = fixed_ip_ref['instance']658 instance_ref = fixed_ip_ref['instance']
631 return "%s,%s.%s,%s" % (instance_ref['mac_address'],659 return "%s,%s.%s,%s" % (instance_ref['mac_address'],
632 instance_ref['hostname'],660 instance_ref['hostname'],
633661
=== modified file 'nova/tests/test_network.py'
--- nova/tests/test_network.py 2011-03-09 22:39:12 +0000
+++ nova/tests/test_network.py 2011-03-14 13:45:28 +0000
@@ -20,6 +20,7 @@
20"""20"""
21import IPy21import IPy
22import os22import os
23import time
2324
24from nova import context25from nova import context
25from nova import db26from nova import db
@@ -463,6 +464,31 @@
463 network['id'])464 network['id'])
464 self.assertEqual(ip_count, num_available_ips)465 self.assertEqual(ip_count, num_available_ips)
465466
467 def test_dhcp_lease_output(self):
468 admin_ctxt = context.get_admin_context()
469 address = self._create_address(0, self.instance_id)
470 lease_ip(address)
471 network_ref = db.network_get_by_instance(admin_ctxt, self.instance_id)
472 leases = linux_net.get_dhcp_leases(context.get_admin_context(),
473 network_ref['id'])
474 for line in leases.split('\n'):
475 seconds, mac, ip, hostname, client_id = line.split(' ')
476 self.assertTrue(int(seconds) > time.time(), 'Lease expires in '
477 'the past')
478 octets = mac.split(':')
479 self.assertEqual(len(octets), 6, "Wrong number of octets "
480 "in %s" % (max,))
481 for octet in octets:
482 self.assertEqual(len(octet), 2, "Oddly sized octet: %s"
483 % (octet,))
484 # This will throw an exception if the octet is invalid
485 int(octet, 16)
486
487 # And this will raise an exception in case of an invalid IP
488 IPy.IP(ip)
489
490 release_ip(address)
491
466492
467def is_allocated_in_project(address, project_id):493def is_allocated_in_project(address, project_id):
468 """Returns true if address is in specified project"""494 """Returns true if address is in specified project"""