Add SRIOV support

- Pass required options to nova/neutron services
- Disable security groups for sriov case
- Deploy Neutron SRIOV agent on compute nodes
- Add noop tests

Partially implements: blueprint support-sriov
Implements: blueprint sriov-os-puppet-support

Change-Id: I96e1ff0360842e303ff899bd430b92952b7996c5
This commit is contained in:
Sergey Kolekonov 2016-01-26 21:10:37 +03:00
parent c776b59bdb
commit 894ff5b606
12 changed files with 259 additions and 27 deletions

View File

@ -111,6 +111,7 @@ class openstack::compute (
$ssh_public_key = '/var/lib/astute/nova/nova.pub',
$cache_server_ip = ['127.0.0.1'],
$cache_server_port = '11211',
$pci_passthrough = undef,
# if the cinder management components should be installed
$manage_volumes = false,
$nv_physical_volume = undef,
@ -315,6 +316,7 @@ class openstack::compute (
force_config_drive => $nova_hash['force_config_drive'],
#NOTE(bogdando) default became true in 4.0.0 puppet-nova (was false)
neutron_enabled => ($network_provider == 'neutron'),
pci_passthrough => $pci_passthrough,
install_bridge_utils => $install_bridge_utils,
network_device_mtu => $network_device_mtu,
instance_usage_audit => $instance_usage_audit,

View File

@ -0,0 +1,15 @@
Puppet::Parser::Functions::newfunction(:nic_whitelist_to_json, :type => :rvalue, :doc => <<-EOS
converts nic whitelist to json
EOS
) do |argv|
if argv.size > 1
raise Puppet::ParseError, 'Only one argument is allowed.'
elsif argv.size == 0
return
end
nics = argv[0]
return nics.to_json
end

View File

@ -0,0 +1,15 @@
Puppet::Parser::Functions::newfunction(:nic_whitelist_to_mappings, :type => :rvalue, :doc => <<-EOS
converts nic whitelist to bridge mappings
EOS
) do |argv|
if argv.size > 1
raise Puppet::ParseError, 'Only one argument is allowed.'
elsif argv.size == 0
return
end
nics = argv[0]
return nics.map {|x| "#{x['physical_network']}:#{x['devname']}"}
end

View File

@ -32,6 +32,7 @@ $api_bind_address = get_network_role_property('nova/api', 'ipaddr')
$rabbit_hash = hiera_hash('rabbit_hash', {})
$service_endpoint = hiera('service_endpoint')
$ssl_hash = hiera_hash('use_ssl', {})
$sahara_enabled = pick($sahara_hash['enabled'], false)
$internal_auth_protocol = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'protocol', [$nova_hash['auth_protocol'], 'http'])
$internal_auth_address = get_ssl_property($ssl_hash, {}, 'keystone', 'internal', 'hostname', [$service_endpoint, $management_vip])
@ -68,6 +69,14 @@ $external_lb = hiera('external_lb', false)
$neutron_config = hiera_hash('quantum_settings')
$neutron_metadata_proxy_secret = $neutron_config['metadata']['metadata_proxy_shared_secret']
$default_floating_net = pick($neutron_config['default_floating_net'], 'net04_ext')
$pci_vendor_devs = pick($neutron_config['supported_pci_vendor_devs'], false)
# Boolean value for further usage
if $pci_vendor_devs {
$sriov_enabled = true
} else {
$sriov_enabled = false
}
$db_type = 'mysql'
$db_host = pick($nova_hash['db_host'], hiera('database_vip'))
@ -406,11 +415,10 @@ nova_config {
'DEFAULT/teardown_unused_network_gateway': value => 'True'
}
if $sahara_hash['enabled'] {
$nova_scheduler_default_filters = [ 'DifferentHostFilter' ]
} else {
$nova_scheduler_default_filters = []
}
$nova_scheduler_default_filters = [ 'RetryFilter', 'AvailabilityZoneFilter', 'RamFilter', 'CoreFilter', 'DiskFilter', 'ComputeFilter', 'ComputeCapabilitiesFilter', 'ImagePropertiesFilter', 'ServerGroupAntiAffinityFilter', 'ServerGroupAffinityFilter' ]
$sriov_filters = $sriov_enabled ? { true => [ 'PciPassthroughFilter','AggregateInstanceExtraSpecsFilter' ], default => []}
$sahara_filters = $sahara_enabled ? { true => [ 'DifferentHostFilter' ], default => []}
$nova_scheduler_filters = unique(concat(pick($nova_config_hash['default_filters'], $nova_scheduler_default_filters), $sahara_filters, $sriov_filters))
if $ironic_hash['enabled'] {
$scheduler_host_manager = 'nova.scheduler.ironic_host_manager.IronicHostManager'
@ -421,7 +429,7 @@ class { '::nova::scheduler::filter':
disk_allocation_ratio => pick($nova_hash['disk_allocation_ratio'], '1.0'),
ram_allocation_ratio => pick($nova_hash['ram_allocation_ratio'], '1.0'),
scheduler_host_subset_size => pick($nova_hash['scheduler_host_subset_size'], '30'),
scheduler_default_filters => concat($nova_scheduler_default_filters, pick($nova_config_hash['default_filters'], [ 'RetryFilter', 'AvailabilityZoneFilter', 'RamFilter', 'CoreFilter', 'DiskFilter', 'ComputeFilter', 'ComputeCapabilitiesFilter', 'ImagePropertiesFilter', 'ServerGroupAntiAffinityFilter', 'ServerGroupAffinityFilter' ])),
scheduler_default_filters => $nova_scheduler_filters,
scheduler_host_manager => $scheduler_host_manager,
}

View File

@ -0,0 +1,35 @@
notice('MODULAR: openstack-network/agents/sriov.pp')
$use_neutron = hiera('use_neutron', false)
$network_scheme = hiera_hash('network_scheme', {})
$neutron_config = hiera_hash('neutron_config')
$pci_vendor_devs = pick($neutron_config['supported_pci_vendor_devs'], false)
class neutron {}
class { 'neutron' :}
if $use_neutron and $pci_vendor_devs {
prepare_network_config($network_scheme)
$pci_passthrough_whitelist = get_nic_passthrough_whitelist('sriov')
$physical_device_mappings = nic_whitelist_to_mappings($pci_passthrough_whitelist)
class { 'neutron::agents::ml2::sriov':
physical_device_mappings => $physical_device_mappings,
manage_service => true,
enabled => true,
}
# stub package for 'neutron::agents::sriov' class
package { 'neutron':
name => 'binutils',
ensure => 'installed',
}
# override neutron options
$override_configuration = hiera_hash('configuration', {})
override_resources { 'neutron_sriov_agent_config':
data => $override_configuration['neutron_sriov_agent_config']
}
}

View File

@ -30,6 +30,7 @@ if $use_neutron {
$nova_endpoint = hiera('nova_endpoint', $management_vip)
$nova_hash = hiera_hash('nova', { })
$primary_controller = roles_include(['primary-controller'])
$pci_vendor_devs = $neutron_config['supported_pci_vendor_devs']
$db_type = 'mysql'
$db_password = $neutron_config['database']['passwd']
@ -51,6 +52,15 @@ if $use_neutron {
'extra' => $extra_params
})
if $pci_vendor_devs {
# Boolean value for further usage
$use_sriov = true
$ml2_sriov_value = 'set DAEMON_ARGS \'"--config-file /etc/neutron/plugins/ml2/ml2_conf_sriov.ini"\''
} else {
$use_sriov = false
$ml2_sriov_value = 'rm DAEMON_ARGS'
}
$auth_password = $neutron_config['keystone']['admin_password']
$auth_user = pick($neutron_config['keystone']['admin_user'], 'neutron')
$auth_tenant = pick($neutron_config['keystone']['admin_tenant'], 'services')
@ -86,15 +96,26 @@ if $use_neutron {
$nova_auth_password = $nova_hash['user_password']
$nova_auth_tenant = pick($nova_hash['tenant'], 'services')
$type_drivers = ['local', 'flat', 'vlan', 'gre', 'vxlan']
$default_mechanism_drivers = $l2_population ? { true => 'openvswitch,l2population', default => 'openvswitch'}
$mechanism_drivers = split(try_get_value($neutron_config, 'L2/mechanism_drivers', $default_mechanism_drivers), ',')
$flat_networks = ['*']
$segmentation_type = try_get_value($neutron_config, 'L2/segmentation_type')
$type_drivers = ['local', 'flat', 'vlan', 'gre', 'vxlan']
$default_mechanism_drivers = ['openvswitch']
$l2_population_mech_driver = $l2_population ? { true => ['l2population'], default => []}
$sriov_mech_driver = $use_sriov ? { true => ['sriovnicswitch'], default => []}
$mechanism_drivers = delete(try_get_value($neutron_config, 'L2/mechanism_drivers', concat($default_mechanism_drivers,$l2_population_mech_driver,$sriov_mech_driver)), "")
$flat_networks = ['*']
$segmentation_type = try_get_value($neutron_config, 'L2/segmentation_type')
$network_scheme = hiera_hash('network_scheme')
$network_scheme = hiera_hash('network_scheme', {})
prepare_network_config($network_scheme)
if ! $compute and $::osfamily == 'Debian' {
augeas { '/etc/default/neutron-server:ml2_sriov_config':
context => '/files/etc/default/neutron-server',
changes => $ml2_sriov_value,
notify => Service['neutron-server'],
}
Class['neutron::plugins::ml2'] -> Augeas['/etc/default/neutron-server:ml2_sriov_config']
}
if $segmentation_type == 'vlan' {
$net_role_property = 'neutron/private'
$iface = get_network_role_property($net_role_property, 'phys_dev')
@ -153,17 +174,19 @@ if $use_neutron {
$tenant_network_types = ['flat', $network_type]
class { 'neutron::plugins::ml2':
type_drivers => $type_drivers,
tenant_network_types => $tenant_network_types,
mechanism_drivers => $mechanism_drivers,
flat_networks => $flat_networks,
network_vlan_ranges => $network_vlan_ranges,
tunnel_id_ranges => $tunnel_id_ranges,
vxlan_group => $vxlan_group,
vni_ranges => $tunnel_id_ranges,
physical_network_mtus => $physical_network_mtus,
path_mtu => $overlay_net_mtu,
extension_drivers => $extension_drivers,
type_drivers => $type_drivers,
tenant_network_types => $tenant_network_types,
mechanism_drivers => $mechanism_drivers,
flat_networks => $flat_networks,
network_vlan_ranges => $network_vlan_ranges,
tunnel_id_ranges => $tunnel_id_ranges,
vxlan_group => $vxlan_group,
vni_ranges => $tunnel_id_ranges,
physical_network_mtus => $physical_network_mtus,
path_mtu => $overlay_net_mtu,
extension_drivers => $extension_drivers,
supported_pci_vendor_devs => $pci_vendor_devs,
sriov_agent_required => $use_sriov,
}
class { 'neutron::server':

View File

@ -152,6 +152,18 @@
puppet_modules: /etc/puppet/modules
timeout: 1800
- id: openstack-network-agents-sriov
type: puppet
version: 2.0.0
groups: [compute]
required_for: [openstack-network-end]
requires: [openstack-network-plugins-l2]
refresh_on: [neutron_sriov_agent_config]
parameters:
puppet_manifest: /etc/puppet/modules/osnailyfacter/modular/openstack-network/agents/sriov.pp
puppet_modules: /etc/puppet/modules
timeout: 1800
- id: openstack-network-server-nova
type: puppet
version: 2.0.0

View File

@ -309,6 +309,7 @@ class { '::openstack::compute':
network_provider => $network_provider,
neutron_user_password => $oc_neutron_user_password,
base_mac => $base_mac,
pci_passthrough => nic_whitelist_to_json(get_nic_passthrough_whitelist('sriov')),
use_syslog => $use_syslog,
syslog_log_facility => $syslog_log_facility_nova,

View File

@ -392,6 +392,30 @@ describe manifest do
end
end
it 'should declare nova::scheduler::filter with an appropriate filters' do
nova_scheduler_filters = []
nova_scheduler_default_filters = [ 'RetryFilter', 'AvailabilityZoneFilter', 'RamFilter', 'CoreFilter', 'DiskFilter', 'ComputeFilter', 'ComputeCapabilitiesFilter', 'ImagePropertiesFilter', 'ServerGroupAntiAffinityFilter', 'ServerGroupAffinityFilter' ]
sahara_filters = [ 'DifferentHostFilter' ]
sriov_filters = [ 'PciPassthroughFilter','AggregateInstanceExtraSpecsFilter' ]
enable_sahara = Noop.hiera_structure 'sahara/enabled', false
enable_sriov = Noop.hiera_structure 'quantum_settings/supported_pci_vendor_devs', false
nova_scheduler_filters = nova_scheduler_filters.concat(nova_scheduler_default_filters)
if enable_sahara
nova_scheduler_filters = nova_scheduler_filters.concat(sahara_filters)
end
if enable_sriov
nova_scheduler_filters = nova_scheduler_filters.concat(sriov_filters)
end
should contain_class('nova::scheduler::filter').with(
'scheduler_default_filters' => nova_scheduler_filters.uniq(),
)
end
if primary_controller
it 'should have explicit ordering between LB classes and particular actions' do
expect(graph).to ensure_transitive_dependency("Class[nova::api]","Haproxy_backend_status[nova-api]")

View File

@ -0,0 +1,44 @@
require 'spec_helper'
require 'shared-examples'
manifest = 'openstack-network/agents/sriov.pp'
describe manifest do
before(:each) do
Noop.puppet_function_load :is_pkg_installed
MockFunction.new(:is_pkg_installed) do |function|
allow(function).to receive(:call).and_return false
end
end
enable_sriov = Noop.hiera_structure 'quantum_settings/supported_pci_vendor_devs', false
shared_examples 'catalog' do
if Noop.hiera('use_neutron') and enable_sriov
let(:network_scheme) do
Noop.hiera_hash('network_scheme', {})
end
let(:prepare) do
Noop.puppet_function('prepare_network_config', network_scheme)
end
let(:pci_passthrough) do
prepare
Noop.puppet_function('get_nic_passthrough_whitelist', 'sriov')
end
context 'with Neutron SRIOV agent' do
it { should contain_class('neutron::agents::ml2::sriov').with(
'manage_service' => true,
'enabled' => true,
'physical_device_mappings' => Noop.puppet_function('nic_whitelist_to_mappings', pci_passthrough)
)}
end
end
end
test_ubuntu_and_centos manifest
end

View File

@ -46,6 +46,15 @@ describe manifest do
role = Noop.hiera('role')
adv_neutron_config = Noop.hiera_hash('neutron_advanced_configuration')
dvr = adv_neutron_config.fetch('neutron_dvr', false)
pci_vendor_devs = neutron_config.fetch('supported_pci_vendor_devs', false)
if pci_vendor_devs
use_sriov = true
ml2_sriov_value = 'set DAEMON_ARGS \'"--config-file /etc/neutron/plugins/ml2/ml2_conf_sriov.ini"\''
else
use_sriov = false
ml2_sriov_value = 'rm DAEMON_ARGS'
end
if segmentation_type == 'vlan'
network_type = 'vlan'
@ -210,10 +219,35 @@ describe manifest do
l2_population = adv_neutron_config.fetch('neutron_l2_pop', false)
default_mechanism_drivers = ['openvswitch']
l2_population_mech_driver = ['l2population']
sriov_mech_driver = ['sriovnicswitch']
mechanism_drivers = default_mechanism_drivers
if l2_population
default_mechanism_drivers = 'openvswitch,l2population'
else
default_mechanism_drivers = 'openvswitch'
mechanism_drivers = mechanism_drivers.concat(l2_population_mech_driver)
end
if use_sriov
mechanism_drivers = mechanism_drivers.concat(sriov_mech_driver)
end
it 'sets up ml2_sriov_config for neutron-server' do
if role != 'compute' and facts[:osfamily] == 'Debian'
should contain_augeas('/etc/default/neutron-server:ml2_sriov_config').with(
'context' => '/files/etc/default/neutron-server',
'changes' => ml2_sriov_value,
).that_notifies('Service[neutron-server]')
should contain_class('neutron::plugins::ml2').that_comes_before('Augeas[/etc/default/neutron-server:ml2_sriov_config]')
end
end
if pci_vendor_devs
it { should contain_class('neutron::plugins::ml2').with(
'supported_pci_vendor_devs' => pci_vendor_devs,
)}
it { should contain_class('neutron::plugins::ml2').with(
'sriov_agent_required' => use_sriov,
)}
end
it { should contain_service('neutron-server').with(
@ -233,7 +267,7 @@ describe manifest do
'tenant_network_types' => ['flat', network_type],
)}
it { should contain_class('neutron::plugins::ml2').with(
'mechanism_drivers' => neutron_config.fetch('L2', {}).fetch('mechanism_drivers', default_mechanism_drivers).split(',')
'mechanism_drivers' => neutron_config.fetch('L2', {}).fetch('mechanism_drivers', mechanism_drivers)
)}
it { should contain_class('neutron::plugins::ml2').with(
'network_vlan_ranges' => network_vlan_ranges,

View File

@ -44,6 +44,19 @@ describe manifest do
{ 'reserved_host_memory' => [[Float(facts[:memorysize_mb]).floor * 0.2, 512].max, 1536].min }
end
let(:network_scheme) do
Noop.hiera_hash('network_scheme', {})
end
let(:prepare) do
Noop.puppet_function('prepare_network_config', network_scheme)
end
let(:nic_passthrough_whitelist) do
prepare
Noop.puppet_function('get_nic_passthrough_whitelist', 'sriov')
end
# Libvirtd.conf
it 'should configure listen_tls, listen_tcp and auth_tcp in libvirtd.conf' do
should contain_augeas('libvirt-conf').with(
@ -218,6 +231,12 @@ describe manifest do
)
end
enable_sriov = Noop.hiera_structure 'quantum_settings/supported_pci_vendor_devs', false
it 'should pass pci_passthrough_whitelist to nova::compute' , :if => enable_sriov do
pci_passthrough_json = Noop.puppet_function 'nic_whitelist_to_json', nic_passthrough_whitelist
should contain_class('nova::compute').with('pci_passthrough' => pci_passthrough_json)
end
# Check out nova config params
it 'should properly configure nova' do
node_name = Noop.hiera('node_name')