From 80941110b74d463a6a79fd77a97789113f71955e Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Thu, 17 Mar 2022 21:58:51 +0900 Subject: [PATCH] Support [mdev_] mdev_class Since Xena release, nova supports defining device class for each mdev type[1]. This change introduces the new mdev_types parameter and the resource type support for the parameter. [1] 9be996c696e91e82d11d81db72ffb4cc151598b6 The existing interface is still kept, to make this change backportable to older stable branches, but will be deprecated in master later. Change-Id: I7a7d22eb9aa27cebabb2cf04a7f1451741c6d4c3 --- manifests/compute/mdev.pp | 63 +++++++++-------- manifests/compute/mdev_type.pp | 45 ++++++++++++ manifests/compute/vgpu.pp | 4 ++ .../notes/mdev-opts-f0f62793096d890c.yaml | 7 ++ spec/classes/nova_compute_mdev_spec.rb | 69 +++++++++++++++---- spec/classes/nova_compute_vgpu_spec.rb | 2 +- 6 files changed, 146 insertions(+), 44 deletions(-) create mode 100644 manifests/compute/mdev_type.pp create mode 100644 releasenotes/notes/mdev-opts-f0f62793096d890c.yaml diff --git a/manifests/compute/mdev.pp b/manifests/compute/mdev.pp index ace076aef..e2b4e45da 100644 --- a/manifests/compute/mdev.pp +++ b/manifests/compute/mdev.pp @@ -4,52 +4,55 @@ # # === Parameters: # -# [*mdev_types_device_addresses_mapping*] -# (optional) Map of mdev type(s) the instances can get as key and list of -# corresponding device addresses as value. +# [*mdev_types*] +# (Optional) A hash to define the nova::compute::mdev_type resources. # Defaults to {} # +# [*mdev_types_device_addresses_mapping*] +# (Optional) Map of mdev type(s) the instances can get as key and list of +# corresponding device addresses as value. +# Defaults to undef +# class nova::compute::mdev( - $mdev_types_device_addresses_mapping = {}, + $mdev_types = {}, + $mdev_types_device_addresses_mapping = undef, ) { include nova::deps - # TODO(tkajinam): Remove this when we remove nova::compute::vgpu - $mdev_types_device_addresses_mapping_real = pick( + validate_legacy(Hash, 'validate_hash', $mdev_types) + if $mdev_types_device_addresses_mapping != undef { + validate_legacy(Hash, 'validate_hash', $mdev_types_device_addresses_mapping) + } + + # TODO(tkajinam): Remove vgpu parameter when we remove nova::compute::vgpu + $dev_addr_mapping_real = pick_default( $::nova::compute::vgpu::vgpu_types_device_addresses_mapping, - $mdev_types_device_addresses_mapping) + pick_default($mdev_types_device_addresses_mapping, {})) - if !empty($mdev_types_device_addresses_mapping_real) { - validate_legacy(Hash, 'validate_hash', $mdev_types_device_addresses_mapping_real) - $mdev_types_real = keys($mdev_types_device_addresses_mapping_real) + if !empty($dev_addr_mapping_real) { nova_config { - 'devices/enabled_mdev_types': value => join(any2array($mdev_types_real), ','); + 'devices/enabled_mdev_types': value => join(keys($dev_addr_mapping_real), ','); } - # TODO(tkajinam): Remove this when we remove nova::compute::vgpu - nova_config { - 'devices/enabled_vgpu_types': ensure => absent; - } - - $mdev_types_device_addresses_mapping_real.each |$mdev_type, $device_addresses| { - if !empty($device_addresses) { - nova_config { - "mdev_${mdev_type}/device_addresses": value => join(any2array($device_addresses), ','); - } - - # TODO(tkajinam): Remove this when we remove nova::compute::vgpu - nova_config { - "vgpu_${mdev_type}/device_addresses": ensure => absent; - } - } else { - nova_config { - "mdev_${mdev_type}/device_addresses": ensure => absent; - } + $dev_addr_mapping_real.each |$mdev_type, $device_addresses| { + nova::compute::mdev_type { $mdev_type : + device_addresses => $device_addresses; } } + } elsif !empty($mdev_types) { + nova_config { + 'devices/enabled_mdev_types': value => join(keys($mdev_types), ',') + } + create_resources('nova::compute::mdev_type', $mdev_types) } else { nova_config { 'devices/enabled_mdev_types': ensure => absent; } } + + # TODO(tkajinam): Remove this when we remove nova::compute::vgpu + nova_config { + 'devices/enabled_vgpu_types': ensure => absent; + } + } diff --git a/manifests/compute/mdev_type.pp b/manifests/compute/mdev_type.pp new file mode 100644 index 000000000..bb1418d71 --- /dev/null +++ b/manifests/compute/mdev_type.pp @@ -0,0 +1,45 @@ +# Define nova::compute::mdev_type +# +# Configures nova compute mdev_ options +# +# === Parameters: +# +# [*mdev_type*] +# (Optional) mdev type +# Defaults to $name +# +# [*device_addresses*] +# (Optional) A list of PCI addresses corresponding to the physical GPU(s) or +# mdev-capable hardware. +# Defaults to $::os_service_default +# +# [*mdev_class*] +# (Optional) Class of mediated device to manage used to differentiate between +# device type. +# Defaults to $::os_service_default +# +define nova::compute::mdev_type ( + $mdev_type = $name, + $device_addresses = $::os_service_default, + $mdev_class = $::os_service_default, +) { + + if empty($device_addresses) { + nova_config { + "mdev_${mdev_type}/device_addresses": value => $::os_service_default + } + } else { + nova_config { + "mdev_${mdev_type}/device_addresses": value => join(any2array($device_addresses), ','); + } + } + + # TODO(tkajinam): Remove this when we remove nova::compute::vgpu + nova_config { + "vgpu_${mdev_type}/device_addresses": ensure => absent; + } + + nova_config { + "mdev_${mdev_type}/mdev_class": value => $mdev_class; + } +} diff --git a/manifests/compute/vgpu.pp b/manifests/compute/vgpu.pp index 4ea36bd24..e62ece7d1 100644 --- a/manifests/compute/vgpu.pp +++ b/manifests/compute/vgpu.pp @@ -15,6 +15,10 @@ class nova::compute::vgpu( ) { include nova::deps + if $vgpu_types_device_addresses_mapping != undef { + validate_legacy(Hash, 'validate_hash', $vgpu_types_device_addresses_mapping) + } + if $vgpu_types_device_addresses_mapping != undef or ! defined(Class[nova::compute]) { # NOTE(tkajinam): If the nova::compute class is not yet included then it is # likely this class is included explicitly. diff --git a/releasenotes/notes/mdev-opts-f0f62793096d890c.yaml b/releasenotes/notes/mdev-opts-f0f62793096d890c.yaml new file mode 100644 index 000000000..05d698b42 --- /dev/null +++ b/releasenotes/notes/mdev-opts-f0f62793096d890c.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + The new ``nova::compute::mdev_type`` resource type has been added. + + - | + The new ``nova::compute::mdev::mdev_types`` parameter has been added. diff --git a/spec/classes/nova_compute_mdev_spec.rb b/spec/classes/nova_compute_mdev_spec.rb index c17039e75..5471cd1ce 100644 --- a/spec/classes/nova_compute_mdev_spec.rb +++ b/spec/classes/nova_compute_mdev_spec.rb @@ -9,27 +9,70 @@ describe 'nova::compute::mdev' do end end - context 'with mdev types and device addresses mapping' do + context 'with mdev_types' do let :params do { - :mdev_types_device_addresses_mapping => { "nvidia-35" => [] }, + :mdev_types => { + 'nvidia-35' => { + 'device_addresses' => ['0000:84:00.0', '0000:85:00.0'] + }, + 'nvidia-36' => { + 'device_addresses' => [], + 'mdev_class' => 'CUSTOM_MDEV1' + }, + 'nvidia-37' => { + 'mdev_class' => 'VGPU' + } + } } end - it { is_expected.to contain_nova_config('devices/enabled_mdev_types').with_value('nvidia-35') } - it { is_expected.to contain_nova_config('mdev_nvidia-35/device_addresses').with_ensure('absent') } + + it 'configures mdev devices' do + is_expected.to contain_nova_config('devices/enabled_mdev_types').with_value('nvidia-35,nvidia-36,nvidia-37') + is_expected.to contain_nova_config('mdev_nvidia-35/device_addresses').with_value('0000:84:00.0,0000:85:00.0') + is_expected.to contain_nova_config('mdev_nvidia-35/mdev_class').with_value('') + is_expected.to contain_nova_config('mdev_nvidia-36/device_addresses').with_value('') + is_expected.to contain_nova_config('mdev_nvidia-36/mdev_class').with_value('CUSTOM_MDEV1') + is_expected.to contain_nova_config('mdev_nvidia-37/device_addresses').with_value('') + is_expected.to contain_nova_config('mdev_nvidia-37/mdev_class').with_value('VGPU') + end end - context 'with multiple mdev types and corresponding device addresses mapping' do - let :params do - { - :mdev_types_device_addresses_mapping => { "nvidia-35" => ['0000:84:00.0', '0000:85:00.0'], - "nvidia-36" => ['0000:86:00.0'] } - } + context 'with device addresses mapping' do + context 'with a single mdev type' do + let :params do + { + :mdev_types_device_addresses_mapping => { + "nvidia-35" => [] + } + } + end + + it 'configures mdev devices' do + is_expected.to contain_nova_config('devices/enabled_mdev_types').with_value('nvidia-35') + is_expected.to contain_nova_config('mdev_nvidia-35/device_addresses').with_value('') + is_expected.to contain_nova_config('mdev_nvidia-35/mdev_class').with_value('') + end end - it { is_expected.to contain_nova_config('devices/enabled_mdev_types').with_value('nvidia-35,nvidia-36') } - it { is_expected.to contain_nova_config('mdev_nvidia-35/device_addresses').with_value('0000:84:00.0,0000:85:00.0') } - it { is_expected.to contain_nova_config('mdev_nvidia-36/device_addresses').with_value('0000:86:00.0') } + context 'with multiple mdev types' do + let :params do + { + :mdev_types_device_addresses_mapping => { + 'nvidia-35' => ['0000:84:00.0', '0000:85:00.0'], + 'nvidia-36' => [] + } + } + end + + it 'configures mdev devices' do + is_expected.to contain_nova_config('devices/enabled_mdev_types').with_value('nvidia-35,nvidia-36') + is_expected.to contain_nova_config('mdev_nvidia-35/device_addresses').with_value('0000:84:00.0,0000:85:00.0') + is_expected.to contain_nova_config('mdev_nvidia-35/mdev_class').with_value('') + is_expected.to contain_nova_config('mdev_nvidia-36/device_addresses').with_value('') + is_expected.to contain_nova_config('mdev_nvidia-36/mdev_class').with_value('') + end + end end end diff --git a/spec/classes/nova_compute_vgpu_spec.rb b/spec/classes/nova_compute_vgpu_spec.rb index 1352c3203..56f9ab74c 100644 --- a/spec/classes/nova_compute_vgpu_spec.rb +++ b/spec/classes/nova_compute_vgpu_spec.rb @@ -16,7 +16,7 @@ describe 'nova::compute::vgpu' do } end it { is_expected.to contain_nova_config('devices/enabled_mdev_types').with_value('nvidia-35') } - it { is_expected.to contain_nova_config('mdev_nvidia-35/device_addresses').with_ensure('absent') } + it { is_expected.to contain_nova_config('mdev_nvidia-35/device_addresses').with_value('') } end context 'with multiple vgpu types and corresponding device addresses mapping' do