summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicardo Noriega <rnoriega@redhat.com>2018-02-12 12:58:14 +0100
committerRicardo Noriega <rnoriega@redhat.com>2018-03-15 21:12:34 +0100
commit974993a17188f10acd6a1f9b2f48002b9c77ef24 (patch)
tree8c269c3fe710f6687bcbf6a0a45f3a3112db06da
parent67e7b3c76402445d7e62d5953d661794ec1f7c6d (diff)
Adding SRIOV scenario
This scenario should enable SRIOV interfaces to be used by Neutron. Only will be supported in baremetal deployments with SRIOV capable NICs. The name of the interface must be known in advance and the physnet of the SRIOV network is set as nfv_sriov. Change-Id: Ie4295413e0be2197bd9ada4f887f6b47cd486765 Signed-off-by: Ricardo Noriega <rnoriega@redhat.com>
-rw-r--r--apex/deploy.py1
-rw-r--r--apex/overcloud/deploy.py51
-rw-r--r--apex/settings/deploy_settings.py8
-rw-r--r--apex/tests/test_apex_overcloud_deploy.py61
-rw-r--r--build/rpm_specs/opnfv-apex-common.spec2
-rw-r--r--config/deploy/deploy_settings.yaml5
-rw-r--r--config/deploy/os-odl-sriov-ha.yaml21
-rw-r--r--config/deploy/os-odl-sriov-noha.yaml21
-rw-r--r--docs/release/installation/architecture.rst8
-rw-r--r--lib/ansible/playbooks/configure_undercloud.yml5
-rw-r--r--lib/ansible/playbooks/deploy_overcloud.yml6
11 files changed, 183 insertions, 6 deletions
diff --git a/apex/deploy.py b/apex/deploy.py
index 5703e081..b9267a3c 100644
--- a/apex/deploy.py
+++ b/apex/deploy.py
@@ -523,6 +523,7 @@ def main():
deploy_vars['sfc'] = ds_opts['sfc']
deploy_vars['vpn'] = ds_opts['vpn']
deploy_vars['l2gw'] = ds_opts.get('l2gw')
+ deploy_vars['sriov'] = ds_opts.get('sriov')
# TODO(trozet): pull all logs and store in tmp dir in overcloud
# playbook
post_overcloud = os.path.join(args.lib_dir, ANSIBLE_PATH,
diff --git a/apex/overcloud/deploy.py b/apex/overcloud/deploy.py
index 5bbcaede..33641ed5 100644
--- a/apex/overcloud/deploy.py
+++ b/apex/overcloud/deploy.py
@@ -39,6 +39,7 @@ SDN_FILE_MAP = {
'default': 'neutron-opendaylight-honeycomb.yaml'
},
'l2gw': 'neutron-l2gw-opendaylight.yaml',
+ 'sriov': 'neutron-opendaylight-sriov.yaml',
'default': 'neutron-opendaylight.yaml',
},
'onos': {
@@ -137,6 +138,9 @@ def create_deploy_cmd(ds, ns, inv, tmp_dir,
prep_storage_env(ds, tmp_dir)
deploy_options.append(os.path.join(con.THT_ENV_DIR,
'storage-environment.yaml'))
+ if ds_opts['sriov']:
+ prep_sriov_env(ds, tmp_dir)
+
if ds['global_params']['ha_enabled']:
deploy_options.append(os.path.join(con.THT_ENV_DIR,
'puppet-pacemaker.yaml'))
@@ -459,6 +463,13 @@ def prep_env(ds, ns, inv, opnfv_env, net_env, tmp_dir):
elif 'ComputeServices' in line:
output_line = (" ComputeServices:\n"
" - OS::TripleO::Services::NeutronDhcpAgent")
+ # SRIOV networks are VLAN based provider networks. In order to simplify
+ # the deployment, nfv_sriov will be the default physnet. VLANs are not
+ # needed in advance, and the user will have to create the network
+ # specifying the segmentation-id.
+ if ds_opts['sriov']:
+ if 'NeutronNetworkVLANRanges' in line:
+ output_line = ("{},nfv_sriov'".format(line[:-1]))
if perf:
for role in 'NovaCompute', 'Controller':
@@ -569,6 +580,46 @@ def prep_storage_env(ds, tmp_dir):
))
+def prep_sriov_env(ds, tmp_dir):
+ """
+ Creates SRIOV environment file for deployment. Source file is copied by
+ undercloud playbook to host.
+ :param ds:
+ :param tmp_dir:
+ :return:
+ """
+ ds_opts = ds['deploy_options']
+ sriov_iface = ds_opts['sriov']
+ sriov_file = os.path.join(tmp_dir, 'neutron-opendaylight-sriov.yaml')
+ if not os.path.isfile(sriov_file):
+ logging.error("sriov-environment file is not in tmp directory: {}. "
+ "Check if file was copied from "
+ "undercloud".format(tmp_dir))
+ raise ApexDeployException("sriov-environment file not copied from "
+ "undercloud")
+ # TODO(rnoriega): Instead of line editing, refactor this code to load
+ # yaml file into a dict, edit it and write the file back.
+ for line in fileinput.input(sriov_file, inplace=True):
+ line = line.strip('\n')
+ if 'NovaSchedulerDefaultFilters' in line:
+ print(" {}".format(line[3:]))
+ elif 'NovaSchedulerAvailableFilters' in line:
+ print(" {}".format(line[3:]))
+ elif 'NeutronPhysicalDevMappings' in line:
+ print(" NeutronPhysicalDevMappings: \"nfv_sriov:{}\""
+ .format(sriov_iface))
+ elif 'NeutronSriovNumVFs' in line:
+ print(" NeutronSriovNumVFs: \"{}:8\"".format(sriov_iface))
+ elif 'NovaPCIPassthrough' in line:
+ print(" NovaPCIPassthrough:")
+ elif 'devname' in line:
+ print(" - devname: \"{}\"".format(sriov_iface))
+ elif 'physical_network' in line:
+ print(" physical_network: \"nfv_sriov\"")
+ else:
+ print(line)
+
+
def external_network_cmds(ns):
"""
Generates external network openstack commands
diff --git a/apex/settings/deploy_settings.py b/apex/settings/deploy_settings.py
index eec98225..c05922bf 100644
--- a/apex/settings/deploy_settings.py
+++ b/apex/settings/deploy_settings.py
@@ -24,7 +24,8 @@ REQ_DEPLOY_SETTINGS = ['sdn_controller',
'gluon',
'rt_kvm',
'os_version',
- 'l2gw']
+ 'l2gw',
+ 'sriov']
OPT_DEPLOY_SETTINGS = ['performance',
'vsperf',
@@ -116,6 +117,11 @@ class DeploySettings(dict):
raise DeploySettingsException(
"Invalid ODL version: {}".format(self[deploy_options][
'odl_version']))
+ elif req_set == 'sriov':
+ if self['deploy_options'][req_set] is True:
+ raise DeploySettingsException(
+ "Invalid SRIOV interface name: {}".format(
+ self['deploy_options']['sriov']))
if self['deploy_options']['odl_version'] == 'oxygen':
self['deploy_options']['odl_version'] = 'master'
diff --git a/apex/tests/test_apex_overcloud_deploy.py b/apex/tests/test_apex_overcloud_deploy.py
index 420a70d6..b5b1b75e 100644
--- a/apex/tests/test_apex_overcloud_deploy.py
+++ b/apex/tests/test_apex_overcloud_deploy.py
@@ -25,6 +25,7 @@ from apex.overcloud.deploy import make_ssh_key
from apex.overcloud.deploy import prep_env
from apex.overcloud.deploy import generate_ceph_key
from apex.overcloud.deploy import prep_storage_env
+from apex.overcloud.deploy import prep_sriov_env
from apex.overcloud.deploy import external_network_cmds
from apex.overcloud.deploy import create_congress_cmds
from apex.overcloud.deploy import SDN_FILE_MAP
@@ -80,10 +81,12 @@ class TestOvercloudDeploy(unittest.TestCase):
os.path.join(prefix, 'neutron-bgpvpn-opendaylight.yaml')]
assert_equal(build_sdn_env_list(ds, SDN_FILE_MAP), res)
+ @patch('apex.overcloud.deploy.prep_sriov_env')
@patch('apex.overcloud.deploy.prep_storage_env')
@patch('apex.overcloud.deploy.build_sdn_env_list')
@patch('builtins.open', mock_open())
- def test_create_deploy_cmd(self, mock_sdn_list, mock_prep_storage):
+ def test_create_deploy_cmd(self, mock_sdn_list, mock_prep_storage,
+ mock_prep_sriov):
mock_sdn_list.return_value = []
ds = {'deploy_options': MagicMock(),
'global_params': MagicMock()}
@@ -106,11 +109,12 @@ class TestOvercloudDeploy(unittest.TestCase):
assert_in('--control-scale 3', result_cmd)
assert_in('--compute-scale 2', result_cmd)
+ @patch('apex.overcloud.deploy.prep_sriov_env')
@patch('apex.overcloud.deploy.prep_storage_env')
@patch('apex.overcloud.deploy.build_sdn_env_list')
@patch('builtins.open', mock_open())
def test_create_deploy_cmd_no_ha_bm(self, mock_sdn_list,
- mock_prep_storage):
+ mock_prep_storage, mock_prep_sriov):
mock_sdn_list.return_value = []
ds = {'deploy_options': MagicMock(),
'global_params': MagicMock()}
@@ -129,9 +133,11 @@ class TestOvercloudDeploy(unittest.TestCase):
assert_not_in('enable_congress.yaml', result_cmd)
assert_not_in('enable_barometer.yaml', result_cmd)
+ @patch('apex.overcloud.deploy.prep_sriov_env')
@patch('apex.overcloud.deploy.prep_storage_env')
@patch('apex.overcloud.deploy.build_sdn_env_list')
- def test_create_deploy_cmd_raises(self, mock_sdn_list, mock_prep_storage):
+ def test_create_deploy_cmd_raises(self, mock_sdn_list, mock_prep_storage,
+ mock_prep_sriov):
mock_sdn_list.return_value = []
ds = {'deploy_options': MagicMock(),
'global_params': MagicMock()}
@@ -251,6 +257,7 @@ class TestOvercloudDeploy(unittest.TestCase):
{'sdn_controller': 'opendaylight',
'odl_vpp_routing_node': 'test',
'dataplane': 'ovs_dpdk',
+ 'sriov': 'xxx',
'performance': {'Compute': {'vpp': {'main-core': 'test',
'corelist-workers': 'test'},
'ovs': {'dpdk_cores': 'test'},
@@ -293,6 +300,7 @@ class TestOvercloudDeploy(unittest.TestCase):
ds = {'deploy_options':
{'sdn_controller': False,
'dataplane': 'fdio',
+ 'sriov': 'xxx',
'performance': {'Compute': {},
'Controller': {}}}}
ns = {'domain_name': 'test.domain',
@@ -332,6 +340,7 @@ class TestOvercloudDeploy(unittest.TestCase):
ds = {'deploy_options':
{'sdn_controller': 'opendaylight',
'dataplane': 'fdio',
+ 'sriov': 'xxx',
'dvr': True}}
ns = {'domain_name': 'test.domain',
'networks':
@@ -385,6 +394,52 @@ class TestOvercloudDeploy(unittest.TestCase):
ds = {'deploy_options': MagicMock()}
assert_raises(ApexDeployException, prep_storage_env, ds, '/tmp')
+ @patch('apex.overcloud.deploy.generate_ceph_key')
+ @patch('apex.overcloud.deploy.fileinput')
+ @patch('apex.overcloud.deploy.os.path.isfile')
+ @patch('builtins.open', mock_open())
+ def test_prep_sriov_env(self, mock_isfile, mock_fileinput, mock_ceph_key):
+ ds = {'deploy_options':
+ {'sdn_controller': 'opendaylight',
+ 'sriov': 'xxx'}}
+ try:
+ # Swap stdout
+ saved_stdout = sys.stdout
+ out = StringIO()
+ sys.stdout = out
+ # Run tests
+ mock_fileinput.input.return_value = \
+ ['# NovaSchedulerDefaultFilters',
+ '# NovaSchedulerAvailableFilters',
+ '#NeutronPhysicalDevMappings: "datacentre:ens20f2"',
+ '#NeutronSriovNumVFs: \"ens20f2:5\"',
+ '#NovaPCIPassthrough:',
+ '# - devname: \"ens20f2\"',
+ '# physical_network: \"datacentre\"']
+ prep_sriov_env(ds, '/tmp')
+ output = out.getvalue().strip()
+ assert_in('NovaSchedulerDefaultFilters', output)
+ assert_in('NovaSchedulerAvailableFilters', output)
+ assert_in('NeutronPhysicalDevMappings: \"nfv_sriov:xxx\"', output)
+ assert_in('NeutronSriovNumVFs: \"xxx:8\"', output)
+ assert_in('NovaPCIPassthrough:', output)
+ assert_in('- devname: \"xxx\"', output)
+ assert_in('physical_network: \"nfv_sriov\"', output)
+ finally:
+ # put stdout back
+ sys.stdout = saved_stdout
+
+ @patch('apex.overcloud.deploy.os.path.isfile')
+ @patch('builtins.open', mock_open())
+ def test_prep_sriov_env_raises(self, mock_isfile):
+ ds_opts = {'sriov': True}
+ ds = {'deploy_options': MagicMock()}
+ ds['deploy_options'].__getitem__.side_effect = \
+ lambda i: ds_opts.get(i, MagicMock())
+ mock_isfile.return_value = False
+ ds = {'deploy_options': MagicMock()}
+ assert_raises(ApexDeployException, prep_sriov_env, ds, '/tmp')
+
def test_external_network_cmds(self):
cidr = MagicMock()
cidr.version = 6
diff --git a/build/rpm_specs/opnfv-apex-common.spec b/build/rpm_specs/opnfv-apex-common.spec
index f8226e43..124f2527 100644
--- a/build/rpm_specs/opnfv-apex-common.spec
+++ b/build/rpm_specs/opnfv-apex-common.spec
@@ -98,6 +98,8 @@ install config/inventory/pod_example_settings.yaml %{buildroot}%{_docdir}/opnfv/
%{_sysconfdir}/opnfv-apex/os-odl-ovs_dpdk-ha.yaml
%{_sysconfdir}/opnfv-apex/os-odl-nofeature-ha.yaml
%{_sysconfdir}/opnfv-apex/os-odl-nofeature-noha.yaml
+%{_sysconfdir}/opnfv-apex/os-odl-sriov-ha.yaml
+%{_sysconfdir}/opnfv-apex/os-odl-sriov-noha.yaml
%{_sysconfdir}/opnfv-apex/os-odl-gluon-noha.yaml
%{_sysconfdir}/opnfv-apex/os-ovn-nofeature-noha.yaml
%{_sysconfdir}/opnfv-apex/os-onos-nofeature-ha.yaml
diff --git a/config/deploy/deploy_settings.yaml b/config/deploy/deploy_settings.yaml
index ab3b0a37..a6721b4a 100644
--- a/config/deploy/deploy_settings.yaml
+++ b/config/deploy/deploy_settings.yaml
@@ -52,6 +52,11 @@ deploy_options:
# The dataplane should be specified as fdio if this is set to true
vpp: false
+ # Whether to install and configure SRIOV service in the compute node(s) to
+ # allow VMs to use VFs/PFs. The user must know in advance the name of the
+ # SRIOV capable NIC that will be configured.
+ sriov: em2
+
# Whether to run vsperf after the install has completed
# vsperf: false
diff --git a/config/deploy/os-odl-sriov-ha.yaml b/config/deploy/os-odl-sriov-ha.yaml
new file mode 100644
index 00000000..03e34a23
--- /dev/null
+++ b/config/deploy/os-odl-sriov-ha.yaml
@@ -0,0 +1,21 @@
+---
+global_params:
+ ha_enabled: true
+
+deploy_options:
+ sdn_controller: opendaylight
+ odl_version: nitrogen
+ tacker: true
+ congress: true
+ sfc: false
+ vpn: false
+ sriov: em2
+ performance:
+ Controller:
+ kernel:
+ Compute:
+ kernel:
+ hugepagesz: 2M
+ hugepages: 2048
+ intel_iommu: 'on'
+ iommu: pt
diff --git a/config/deploy/os-odl-sriov-noha.yaml b/config/deploy/os-odl-sriov-noha.yaml
new file mode 100644
index 00000000..52b5aa18
--- /dev/null
+++ b/config/deploy/os-odl-sriov-noha.yaml
@@ -0,0 +1,21 @@
+---
+global_params:
+ ha_enabled: false
+
+deploy_options:
+ sdn_controller: opendaylight
+ odl_version: nitrogen
+ tacker: true
+ congress: true
+ sfc: false
+ vpn: false
+ sriov: em2
+ performance:
+ Controller:
+ kernel:
+ Compute:
+ kernel:
+ hugepagesz: 2M
+ hugepages: 2048
+ intel_iommu: 'on'
+ iommu: pt
diff --git a/docs/release/installation/architecture.rst b/docs/release/installation/architecture.rst
index b8db7c86..70067ed0 100644
--- a/docs/release/installation/architecture.rst
+++ b/docs/release/installation/architecture.rst
@@ -159,11 +159,15 @@ issues per scenario. The following scenarios correspond to a supported
| os-odl-bgpvpn-ha | SDNVPN | Yes |
+-------------------------+-------------+---------------+
| os-odl-bgpvpn-noha | SDNVPN | Yes |
-++-------------------------+-------------+---------------+
++-------------------------+-------------+---------------+
+| os-odl-sriov-ha | Apex | No |
++-------------------------+-------------+---------------+
+| os-odl-sriov-noha | Apex | No |
++-------------------------+-------------+---------------+
| os-odl-l2gw-ha | Apex | No |
+-------------------------+-------------+---------------+
| os-odl-l2gw-noha | Apex | No |
--------------------------+-------------+---------------+
++-------------------------+-------------+---------------+
| os-odl-sfc-ha | SFC | No |
+-------------------------+-------------+---------------+
| os-odl-sfc-noha | SFC | Yes |
diff --git a/lib/ansible/playbooks/configure_undercloud.yml b/lib/ansible/playbooks/configure_undercloud.yml
index e9ce8754..9ef0d883 100644
--- a/lib/ansible/playbooks/configure_undercloud.yml
+++ b/lib/ansible/playbooks/configure_undercloud.yml
@@ -148,6 +148,11 @@
src: /usr/share/openstack-tripleo-heat-templates/environments/storage-environment.yaml
dest: "{{ apex_temp_dir }}/"
flat: yes
+ - name: fetch sriov environment file
+ fetch:
+ src: /usr/share/openstack-tripleo-heat-templates/environments/neutron-opendaylight-sriov.yaml
+ dest: "{{ apex_temp_dir }}/"
+ flat: yes
- include: undercloud_aarch64.yml
when: aarch64
diff --git a/lib/ansible/playbooks/deploy_overcloud.yml b/lib/ansible/playbooks/deploy_overcloud.yml
index aa3d8067..268a5173 100644
--- a/lib/ansible/playbooks/deploy_overcloud.yml
+++ b/lib/ansible/playbooks/deploy_overcloud.yml
@@ -30,6 +30,12 @@
owner: root
group: root
mode: 0664
+ - copy:
+ src: "{{ apex_temp_dir }}/neutron-opendaylight-sriov.yaml"
+ dest: /usr/share/openstack-tripleo-heat-templates/environments/neutron-opendaylight-sriov.yaml
+ owner: root
+ group: root
+ mode: 0664
- systemd:
name: openstack-swift-proxy
state: restarted