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:
parent
5dcf4e4521
commit
650a7d7c87
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)])
|
||||
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user