From 0b396e1315a76112ab978a677e96d7b3a371faa9 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 15 Jul 2010 23:11:33 +0000 Subject: Fixes to dhcp lease code to use a flagfile --- bin/dhcpleasor.py | 90 ---------------------------------------- bin/nova-dhcpbridge | 94 ++++++++++++++++++++++++++++++++++++++++++ debian/nova-api.conf | 3 +- debian/nova-api.install | 1 + debian/nova-compute.conf | 2 - debian/nova-dhcp.conf | 2 + debian/nova-objectstore.conf | 1 - debian/nova-volume.conf | 1 - nova/compute/linux_net.py | 16 ++++--- nova/compute/network.py | 6 +-- nova/tests/network_unittest.py | 23 +++++++---- 11 files changed, 127 insertions(+), 112 deletions(-) delete mode 100755 bin/dhcpleasor.py create mode 100755 bin/nova-dhcpbridge create mode 100644 debian/nova-dhcp.conf diff --git a/bin/dhcpleasor.py b/bin/dhcpleasor.py deleted file mode 100755 index 31f4433fb..000000000 --- a/bin/dhcpleasor.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# 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. - -""" -dhcpleasor.py - -Handle lease database updates from DHCP servers. -""" - -import sys -import os -import logging -sys.path.append(os.path.abspath(os.path.join(__file__, "../../"))) - -logging.debug(sys.path) -import getopt -from os import environ -from nova.compute import linux_net -from nova.compute import network -from nova import rpc - -from nova import flags -FLAGS = flags.FLAGS - - -def add_lease(mac, ip, hostname, interface): - if FLAGS.fake_rabbit: - network.lease_ip(ip) - else: - rpc.cast(FLAGS.cloud_topic, {"method": "lease_ip", - "args" : {"address": ip}}) - -def old_lease(mac, ip, hostname, interface): - logging.debug("Adopted old lease or got a change of mac/hostname") - -def del_lease(mac, ip, hostname, interface): - if FLAGS.fake_rabbit: - network.release_ip(ip) - else: - rpc.cast(FLAGS.cloud_topic, {"method": "release_ip", - "args" : {"address": ip}}) - -def init_leases(interface): - net = network.get_network_by_interface(interface) - res = "" - for host_name in net.hosts: - res += "%s\n" % linux_net.hostDHCP(net, host_name, net.hosts[host_name]) - return res - - -def main(argv=None): - if argv is None: - argv = sys.argv - interface = environ.get('DNSMASQ_INTERFACE', 'br0') - if int(environ.get('TESTING', '0')): - FLAGS.fake_rabbit = True - FLAGS.redis_db = 8 - FLAGS.network_size = 32 - FLAGS.fake_libvirt=True - FLAGS.fake_network=True - FLAGS.fake_users = True - action = argv[1] - if action in ['add','del','old']: - mac = argv[2] - ip = argv[3] - hostname = argv[4] - logging.debug("Called %s for mac %s with ip %s and hostname %s on interface %s" % (action, mac, ip, hostname, interface)) - globals()[action+'_lease'](mac, ip, hostname, interface) - else: - print init_leases(interface) - exit(0) - -if __name__ == "__main__": - sys.exit(main()) diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge new file mode 100755 index 000000000..cd0eab2a8 --- /dev/null +++ b/bin/nova-dhcpbridge @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 United States Government as represented by the +# Administrator of the National Aeronautics and Space Administration. +# All Rights Reserved. +# +# 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. + +""" +nova-dhcpbridge + +Handle lease database updates from DHCP servers. +""" + +import logging +import os +import sys + +#TODO(joshua): there is concern that the user dnsmasq runs under will not +# have nova in the path. This should be verified and if it is +# not true the ugly line below can be removed +sys.path.append(os.path.abspath(os.path.join(__file__, "../../"))) + +from nova import rpc +from nova import utils + +from nova.compute import linux_net +from nova.compute import network + +from nova import flags +FLAGS = flags.FLAGS + + +def add_lease(mac, ip, hostname, interface): + if FLAGS.fake_rabbit: + network.lease_ip(ip) + else: + rpc.cast(FLAGS.cloud_topic, {"method": "lease_ip", + "args" : {"address": ip}}) + +def old_lease(mac, ip, hostname, interface): + logging.debug("Adopted old lease or got a change of mac/hostname") + +def del_lease(mac, ip, hostname, interface): + if FLAGS.fake_rabbit: + network.release_ip(ip) + else: + rpc.cast(FLAGS.cloud_topic, {"method": "release_ip", + "args" : {"address": ip}}) + +def init_leases(interface): + net = network.get_network_by_interface(interface) + res = "" + for host_name in net.hosts: + res += "%s\n" % linux_net.hostDHCP(net, host_name, net.hosts[host_name]) + return res + + +def main(): + flagfile = os.environ.get('FLAGFILE', FLAGS.dhcpbridge_flagfile) + utils.default_flagfile(flagfile) + argv = FLAGS(sys.argv) + interface = os.environ.get('DNSMASQ_INTERFACE', 'br0') + if int(os.environ.get('TESTING', '0')): + FLAGS.fake_rabbit = True + FLAGS.redis_db = 8 + FLAGS.network_size = 32 + FLAGS.fake_libvirt=True + FLAGS.fake_network=True + FLAGS.fake_users = True + action = argv[1] + if action in ['add','del','old']: + mac = argv[2] + ip = argv[3] + hostname = argv[4] + logging.debug("Called %s for mac %s with ip %s and hostname %s on interface %s" % (action, mac, ip, hostname, interface)) + globals()[action+'_lease'](mac, ip, hostname, interface) + else: + print init_leases(interface) + exit(0) + +if __name__ == "__main__": + sys.exit(main()) diff --git a/debian/nova-api.conf b/debian/nova-api.conf index 9cd4051b1..d0b796878 100644 --- a/debian/nova-api.conf +++ b/debian/nova-api.conf @@ -1,5 +1,6 @@ --daemonize=1 --ca_path=/var/lib/nova/CA --keys_path=/var/lib/nova/keys +--networks_path=/var/lib/nova/networks +--dhcpbridge_flagfile=/etc/nova/nova-dhcpbridge.conf --fake_users=1 ---datastore_path=/var/lib/nova/keeper diff --git a/debian/nova-api.install b/debian/nova-api.install index 02dbda02d..89615d302 100644 --- a/debian/nova-api.install +++ b/debian/nova-api.install @@ -1,2 +1,3 @@ bin/nova-api usr/bin debian/nova-api.conf etc/nova +debian/nova-dhcpbridge.conf etc/nova diff --git a/debian/nova-compute.conf b/debian/nova-compute.conf index e4ca3fe95..d862f2328 100644 --- a/debian/nova-compute.conf +++ b/debian/nova-compute.conf @@ -1,8 +1,6 @@ --ca_path=/var/lib/nova/CA --keys_path=/var/lib/nova/keys ---datastore_path=/var/lib/nova/keeper --instances_path=/var/lib/nova/instances ---networks_path=/var/lib/nova/networks --simple_network_template=/usr/share/nova/interfaces.template --libvirt_xml_template=/usr/share/nova/libvirt.xml.template --vpn_client_template=/usr/share/nova/client.ovpn.template diff --git a/debian/nova-dhcp.conf b/debian/nova-dhcp.conf new file mode 100644 index 000000000..0aafe7549 --- /dev/null +++ b/debian/nova-dhcp.conf @@ -0,0 +1,2 @@ +--networks_path=/var/lib/nova/networks +--fake_users=1 diff --git a/debian/nova-objectstore.conf b/debian/nova-objectstore.conf index af3271d3b..03f5df051 100644 --- a/debian/nova-objectstore.conf +++ b/debian/nova-objectstore.conf @@ -1,7 +1,6 @@ --daemonize=1 --ca_path=/var/lib/nova/CA --keys_path=/var/lib/nova/keys ---datastore_path=/var/lib/nova/keeper --fake_users=1 --images_path=/var/lib/nova/images --buckets_path=/var/lib/nova/buckets diff --git a/debian/nova-volume.conf b/debian/nova-volume.conf index af3271d3b..03f5df051 100644 --- a/debian/nova-volume.conf +++ b/debian/nova-volume.conf @@ -1,7 +1,6 @@ --daemonize=1 --ca_path=/var/lib/nova/CA --keys_path=/var/lib/nova/keys ---datastore_path=/var/lib/nova/keeper --fake_users=1 --images_path=/var/lib/nova/images --buckets_path=/var/lib/nova/buckets diff --git a/nova/compute/linux_net.py b/nova/compute/linux_net.py index 358f184af..2e5f2519f 100644 --- a/nova/compute/linux_net.py +++ b/nova/compute/linux_net.py @@ -27,12 +27,16 @@ import subprocess from nova import flags FLAGS=flags.FLAGS -def execute(cmd): +flags.DEFINE_string('dhcpbridge_flagfile', + '/etc/nova-dhcpbridge.conf', + 'location of flagfile for dhcpbridge') + +def execute(cmd, addl_env=None): if FLAGS.fake_network: logging.debug("FAKE NET: %s" % cmd) return "fake", 0 else: - return nova.utils.execute(cmd) + return nova.utils.execute(cmd, addl_env=addl_env) def runthis(desc, cmd): if FLAGS.fake_network: @@ -60,7 +64,7 @@ def remove_rule(cmd): def bind_public_ip(ip, interface): runthis("Binding IP to interface: %s", "sudo ip addr add %s dev %s" % (ip, interface)) - + def unbind_public_ip(ip, interface): runthis("Binding IP to interface: %s", "sudo ip addr del %s dev %s" % (ip, interface)) @@ -98,7 +102,7 @@ def dnsmasq_cmd(net): ' --except-interface=lo', ' --dhcp-range=%s,static,600s' % (net.dhcp_range_start), ' --dhcp-hostsfile=%s' % dhcp_file(net['vlan'], 'conf'), - ' --dhcp-script=%s' % bin_file('dhcpleasor.py'), + ' --dhcp-script=%s' % bin_file('nova-dhcpbridge'), ' --leasefile-ro'] return ''.join(cmd) @@ -138,7 +142,9 @@ def start_dnsmasq(network): if os.path.exists(lease_file): os.unlink(lease_file) - Popen(dnsmasq_cmd(network).split(" ")) + # FLAGFILE in env + env = {'FLAGFILE' : FLAGS.dhcpbridge_flagfile} + execute(dnsmasq_cmd(network), addl_env=env) def stop_dnsmasq(network): """ stops the dnsmasq instance for a given network """ diff --git a/nova/compute/network.py b/nova/compute/network.py index 8592d7af7..3904fcff0 100644 --- a/nova/compute/network.py +++ b/nova/compute/network.py @@ -253,7 +253,7 @@ class BaseNetwork(datastore.BasicModel): raise compute_exception.NoMoreAddresses("Project %s with network %s" % (project_id, str(self.network))) - def lease_ip(self, ip_str): + def lease_ip(self, ip_str): logging.debug("Leasing allocated IP %s" % (ip_str)) def release_ip(self, ip_str): @@ -563,10 +563,10 @@ def allocate_ip(user_id, project_id, mac): def deallocate_ip(address): return get_network_by_address(address).deallocate_ip(address) - + def release_ip(address): return get_network_by_address(address).release_ip(address) - + def lease_ip(address): return get_network_by_address(address).lease_ip(address) diff --git a/nova/tests/network_unittest.py b/nova/tests/network_unittest.py index dd1966ffa..d24ae133c 100644 --- a/nova/tests/network_unittest.py +++ b/nova/tests/network_unittest.py @@ -18,19 +18,18 @@ import os import logging -import unittest from nova import vendor import IPy from nova import flags from nova import test -from nova import exception -from nova.compute.exception import NoMoreAddresses -from nova.compute import network -from nova.auth import users from nova import utils +from nova.auth import users +from nova.compute import network +from nova.compute.exception import NoMoreAddresses +FLAGS = flags.FLAGS class NetworkTestCase(test.TrialTestCase): def setUp(self): @@ -182,14 +181,20 @@ def binpath(script): class FakeDNSMasq(object): def issue_ip(self, mac, ip, hostname, interface): - cmd = "%s add %s %s %s" % (binpath('dhcpleasor.py'), mac, ip, hostname) - env = {'DNSMASQ_INTERFACE': interface, 'TESTING' : '1'} + cmd = "%s add %s %s %s" % (binpath('nova-dhcpbridge'), + mac, ip, hostname) + env = {'DNSMASQ_INTERFACE': interface, + 'TESTING' : '1', + 'FLAGFILE' : FLAGS.dhcpbridge_flagfile} (out, err) = utils.execute(cmd, addl_env=env) logging.debug("ISSUE_IP: %s, %s " % (out, err)) def release_ip(self, mac, ip, hostname, interface): - cmd = "%s del %s %s %s" % (binpath('dhcpleasor.py'), mac, ip, hostname) - env = {'DNSMASQ_INTERFACE': interface, 'TESTING' : '1'} + cmd = "%s del %s %s %s" % (binpath('nova-dhcpbridge'), + mac, ip, hostname) + env = {'DNSMASQ_INTERFACE': interface, + 'TESTING' : '1', + 'FLAGFILE' : FLAGS.dhcpbridge_flagfile} (out, err) = utils.execute(cmd, addl_env=env) logging.debug("RELEASE_IP: %s, %s " % (out, err)) -- cgit