Mangle network namespace name used by dhcp_agent

fixes bug 1044113

This fix managles the network namespace by prefixing the network id with
qdhcp.

Change-Id: I41f48f805efd83bd3e12049007067200cc384ffe
This commit is contained in:
Mark McClain 2012-08-30 19:18:41 -04:00
parent 5dcf4e4521
commit 650a7d7c87
4 changed files with 37 additions and 27 deletions

View File

@ -41,6 +41,7 @@ from quantum.openstack.common.rpc import proxy
from quantum.version import version_string
LOG = logging.getLogger(__name__)
NS_PREFIX = 'qdhcp-'
class DhcpAgent(object):
@ -76,13 +77,18 @@ class DhcpAgent(object):
def call_driver(self, action, network):
"""Invoke an action on a DHCP driver instance."""
if self.conf.use_namespaces:
namespace = NS_PREFIX + network.id
else:
namespace = None
try:
# the Driver expects something that is duck typed similar to
# the base models.
driver = self.dhcp_driver_cls(self.conf,
network,
self.conf.root_helper,
self.device_manager)
self.device_manager,
namespace)
getattr(driver, action)()
except Exception, e:
@ -355,7 +361,7 @@ class DeviceManager(object):
interface_name = self.get_interface_name(network, port)
if self.conf.use_namespaces:
namespace = network.id
namespace = NS_PREFIX + network.id
else:
namespace = None
@ -388,7 +394,7 @@ class DeviceManager(object):
def destroy(self, network, device_name):
"""Destroy the device used for the network's DHCP on this host."""
if self.conf.use_namespaces:
namespace = network.id
namespace = NS_PREFIX + network.id
else:
namespace = None

View File

@ -64,11 +64,12 @@ class DhcpBase(object):
__metaclass__ = abc.ABCMeta
def __init__(self, conf, network, root_helper='sudo',
device_delegate=None):
device_delegate=None, namespace=None):
self.conf = conf
self.network = network
self.root_helper = root_helper
self.device_delegate = device_delegate
self.namespace = namespace
@abc.abstractmethod
def enable(self):
@ -118,9 +119,8 @@ class DhcpLocalProcess(DhcpBase):
if self.active:
cmd = ['kill', '-9', pid]
if self.conf.use_namespaces:
ip_wrapper = ip_lib.IPWrapper(self.root_helper,
namespace=self.network.id)
if self.namespace:
ip_wrapper = ip_lib.IPWrapper(self.root_helper, self.namespace)
ip_wrapper.netns.execute(cmd)
else:
utils.execute(cmd, self.root_helper)
@ -250,9 +250,8 @@ class Dnsmasq(DhcpLocalProcess):
if self.conf.dnsmasq_dns_server:
cmd.append('--server=%s' % self.conf.dnsmasq_dns_server)
if self.conf.use_namespaces:
ip_wrapper = ip_lib.IPWrapper(self.root_helper,
namespace=self.network.id)
if self.namespace:
ip_wrapper = ip_lib.IPWrapper(self.root_helper, self.namespace)
ip_wrapper.netns.execute(cmd, addl_env=env)
else:
# For normal sudo prepend the env vars before command
@ -272,9 +271,8 @@ class Dnsmasq(DhcpLocalProcess):
self._output_opts_file()
cmd = ['kill', '-HUP', self.pid]
if self.conf.use_namespaces:
ip_wrapper = ip_lib.IPWrapper(self.root_helper,
namespace=self.network.id)
if self.namespace:
ip_wrapper = ip_lib.IPWrapper(self.root_helper, self.namespace)
ip_wrapper.netns.execute(cmd)
else:
utils.execute(cmd, self.root_helper)

View File

@ -118,14 +118,17 @@ class TestDhcpAgent(unittest.TestCase):
self.notification.assert_has_calls([mock.call.run_dispatch()])
def test_call_driver(self):
network = mock.Mock()
network.id = '1'
with mock.patch('quantum.agent.dhcp_agent.DeviceManager') as dev_mgr:
dhcp = dhcp_agent.DhcpAgent(cfg.CONF)
dhcp.call_driver('foo', '1')
dhcp.call_driver('foo', network)
dev_mgr.assert_called()
self.driver.assert_called_once_with(cfg.CONF,
mock.ANY,
'sudo',
mock.ANY)
mock.ANY,
'qdhcp-1')
class TestDhcpAgentEventHandler(unittest.TestCase):
@ -486,9 +489,11 @@ class TestDeviceManager(unittest.TestCase):
plugin.assert_has_calls([
mock.call.get_dhcp_port(fake_network.id, mock.ANY)])
namespace = dhcp_agent.NS_PREFIX + fake_network.id
expected = [mock.call.init_l3('tap12345678-12',
['172.9.9.9/24'],
namespace=fake_network.id)]
namespace=namespace)]
if not reuse_existing:
expected.insert(0,
@ -496,7 +501,7 @@ class TestDeviceManager(unittest.TestCase):
fake_port1.id,
'tap12345678-12',
'aa:bb:cc:dd:ee:ff',
namespace=fake_network.id))
namespace=namespace))
self.mock_driver.assert_has_calls(expected)
@ -538,7 +543,7 @@ class TestDeviceManager(unittest.TestCase):
dvr_cls.assert_called_once_with(cfg.CONF)
mock_driver.assert_has_calls(
[mock.call.unplug('tap12345678-12',
namespace=fake_network.id)])
namespace='qdhcp-' + fake_network.id)])
plugin.assert_has_calls(
[mock.call.release_dhcp_port(fake_network.id, mock.ANY)])

View File

@ -142,7 +142,7 @@ class TestDhcpBase(unittest.TestCase):
def test_restart(self):
class SubClass(dhcp.DhcpBase):
def __init__(self):
dhcp.DhcpBase.__init__(self, None, None)
dhcp.DhcpBase.__init__(self, None, None, None)
self.called = []
def enable(self):
@ -306,12 +306,12 @@ class TestDhcpLocalProcess(TestBase):
mocks['active'].__get__ = mock.Mock(return_value=True)
mocks['pid'].__get__ = mock.Mock(return_value=5)
mocks['interface_name'].__get__ = mock.Mock(return_value='tap0')
lp = LocalChild(self.conf, network, device_delegate=delegate)
lp = LocalChild(self.conf, network, device_delegate=delegate,
namespace='qdhcp-ns')
lp.disable()
delegate.assert_has_calls([mock.call.destroy(network, 'tap0')])
exp_args = ['ip', 'netns', 'exec',
'cccccccc-cccc-cccc-cccc-cccccccccccc', 'kill', '-9', 5]
exp_args = ['ip', 'netns', 'exec', 'qdhcp-ns', 'kill', '-9', 5]
self.execute.assert_called_once_with(exp_args, root_helper='sudo')
def test_pid(self):
@ -372,7 +372,7 @@ class TestDnsmasq(TestBase):
'ip',
'netns',
'exec',
'cccccccc-cccc-cccc-cccc-cccccccccccc',
'qdhcp-ns',
'dnsmasq',
'--no-hosts',
'--no-resolv',
@ -411,7 +411,8 @@ class TestDnsmasq(TestBase):
with mock.patch.object(dhcp.sys, 'argv') as argv:
argv.__getitem__.side_effect = fake_argv
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(),
device_delegate=delegate)
device_delegate=delegate,
namespace='qdhcp-ns')
dm.spawn_process()
self.assertTrue(mocks['_output_opts_file'].called)
self.execute.assert_called_once_with(expected,
@ -480,14 +481,14 @@ tag:tag1,option:classless-static-route,%s,%s""".lstrip() % (fake_v6,
fake_v6_cidr,
fake_v6)
exp_args = ['ip', 'netns', 'exec',
'cccccccc-cccc-cccc-cccc-cccccccccccc', 'kill', '-HUP', 5]
exp_args = ['ip', 'netns', 'exec', 'qdhcp-ns', 'kill', '-HUP', 5]
with mock.patch('os.path.isdir') as isdir:
isdir.return_value = True
with mock.patch.object(dhcp.Dnsmasq, 'pid') as pid:
pid.__get__ = mock.Mock(return_value=5)
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork())
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(),
namespace='qdhcp-ns')
dm.reload_allocations()
self.safe.assert_has_calls([mock.call(exp_host_name, exp_host_data),