__metaclass__ = abc.ABCMeta
def __init__(self, conf, network, root_helper='sudo',
- device_delegate=None, namespace=None):
+ device_delegate=None, namespace=None, version=None):
self.conf = conf
self.network = network
self.root_helper = root_helper
self.device_delegate = device_delegate
self.namespace = namespace
+ self.version = version
@abc.abstractmethod
def enable(self):
@classmethod
def check_version(cls):
- is_valid_version = None
+ ver = 0
try:
cmd = ['dnsmasq', '--version']
out = utils.execute(cmd)
LOG.warning(_('Unable to determine dnsmasq version. '
'Please ensure that its version is %s '
'or above!'), cls.MINIMUM_VERSION)
- return is_valid_version
+ return float(ver)
@classmethod
def existing_dhcp_networks(cls, conf, root_helper):
# TODO(mark): how do we indicate other options
# ra-only, slaac, ra-nameservers, and ra-stateless.
mode = 'static'
- cmd.append('--dhcp-range=set:%s,%s,%s,%ss' %
- (self._TAG_PREFIX % i,
+ if self.version >= self.MINIMUM_VERSION:
+ set_tag = 'set:'
+ else:
+ set_tag = ''
+ cmd.append('--dhcp-range=%s%s,%s,%s,%ss' %
+ (set_tag, self._TAG_PREFIX % i,
netaddr.IPNetwork(subnet.cidr).network,
mode,
self.conf.dhcp_lease_time))
'quantum-dhcp-agent-dnsmasq-lease-update')
def _format_option(self, index, option_name, *args):
- return ','.join(('tag:' + self._TAG_PREFIX % index,
+ if self.version >= self.MINIMUM_VERSION:
+ set_tag = 'tag:'
+ else:
+ set_tag = ''
+ return ','.join((set_tag + self._TAG_PREFIX % index,
'option:%s' % option_name) + args)
@classmethod
argv.__getitem__.side_effect = fake_argv
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(),
device_delegate=delegate,
- namespace='qdhcp-ns')
+ namespace='qdhcp-ns',
+ version=float(2.59))
dm.spawn_process()
self.assertTrue(mocks['_output_opts_file'].called)
self.execute.assert_called_once_with(expected,
with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn:
conf_fn.return_value = '/foo/opts'
- dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork())
+ dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(),
+ version=float(2.59))
dm._output_opts_file()
self.safe.assert_called_once_with('/foo/opts', expected)
tag:tag0,option:router,192.168.0.1""".lstrip()
with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn:
conf_fn.return_value = '/foo/opts'
- dm = dhcp.Dnsmasq(self.conf, FakeDualNetworkSingleDHCP())
+ dm = dhcp.Dnsmasq(self.conf, FakeDualNetworkSingleDHCP(),
+ version=float(2.59))
+ dm._output_opts_file()
+
+ self.safe.assert_called_once_with('/foo/opts', expected)
+
+ def test_output_opts_file_single_dhcp_ver2_48(self):
+ expected = """
+tag0,option:dns-server,8.8.8.8
+tag0,option:classless-static-route,20.0.0.1/24,20.0.0.1
+tag0,option:router,192.168.0.1""".lstrip()
+ with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn:
+ conf_fn.return_value = '/foo/opts'
+ dm = dhcp.Dnsmasq(self.conf, FakeDualNetworkSingleDHCP(),
+ version=float(2.48))
dm._output_opts_file()
self.safe.assert_called_once_with('/foo/opts', expected)
with mock.patch.object(dhcp.Dnsmasq, 'get_conf_file_name') as conf_fn:
conf_fn.return_value = '/foo/opts'
- dm = dhcp.Dnsmasq(self.conf, FakeV4NoGatewayNetwork())
+ dm = dhcp.Dnsmasq(self.conf, FakeV4NoGatewayNetwork(),
+ version=float(2.59))
with mock.patch.object(dm, '_make_subnet_interface_ip_map') as ipm:
ipm.return_value = {FakeV4SubnetNoGateway.id: '192.168.1.1'}
with mock.patch.object(dhcp.Dnsmasq, 'pid') as pid:
pid.__get__ = mock.Mock(return_value=5)
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(),
- namespace='qdhcp-ns')
+ namespace='qdhcp-ns',
+ version=float(2.59))
method_name = '_make_subnet_interface_ip_map'
with mock.patch.object(dhcp.Dnsmasq,
with mock.patch.object(dhcp.Dnsmasq, 'pid') as pid:
pid.__get__ = mock.Mock(return_value=5)
dm = dhcp.Dnsmasq(self.conf, FakeDualNetwork(),
- namespace='qdhcp-ns')
+ namespace='qdhcp-ns', version=float(2.59))
method_name = '_make_subnet_interface_ip_map'
with mock.patch.object(dhcp.Dnsmasq, method_name) as ip_map:
self.assertEqual(result, expected_value)
def test_check_minimum_version(self):
- self._check_version('Dnsmasq version 2.59 Copyright (c)...', True)
+ self._check_version('Dnsmasq version 2.59 Copyright (c)...',
+ float(2.59))
def test_check_future_version(self):
- self._check_version('Dnsmasq version 2.65 Copyright (c)...', True)
+ self._check_version('Dnsmasq version 2.65 Copyright (c)...',
+ float(2.65))
def test_check_fail_version(self):
- self._check_version('Dnsmasq version 2.48 Copyright (c)...', False)
+ self._check_version('Dnsmasq version 2.48 Copyright (c)...',
+ float(2.48))
def test_check_version_failed_cmd_execution(self):
- self._check_version('Error while executing command', None)
+ self._check_version('Error while executing command', 0)