Add vtpm_secret_(uuid|value) to LibvirtLiveMigrateData

This is needed in order to pass TPM secret information to the
destination over RPC to support the 'host' secret security mode.

The fields are nullable so that secret security modes 'user' and
'deployment' may set them to None.

A setting of None lets the other security modes convey that they are
actively choosing not to pass any data in the vTPM fields. This is
important for interacting with older compute hosts in the middle of a
rolling upgrade. We do not want to backlevel new LibvirtLiveMigrateData
objects involving vTPM because older compute hosts cannot support vTPM
live migration in any capacity.

Related to blueprint vtpm-live-migration

Change-Id: If2ff2a7bb41dea6e0959c965477b79f3f7d633e7
Signed-off-by: melanie witt <melwittt@gmail.com>
This commit is contained in:
melanie witt
2025-06-12 20:00:55 +00:00
parent 59a7093915
commit 8b3701490e
3 changed files with 32 additions and 2 deletions
+19 -1
View File
@@ -256,7 +256,8 @@ class LibvirtLiveMigrateData(LiveMigrateData):
# source_mdev_types and target_mdevs fields
# Version 1.12: Added dst_cpu_shared_set_info
# Version 1.13: Inherited pci_dev_map_src_dst from LiveMigrateData
VERSION = '1.13'
# Version 1.14: Added vtpm_secret_uuid and vtpm_secret_value
VERSION = '1.14'
fields = {
'filename': fields.StringField(),
@@ -295,12 +296,29 @@ class LibvirtLiveMigrateData(LiveMigrateData):
# key is source mdev UUID and value is the destination mdev UUID.
'target_mdevs': fields.DictOfStringsField(),
'dst_cpu_shared_set_info': fields.SetOfIntegersField(),
'vtpm_secret_uuid': fields.UUIDField(nullable=True),
'vtpm_secret_value': fields.SensitiveStringField(nullable=True),
}
def obj_make_compatible(self, primitive, target_version):
super(LibvirtLiveMigrateData, self).obj_make_compatible(
primitive, target_version)
target_version = versionutils.convert_version_to_tuple(target_version)
if (target_version < (1, 14)):
# In an object primitive, a field will be included if and only if
# it is set to something (including None, if the field is
# nullable). So instances with no vTPM will not have these fields
# set.
vtpm_fields = ['vtpm_secret_uuid', 'vtpm_secret_value']
if any(field in vtpm_fields for field in primitive):
# If either field is set, then we know this object was passed
# from newer compute which could support vTPM live migration.
# We raise here instead of silently removing the fields because
# we cannot backport the object to something compatible.
raise exception.ObjectActionError(
action='obj_make_compatible',
reason='Unable to backport newer vTPM support to '
'requested version %d.%d' % target_version)
if (target_version < (1, 13)):
primitive.pop('pci_dev_map_src_dst', None)
if (target_version < (1, 12)):
@@ -161,6 +161,18 @@ class _TestLibvirtLiveMigrateData(object):
self.assertIn(
'encryption_secret_uuid', primitive['nova_object.data'])
def test_vtpm_obj_make_compatible(self):
obj = migrate_data.LibvirtLiveMigrateData(
vtpm_secret_uuid=uuids.vtpm_secret,
vtpm_secret_value='password')
manifest = ovo_base.obj_tree_get_versions(obj.obj_name())
ex = self.assertRaises(
exception.ObjectActionError, obj.obj_to_primitive,
target_version='1.13', version_manifest=manifest)
self.assertIn(
'Unable to backport newer vTPM support to requested version '
'1.13', str(ex))
def test_vif_migrate_data(self):
source_vif = network_model.VIF(
id=uuids.port_id,
+1 -1
View File
@@ -1128,7 +1128,7 @@ object_data = {
'KeyPair': '1.4-1244e8d1b103cc69d038ed78ab3a8cc6',
'KeyPairList': '1.3-94aad3ac5c938eef4b5e83da0212f506',
'LibvirtLiveMigrateBDMInfo': '1.1-5f4a68873560b6f834b74e7861d71aaf',
'LibvirtLiveMigrateData': '1.13-c92e9c98bfccafe84e52c08efbec41d8',
'LibvirtLiveMigrateData': '1.14-0d605656259dc382c242f7496419ca76',
'LibvirtLiveMigrateNUMAInfo': '1.0-0e777677f3459d0ed1634eabbdb6c22f',
'LibvirtVPMEMDevice': '1.0-17ffaf47585199eeb9a2b83d6bde069f',
'MemoryDiagnostics': '1.0-2c995ae0f2223bb0f8e523c5cc0b83da',