From 8b3701490eeab18b6e05b06151a1e13f2f811899 Mon Sep 17 00:00:00 2001 From: melanie witt Date: Thu, 12 Jun 2025 20:00:55 +0000 Subject: [PATCH] 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 --- nova/objects/migrate_data.py | 20 +++++++++++++++++++- nova/tests/unit/objects/test_migrate_data.py | 12 ++++++++++++ nova/tests/unit/objects/test_objects.py | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/nova/objects/migrate_data.py b/nova/objects/migrate_data.py index a42d1dbc6c..bab85f4d2e 100644 --- a/nova/objects/migrate_data.py +++ b/nova/objects/migrate_data.py @@ -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)): diff --git a/nova/tests/unit/objects/test_migrate_data.py b/nova/tests/unit/objects/test_migrate_data.py index 14759a721d..830d0516ca 100644 --- a/nova/tests/unit/objects/test_migrate_data.py +++ b/nova/tests/unit/objects/test_migrate_data.py @@ -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, diff --git a/nova/tests/unit/objects/test_objects.py b/nova/tests/unit/objects/test_objects.py index 4a60fd4086..d96b372dac 100644 --- a/nova/tests/unit/objects/test_objects.py +++ b/nova/tests/unit/objects/test_objects.py @@ -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',