libvirt: Add vTPM config support
There are two changes to our XML element generation code needed for vTPM support: the '<secret>' element needs to gain support for the 'vtpm' usage type, and a wholly new '<tpm>' element [1]. None of this is actually used yet, outside of tests. That will come later. Part of blueprint add-emulated-virtual-tpm [1] https://libvirt.org/formatsecret.html [2] https://libvirt.org/formatdomain.html#elementsTpm Change-Id: I8b7d2d45963160bc8acf19f36f7945c7545570b3 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
parent
969a6d49e5
commit
e3b0412dda
@ -19,6 +19,7 @@ from oslo_utils import units
|
||||
from nova.objects import fields as obj_fields
|
||||
from nova import test
|
||||
from nova.tests.unit.virt.libvirt import fake_libvirt_data
|
||||
from nova.virt import hardware
|
||||
from nova.virt.libvirt import config
|
||||
|
||||
|
||||
@ -3729,8 +3730,8 @@ class LibvirtConfigSecretTest(LibvirtConfigBaseTest):
|
||||
|
||||
def test_config_secret_volume(self):
|
||||
secret = config.LibvirtConfigSecret()
|
||||
secret.ephemeral = True
|
||||
secret.private = True
|
||||
secret.ephemeral = False
|
||||
secret.private = False
|
||||
secret.description = 'sample desc'
|
||||
secret.uuid = 'c7a5fdbd-edaf-9455-926a-d65c16db1809'
|
||||
secret.usage_type = 'volume'
|
||||
@ -3738,7 +3739,7 @@ class LibvirtConfigSecretTest(LibvirtConfigBaseTest):
|
||||
|
||||
xml = secret.to_xml()
|
||||
expected_xml = """
|
||||
<secret ephemeral="yes" private="yes">
|
||||
<secret ephemeral="no" private="no">
|
||||
<description>sample desc</description>
|
||||
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||
<usage type="volume">
|
||||
@ -3750,15 +3751,15 @@ class LibvirtConfigSecretTest(LibvirtConfigBaseTest):
|
||||
|
||||
def test_config_secret_ceph(self):
|
||||
secret = config.LibvirtConfigSecret()
|
||||
secret.ephemeral = True
|
||||
secret.private = True
|
||||
secret.ephemeral = False
|
||||
secret.private = False
|
||||
secret.description = 'sample desc'
|
||||
secret.usage_type = 'ceph'
|
||||
secret.usage_id = 'sample_name'
|
||||
|
||||
xml = secret.to_xml()
|
||||
expected_xml = """
|
||||
<secret ephemeral="yes" private="yes">
|
||||
<secret ephemeral="no" private="no">
|
||||
<description>sample desc</description>
|
||||
<usage type="ceph">
|
||||
<name>sample_name</name>
|
||||
@ -3767,17 +3768,36 @@ class LibvirtConfigSecretTest(LibvirtConfigBaseTest):
|
||||
|
||||
self.assertXmlEqual(expected_xml, xml)
|
||||
|
||||
def test_config_secret_iscsi(self):
|
||||
def test_config_secret_vtpm(self):
|
||||
secret = config.LibvirtConfigSecret()
|
||||
secret.ephemeral = True
|
||||
secret.private = True
|
||||
secret.usage_type = 'vtpm'
|
||||
secret.usage_id = 'sample_name'
|
||||
secret.uuid = uuids.vtpm
|
||||
|
||||
xml = secret.to_xml()
|
||||
expected_xml = f"""
|
||||
<secret ephemeral="yes" private="yes">
|
||||
<uuid>{uuids.vtpm}</uuid>
|
||||
<usage type="vtpm">
|
||||
<name>sample_name</name>
|
||||
</usage>
|
||||
</secret>"""
|
||||
|
||||
self.assertXmlEqual(expected_xml, xml)
|
||||
|
||||
def test_config_secret_iscsi(self):
|
||||
secret = config.LibvirtConfigSecret()
|
||||
secret.ephemeral = False
|
||||
secret.private = False
|
||||
secret.description = 'sample desc'
|
||||
secret.usage_type = 'iscsi'
|
||||
secret.usage_id = 'sample_target'
|
||||
|
||||
xml = secret.to_xml()
|
||||
expected_xml = """
|
||||
<secret ephemeral="yes" private="yes">
|
||||
<secret ephemeral="no" private="no">
|
||||
<description>sample desc</description>
|
||||
<usage type="iscsi">
|
||||
<target>sample_target</target>
|
||||
@ -3937,3 +3957,51 @@ class LibvirtConfigDomainCapsDevicesTests(LibvirtConfigBaseTest):
|
||||
obj.disk, config.LibvirtConfigDomainCapsDiskBuses)
|
||||
self.assertIsInstance(
|
||||
obj.video, config.LibvirtConfigDomainCapsVideoModels)
|
||||
|
||||
|
||||
class LibvirtConfigTPMTest(LibvirtConfigBaseTest):
|
||||
|
||||
def test_config_tpm_tis_1_2(self):
|
||||
vtpm_config = hardware.VTPMConfig('1.2', 'tpm-tis')
|
||||
vtpm_secret_uuid = 'b028130c-bdcb-4d5f-9bca-b9175ca6c28c'
|
||||
expected_xml = """
|
||||
<tpm model='tpm-tis'>
|
||||
<backend type='emulator' version='1.2'>
|
||||
<encryption secret='b028130c-bdcb-4d5f-9bca-b9175ca6c28c'/>
|
||||
</backend>
|
||||
</tpm>"""
|
||||
|
||||
tpm = config.LibvirtConfigGuestVTPM(vtpm_config, vtpm_secret_uuid)
|
||||
xml = tpm.to_xml()
|
||||
|
||||
self.assertXmlEqual(expected_xml, xml)
|
||||
|
||||
def test_config_tpm_tis_2_0(self):
|
||||
vtpm_config = hardware.VTPMConfig('2.0', 'tpm-tis')
|
||||
vtpm_secret_uuid = 'b028130c-bdcb-4d5f-9bca-b9175ca6c28c'
|
||||
expected_xml = """
|
||||
<tpm model='tpm-tis'>
|
||||
<backend type='emulator' version='2.0'>
|
||||
<encryption secret='b028130c-bdcb-4d5f-9bca-b9175ca6c28c'/>
|
||||
</backend>
|
||||
</tpm>"""
|
||||
|
||||
tpm = config.LibvirtConfigGuestVTPM(vtpm_config, vtpm_secret_uuid)
|
||||
xml = tpm.to_xml()
|
||||
|
||||
self.assertXmlEqual(expected_xml, xml)
|
||||
|
||||
def test_config_tpm_crb_2_0(self):
|
||||
vtpm_config = hardware.VTPMConfig('2.0', 'tpm-crb')
|
||||
vtpm_secret_uuid = 'b028130c-bdcb-4d5f-9bca-b9175ca6c28c'
|
||||
expected_xml = """
|
||||
<tpm model='tpm-crb'>
|
||||
<backend type='emulator' version='2.0'>
|
||||
<encryption secret='b028130c-bdcb-4d5f-9bca-b9175ca6c28c'/>
|
||||
</backend>
|
||||
</tpm>"""
|
||||
|
||||
tpm = config.LibvirtConfigGuestVTPM(vtpm_config, vtpm_secret_uuid)
|
||||
xml = tpm.to_xml()
|
||||
|
||||
self.assertXmlEqual(expected_xml, xml)
|
||||
|
@ -917,6 +917,7 @@ class HostTestCase(test.NoDBTestCase):
|
||||
self.host.create_secret('ceph', 'cephvol')
|
||||
self.host.create_secret('iscsi', 'iscsivol')
|
||||
self.host.create_secret('volume', 'vol')
|
||||
self.host.create_secret('vtpm', 'vtpmdev')
|
||||
self.assertRaises(exception.NovaException,
|
||||
self.host.create_secret, "foo", "foovol")
|
||||
|
||||
|
@ -42,6 +42,11 @@ MEMPAGES_LARGE = -2
|
||||
MEMPAGES_ANY = -3
|
||||
|
||||
|
||||
class VTPMConfig(ty.NamedTuple):
|
||||
version: str
|
||||
model: str
|
||||
|
||||
|
||||
def get_vcpu_pin_set():
|
||||
"""Parse ``vcpu_pin_set`` config.
|
||||
|
||||
|
@ -958,6 +958,33 @@ class LibvirtConfigGuestDevice(LibvirtConfigObject):
|
||||
return False
|
||||
|
||||
|
||||
class LibvirtConfigGuestVTPM(LibvirtConfigGuestDevice):
|
||||
|
||||
def __init__(self, vtpm_config, vtpm_secret_uuid, **kwargs):
|
||||
super(LibvirtConfigGuestVTPM, self).__init__(root_name="tpm", **kwargs)
|
||||
|
||||
self.version = vtpm_config.version
|
||||
self.model = vtpm_config.model
|
||||
self.secret_uuid = vtpm_secret_uuid
|
||||
|
||||
def format_dom(self):
|
||||
# <tpm model='$model'>
|
||||
dev = super(LibvirtConfigGuestVTPM, self).format_dom()
|
||||
dev.set("model", self.model)
|
||||
# <backend type='emulator' version='$version'>
|
||||
back = etree.Element("backend")
|
||||
back.set("type", "emulator")
|
||||
back.set("version", self.version)
|
||||
# <encryption secret='$secret_uuid'/>
|
||||
enc = etree.Element("encryption")
|
||||
enc.set("secret", self.secret_uuid)
|
||||
|
||||
back.append(enc)
|
||||
dev.append(back)
|
||||
|
||||
return dev
|
||||
|
||||
|
||||
class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@ -3272,7 +3299,7 @@ class LibvirtConfigSecret(LibvirtConfigObject):
|
||||
root.append(self._text_node("uuid", str(self.uuid)))
|
||||
usage = self._new_node("usage")
|
||||
usage.set("type", self.usage_type)
|
||||
if self.usage_type == 'ceph':
|
||||
if self.usage_type in ('ceph', 'vtpm'):
|
||||
usage.append(self._text_node('name', str(self.usage_id)))
|
||||
elif self.usage_type == 'iscsi':
|
||||
usage.append(self._text_node('target', str(self.usage_id)))
|
||||
|
@ -996,24 +996,30 @@ class Host(object):
|
||||
if e.get_error_code() == libvirt.VIR_ERR_NO_SECRET:
|
||||
return None
|
||||
|
||||
def create_secret(self, usage_type, usage_id, password=None):
|
||||
def create_secret(self, usage_type, usage_id, password=None, uuid=None):
|
||||
"""Create a secret.
|
||||
|
||||
:param usage_type: one of 'iscsi', 'ceph', 'rbd' or 'volume'
|
||||
'rbd' will be converted to 'ceph'.
|
||||
:param usage_type: one of 'iscsi', 'ceph', 'rbd', 'volume', 'vtpm'.
|
||||
'rbd' will be converted to 'ceph'. 'vtpm' secrets
|
||||
are private and ephemeral; others are not.
|
||||
:param usage_id: name of resource in secret
|
||||
:param password: optional secret value to set
|
||||
:param uuid: optional UUID of the secret; else one is generated by
|
||||
libvirt
|
||||
"""
|
||||
secret_conf = vconfig.LibvirtConfigSecret()
|
||||
secret_conf.ephemeral = False
|
||||
secret_conf.private = False
|
||||
secret_conf.ephemeral = usage_type == 'vtpm'
|
||||
secret_conf.private = usage_type == 'vtpm'
|
||||
secret_conf.usage_id = usage_id
|
||||
secret_conf.uuid = uuid
|
||||
if usage_type in ('rbd', 'ceph'):
|
||||
secret_conf.usage_type = 'ceph'
|
||||
elif usage_type == 'iscsi':
|
||||
secret_conf.usage_type = 'iscsi'
|
||||
elif usage_type == 'volume':
|
||||
secret_conf.usage_type = 'volume'
|
||||
elif usage_type == 'vtpm':
|
||||
secret_conf.usage_type = 'vtpm'
|
||||
else:
|
||||
msg = _("Invalid usage_type: %s")
|
||||
raise exception.InternalError(msg % usage_type)
|
||||
|
Loading…
x
Reference in New Issue
Block a user