Merge "manager: Prevent compute startup on invalid vTPM config"
This commit is contained in:
commit
96cce4070e
|
@ -900,6 +900,26 @@ class ComputeManager(manager.Manager):
|
|||
{'cpus': list(pinned_cpus)},
|
||||
instance=instance)
|
||||
|
||||
def _validate_vtpm_configuration(self, instances):
|
||||
if self.driver.capabilities.get('supports_vtpm', False):
|
||||
return
|
||||
|
||||
for instance in instances:
|
||||
if instance.deleted:
|
||||
continue
|
||||
|
||||
# NOTE(stephenfin): We don't have an attribute on the instance to
|
||||
# check for this, so we need to inspect the flavor/image metadata
|
||||
if hardware.get_vtpm_constraint(
|
||||
instance.flavor, instance.image_meta,
|
||||
):
|
||||
msg = _(
|
||||
'This host has instances with the vTPM feature enabled, '
|
||||
'but the host is not correctly configured; enable '
|
||||
'vTPM support.'
|
||||
)
|
||||
raise exception.InvalidConfiguration(msg)
|
||||
|
||||
def _reset_live_migration(self, context, instance):
|
||||
migration = None
|
||||
try:
|
||||
|
@ -1383,6 +1403,7 @@ class ComputeManager(manager.Manager):
|
|||
self.init_virt_events()
|
||||
|
||||
self._validate_pinning_configuration(instances)
|
||||
self._validate_vtpm_configuration(instances)
|
||||
|
||||
# NOTE(gibi): At this point the compute_nodes of the resource tracker
|
||||
# has not been populated yet so we cannot rely on the resource tracker
|
||||
|
|
|
@ -819,10 +819,12 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||
'_destroy_evacuated_instances')
|
||||
@mock.patch.object(manager.ComputeManager,
|
||||
'_validate_pinning_configuration')
|
||||
@mock.patch.object(manager.ComputeManager,
|
||||
'_validate_vtpm_configuration')
|
||||
@mock.patch.object(manager.ComputeManager, '_init_instance')
|
||||
@mock.patch.object(self.compute, '_update_scheduler_instance_info')
|
||||
def _do_mock_calls(mock_update_scheduler, mock_inst_init,
|
||||
mock_validate_pinning,
|
||||
mock_validate_vtpm, mock_validate_pinning,
|
||||
mock_destroy, mock_admin_ctxt, mock_host_get,
|
||||
mock_init_host,
|
||||
mock_error_interrupted, mock_get_nodes):
|
||||
|
@ -837,6 +839,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||
self.compute.init_host()
|
||||
|
||||
mock_validate_pinning.assert_called_once_with(inst_list)
|
||||
mock_validate_vtpm.assert_called_once_with(inst_list)
|
||||
mock_destroy.assert_called_once_with(
|
||||
self.context, {uuids.our_node_uuid: our_node})
|
||||
mock_inst_init.assert_has_calls(
|
||||
|
@ -1026,8 +1029,10 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||
"""
|
||||
active_instance = fake_instance.fake_instance_obj(
|
||||
self.context, host=self.compute.host, uuid=uuids.active_instance)
|
||||
active_instance.system_metadata = {}
|
||||
evacuating_instance = fake_instance.fake_instance_obj(
|
||||
self.context, host=self.compute.host, uuid=uuids.evac_instance)
|
||||
evacuating_instance.system_metadata = {}
|
||||
instance_list = objects.InstanceList(self.context,
|
||||
objects=[active_instance, evacuating_instance])
|
||||
|
||||
|
@ -1125,6 +1130,23 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||
self.assertRaises(exception.InvalidConfiguration,
|
||||
self.compute.init_host)
|
||||
|
||||
@mock.patch.object(objects.InstanceList, 'get_by_host',
|
||||
new=mock.Mock())
|
||||
@mock.patch('nova.compute.manager.ComputeManager.'
|
||||
'_validate_pinning_configuration',
|
||||
new=mock.Mock())
|
||||
@mock.patch('nova.compute.manager.ComputeManager.'
|
||||
'_validate_vtpm_configuration')
|
||||
def test_init_host_vtpm_configuration_validation_failure(self,
|
||||
mock_validate_vtpm):
|
||||
"""Test that we fail init_host if the vTPM configuration check
|
||||
fails.
|
||||
"""
|
||||
mock_validate_vtpm.side_effect = exception.InvalidConfiguration
|
||||
|
||||
self.assertRaises(exception.InvalidConfiguration,
|
||||
self.compute.init_host)
|
||||
|
||||
@mock.patch.object(objects.Instance, 'save')
|
||||
@mock.patch.object(objects.InstanceList, 'get_by_filters')
|
||||
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
|
||||
|
@ -1349,6 +1371,51 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||
"""
|
||||
self._test__validate_pinning_configuration(supports_pcpus=False)
|
||||
|
||||
def _test__validate_vtpm_configuration(self, supports_vtpm):
|
||||
instance_1 = fake_instance.fake_instance_obj(
|
||||
self.context, uuid=uuids.instance_1)
|
||||
instance_2 = fake_instance.fake_instance_obj(
|
||||
self.context, uuid=uuids.instance_2)
|
||||
instance_3 = fake_instance.fake_instance_obj(
|
||||
self.context, uuid=uuids.instance_3)
|
||||
image_meta = objects.ImageMeta.from_dict({})
|
||||
|
||||
instance_2.flavor.extra_specs = {'hw:tpm_version': '2.0'}
|
||||
|
||||
instance_3.deleted = True
|
||||
|
||||
instances = objects.InstanceList(objects=[
|
||||
instance_1, instance_2, instance_3])
|
||||
|
||||
with test.nested(
|
||||
mock.patch.dict(
|
||||
self.compute.driver.capabilities, supports_vtpm=supports_vtpm,
|
||||
),
|
||||
mock.patch.object(
|
||||
objects.ImageMeta, 'from_instance', return_value=image_meta,
|
||||
),
|
||||
):
|
||||
self.compute._validate_vtpm_configuration(instances)
|
||||
|
||||
def test__validate_vtpm_configuration_unsupported(self):
|
||||
"""Test that the check fails if the driver does not support vTPM and
|
||||
instances request it.
|
||||
"""
|
||||
ex = self.assertRaises(
|
||||
exception.InvalidConfiguration,
|
||||
self._test__validate_vtpm_configuration,
|
||||
supports_vtpm=False)
|
||||
self.assertIn(
|
||||
'This host has instances with the vTPM feature enabled, but the '
|
||||
'host is not correctly configured; ',
|
||||
str(ex))
|
||||
|
||||
def test__validate_vtpm_configuration_supported(self):
|
||||
"""Test that the entire check is skipped if the driver supports
|
||||
vTPM.
|
||||
"""
|
||||
self._test__validate_vtpm_configuration(supports_vtpm=True)
|
||||
|
||||
def test__get_power_state_InstanceNotFound(self):
|
||||
instance = fake_instance.fake_instance_obj(
|
||||
self.context,
|
||||
|
|
|
@ -1013,6 +1013,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
|||
'Driver capabilities for '
|
||||
'\'supports_image_type_ploop\' '
|
||||
'is invalid')
|
||||
self.assertFalse(
|
||||
drvr.capabilities['supports_vtpm'],
|
||||
"Driver capabilities for 'supports_vtpm' is invalid",
|
||||
)
|
||||
|
||||
def test_driver_capabilities_qcow2_with_rbd(self):
|
||||
self.flags(images_type='rbd', group='libvirt')
|
||||
|
|
|
@ -182,6 +182,7 @@ class ComputeDriver(object):
|
|||
"supports_pcpus": False,
|
||||
"supports_accelerators": False,
|
||||
"supports_bfv_rescue": False,
|
||||
"supports_vtpm": False,
|
||||
|
||||
# Image type support flags
|
||||
"supports_image_type_aki": False,
|
||||
|
|
|
@ -328,6 +328,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
|||
"supports_pcpus": True,
|
||||
"supports_accelerators": True,
|
||||
"supports_bfv_rescue": True,
|
||||
"supports_vtpm": False,
|
||||
}
|
||||
super(LibvirtDriver, self).__init__(virtapi)
|
||||
|
||||
|
|
|
@ -79,7 +79,8 @@ class PowerVMDriver(driver.ComputeDriver):
|
|||
'supports_multiattach': False,
|
||||
'supports_trusted_certs': False,
|
||||
'supports_pcpus': False,
|
||||
"supports_accelerators": False,
|
||||
'supports_accelerators': False,
|
||||
'supports_vtpm': False,
|
||||
|
||||
# Supported image types
|
||||
"supports_image_type_aki": False,
|
||||
|
|
Loading…
Reference in New Issue