diff --git a/lib/puppet/provider/neutron_agent_sriov_numvfs/sriov_numvfs.rb b/lib/puppet/provider/neutron_agent_sriov_numvfs/sriov_numvfs.rb new file mode 100644 index 000000000..1ea62c133 --- /dev/null +++ b/lib/puppet/provider/neutron_agent_sriov_numvfs/sriov_numvfs.rb @@ -0,0 +1,58 @@ +Puppet::Type.type(:neutron_agent_sriov_numvfs).provide(:sriov_numvfs) do + desc <<-EOT + The file /sys/class/net//device/sriov_numvfs will be + present when a physical PCIe device supports SR-IOV. A number written to + this file will enable the specified number of VFs. This provider shall read + the file and ensure that the value is zero, before writing the number of + VFs that should be enabled. If the VFs needs to be disabled then we shall + write a zero to this file. + EOT + + def create + if File.file?(sriov_numvfs_path) + _set_numvfs + else + fail("#{sriov_numvfs_path} doesn't exist. Check if #{sriov_get_interface} is a valid network interface supporting SR-IOV") + end + end + + def destroy + if File.file?(sriov_numvfs_path) + File.write(sriov_numvfs_path,"0") + end + end + + def exists? + if File.file?(sriov_numvfs_path) + cur_value = File.read(sriov_numvfs_path) + if cur_value.to_i == sriov_numvfs_value + return true + end + end + return false + end + + def _set_numvfs + # During an update, the content of file sriov_numvfs_path has to be set + # to 0 (ZERO), before writing the actual value + cur_value = File.read(sriov_numvfs_path) + if cur_value != 0 + File.write(sriov_numvfs_path,"0") + end + File.write(sriov_numvfs_path,sriov_numvfs_value) + end + + def sriov_numvfs_path + "/sys/class/net/#{sriov_get_interface}/device/sriov_numvfs" + end + + def sriov_get_interface + resource[:name].split(':', 2).first + end + + def sriov_numvfs_value + resource[:name].split(':', 2).last.to_i + end + +end + diff --git a/lib/puppet/type/neutron_agent_sriov_numvfs.rb b/lib/puppet/type/neutron_agent_sriov_numvfs.rb new file mode 100644 index 000000000..27cfee4f2 --- /dev/null +++ b/lib/puppet/type/neutron_agent_sriov_numvfs.rb @@ -0,0 +1,11 @@ +Puppet::Type.newtype(:neutron_agent_sriov_numvfs) do + + ensurable + + newparam(:name) do + desc "sriov_numvfs conf as : format" + newvalues(/^[a-z0-9-_]+:[0-9]+$/) + end + +end + diff --git a/manifests/agents/ml2/sriov.pp b/manifests/agents/ml2/sriov.pp index fba57d8c3..95162e947 100644 --- a/manifests/agents/ml2/sriov.pp +++ b/manifests/agents/ml2/sriov.pp @@ -62,6 +62,13 @@ # in the sriov config. # Defaults to false. # +# [*number_of_vfs*] +# (optional) List of : specifying the number +# VFs to be exposed per physical interface. +# For example, to configure two inteface with number of VFs, specify +# it as "eth1:4,eth2:10" +# Defaults to $::os_service_default. +# class neutron::agents::ml2::sriov ( $package_ensure = 'present', $enabled = true, @@ -71,6 +78,7 @@ class neutron::agents::ml2::sriov ( $exclude_devices = $::os_service_default, $extensions = $::os_service_default, $purge_config = false, + $number_of_vfs = $::os_service_default, ) { include ::neutron::deps @@ -87,6 +95,10 @@ class neutron::agents::ml2::sriov ( 'agent/extensions': value => join(any2array($extensions), ','); } + if !is_service_default($number_of_vfs) and !empty($number_of_vfs) { + neutron_agent_sriov_numvfs { $number_of_vfs: ensure => present } + } + package { 'neutron-sriov-nic-agent': ensure => $package_ensure, name => $::neutron::params::sriov_nic_agent_package, diff --git a/releasenotes/notes/sriov-numvfs-configuration-3ae862cf09a9a813.yaml b/releasenotes/notes/sriov-numvfs-configuration-3ae862cf09a9a813.yaml new file mode 100644 index 000000000..d861377df --- /dev/null +++ b/releasenotes/notes/sriov-numvfs-configuration-3ae862cf09a9a813.yaml @@ -0,0 +1,3 @@ +--- +features: + - Added a provider to configure VFs for SR-IOV interface diff --git a/spec/classes/neutron_agents_ml2_sriov_spec.rb b/spec/classes/neutron_agents_ml2_sriov_spec.rb index aa347ab23..a854fb014 100644 --- a/spec/classes/neutron_agents_ml2_sriov_spec.rb +++ b/spec/classes/neutron_agents_ml2_sriov_spec.rb @@ -46,7 +46,9 @@ describe 'neutron::agents::ml2::sriov' do is_expected.to contain_neutron_sriov_agent_config('agent/extensions').with_value(['']) end - + it 'does not configure numvfs by default' do + is_expected.not_to contain_neutron_agents_ml2_sriov_numvfs('') + end it 'installs neutron sriov-nic agent package' do is_expected.to contain_package('neutron-sriov-nic-agent').with( @@ -69,6 +71,27 @@ describe 'neutron::agents::ml2::sriov' do is_expected.to contain_service('neutron-sriov-nic-agent-service').that_notifies('Anchor[neutron::service::end]') end + context 'when number_of_vfs is empty' do + before :each do + params.merge!(:number_of_vfs => "") + end + + it 'does not configure numvfs ' do + is_expected.not_to contain_neutron_agents_ml2_sriov_numvfs('') + end + end + + context 'when number_of_vfs is configured' do + before :each do + params.merge!(:number_of_vfs => ['eth0:4','eth1:5']) + end + + it 'configures numvfs' do + is_expected.to contain_neutron_agent_sriov_numvfs('eth0:4').with( :ensure => 'present' ) + is_expected.to contain_neutron_agent_sriov_numvfs('eth1:5').with( :ensure => 'present') + end + end + context 'with manage_service as false' do before :each do params.merge!(:manage_service => false) diff --git a/spec/unit/provider/neutron_agent_sriov_numvfs/sriov_numvfs_spec.rb b/spec/unit/provider/neutron_agent_sriov_numvfs/sriov_numvfs_spec.rb new file mode 100644 index 000000000..737846f2b --- /dev/null +++ b/spec/unit/provider/neutron_agent_sriov_numvfs/sriov_numvfs_spec.rb @@ -0,0 +1,36 @@ +require 'puppet' +require 'spec_helper' +require 'puppet/provider/neutron_agent_sriov_numvfs/sriov_numvfs' + +provider_class = Puppet::Type.type(:neutron_agent_sriov_numvfs). + provider(:sriov_numvfs) + +describe provider_class do + + let :numvfs_conf do + { + :name => 'eth0:10', + :ensure => 'present', + } + end + + describe 'when setting the attributes' do + let :resource do + Puppet::Type::Neutron_agent_sriov_numvfs.new(numvfs_conf) + end + + let :provider do + provider_class.new(resource) + end + + it 'should return the correct interface name' do + expect(provider.sriov_get_interface).to eql('eth0') + end + + it 'should return the correct numvfs value' do + expect(provider.sriov_numvfs_value).to eql(10) + end + + end + +end diff --git a/spec/unit/type/neutron_agent_sriov_numvfs_spec.rb b/spec/unit/type/neutron_agent_sriov_numvfs_spec.rb new file mode 100644 index 000000000..45e14d17c --- /dev/null +++ b/spec/unit/type/neutron_agent_sriov_numvfs_spec.rb @@ -0,0 +1,47 @@ +require 'puppet' +require 'puppet/type/neutron_agent_sriov_numvfs' + +describe 'Puppet::Type.type(:neutron_agent_sriov_numvfs)' do + it 'should allow name to be passed' do + expect{Puppet::Type.type(:neutron_agent_sriov_numvfs).new( + :name => 'eth0:10', + :ensure => 'present' + )}.not_to raise_error + end + it 'should allow name to be passed with -' do + expect{Puppet::Type.type(:neutron_agent_sriov_numvfs).new( + :name => 'eth-0:10', + :ensure => 'present' + )}.not_to raise_error + end + it 'should allow name to be passed with _' do + expect{Puppet::Type.type(:neutron_agent_sriov_numvfs).new( + :name => 'eth_0:10', + :ensure => 'present' + )}.not_to raise_error + end + it 'should throw error for invalid format' do + expect{Puppet::Type.type(:neutron_agent_sriov_numvfs).new( + :name => 'eth0', + :ensure => 'present' + )}.to raise_error(Puppet::ResourceError) + end + it 'should throw error for invalid format without interface name' do + expect{Puppet::Type.type(:neutron_agent_sriov_numvfs).new( + :name => ':9', + :ensure => 'present' + )}.to raise_error(Puppet::ResourceError) + end + it 'should throw error for invalid format for numvfs' do + expect{Puppet::Type.type(:neutron_agent_sriov_numvfs).new( + :name => 'eth8:none', + :ensure => 'present' + )}.to raise_error(Puppet::ResourceError) + end + it 'should throw error for invalid format without numvfs' do + expect{Puppet::Type.type(:neutron_agent_sriov_numvfs).new( + :name => 'eth0:', + :ensure => 'present' + )}.to raise_error(Puppet::ResourceError) + end +end