Merge "libvirt: Skip encryption metadata lookups if secret already exists on host"

This commit is contained in:
Zuul 2020-12-05 17:01:08 +00:00 committed by Gerrit Code Review
commit 200cd653a1
3 changed files with 42 additions and 1 deletions

View File

@ -9119,6 +9119,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
'encryption_key_id': uuids.encryption_key_id}
instance = mock.sentinel.instance
# Mock out find_secret so we don't skip ahead
drvr._host.find_secret.return_value = None
# Mock out the encryptors
mock_encryptor = mock.Mock()
mock_get_volume_encryptor.return_value = mock_encryptor
@ -10179,6 +10182,21 @@ class LibvirtConnTestCase(test.NoDBTestCase,
crt_scrt.assert_called_once_with(
'volume', uuids.serial, password=key)
@mock.patch.object(key_manager, 'API')
def test_attach_encryptor_secret_exists(self, mock_key_manager_api):
connection_info = {'data': {'volume_id': uuids.volume_id}}
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
with test.nested(
mock.patch.object(drvr, '_get_volume_encryption'),
mock.patch.object(drvr._host, 'find_secret')
) as (mock_get_volume_encryption, mock_find_secret):
drvr._attach_encryptor(self.context, connection_info, None)
# Assert we called find_secret and nothing else
mock_find_secret.assert_called_once_with('volume', uuids.volume_id)
mock_get_volume_encryption.assert_not_called()
mock_key_manager_api.assert_not_called()
@mock.patch('os_brick.encryptors.get_encryption_metadata')
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_encryptor')
def test_detach_encryptor_connection_info_incomplete(self,

View File

@ -1715,6 +1715,17 @@ class LibvirtDriver(driver.ComputeDriver):
to determine if an attempt to attach the encryptor should be made.
"""
# NOTE(lyarwood): Skip any attempt to fetch encryption metadata or the
# actual passphrase from the key manager if a libvirt secert already
# exists locally for the volume. This suggests that the instance was
# only powered off or the underlying host rebooted.
volume_id = driver_block_device.get_volume_id(connection_info)
if self._host.find_secret('volume', volume_id):
LOG.debug("A libvirt secret for volume %s has been found on the "
"host, skipping any attempt to create another or attach "
"an os-brick encryptor.", volume_id)
return
if encryption is None:
encryption = self._get_volume_encryption(context, connection_info)
@ -1746,7 +1757,6 @@ class LibvirtDriver(driver.ComputeDriver):
# NOTE(lyarwood): Store the passphrase as a libvirt secret locally
# on the compute node. This secret is used later when generating
# the volume config.
volume_id = driver_block_device.get_volume_id(connection_info)
self._host.create_secret('volume', volume_id, password=passphrase)
elif encryption:
encryptor = self._get_volume_encryptor(connection_info,

View File

@ -0,0 +1,13 @@
---
fixes:
- |
The libvirt virt driver will no longer attempt to fetch volume
encryption metadata or the associated secret key when attaching ``LUKSv1``
encrypted volumes if a libvirt secret already exists on the host.
This resolves `bug 1905701`_ where instances with ``LUKSv1`` encrypted
volumes could not be restarted automatically by the ``nova-compute``
service after a host reboot when the
``[DEFAULT]/resume_guests_state_on_host_boot`` configurable was enabled.
.. _bug 1905701: https://launchpad.net/bugs/1905701