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
1=== modified file 'bin/nova-dhcpbridge'
2--- bin/nova-dhcpbridge 2011-02-23 19:20:52 +0000
3+++ bin/nova-dhcpbridge 2011-03-14 13:45:28 +0000
4@@ -94,7 +94,7 @@
5 """Get the list of hosts for an interface."""
6 ctxt = context.get_admin_context()
7 network_ref = db.network_get_by_bridge(ctxt, interface)
8- return linux_net.get_dhcp_hosts(ctxt, network_ref['id'])
9+ return linux_net.get_dhcp_leases(ctxt, network_ref['id'])
10
11
12 def main():
13
14=== modified file 'nova/network/linux_net.py'
15--- nova/network/linux_net.py 2011-03-11 02:44:01 +0000
16+++ nova/network/linux_net.py 2011-03-14 13:45:28 +0000
17@@ -19,6 +19,7 @@
18
19 import inspect
20 import os
21+import calendar
22
23 from eventlet import semaphore
24
25@@ -56,6 +57,8 @@
26 'Public IP of network host')
27 flags.DEFINE_string('input_chain', 'INPUT',
28 'chain to add nova_input to')
29+flags.DEFINE_integer('dhcp_lease_time', 120,
30+ 'Lifetime of a DHCP lease')
31
32 flags.DEFINE_string('dns_server', None,
33 'if set, uses specific dns server for dnsmasq')
34@@ -533,8 +536,17 @@
35 bridge)
36
37
38+def get_dhcp_leases(context, network_id):
39+ """Return a network's hosts config in dnsmasq leasefile format"""
40+ hosts = []
41+ for fixed_ip_ref in db.network_get_associated_fixed_ips(context,
42+ network_id):
43+ hosts.append(_host_lease(fixed_ip_ref))
44+ return '\n'.join(hosts)
45+
46+
47 def get_dhcp_hosts(context, network_id):
48- """Get a string containing a network's hosts config in dnsmasq format"""
49+ """Get a string containing a network's hosts config in dhcp-host format"""
50 hosts = []
51 for fixed_ip_ref in db.network_get_associated_fixed_ips(context,
52 network_id):
53@@ -625,8 +637,24 @@
54 utils.get_my_linklocal(network_ref['bridge'])})
55
56
57+def _host_lease(fixed_ip_ref):
58+ """Return a host string for an address in leasefile format"""
59+ instance_ref = fixed_ip_ref['instance']
60+ if instance_ref['updated_at']:
61+ timestamp = instance_ref['updated_at']
62+ else:
63+ timestamp = instance_ref['created_at']
64+
65+ seconds_since_epoch = calendar.timegm(timestamp.utctimetuple())
66+
67+ return "%d %s %s %s *" % (seconds_since_epoch + FLAGS.dhcp_lease_time,
68+ instance_ref['mac_address'],
69+ fixed_ip_ref['address'],
70+ instance_ref['hostname'] or '*')
71+
72+
73 def _host_dhcp(fixed_ip_ref):
74- """Return a host string for an address"""
75+ """Return a host string for an address in dhcp-host format"""
76 instance_ref = fixed_ip_ref['instance']
77 return "%s,%s.%s,%s" % (instance_ref['mac_address'],
78 instance_ref['hostname'],
79
80=== modified file 'nova/tests/test_network.py'
81--- nova/tests/test_network.py 2011-03-09 22:39:12 +0000
82+++ nova/tests/test_network.py 2011-03-14 13:45:28 +0000
83@@ -20,6 +20,7 @@
84 """
85 import IPy
86 import os
87+import time
88
89 from nova import context
90 from nova import db
91@@ -463,6 +464,31 @@
92 network['id'])
93 self.assertEqual(ip_count, num_available_ips)
94
95+ def test_dhcp_lease_output(self):
96+ admin_ctxt = context.get_admin_context()
97+ address = self._create_address(0, self.instance_id)
98+ lease_ip(address)
99+ network_ref = db.network_get_by_instance(admin_ctxt, self.instance_id)
100+ leases = linux_net.get_dhcp_leases(context.get_admin_context(),
101+ network_ref['id'])
102+ for line in leases.split('\n'):
103+ seconds, mac, ip, hostname, client_id = line.split(' ')
104+ self.assertTrue(int(seconds) > time.time(), 'Lease expires in '
105+ 'the past')
106+ octets = mac.split(':')
107+ self.assertEqual(len(octets), 6, "Wrong number of octets "
108+ "in %s" % (max,))
109+ for octet in octets:
110+ self.assertEqual(len(octet), 2, "Oddly sized octet: %s"
111+ % (octet,))
112+ # This will throw an exception if the octet is invalid
113+ int(octet, 16)
114+
115+ # And this will raise an exception in case of an invalid IP
116+ IPy.IP(ip)
117+
118+ release_ip(address)
119+
120
121 def is_allocated_in_project(address, project_id):
122 """Returns true if address is in specified project"""