Merge "libvirt: Report available TPM models"
This commit is contained in:
commit
cf71be0ef0
@ -295,14 +295,20 @@ class ResourceRequest(object):
|
||||
if not vtpm_config:
|
||||
return
|
||||
|
||||
# Require the appropriate vTPM version support trait on a host.
|
||||
if vtpm_config.version == obj_fields.TPMVersion.v1_2:
|
||||
trait = os_traits.COMPUTE_SECURITY_TPM_1_2
|
||||
else:
|
||||
trait = os_traits.COMPUTE_SECURITY_TPM_2_0
|
||||
# Require the appropriate vTPM model support trait on a host.
|
||||
model_trait = os_traits.COMPUTE_SECURITY_TPM_TIS
|
||||
if vtpm_config.model == obj_fields.TPMModel.CRB:
|
||||
model_trait = os_traits.COMPUTE_SECURITY_TPM_CRB
|
||||
|
||||
self._add_trait(trait, 'required')
|
||||
LOG.debug("Requiring emulated TPM support via trait %s.", trait)
|
||||
# Require the appropriate vTPM version support trait on a host.
|
||||
version_trait = os_traits.COMPUTE_SECURITY_TPM_1_2
|
||||
if vtpm_config.version == obj_fields.TPMVersion.v2_0:
|
||||
version_trait = os_traits.COMPUTE_SECURITY_TPM_2_0
|
||||
|
||||
self._add_trait(model_trait, 'required')
|
||||
self._add_trait(version_trait, 'required')
|
||||
LOG.debug("Requiring emulated TPM support via trait %s and %s.",
|
||||
version_trait, model_trait)
|
||||
|
||||
def _translate_memory_encryption(self, flavor, image):
|
||||
"""When the hw:mem_encryption extra spec or the hw_mem_encryption
|
||||
|
1
nova/tests/fixtures/libvirt.py
vendored
1
nova/tests/fixtures/libvirt.py
vendored
@ -2116,7 +2116,6 @@ class Connection(object):
|
||||
<tpm supported='yes'>
|
||||
<enum name='model'>
|
||||
<value>tpm-tis</value>
|
||||
<value>tpm-crb</value>
|
||||
</enum>
|
||||
<enum name='backendModel'>
|
||||
<value>passthrough</value>
|
||||
|
@ -1308,6 +1308,33 @@ class TestUtils(TestUtilsBase):
|
||||
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||
self.assertResourceRequestsEqual(expected, rr)
|
||||
|
||||
def test_resource_request_from_request_spec_with_vtpm_version_only(self):
|
||||
flavor = objects.Flavor(
|
||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
||||
extra_specs={'hw:tpm_version': '1.2'},
|
||||
)
|
||||
image = objects.ImageMeta(
|
||||
properties=objects.ImageMetaProps(
|
||||
hw_tpm_version='1.2',
|
||||
)
|
||||
)
|
||||
expected = FakeResourceRequest()
|
||||
expected._rg_by_id[None] = objects.RequestGroup(
|
||||
use_same_provider=False,
|
||||
required_traits={
|
||||
'COMPUTE_SECURITY_TPM_1_2',
|
||||
'COMPUTE_SECURITY_TPM_TIS',
|
||||
},
|
||||
resources={
|
||||
'VCPU': 1,
|
||||
'MEMORY_MB': 1024,
|
||||
'DISK_GB': 15,
|
||||
},
|
||||
)
|
||||
rs = objects.RequestSpec(flavor=flavor, image=image, is_bfv=False)
|
||||
rr = utils.ResourceRequest.from_request_spec(rs)
|
||||
self.assertResourceRequestsEqual(expected, rr)
|
||||
|
||||
def test_resource_request_from_request_spec_with_vtpm_1_2(self):
|
||||
flavor = objects.Flavor(
|
||||
vcpus=1, memory_mb=1024, root_gb=10, ephemeral_gb=5, swap=0,
|
||||
@ -1322,7 +1349,10 @@ class TestUtils(TestUtilsBase):
|
||||
expected = FakeResourceRequest()
|
||||
expected._rg_by_id[None] = objects.RequestGroup(
|
||||
use_same_provider=False,
|
||||
required_traits={'COMPUTE_SECURITY_TPM_1_2'},
|
||||
required_traits={
|
||||
'COMPUTE_SECURITY_TPM_1_2',
|
||||
'COMPUTE_SECURITY_TPM_TIS',
|
||||
},
|
||||
resources={
|
||||
'VCPU': 1,
|
||||
'MEMORY_MB': 1024,
|
||||
@ -1347,7 +1377,10 @@ class TestUtils(TestUtilsBase):
|
||||
expected = FakeResourceRequest()
|
||||
expected._rg_by_id[None] = objects.RequestGroup(
|
||||
use_same_provider=False,
|
||||
required_traits={'COMPUTE_SECURITY_TPM_2_0'},
|
||||
required_traits={
|
||||
'COMPUTE_SECURITY_TPM_2_0',
|
||||
'COMPUTE_SECURITY_TPM_CRB',
|
||||
},
|
||||
resources={
|
||||
'VCPU': 1,
|
||||
'MEMORY_MB': 1024,
|
||||
|
@ -1007,6 +1007,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
'COMPUTE_NET_VIRTIO_PACKED': True,
|
||||
'COMPUTE_SECURITY_TPM_1_2': False,
|
||||
'COMPUTE_SECURITY_TPM_2_0': False,
|
||||
'COMPUTE_SECURITY_TPM_TIS': False,
|
||||
'COMPUTE_SECURITY_TPM_CRB': False,
|
||||
'COMPUTE_STORAGE_BUS_VIRTIO': True,
|
||||
'COMPUTE_VIOMMU_MODEL_AUTO': True,
|
||||
'COMPUTE_VIOMMU_MODEL_INTEL': True,
|
||||
@ -1059,6 +1061,8 @@ class LibvirtConnTestCase(test.NoDBTestCase,
|
||||
'COMPUTE_NET_VIRTIO_PACKED': True,
|
||||
'COMPUTE_SECURITY_TPM_1_2': False,
|
||||
'COMPUTE_SECURITY_TPM_2_0': False,
|
||||
'COMPUTE_SECURITY_TPM_TIS': False,
|
||||
'COMPUTE_SECURITY_TPM_CRB': False,
|
||||
'COMPUTE_VIOMMU_MODEL_AUTO': True,
|
||||
'COMPUTE_VIOMMU_MODEL_INTEL': True,
|
||||
'COMPUTE_VIOMMU_MODEL_SMMUV3': True,
|
||||
@ -22564,7 +22568,9 @@ class TestUpdateProviderTree(test.NoDBTestCase):
|
||||
def test_update_provider_tree_with_tpm_traits(self):
|
||||
self.flags(swtpm_enabled=True, group='libvirt')
|
||||
self._test_update_provider_tree()
|
||||
for trait in ('COMPUTE_SECURITY_TPM_2_0', 'COMPUTE_SECURITY_TPM_1_2'):
|
||||
for trait in (
|
||||
'COMPUTE_SECURITY_TPM_TIS', 'COMPUTE_SECURITY_TPM_CRB',
|
||||
'COMPUTE_SECURITY_TPM_2_0', 'COMPUTE_SECURITY_TPM_1_2'):
|
||||
self.assertIn(trait, self.pt.data(self.cn_rp['uuid']).traits)
|
||||
|
||||
@mock.patch.object(
|
||||
@ -22574,7 +22580,9 @@ class TestUpdateProviderTree(test.NoDBTestCase):
|
||||
def test_update_provider_tree_with_tpm_traits_supported(self):
|
||||
self.flags(swtpm_enabled=True, group='libvirt')
|
||||
self._test_update_provider_tree()
|
||||
for trait in ('COMPUTE_SECURITY_TPM_2_0', 'COMPUTE_SECURITY_TPM_1_2'):
|
||||
for trait in (
|
||||
'COMPUTE_SECURITY_TPM_TIS', 'COMPUTE_SECURITY_TPM_CRB',
|
||||
'COMPUTE_SECURITY_TPM_2_0', 'COMPUTE_SECURITY_TPM_1_2'):
|
||||
self.assertIn(trait, self.pt.data(self.cn_rp['uuid']).traits)
|
||||
|
||||
@mock.patch.object(
|
||||
@ -22585,9 +22593,9 @@ class TestUpdateProviderTree(test.NoDBTestCase):
|
||||
def test_update_provider_tree_with_tpm_traits_versions(self):
|
||||
self.flags(swtpm_enabled=True, group='libvirt')
|
||||
self._test_update_provider_tree()
|
||||
for trait in ('COMPUTE_SECURITY_TPM_2_0',):
|
||||
for trait in ('COMPUTE_SECURITY_TPM_TIS', 'COMPUTE_SECURITY_TPM_2_0'):
|
||||
self.assertIn(trait, self.pt.data(self.cn_rp['uuid']).traits)
|
||||
for trait in ('COMPUTE_SECURITY_TPM_1_2',):
|
||||
for trait in ('COMPUTE_SECURITY_TPM_CRB', 'COMPUTE_SECURITY_TPM_1_2',):
|
||||
self.assertNotIn(trait, self.pt.data(self.cn_rp['uuid']).traits)
|
||||
|
||||
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver.'
|
||||
|
@ -920,7 +920,7 @@ class HostTestCase(test.NoDBTestCase):
|
||||
type(caps.devices.tpm))
|
||||
self.assertTrue(caps.devices.tpm.supported)
|
||||
self.assertEqual(
|
||||
['tpm-tis', 'tpm-crb'],
|
||||
['tpm-tis'],
|
||||
caps.devices.tpm.models
|
||||
)
|
||||
self.assertEqual(
|
||||
|
@ -12922,23 +12922,43 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||
return {
|
||||
ot.COMPUTE_SECURITY_TPM_2_0: False,
|
||||
ot.COMPUTE_SECURITY_TPM_1_2: False,
|
||||
ot.COMPUTE_SECURITY_TPM_TIS: False,
|
||||
ot.COMPUTE_SECURITY_TPM_CRB: False,
|
||||
}
|
||||
|
||||
tpm_models = self._host.tpm_models
|
||||
tpm_versions = self._host.tpm_versions
|
||||
# libvirt < 8.6 does not provide supported versions in domain
|
||||
# capabilities
|
||||
|
||||
# TODO(tkajinam): Remove this once libvirt>=8.6.0 is required.
|
||||
tr = {}
|
||||
if tpm_models is None:
|
||||
# TODO(tkajinam): Remove this fallback once libvirt>=8.0.0 is
|
||||
# required.
|
||||
tr.update({
|
||||
ot.COMPUTE_SECURITY_TPM_TIS: True,
|
||||
ot.COMPUTE_SECURITY_TPM_CRB: True,
|
||||
})
|
||||
else:
|
||||
tr.update({
|
||||
ot.COMPUTE_SECURITY_TPM_TIS: 'tpm-tis' in tpm_models,
|
||||
ot.COMPUTE_SECURITY_TPM_CRB: 'tpm-crb' in tpm_models,
|
||||
})
|
||||
|
||||
if tpm_versions is None:
|
||||
return {
|
||||
# TODO(tkajinam): Remove this fallback once libvirt>=8.6.0 is
|
||||
# required.
|
||||
tr.update({
|
||||
ot.COMPUTE_SECURITY_TPM_2_0: True,
|
||||
ot.COMPUTE_SECURITY_TPM_1_2: True,
|
||||
}
|
||||
})
|
||||
else:
|
||||
tr.update({
|
||||
ot.COMPUTE_SECURITY_TPM_2_0: '2.0' in tpm_versions,
|
||||
ot.COMPUTE_SECURITY_TPM_1_2: '1.2' in tpm_versions,
|
||||
})
|
||||
|
||||
return {
|
||||
ot.COMPUTE_SECURITY_TPM_2_0: '2.0' in tpm_versions,
|
||||
ot.COMPUTE_SECURITY_TPM_1_2: '1.2' in tpm_versions,
|
||||
}
|
||||
return tr
|
||||
|
||||
def _get_vif_model_traits(self) -> ty.Dict[str, bool]:
|
||||
"""Get vif model traits based on the currently enabled virt_type.
|
||||
|
@ -1878,6 +1878,24 @@ class Host(object):
|
||||
# safe guard
|
||||
return []
|
||||
|
||||
@property
|
||||
def tpm_models(self) -> ty.Optional[ty.List[str]]:
|
||||
# we only check the host architecture and the first machine type
|
||||
# because vtpm support is independent from cpu architecture
|
||||
arch = self.get_capabilities().host.cpu.arch
|
||||
domain_caps = self.get_domain_capabilities()
|
||||
for machine_type in domain_caps[arch]:
|
||||
_tpm = domain_caps[arch][machine_type].devices.tpm
|
||||
# TODO(tkajinam): Remove first check once libvirt >= 8.0.0 is
|
||||
# required
|
||||
# TODO(tkajinam): Remove second check once libvirt >= 8.6.0 is
|
||||
# required
|
||||
if _tpm is None or _tpm.models is None:
|
||||
return None
|
||||
return _tpm.models
|
||||
# safe guard
|
||||
return []
|
||||
|
||||
def _kernel_supports_amd_sev(self) -> bool:
|
||||
if not os.path.exists(SEV_KERNEL_PARAM_FILE):
|
||||
LOG.debug("%s does not exist", SEV_KERNEL_PARAM_FILE)
|
||||
|
Loading…
Reference in New Issue
Block a user