Merge "libvirt: Remove native LUKS compat code"

This commit is contained in:
Zuul 2020-03-05 04:44:42 +00:00 committed by Gerrit Code Review
commit 19cbbbebdd
2 changed files with 59 additions and 110 deletions

View File

@ -8448,7 +8448,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock_volume_driver.connect_volume.assert_called_once_with( mock_volume_driver.connect_volume.assert_called_once_with(
connection_info, instance) connection_info, instance)
mock_attach_encryptor.assert_called_once_with( mock_attach_encryptor.assert_called_once_with(
self.context, connection_info, encryption, True) self.context, connection_info, encryption)
mock_volume_driver.disconnect_volume.assert_not_called() mock_volume_driver.disconnect_volume.assert_not_called()
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_driver') @mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_driver')
@ -8479,18 +8479,18 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock_volume_driver.connect_volume.assert_called_once_with( mock_volume_driver.connect_volume.assert_called_once_with(
connection_info, instance) connection_info, instance)
mock_attach_encryptor.assert_called_once_with( mock_attach_encryptor.assert_called_once_with(
self.context, connection_info, encryption, True) self.context, connection_info, encryption)
mock_volume_driver.disconnect_volume.assert_called_once_with( mock_volume_driver.disconnect_volume.assert_called_once_with(
connection_info, instance) connection_info, instance)
@mock.patch.object(key_manager, 'API') @mock.patch.object(key_manager, 'API')
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_encryption') @mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_encryption')
@mock.patch.object(libvirt_driver.LibvirtDriver, '_use_native_luks') @mock.patch.object(libvirt_driver.LibvirtDriver, '_is_luks_v1')
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_encryptor') @mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_encryptor')
@mock.patch('nova.virt.libvirt.host.Host') @mock.patch('nova.virt.libvirt.host.Host')
@mock.patch('os_brick.encryptors.luks.is_luks') @mock.patch('os_brick.encryptors.luks.is_luks')
def test_connect_volume_native_luks(self, mock_is_luks, mock_host, def test_connect_volume_luks(self, mock_is_volume_luks, mock_host,
mock_get_volume_encryptor, mock_use_native_luks, mock_get_volume_encryptor, mock_is_luks_v1,
mock_get_volume_encryption, mock_get_key_mgr): mock_get_volume_encryption, mock_get_key_mgr):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
@ -8505,7 +8505,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
# Mock out the encryptors # Mock out the encryptors
mock_encryptor = mock.Mock() mock_encryptor = mock.Mock()
mock_get_volume_encryptor.return_value = mock_encryptor mock_get_volume_encryptor.return_value = mock_encryptor
mock_is_luks.return_value = True mock_is_volume_luks.return_value = True
# Mock out the key manager # Mock out the key manager
key = u'3734363537333734' key = u'3734363537333734'
@ -8517,9 +8517,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock_key.get_encoded.return_value = key_encoded mock_key.get_encoded.return_value = key_encoded
# assert that the secret is created for the encrypted volume during # assert that the secret is created for the encrypted volume during
# _connect_volume when use_native_luks is True # _connect_volume when _is_luks_v1 is True
mock_get_volume_encryption.return_value = encryption mock_get_volume_encryption.return_value = encryption
mock_use_native_luks.return_value = True mock_is_luks_v1.return_value = True
drvr._connect_volume(self.context, connection_info, instance, drvr._connect_volume(self.context, connection_info, instance,
encryption=encryption) encryption=encryption)
@ -8527,10 +8527,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
uuids.volume_id, password=key) uuids.volume_id, password=key)
mock_encryptor.attach_volume.assert_not_called() mock_encryptor.attach_volume.assert_not_called()
# assert that the encryptor is used if use_native_luks is False # assert that the encryptor is used if is_luks is False
drvr._host.create_secret.reset_mock() drvr._host.create_secret.reset_mock()
mock_get_volume_encryption.reset_mock() mock_get_volume_encryption.reset_mock()
mock_use_native_luks.return_value = False mock_is_luks_v1.return_value = False
drvr._connect_volume(self.context, connection_info, instance, drvr._connect_volume(self.context, connection_info, instance,
encryption=encryption) encryption=encryption)
@ -8538,26 +8538,17 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock_encryptor.attach_volume.assert_called_once_with(self.context, mock_encryptor.attach_volume.assert_called_once_with(self.context,
**encryption) **encryption)
# assert that we format the volume if is_luks is False # assert that we format the volume if it is not already formatted
mock_use_native_luks.return_value = True mock_is_luks_v1.return_value = True
mock_is_luks.return_value = False mock_is_volume_luks.return_value = False
drvr._connect_volume(self.context, connection_info, instance, drvr._connect_volume(self.context, connection_info, instance,
encryption=encryption) encryption=encryption)
mock_encryptor._format_volume.assert_called_once_with(key, mock_encryptor._format_volume.assert_called_once_with(key,
**encryption) **encryption)
# assert that os-brick is used when allow_native_luks is False
mock_encryptor.attach_volume.reset_mock()
mock_is_luks.return_value = True
drvr._connect_volume(self.context, connection_info, instance,
encryption=encryption, allow_native_luks=False)
mock_encryptor.attach_volume.assert_called_once_with(self.context,
**encryption)
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_encryptor') @mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_encryptor')
def test_disconnect_volume_native_luks(self, mock_get_volume_encryptor): def test_disconnect_volume_luks(self, mock_get_volume_encryptor):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
drvr._host = mock.Mock() drvr._host = mock.Mock()
drvr._host.find_secret.return_value = mock.Mock() drvr._host.find_secret.return_value = mock.Mock()
@ -9195,7 +9186,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
connection_info = {'data': {}} connection_info = {'data': {}}
drvr._attach_encryptor(self.context, connection_info, None, False) drvr._attach_encryptor(self.context, connection_info, None)
mock_get_metadata.assert_not_called() mock_get_metadata.assert_not_called()
mock_get_encryptor.assert_not_called() mock_get_encryptor.assert_not_called()
@ -9213,7 +9204,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
connection_info = {'data': {'volume_id': uuids.volume_id}} connection_info = {'data': {'volume_id': uuids.volume_id}}
mock_get_metadata.return_value = encryption mock_get_metadata.return_value = encryption
drvr._attach_encryptor(self.context, connection_info, None, False) drvr._attach_encryptor(self.context, connection_info, None)
mock_get_metadata.assert_called_once_with(self.context, mock_get_metadata.assert_called_once_with(self.context,
drvr._volume_api, uuids.volume_id, connection_info) drvr._volume_api, uuids.volume_id, connection_info)
@ -9231,8 +9222,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
encryption = {} encryption = {}
connection_info = {'data': {'volume_id': uuids.volume_id}} connection_info = {'data': {'volume_id': uuids.volume_id}}
drvr._attach_encryptor(self.context, connection_info, encryption, drvr._attach_encryptor(self.context, connection_info, encryption)
False)
mock_get_metadata.assert_not_called() mock_get_metadata.assert_not_called()
mock_get_encryptor.assert_not_called() mock_get_encryptor.assert_not_called()
@ -9247,11 +9237,12 @@ class LibvirtConnTestCase(test.NoDBTestCase,
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
mock_encryptor = mock.MagicMock() mock_encryptor = mock.MagicMock()
mock_get_encryptor.return_value = mock_encryptor mock_get_encryptor.return_value = mock_encryptor
encryption = {'provider': 'luks', 'control_location': 'front-end'} encryption = {'provider': encryptors.PLAIN,
'control_location': 'front-end'}
mock_get_metadata.return_value = encryption mock_get_metadata.return_value = encryption
connection_info = {'data': {'volume_id': uuids.volume_id}} connection_info = {'data': {'volume_id': uuids.volume_id}}
drvr._attach_encryptor(self.context, connection_info, None, False) drvr._attach_encryptor(self.context, connection_info, None)
mock_get_metadata.assert_called_once_with(self.context, mock_get_metadata.assert_called_once_with(self.context,
drvr._volume_api, uuids.volume_id, connection_info) drvr._volume_api, uuids.volume_id, connection_info)
@ -9271,11 +9262,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
mock_encryptor = mock.MagicMock() mock_encryptor = mock.MagicMock()
mock_get_encryptor.return_value = mock_encryptor mock_get_encryptor.return_value = mock_encryptor
encryption = {'provider': 'luks', 'control_location': 'front-end'} encryption = {'provider': encryptors.PLAIN,
'control_location': 'front-end'}
connection_info = {'data': {'volume_id': uuids.volume_id}} connection_info = {'data': {'volume_id': uuids.volume_id}}
drvr._attach_encryptor(self.context, connection_info, drvr._attach_encryptor(self.context, connection_info, encryption)
encryption, False)
mock_get_metadata.assert_not_called() mock_get_metadata.assert_not_called()
mock_get_encryptor.assert_called_once_with(connection_info, mock_get_encryptor.assert_called_once_with(connection_info,
@ -9307,10 +9298,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock_key_mgr.get.return_value = mock_key mock_key_mgr.get.return_value = mock_key
mock_key.get_encoded.return_value = key_encoded mock_key.get_encoded.return_value = key_encoded
with mock.patch.object(drvr, '_use_native_luks', return_value=True): with mock.patch.object(drvr, '_is_luks_v1', return_value=True):
with mock.patch.object(drvr._host, 'create_secret') as crt_scrt: with mock.patch.object(drvr._host, 'create_secret') as crt_scrt:
drvr._attach_encryptor(self.context, connection_info, drvr._attach_encryptor(self.context, connection_info,
encryption, allow_native_luks=True) encryption)
mock_get_metadata.assert_not_called() mock_get_metadata.assert_not_called()
mock_get_encryptor.assert_not_called() mock_get_encryptor.assert_not_called()
@ -9369,9 +9360,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
@mock.patch('os_brick.encryptors.get_encryption_metadata') @mock.patch('os_brick.encryptors.get_encryption_metadata')
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_encryptor') @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_encryptor')
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._use_native_luks') @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._is_luks_v1')
def test_detach_encryptor_encrypted_volume_meta_missing(self, def test_detach_encryptor_encrypted_volume_meta_missing(self,
mock_use_native_luks, mock_get_encryptor, mock_get_metadata): mock_is_luks_v1, mock_get_encryptor, mock_get_metadata):
"""Assert that if missing the encryption metadata of an encrypted """Assert that if missing the encryption metadata of an encrypted
volume is fetched and then used to detach the encryptor for the volume. volume is fetched and then used to detach the encryptor for the volume.
""" """
@ -9381,7 +9372,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
encryption = {'provider': 'luks', 'control_location': 'front-end'} encryption = {'provider': 'luks', 'control_location': 'front-end'}
mock_get_metadata.return_value = encryption mock_get_metadata.return_value = encryption
connection_info = {'data': {'volume_id': uuids.volume_id}} connection_info = {'data': {'volume_id': uuids.volume_id}}
mock_use_native_luks.return_value = False mock_is_luks_v1.return_value = False
drvr._detach_encryptor(self.context, connection_info, None) drvr._detach_encryptor(self.context, connection_info, None)
@ -9393,9 +9384,9 @@ class LibvirtConnTestCase(test.NoDBTestCase,
@mock.patch('os_brick.encryptors.get_encryption_metadata') @mock.patch('os_brick.encryptors.get_encryption_metadata')
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_encryptor') @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_encryptor')
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._use_native_luks') @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._is_luks_v1')
def test_detach_encryptor_encrypted_volume_meta_provided(self, def test_detach_encryptor_encrypted_volume_meta_provided(self,
mock_use_native_luks, mock_get_encryptor, mock_get_metadata): mock_is_luks_v1, mock_get_encryptor, mock_get_metadata):
"""Assert that when provided there are no further attempts to fetch the """Assert that when provided there are no further attempts to fetch the
encryption metadata for the volume and that the provided metadata is encryption metadata for the volume and that the provided metadata is
then used to detach the volume. then used to detach the volume.
@ -9405,7 +9396,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock_get_encryptor.return_value = mock_encryptor mock_get_encryptor.return_value = mock_encryptor
encryption = {'provider': 'luks', 'control_location': 'front-end'} encryption = {'provider': 'luks', 'control_location': 'front-end'}
connection_info = {'data': {'volume_id': uuids.volume_id}} connection_info = {'data': {'volume_id': uuids.volume_id}}
mock_use_native_luks.return_value = False mock_is_luks_v1.return_value = False
drvr._detach_encryptor(self.context, connection_info, encryption) drvr._detach_encryptor(self.context, connection_info, encryption)
@ -9415,10 +9406,10 @@ class LibvirtConnTestCase(test.NoDBTestCase,
mock_encryptor.detach_volume.assert_called_once_with(**encryption) mock_encryptor.detach_volume.assert_called_once_with(**encryption)
@mock.patch('nova.virt.libvirt.host.Host.find_secret') @mock.patch('nova.virt.libvirt.host.Host.find_secret')
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._use_native_luks') @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._is_luks_v1')
@mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_encryptor') @mock.patch('nova.virt.libvirt.driver.LibvirtDriver._get_volume_encryptor')
def test_detach_encryptor_native_luks_device_path_secret_missing(self, def test_detach_encryptor_native_luks_device_path_secret_missing(self,
mock_get_encryptor, mock_use_native_luks, mock_find_secret): mock_get_encryptor, mock_is_luks_v1, mock_find_secret):
"""Assert that the encryptor is not built when native LUKS is """Assert that the encryptor is not built when native LUKS is
available, the associated volume secret is missing and device_path is available, the associated volume secret is missing and device_path is
also missing from the connection_info. also missing from the connection_info.
@ -9428,33 +9419,28 @@ class LibvirtConnTestCase(test.NoDBTestCase,
'encryption_key_id': uuids.encryption_key_id} 'encryption_key_id': uuids.encryption_key_id}
connection_info = {'data': {'volume_id': uuids.volume_id}} connection_info = {'data': {'volume_id': uuids.volume_id}}
mock_find_secret.return_value = False mock_find_secret.return_value = False
mock_use_native_luks.return_value = True mock_is_luks_v1.return_value = True
drvr._detach_encryptor(self.context, connection_info, encryption) drvr._detach_encryptor(self.context, connection_info, encryption)
mock_find_secret.assert_called_once_with('volume', uuids.volume_id) mock_find_secret.assert_called_once_with('volume', uuids.volume_id)
mock_get_encryptor.assert_not_called() mock_get_encryptor.assert_not_called()
@mock.patch.object(host.Host, "has_min_version") def test_is_luks_v1(self):
def test_use_native_luks(self, mock_has_min_version):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False) drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
# The required QEMU and Libvirt versions are always available self.assertFalse(drvr._is_luks_v1({}))
# on the host and a valid LUKS provider is present within the self.assertFalse(drvr._is_luks_v1({
# encryption metadata dict.
mock_has_min_version.return_value = True
self.assertFalse(drvr._use_native_luks({}))
self.assertFalse(drvr._use_native_luks({
'provider': 'nova.volume.encryptors.cryptsetup.CryptSetupEncryptor' 'provider': 'nova.volume.encryptors.cryptsetup.CryptSetupEncryptor'
})) }))
self.assertFalse(drvr._use_native_luks({ self.assertFalse(drvr._is_luks_v1({
'provider': 'CryptSetupEncryptor'})) 'provider': 'CryptSetupEncryptor'}))
self.assertFalse(drvr._use_native_luks({ self.assertFalse(drvr._is_luks_v1({
'provider': encryptors.PLAIN})) 'provider': encryptors.PLAIN}))
self.assertTrue(drvr._use_native_luks({ self.assertTrue(drvr._is_luks_v1({
'provider': 'nova.volume.encryptors.luks.LuksEncryptor'})) 'provider': 'nova.volume.encryptors.luks.LuksEncryptor'}))
self.assertTrue(drvr._use_native_luks({ self.assertTrue(drvr._is_luks_v1({
'provider': 'LuksEncryptor'})) 'provider': 'LuksEncryptor'}))
self.assertTrue(drvr._use_native_luks({ self.assertTrue(drvr._is_luks_v1({
'provider': encryptors.LUKS})) 'provider': encryptors.LUKS}))
def test_multi_nic(self): def test_multi_nic(self):
@ -12887,7 +12873,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
is_shared_block_storage=False, is_shared_block_storage=False,
is_shared_instance_path=False, is_shared_instance_path=False,
serial_listen_ports=[], serial_listen_ports=[],
src_supports_native_luks=True,
supported_perf_events=[], supported_perf_events=[],
graphics_listen_addr_spice='127.0.0.1', graphics_listen_addr_spice='127.0.0.1',
graphics_listen_addr_vnc='127.0.0.1', graphics_listen_addr_vnc='127.0.0.1',
@ -12921,21 +12906,13 @@ class LibvirtConnTestCase(test.NoDBTestCase,
self._test_pre_live_migration_works_correctly_mocked( self._test_pre_live_migration_works_correctly_mocked(
target_ret=target_ret) target_ret=target_ret)
def test_pre_live_migration_only_dest_supports_native_luks(self):
# Assert that allow_native_luks is False when src_supports_native_luks
# is missing from migrate data during a P to Q LM.
self._test_pre_live_migration_works_correctly_mocked(
src_supports_native_luks=None, dest_supports_native_luks=True,
allow_native_luks=False)
@mock.patch.object(libvirt_driver.LibvirtDriver, 'plug_vifs') @mock.patch.object(libvirt_driver.LibvirtDriver, 'plug_vifs')
@mock.patch.object(libvirt_driver.LibvirtDriver, '_connect_volume') @mock.patch.object(libvirt_driver.LibvirtDriver, '_connect_volume')
@mock.patch('nova.virt.libvirt.utils.file_open', @mock.patch('nova.virt.libvirt.utils.file_open',
side_effect=[io.BytesIO(b''), io.BytesIO(b'')]) side_effect=[io.BytesIO(b''), io.BytesIO(b'')])
def _test_pre_live_migration_works_correctly_mocked( def _test_pre_live_migration_works_correctly_mocked(
self, mock_file_open, mock_connect, mock_plug, self, mock_file_open, mock_connect, mock_plug,
target_ret=None, src_supports_native_luks=True, target_ret=None):
dest_supports_native_luks=True, allow_native_luks=True):
# Creating testdata # Creating testdata
c = context.get_admin_context() c = context.get_admin_context()
instance = objects.Instance(root_device_name='/dev/vda', instance = objects.Instance(root_device_name='/dev/vda',
@ -12989,8 +12966,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
expected_connect_calls = [] expected_connect_calls = []
for v in block_device_info['block_device_mapping']: for v in block_device_info['block_device_mapping']:
expected_connect_calls.append( expected_connect_calls.append(
mock.call(c, v['connection_info'], instance, mock.call(c, v['connection_info'], instance))
allow_native_luks=allow_native_luks))
migrate_data = migrate_data_obj.LibvirtLiveMigrateData( migrate_data = migrate_data_obj.LibvirtLiveMigrateData(
block_migration=False, block_migration=False,
@ -13004,10 +12980,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
if not target_ret: if not target_ret:
target_ret = self._generate_target_ret() target_ret = self._generate_target_ret()
if src_supports_native_luks:
migrate_data.src_supports_native_luks = True
else:
target_ret.pop('src_supports_native_luks')
result = drvr.pre_live_migration( result = drvr.pre_live_migration(
c, instance, block_device_info, nw_info, None, c, instance, block_device_info, nw_info, None,
migrate_data=migrate_data) migrate_data=migrate_data)
@ -13168,7 +13140,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
disk_available_mb=123, disk_available_mb=123,
image_type='qcow2', image_type='qcow2',
filename='foo', filename='foo',
src_supports_native_luks=True,
) )
expected_migrate_data = migrate_data_obj.LibvirtLiveMigrateData( expected_migrate_data = migrate_data_obj.LibvirtLiveMigrateData(
@ -13184,7 +13155,6 @@ class LibvirtConnTestCase(test.NoDBTestCase,
serial_listen_ports=[], serial_listen_ports=[],
supported_perf_events=[], supported_perf_events=[],
target_connect_addr=None, target_connect_addr=None,
src_supports_native_luks=True
) )
bdmi_vol1 = migrate_data_obj.LibvirtLiveMigrateBDMInfo() bdmi_vol1 = migrate_data_obj.LibvirtLiveMigrateBDMInfo()
@ -13222,7 +13192,7 @@ class LibvirtConnTestCase(test.NoDBTestCase,
expected_connect_volume_calls = [] expected_connect_volume_calls = []
for bdm in block_device_info['block_device_mapping']: for bdm in block_device_info['block_device_mapping']:
expected_call = mock.call(self.context, bdm['connection_info'], expected_call = mock.call(self.context, bdm['connection_info'],
inst_ref, allow_native_luks=True) inst_ref)
expected_connect_volume_calls.append(expected_call) expected_connect_volume_calls.append(expected_call)
mock_connect_volume.assert_has_calls(expected_connect_volume_calls) mock_connect_volume.assert_has_calls(expected_connect_volume_calls)
@ -18566,11 +18536,11 @@ class LibvirtConnTestCase(test.NoDBTestCase,
save.assert_called_once_with() save.assert_called_once_with()
@mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_encryption') @mock.patch.object(libvirt_driver.LibvirtDriver, '_get_volume_encryption')
@mock.patch.object(libvirt_driver.LibvirtDriver, '_use_native_luks') @mock.patch.object(libvirt_driver.LibvirtDriver, '_is_luks_v1')
def test_swap_volume_native_luks_blocked(self, mock_use_native_luks, def test_swap_volume_native_luks_blocked(self, mock_is_luks_v1,
mock_get_encryption): mock_get_encryption):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI()) drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI())
mock_use_native_luks.return_value = True mock_is_luks_v1.return_value = True
# dest volume is encrypted # dest volume is encrypted
mock_get_encryption.side_effect = [{}, {'provider': 'luks'}] mock_get_encryption.side_effect = [{}, {'provider': 'luks'}]

View File

@ -1499,12 +1499,11 @@ class LibvirtDriver(driver.ComputeDriver):
return self.volume_drivers[driver_type] return self.volume_drivers[driver_type]
def _connect_volume(self, context, connection_info, instance, def _connect_volume(self, context, connection_info, instance,
encryption=None, allow_native_luks=True): encryption=None):
vol_driver = self._get_volume_driver(connection_info) vol_driver = self._get_volume_driver(connection_info)
vol_driver.connect_volume(connection_info, instance) vol_driver.connect_volume(connection_info, instance)
try: try:
self._attach_encryptor( self._attach_encryptor(context, connection_info, encryption)
context, connection_info, encryption, allow_native_luks)
except Exception: except Exception:
# Encryption failed so rollback the volume connection. # Encryption failed so rollback the volume connection.
with excutils.save_and_reraise_exception(logger=LOG): with excutils.save_and_reraise_exception(logger=LOG):
@ -1565,8 +1564,8 @@ class LibvirtDriver(driver.ComputeDriver):
return vol_driver.extend_volume(connection_info, instance, return vol_driver.extend_volume(connection_info, instance,
requested_size) requested_size)
def _use_native_luks(self, encryption=None): def _is_luks_v1(self, encryption=None):
"""Check if LUKS is the required 'provider' """Check if LUKS (v1) is the encryption 'provider'
""" """
provider = None provider = None
if encryption: if encryption:
@ -1598,22 +1597,18 @@ class LibvirtDriver(driver.ComputeDriver):
self._volume_api, volume_id, connection_info) self._volume_api, volume_id, connection_info)
return encryption return encryption
def _attach_encryptor(self, context, connection_info, encryption, def _attach_encryptor(self, context, connection_info, encryption):
allow_native_luks):
"""Attach the frontend encryptor if one is required by the volume. """Attach the frontend encryptor if one is required by the volume.
The request context is only used when an encryption metadata dict is The request context is only used when an encryption metadata dict is
not provided. The encryption metadata dict being populated is then used not provided. The encryption metadata dict being populated is then used
to determine if an attempt to attach the encryptor should be made. to determine if an attempt to attach the encryptor should be made.
If native LUKS decryption is enabled then create a Libvirt volume
secret containing the LUKS passphrase for the volume.
""" """
if encryption is None: if encryption is None:
encryption = self._get_volume_encryption(context, connection_info) encryption = self._get_volume_encryption(context, connection_info)
if (encryption and allow_native_luks and if encryption and self._is_luks_v1(encryption=encryption):
self._use_native_luks(encryption)):
# NOTE(lyarwood): Fetch the associated key for the volume and # NOTE(lyarwood): Fetch the associated key for the volume and
# decode the passphrase from the key. # decode the passphrase from the key.
# FIXME(lyarwood): c-vol currently creates symmetric keys for use # FIXME(lyarwood): c-vol currently creates symmetric keys for use
@ -1664,11 +1659,11 @@ class LibvirtDriver(driver.ComputeDriver):
if encryption is None: if encryption is None:
encryption = self._get_volume_encryption(context, connection_info) encryption = self._get_volume_encryption(context, connection_info)
# NOTE(lyarwood): Handle bug #1821696 where volume secrets have been # NOTE(lyarwood): Handle bug #1821696 where volume secrets have been
# removed manually by returning if native LUKS decryption is available # removed manually by returning if a LUKS provider is being used
# and device_path is not present in the connection_info. This avoids # and device_path is not present in the connection_info. This avoids
# VolumeEncryptionNotSupported being thrown when we incorrectly build # VolumeEncryptionNotSupported being thrown when we incorrectly build
# the encryptor below due to the secrets not being present above. # the encryptor below due to the secrets not being present above.
if (encryption and self._use_native_luks(encryption) and if (encryption and self._is_luks_v1(encryption=encryption) and
not connection_info['data'].get('device_path')): not connection_info['data'].get('device_path')):
return return
if encryption: if encryption:
@ -1830,8 +1825,8 @@ class LibvirtDriver(driver.ComputeDriver):
# NOTE(lyarwood): https://bugzilla.redhat.com/show_bug.cgi?id=760547 # NOTE(lyarwood): https://bugzilla.redhat.com/show_bug.cgi?id=760547
old_encrypt = self._get_volume_encryption(context, old_connection_info) old_encrypt = self._get_volume_encryption(context, old_connection_info)
new_encrypt = self._get_volume_encryption(context, new_connection_info) new_encrypt = self._get_volume_encryption(context, new_connection_info)
if ((old_encrypt and self._use_native_luks(old_encrypt)) or if ((old_encrypt and self._is_luks_v1(old_encrypt)) or
(new_encrypt and self._use_native_luks(new_encrypt))): (new_encrypt and self._is_luks_v1(new_encrypt))):
raise NotImplementedError(_("Swap volume is not supported for " raise NotImplementedError(_("Swap volume is not supported for "
"encrypted volumes when native LUKS decryption is enabled.")) "encrypted volumes when native LUKS decryption is enabled."))
@ -8071,14 +8066,6 @@ class LibvirtDriver(driver.ComputeDriver):
relative=True) relative=True)
dest_check_data.instance_relative_path = instance_path dest_check_data.instance_relative_path = instance_path
# NOTE(lyarwood): Used to indicate to the dest that the src is capable
# of wiring up the encrypted disk configuration for the domain.
# Note that this does not require the QEMU and Libvirt versions to
# decrypt LUKS to be installed on the source node. Only the Nova
# utility code to generate the correct XML is required, so we can
# default to True here for all computes >= Queens.
dest_check_data.src_supports_native_luks = True
# TODO(artom) Set to indicate that the source (us) can perform a # TODO(artom) Set to indicate that the source (us) can perform a
# NUMA-aware live migration. NUMA-aware live migration will become # NUMA-aware live migration. NUMA-aware live migration will become
# unconditionally supported in RPC 6.0, so this sentinel can be removed # unconditionally supported in RPC 6.0, so this sentinel can be removed
@ -9069,15 +9056,7 @@ class LibvirtDriver(driver.ComputeDriver):
for bdm in block_device_mapping: for bdm in block_device_mapping:
connection_info = bdm['connection_info'] connection_info = bdm['connection_info']
# NOTE(lyarwood): Handle the P to Q LM during upgrade use case self._connect_volume(context, connection_info, instance)
# where an instance has encrypted volumes attached using the
# os-brick encryptors. Do not attempt to attach the encrypted
# volume using native LUKS decryption on the destionation.
src_native_luks = False
if migrate_data.obj_attr_is_set('src_supports_native_luks'):
src_native_luks = migrate_data.src_supports_native_luks
self._connect_volume(context, connection_info, instance,
allow_native_luks=src_native_luks)
self._pre_live_migration_plug_vifs( self._pre_live_migration_plug_vifs(
instance, network_info, migrate_data) instance, network_info, migrate_data)