Merge "Validate [pci]alias at service startup"

This commit is contained in:
Zuul
2025-06-12 03:31:11 +00:00
committed by Gerrit Code Review
6 changed files with 43 additions and 12 deletions
+6
View File
@@ -26,6 +26,7 @@ from nova import config
from nova import context
from nova import exception
from nova import objects
from nova.pci import request
from nova import service
from nova import utils
from nova import version
@@ -51,6 +52,11 @@ def _get_config_files(env=None):
def _setup_service(host, name):
# NOTE(gibi): validate the [pci]alias config early to avoid late failures
# at instance creation due to config errors.
request.get_alias_from_config()
try:
utils.raise_if_old_compute()
except exception.TooOldComputeService as e:
+4
View File
@@ -1620,6 +1620,10 @@ class ComputeManager(manager.Manager):
# if the configuration is wrong.
whitelist.Whitelist(CONF.pci.device_spec)
# NOTE(gibi): validate the [pci]alias config early to avoid late
# failures at instance lifecycle operations due to config errors.
pci_req_module.get_alias_from_config()
nova.conf.neutron.register_dynamic_opts(CONF)
# Even if only libvirt uses them, make it available for all drivers
nova.conf.devices.register_dynamic_opts(CONF)
+2 -2
View File
@@ -173,7 +173,7 @@ def _validate_aliases(aliases):
_validate_required_ids(aliases)
def _get_alias_from_config() -> Alias:
def get_alias_from_config() -> Alias:
"""Parse and validate PCI aliases from the nova config.
:returns: A dictionary where the keys are alias names and the values are
@@ -237,7 +237,7 @@ def _translate_alias_to_requests(
alias_spec: str, affinity_policy: ty.Optional[str] = None,
) -> ty.List['objects.InstancePCIRequest']:
"""Generate complete pci requests from pci aliases in extra_spec."""
pci_aliases = _get_alias_from_config()
pci_aliases = get_alias_from_config()
pci_requests: ty.List[objects.InstancePCIRequest] = []
for name, count in [spec.split(':') for spec in alias_spec.split(',')]:
@@ -15,6 +15,7 @@ from unittest import mock
import fixtures
from oslo_config import fixture as config_fixture
from oslo_serialization import jsonutils
from oslotest import base
from nova.api.openstack import wsgi_app
@@ -127,6 +128,14 @@ document_root = /tmp
group='workarounds')
wsgi_app._setup_service('myhost', 'api')
def test_setup_service_pci_alias_validation(self):
wsgi_app.CONF.set_override(
'alias', jsonutils.dumps({'name': 'foo'}),
group='pci')
self.assertRaises(
exception.PciInvalidAlias,
wsgi_app._setup_service, 'myhost', 'api')
def test__get_config_files_empty_env(self):
env = {}
result = wsgi_app._get_config_files(env)
@@ -6954,6 +6954,18 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
self.assertRaises(exception.PciDeviceInvalidDeviceName,
self.compute.init_host, None)
def test_init_host_pci_alias_validation_failure(self):
# Tests that we fail init_host if the pci.alias is
# configured incorrectly.
self.flags(
alias=[
jsonutils.dumps({'name': 'foo'})
],
group='pci'
)
self.assertRaises(
exception.PciInvalidAlias, self.compute.init_host, None)
@mock.patch('nova.compute.manager.ComputeManager._instance_update')
def test_error_out_instance_on_exception_not_implemented_err(self,
inst_update_mock):
+10 -10
View File
@@ -81,7 +81,7 @@ class PciRequestTestCase(test.NoDBTestCase):
def test_get_alias_from_config_valid(self):
self.flags(alias=[_fake_alias1], group='pci')
result = request._get_alias_from_config()
result = request.get_alias_from_config()
expected_result = (
'legacy',
[{
@@ -103,7 +103,7 @@ class PciRequestTestCase(test.NoDBTestCase):
})
self.flags(alias=[_fake_alias1, _fake_alias], group='pci')
result = request._get_alias_from_config()
result = request.get_alias_from_config()
expected_result = (
'legacy',
[{
@@ -133,7 +133,7 @@ class PciRequestTestCase(test.NoDBTestCase):
self.flags(alias=[_fake_alias1, _fake_alias], group='pci')
ex = self.assertRaises(
exception.PciInvalidAlias, request._get_alias_from_config)
exception.PciInvalidAlias, request.get_alias_from_config)
self.assertEqual(
"The PCI alias(es) QuickAssist have multiple specs but "
"[filter_scheduler]pci_in_placement is True. The PCI in Placement "
@@ -146,7 +146,7 @@ class PciRequestTestCase(test.NoDBTestCase):
self.flags(alias=[alias], group='pci')
self.assertRaises(
exception.PciInvalidAlias,
request._get_alias_from_config)
request.get_alias_from_config)
def test_get_alias_from_config_invalid_device_type(self):
fake_alias = jsonutils.dumps({
@@ -215,7 +215,7 @@ class PciRequestTestCase(test.NoDBTestCase):
"numa_policy": policy,
})
self.flags(alias=[fake_alias], group='pci')
aliases = request._get_alias_from_config()
aliases = request.get_alias_from_config()
self.assertIsNotNone(aliases)
self.assertIn("xxx", aliases)
self.assertEqual(policy, aliases["xxx"][0])
@@ -228,7 +228,7 @@ class PciRequestTestCase(test.NoDBTestCase):
})
self.flags(pci_in_placement=True, group='filter_scheduler')
self.flags(alias=[fake_alias], group='pci')
aliases = request._get_alias_from_config()
aliases = request.get_alias_from_config()
self.assertIsNotNone(aliases)
self.assertIn("xxx", aliases)
self.assertEqual(
@@ -256,7 +256,7 @@ class PciRequestTestCase(test.NoDBTestCase):
self.flags(alias=[fake_alias_a, fake_alias_b], group='pci')
self.assertRaises(
exception.PciInvalidAlias,
request._get_alias_from_config)
request.get_alias_from_config)
def test_get_alias_from_config_conflicting_numa_policy(self):
"""Check behavior when numa_policy conflicts occur."""
@@ -277,7 +277,7 @@ class PciRequestTestCase(test.NoDBTestCase):
self.flags(alias=[fake_alias_a, fake_alias_b], group='pci')
self.assertRaises(
exception.PciInvalidAlias,
request._get_alias_from_config)
request.get_alias_from_config)
def test_get_alias_from_config_missing_ids(self):
a1 = jsonutils.dumps({
@@ -304,7 +304,7 @@ class PciRequestTestCase(test.NoDBTestCase):
self.flags(alias=[a1, a2, a3, a4, a5], group='pci')
ex = self.assertRaises(
exception.PciInvalidAlias, request._get_alias_from_config)
exception.PciInvalidAlias, request.get_alias_from_config)
self.assertEqual(
"The PCI alias(es) a1,a2,a3,a4 does not have vendor_id and "
"product_id fields set.",
@@ -336,7 +336,7 @@ class PciRequestTestCase(test.NoDBTestCase):
self.flags(alias=[a1, a2, a3, a4, a5], group='pci')
ex = self.assertRaises(
exception.PciInvalidAlias, request._get_alias_from_config)
exception.PciInvalidAlias, request.get_alias_from_config)
self.assertEqual(
"The PCI alias(es) a1,a2,a3 does not have vendor_id and "
"product_id fields set or resource_class field set.",