diff --git a/config.yaml b/config.yaml index dac9b40b..3b3e048a 100644 --- a/config.yaml +++ b/config.yaml @@ -395,6 +395,27 @@ options: Set to a named libvirt CPU model (see names listed in /usr/share/libvirt/cpu_map.xml). Only has effect if cpu_mode='custom' and virt_type='kvm|qemu'. + . + Starting from the Train release this option is deprecated and + has been superseded by the 'cpu-models' option. This option will be + silently ignored if the 'cpu-models' option is non-empty. + cpu-models: + type: string + default: + description: | + An ordered, comma separated, list of the CPU models supported by the host. + The models on the list must be ordered according to the features they + support. The less advanced models must precede more advanced, feature + rich, models. + . + Example: 'SandyBridge,IvyBridge,Haswell,Broadwell' + . + CPU models are listed in: + * /usr/share/libvirt/cpu_map.xml (libvirt version < 4.7.0) + * /usr/share/libvirt/cpu_map/*.xml (libvirt version >= 4.7.0) + . + This option only has effect if cpu_mode='custom' and + virt_type='kvm|qemu'. cpu-model-extra-flags: type: string default: diff --git a/hooks/nova_compute_context.py b/hooks/nova_compute_context.py index 89e1780f..63b11378 100644 --- a/hooks/nova_compute_context.py +++ b/hooks/nova_compute_context.py @@ -278,7 +278,9 @@ class NovaComputeLibvirtContext(context.OSContextGenerator): elif ctxt['arch'] == 's390x': ctxt['cpu_mode'] = 'none' - if config('cpu-model'): + if config('cpu-models'): + ctxt['cpu_models'] = config('cpu-models') + elif config('cpu-model'): ctxt['cpu_model'] = config('cpu-model') if config('cpu-model-extra-flags'): diff --git a/templates/train/nova.conf b/templates/train/nova.conf index 6fc71653..702c813e 100644 --- a/templates/train/nova.conf +++ b/templates/train/nova.conf @@ -287,6 +287,9 @@ inject_partition = {{ inject_partition }} {% if cpu_mode -%} cpu_mode = {{ cpu_mode }} {% endif -%} +{% if cpu_models -%} +cpu_models = {{ cpu_models }} +{% endif -%} {% if cpu_model -%} cpu_model = {{ cpu_model }} {% endif -%} diff --git a/templates/yoga/nova.conf b/templates/yoga/nova.conf index 16e702d1..f9f74f20 100644 --- a/templates/yoga/nova.conf +++ b/templates/yoga/nova.conf @@ -270,6 +270,9 @@ inject_partition = {{ inject_partition }} {% if cpu_mode -%} cpu_mode = {{ cpu_mode }} {% endif -%} +{% if cpu_models -%} +cpu_models = {{ cpu_models }} +{% endif -%} {% if cpu_model -%} cpu_model = {{ cpu_model }} {% endif -%} diff --git a/unit_tests/test_nova_compute_contexts.py b/unit_tests/test_nova_compute_contexts.py index 3f6558b6..db09d7e4 100644 --- a/unit_tests/test_nova_compute_contexts.py +++ b/unit_tests/test_nova_compute_contexts.py @@ -842,6 +842,41 @@ class NovaComputeContextTests(CharmTestCase): self.assertEqual(libvirt()['cpu_mode'], 'none') + @patch.object(context.uuid, 'uuid4') + def test_libvirt_cpu_mode_custom_model(self, mock_uuid): + self.test_config.set('cpu-mode', 'custom') + self.test_config.set('cpu-model', 'Broadwell') + self.lsb_release.return_value = {'DISTRIB_CODENAME': 'bionic'} + mock_uuid.return_value = 'e46e530d-18ae-4a67-9ff0-e6e2ba7c60a7' + libvirt = context.NovaComputeLibvirtContext() + + self.assertEqual(libvirt()['cpu_mode'], 'custom') + self.assertEqual(libvirt()['cpu_model'], 'Broadwell') + + # should be ignored + self.test_config.set('cpu-mode', 'host-model') + self.test_config.set('cpu-model', 'Haswell') + libvirt = context.NovaComputeLibvirtContext() + self.assertNotIn('cpu-model', libvirt()) + + @patch.object(context.uuid, 'uuid4') + def test_libvirt_cpu_mode_custom_models(self, mock_uuid): + self.test_config.set('cpu-mode', 'custom') + self.test_config.set('cpu-models', + 'SandyBridge,IvyBridge,Haswell,Broadwell') + self.lsb_release.return_value = {'DISTRIB_CODENAME': 'bionic'} + mock_uuid.return_value = 'e46e530d-18ae-4a67-9ff0-e6e2ba7c60a7' + libvirt = context.NovaComputeLibvirtContext() + + self.assertEqual(libvirt()['cpu_mode'], 'custom') + self.assertEqual(libvirt()['cpu_models'], + 'SandyBridge,IvyBridge,Haswell,Broadwell') + + # should be ignored + self.test_config.set('cpu-model', 'Haswell') + libvirt = context.NovaComputeLibvirtContext() + self.assertNotIn('cpu_model', libvirt()) + @patch.object(context, 'platform') @patch.object(context.uuid, 'uuid4') def test_libvirt_cpu_mode_aarch64(self, mock_uuid, mock_platform):