hardware: Fix image_meta.id within get_mem_encryption_constraint
In get_mem_encryption_constraint, image_meta.id may not exist. For example, a volume booted instance. So we check whether the id exists. If there is no value, we set it to a sentinel value that can be detected later. i.e. '<no id>', as Sean suggested. Closes-Bug: #2041511 Related-Bug: #2047399 Change-Id: Id4a9d3972589ed7f1c21ffbe0a13d61136b73470 Signed-off-by: songjie <songjie_yewu@cmss.chinamobile.com>
This commit is contained in:
@@ -5454,6 +5454,16 @@ class MemEncryptionRequestedWithInvalidMachineTypeTestCase(
|
||||
enc_image_prop,
|
||||
image_props, error_data)
|
||||
|
||||
def _test_encrypted_memory_support_pc_image_id(self, image_meta,
|
||||
error_data):
|
||||
extra_specs = {'hw:mem_encryption': True}
|
||||
flavor = objects.Flavor(name=self.flavor_name,
|
||||
extra_specs=extra_specs)
|
||||
exc = self.assertRaises(self.expected_exception,
|
||||
hw.get_mem_encryption_constraint,
|
||||
flavor, image_meta)
|
||||
self.assertEqual(self.expected_error % error_data, str(exc))
|
||||
|
||||
def test_flavor_requires_encrypted_memory_support_pc(self):
|
||||
for extra_spec in ('1', 'true', 'True'):
|
||||
self._test_encrypted_memory_support_pc(extra_spec, None)
|
||||
@@ -5468,6 +5478,31 @@ class MemEncryptionRequestedWithInvalidMachineTypeTestCase(
|
||||
self._test_encrypted_memory_support_pc(
|
||||
extra_spec, image_prop)
|
||||
|
||||
def test_encrypted_memory_support_pc_no_image_id(self):
|
||||
image_props = {'hw_mem_encryption': True,
|
||||
'hw_firmware_type': 'uefi',
|
||||
'hw_machine_type': 'pc'}
|
||||
image_meta = fake_image_obj(
|
||||
{'name': self.image_name}, {}, image_props)
|
||||
error_data = {'image_id': '<no-id>',
|
||||
'image_name': self.image_name,
|
||||
'mtype': 'pc'}
|
||||
self._test_encrypted_memory_support_pc_image_id(image_meta,
|
||||
error_data)
|
||||
|
||||
def test_encrypted_memory_support_pc_has_image_id(self):
|
||||
image_props = {'hw_mem_encryption': True,
|
||||
'hw_firmware_type': 'uefi',
|
||||
'hw_machine_type': 'pc'}
|
||||
image_meta = fake_image_obj(
|
||||
{'id': self.image_id, 'name': self.image_name},
|
||||
{}, image_props)
|
||||
error_data = {'image_id': self.image_id,
|
||||
'image_name': self.image_name,
|
||||
'mtype': 'pc'}
|
||||
self._test_encrypted_memory_support_pc_image_id(image_meta,
|
||||
error_data)
|
||||
|
||||
|
||||
class MemEncryptionRequiredTestCase(test.NoDBTestCase):
|
||||
flavor_name = "m1.faketiny"
|
||||
@@ -5544,6 +5579,34 @@ class MemEncryptionRequiredTestCase(test.NoDBTestCase):
|
||||
hw.get_mem_encryption_constraint, flavor,
|
||||
image_meta)
|
||||
|
||||
@mock.patch.object(hw, 'LOG')
|
||||
def test_encrypted_memory_support_no_id_for_volume(self, mock_log):
|
||||
extra_specs = {'hw:mem_encryption': True}
|
||||
flavor = objects.Flavor(name=self.flavor_name,
|
||||
extra_specs=extra_specs)
|
||||
|
||||
image_props = {'hw_mem_encryption': True,
|
||||
'hw_firmware_type': 'uefi'}
|
||||
image_meta = objects.ImageMeta.from_dict({
|
||||
'min_disk': 0,
|
||||
'min_ram': 0,
|
||||
'properties': image_props,
|
||||
'size': 0,
|
||||
'status': 'active'})
|
||||
|
||||
self.assertTrue(hw.get_mem_encryption_constraint(flavor,
|
||||
image_meta))
|
||||
|
||||
requesters = "hw:mem_encryption extra spec in %s flavor and " \
|
||||
"hw_mem_encryption property of image %s" % \
|
||||
(self.flavor_name, '<no-id>')
|
||||
# Confirm that it can handle the situation that there is
|
||||
# no image_id when booting from volume. We set it to
|
||||
# '<no-id>' that we can detect later.
|
||||
mock_log.debug.assert_has_calls([
|
||||
mock.call("Memory encryption requested by %s", requesters)
|
||||
])
|
||||
|
||||
|
||||
class PCINUMAAffinityPolicyTest(test.NoDBTestCase):
|
||||
|
||||
|
||||
@@ -1191,13 +1191,18 @@ def get_mem_encryption_constraint(
|
||||
# If we get this far, either the extra spec or image property explicitly
|
||||
# specified a requirement regarding memory encryption, and if both did,
|
||||
# they are asking for the same thing.
|
||||
# NOTE(jie, sean): When creating a volume booted instance with memory
|
||||
# encryption enabled, image_meta has no id key. See bug #2041511.
|
||||
# So we check whether id exists. If there is no value, we set it
|
||||
# to a sentinel value we can detect later. i.e. '<no-id>'.
|
||||
requesters = []
|
||||
if flavor_mem_enc:
|
||||
requesters.append("hw:mem_encryption extra spec in %s flavor" %
|
||||
flavor.name)
|
||||
if image_mem_enc:
|
||||
image_id = (image_meta.id if 'id' in image_meta else '<no-id>')
|
||||
requesters.append("hw_mem_encryption property of image %s" %
|
||||
image_meta.id)
|
||||
image_id)
|
||||
|
||||
_check_mem_encryption_uses_uefi_image(requesters, image_meta)
|
||||
_check_mem_encryption_machine_type(image_meta, machine_type)
|
||||
@@ -1275,12 +1280,14 @@ def _check_mem_encryption_machine_type(image_meta, machine_type=None):
|
||||
|
||||
# image_meta.name is not set if image object represents root Cinder volume.
|
||||
image_name = (image_meta.name if 'name' in image_meta else None)
|
||||
# image_meta.id is not set when booting from volume.
|
||||
image_id = (image_meta.id if 'id' in image_meta else '<no-id>')
|
||||
# Could be something like pc-q35-2.11 if a specific version of the
|
||||
# machine type is required, so do substring matching.
|
||||
if 'q35' not in mach_type:
|
||||
raise exception.InvalidMachineType(
|
||||
mtype=mach_type,
|
||||
image_id=image_meta.id, image_name=image_name,
|
||||
image_id=image_id, image_name=image_name,
|
||||
reason=_("q35 type is required for SEV to work"))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user