Add new DPDK validation to CheckBeforeDeploymentTask

That checks that if DPDK enabled:
 * only network with neutron/private role assigned to DPDK enabled interface
 * hugepages are configured
 * hypervisor is kvm

Partial-Bug: #1559224
Related to blueprint support-dpdk
Change-Id: I68797a30431f4c618b59471033b1c0b5bbacba95
This commit is contained in:
Nikita Zubkov 2016-03-29 16:05:42 +03:00
parent 573c7ee3a5
commit 63eeba6da0
2 changed files with 162 additions and 0 deletions

View File

@ -1316,6 +1316,7 @@ class CheckBeforeDeploymentTask(object):
cls._validate_network_template(task)
cls._check_deployment_graph_for_correctness(task)
cls._check_sriov_properties(task)
cls._check_dpdk_properties(task)
if objects.Release.is_external_mongo_enabled(task.cluster.release):
cls._check_mongo_nodes(task)
@ -1595,6 +1596,9 @@ class CheckBeforeDeploymentTask(object):
template_node_roles.update(
template_for_node_group['templates_for_node_role'])
cls._check_dpdk_network_scheme(
template_for_node_group['network_scheme'], node_group)
cluster_roles = objects.Cluster.get_assigned_roles(cluster)
missing_roles = cluster_roles - template_node_roles
@ -1630,6 +1634,72 @@ class CheckBeforeDeploymentTask(object):
raise errors.InvalidData(
'Only KVM hypervisor works with SRIOV.')
@classmethod
def _check_dpdk_network_scheme(cls, network_scheme, node_group):
"""Check that endpoint with dpdk provider mapped only to neutron/private
"""
for net_template in network_scheme.values():
roles = net_template['roles']
endpoints = set()
for transformation in net_template['transformations']:
if (
transformation.get('provider') ==
consts.NEUTRON_L23_PROVIDERS.dpdkovs
):
endpoints.add(transformation['bridge'])
if not endpoints:
continue
if len(endpoints) > 1:
raise errors.NetworkCheckError(
'dpdkovs provider can be assigned only for one endpoint.'
' You trying for {}: {}'.format(len(endpoints),
', '.join(endpoints))
)
endpoint_roles = collections.defaultdict(set)
for role_name, endpoint in roles.items():
endpoint_roles[endpoint].add(role_name)
endpoint = endpoints.pop()
if endpoint_roles[endpoint] != {'neutron/private'}:
raise errors.NetworkCheckError(
"Only neutron/private network role could be assigned to"
" node group '{}' with DPDK".format(
node_group.name)
)
@classmethod
def _check_dpdk_properties(self, task):
dpdk_enabled = False
for node in task.cluster.nodes:
if not objects.Node.dpdk_enabled(node):
continue
dpdk_enabled = True
if not objects.NodeAttributes.is_dpdk_hugepages_enabled(node):
raise errors.InvalidData(
"Hugepages for DPDK are not configured"
" for node '{}'".format(node.id))
if not objects.NodeAttributes.is_nova_hugepages_enabled(node):
raise errors.InvalidData(
"Hugepages for Nova are not configured"
" for node '{}'".format(node.id))
if dpdk_enabled:
# check hypervisor type
h_type = objects.Cluster.get_editable_attributes(
task.cluster)['common']['libvirt_type']['value']
if h_type != consts.HYPERVISORS.kvm:
raise errors.InvalidData(
'Only KVM hypervisor works with DPDK.')
class DumpTask(object):
@classmethod

View File

@ -495,6 +495,98 @@ class TestCheckBeforeDeploymentTask(BaseTestCase):
self.task,
)
def test_wrong_net_role_for_dpdk(self):
objects.Cluster.set_network_template(
self.cluster,
self.env.read_fixtures(['network_template_90'])[0]
)
conf_template = self.cluster.network_config.configuration_template
template = conf_template['adv_net_template']['default']
network_scheme = template['network_scheme']['private']
network_scheme['roles'] = {'test': 'br-prv'}
self.assertRaisesRegexp(
errors.NetworkCheckError,
'Only neutron/private network role .* with DPDK',
task.CheckBeforeDeploymentTask._validate_network_template,
self.task,
)
def test_wrong_dpdk_endpoints_count(self):
objects.Cluster.set_network_template(
self.cluster,
self.env.read_fixtures(['network_template_90'])[0],
)
conf_template = self.cluster.network_config.configuration_template
template = conf_template['adv_net_template']['default']
network_scheme = template['network_scheme']['private']
network_scheme['transformations'].append({
'action': 'add-port',
'bridge': 'br-derp',
'name': '<% if3 %>.101',
'provider': 'dpdkovs',
})
self.assertRaisesRegexp(
errors.NetworkCheckError,
'dpdkovs provider can be assigned only for one endpoint',
task.CheckBeforeDeploymentTask._validate_network_template,
self.task,
)
def test_dpdk_hugepages_are_not_configured(self):
net_template = self.env.read_fixtures(['network_template_90'])[0]
objects.Cluster.set_network_template(
self.cluster,
net_template
)
objects.Node.update_attributes(
self.node, {'hugepages': {'dpdk': {'value': 0}}})
objects.NIC.update(self.node.nic_interfaces[0],
{'interface_properties':
{
'dpdk': {'enabled': True,
'available': True},
}})
self.assertRaisesRegexp(
errors.InvalidData,
'Hugepages for DPDK are not configured',
task.CheckBeforeDeploymentTask._check_dpdk_properties,
self.task,
)
def test_nova_hugepages_are_not_configured_with_dpdk_enabled(self):
net_template = self.env.read_fixtures(['network_template_90'])[0]
objects.Cluster.set_network_template(
self.cluster,
net_template
)
objects.Node.update_attributes(
self.node, {'hugepages': {
'nova': {'value': {'2048': 0}},
'dpdk': {'value': 1},
}})
objects.NIC.update(self.node.nic_interfaces[0],
{'interface_properties':
{
'dpdk': {'enabled': True,
'available': True},
}})
self.assertRaisesRegexp(
errors.InvalidData,
'Hugepages for Nova are not configured',
task.CheckBeforeDeploymentTask._check_dpdk_properties,
self.task,
)
def test_check_public_networks(self):
cluster = self.env.clusters[0]
self.env.create_nodes(