Make dhcp agent configurable for namespace

Bug #1035769

Change-Id: I9f0d48a73f059a4985d629c7f0209675f5b01bec
This commit is contained in:
Aaron Rosen 2012-08-11 17:17:30 -07:00
parent 56ab50beaf
commit 314134bdcb
5 changed files with 38 additions and 16 deletions

View File

@ -22,6 +22,10 @@ interface_driver = quantum.agent.linux.interface.OVSInterfaceDriver
# no additional setup of the DHCP server. # no additional setup of the DHCP server.
dhcp_driver = quantum.agent.linux.dhcp.Dnsmasq dhcp_driver = quantum.agent.linux.dhcp.Dnsmasq
# Allow overlapping IP (Must have kernel build with CONFIG_NET_NS=y and
# iproute2 package that supports namespaces).
use_namespaces = True
# #
# Temporary F2 variables until the Agent <> Quantum Server is reworked in F3 # Temporary F2 variables until the Agent <> Quantum Server is reworked in F3
# #

View File

@ -53,7 +53,9 @@ class DhcpAgent(object):
help="The time in seconds between state poll requests."), help="The time in seconds between state poll requests."),
cfg.IntOpt('reconnect_interval', cfg.IntOpt('reconnect_interval',
default=5, default=5,
help="The time in seconds between db reconnect attempts.") help="The time in seconds between db reconnect attempts."),
cfg.BoolOpt('use_namespaces', default=True,
help="Allow overlapping IP.")
] ]
def __init__(self, conf): def __init__(self, conf):
@ -211,7 +213,6 @@ class DeviceManager(object):
def __init__(self, conf, db): def __init__(self, conf, db):
self.conf = conf self.conf = conf
self.db = db self.db = db
if not conf.interface_driver: if not conf.interface_driver:
LOG.error(_('You must specify an interface driver')) LOG.error(_('You must specify an interface driver'))
self.driver = importutils.import_object(conf.interface_driver, conf) self.driver = importutils.import_object(conf.interface_driver, conf)
@ -232,9 +233,14 @@ class DeviceManager(object):
port = self._get_or_create_port(network) port = self._get_or_create_port(network)
interface_name = self.get_interface_name(network, port) interface_name = self.get_interface_name(network, port)
if ip_lib.device_exists(interface_name, if self.conf.use_namespaces:
self.conf.root_helper, namespace = network.id
network.id): else:
namespace = None
if ip_lib.device_exists(interface_name,
self.conf.root_helper,
namespace):
if not reuse_existing: if not reuse_existing:
raise exceptions.PreexistingDeviceFailure( raise exceptions.PreexistingDeviceFailure(
dev_name=interface_name) dev_name=interface_name)
@ -245,7 +251,7 @@ class DeviceManager(object):
port.id, port.id,
interface_name, interface_name,
port.mac_address, port.mac_address,
namespace=network.id) namespace=namespace)
ip_cidrs = [] ip_cidrs = []
for fixed_ip in port.fixed_ips: for fixed_ip in port.fixed_ips:
subnet = fixed_ip.subnet subnet = fixed_ip.subnet
@ -254,7 +260,7 @@ class DeviceManager(object):
ip_cidrs.append(ip_cidr) ip_cidrs.append(ip_cidr)
self.driver.init_l3(interface_name, ip_cidrs, self.driver.init_l3(interface_name, ip_cidrs,
namespace=network.id) namespace=namespace)
def destroy(self, network): def destroy(self, network):
self.driver.unplug(self.get_interface_name(network)) self.driver.unplug(self.get_interface_name(network))

View File

@ -112,9 +112,12 @@ class DhcpLocalProcess(DhcpBase):
if self.active: if self.active:
cmd = ['kill', '-9', pid] cmd = ['kill', '-9', pid]
ip_wrapper = ip_lib.IPWrapper(self.root_helper, if self.conf.use_namespaces:
namespace=self.network.id) ip_wrapper = ip_lib.IPWrapper(self.root_helper,
ip_wrapper.netns.execute(cmd) namespace=self.network.id)
ip_wrapper.netns.execute(cmd)
else:
utils.execute(cmd, self.root_helper)
self.device_delegate.destroy(self.network) self.device_delegate.destroy(self.network)
elif pid: elif pid:
LOG.debug(_('DHCP for %s pid %d is stale, ignoring command') % LOG.debug(_('DHCP for %s pid %d is stale, ignoring command') %
@ -222,9 +225,12 @@ class Dnsmasq(DhcpLocalProcess):
if self.conf.dnsmasq_dns_server: if self.conf.dnsmasq_dns_server:
cmd.append('--server=%s' % self.conf.dnsmasq_dns_server) cmd.append('--server=%s' % self.conf.dnsmasq_dns_server)
ip_wrapper = ip_lib.IPWrapper(self.root_helper, if self.conf.use_namespaces:
namespace=self.network.id) ip_wrapper = ip_lib.IPWrapper(self.root_helper,
ip_wrapper.netns.execute(cmd) namespace=self.network.id)
ip_wrapper.netns.execute(cmd)
else:
utils.execute(cmd, self.root_helper)
def reload_allocations(self): def reload_allocations(self):
"""If all subnets turn off dhcp, kill the process.""" """If all subnets turn off dhcp, kill the process."""
@ -238,9 +244,13 @@ class Dnsmasq(DhcpLocalProcess):
self._output_hosts_file() self._output_hosts_file()
self._output_opts_file() self._output_opts_file()
cmd = ['kill', '-HUP', self.pid] cmd = ['kill', '-HUP', self.pid]
ip_wrapper = ip_lib.IPWrapper(self.root_helper,
namespace=self.network.id) if self.conf.use_namespaces:
ip_wrapper.netns.execute(cmd) ip_wrapper = ip_lib.IPWrapper(self.root_helper,
namespace=self.network.id)
ip_wrapper.netns.execute(cmd)
else:
utils.execute(cmd, self.root_helper)
LOG.debug(_('Reloading allocations for network: %s') % self.network.id) LOG.debug(_('Reloading allocations for network: %s') % self.network.id)
def _output_hosts_file(self): def _output_hosts_file(self):

View File

@ -378,6 +378,7 @@ class TestDeviceManager(unittest.TestCase):
self.conf.set_override('interface_driver', self.conf.set_override('interface_driver',
'quantum.agent.linux.interface.NullDriver') 'quantum.agent.linux.interface.NullDriver')
self.conf.root_helper = 'sudo' self.conf.root_helper = 'sudo'
self.conf.use_namespaces = True
self.client_cls_p = mock.patch('quantumclient.v2_0.client.Client') self.client_cls_p = mock.patch('quantumclient.v2_0.client.Client')
client_cls = self.client_cls_p.start() client_cls = self.client_cls_p.start()

View File

@ -168,6 +168,7 @@ class TestBase(unittest.TestCase):
self.conf.register_opts(dhcp.OPTS) self.conf.register_opts(dhcp.OPTS)
self.conf(args=args) self.conf(args=args)
self.conf.set_override('state_path', '') self.conf.set_override('state_path', '')
self.conf.use_namespaces = True
self.replace_p = mock.patch('quantum.agent.linux.dhcp.replace_file') self.replace_p = mock.patch('quantum.agent.linux.dhcp.replace_file')
self.execute_p = mock.patch('quantum.agent.linux.utils.execute') self.execute_p = mock.patch('quantum.agent.linux.utils.execute')