Don't allow image creation with encrypted nfs volumes

With change[1], we will enabled encrypted volume support for cinder
nfs driver.
Before enabling that, we require handling in cinder consuming projects
(like glance_store) to not have unexpected behavior.
This patch blocks image creation if the destination volume (in which
the image will be written) is an encrypted nfs volume.

[1] https://review.opendev.org/#/c/597148/

Closes-Bug: #1884482

Change-Id: I3b4c6782e561f22a7118624e26bf056cd6405a30
This commit is contained in:
Rajat Dhasmana 2020-06-02 09:15:50 +00:00
parent 7eb1635425
commit becd57467a
3 changed files with 52 additions and 11 deletions

View File

@ -305,6 +305,11 @@ Possible values:
Related options:
* None
NOTE: You cannot use an encrypted volume_type associated with an NFS backend.
An encrypted volume stored on an NFS backend will raise an exception whenever
glance_store tries to write or access image data stored in that volume.
Consult your Cinder administrator to determine an appropriate volume_type.
"""),
cfg.BoolOpt('cinder_enforce_multipath',
default=False,
@ -581,6 +586,16 @@ class Store(glance_store.driver.Store):
connection_info['driver_volume_type'], root_helper,
conn=connection_info)
if connection_info['driver_volume_type'] == 'nfs':
if volume.encrypted:
volume.unreserve(volume)
volume.delete()
msg = (_('Encrypted volume creation for cinder nfs is not '
'supported from glance_store. Failed to create '
'volume %(volume_id)s')
% {'volume_id': volume.id})
LOG.error(msg)
raise exceptions.BackendException(msg)
@utils.synchronized(connection_info['data']['export'])
def connect_volume_nfs():
data = connection_info['data']

View File

@ -151,7 +151,8 @@ class TestCinderStore(base.StoreBaseTest,
def _test_open_cinder_volume(self, open_mode, attach_mode, error,
multipath_supported=False,
enforce_multipath=False):
enforce_multipath=False,
encrypted_nfs=False):
self.config(cinder_mount_point_base=None)
fake_volume = mock.MagicMock(id=str(uuid.uuid4()), status='available')
fake_volumes = FakeObject(get=lambda id: fake_volume,
@ -193,19 +194,35 @@ class TestCinderStore(base.StoreBaseTest,
'get_connector_properties') as mock_conn:
if error:
self.assertRaises(error, do_open)
elif encrypted_nfs:
fake_volume.initialize_connection.return_value = {
'driver_volume_type': 'nfs'
}
fake_volume.encrypted = True
try:
with self.store._open_cinder_volume(
fake_client, fake_volume, open_mode):
pass
except exceptions.BackendException:
self.assertEqual(1,
fake_volume.unreserve.call_count)
self.assertEqual(1,
fake_volume.delete.call_count)
else:
do_open()
mock_conn.assert_called_once_with(
root_helper, socket.gethostname(), multipath_supported,
enforce_multipath)
fake_connector.connect_volume.assert_called_once_with(mock.ANY)
fake_connector.disconnect_volume.assert_called_once_with(
mock.ANY, fake_devinfo)
fake_volume.attach.assert_called_once_with(
None, 'glance_store', attach_mode,
host_name=socket.gethostname())
fake_volumes.detach.assert_called_once_with(fake_volume)
if not encrypted_nfs:
mock_conn.assert_called_once_with(
root_helper, socket.gethostname(),
multipath_supported, enforce_multipath)
fake_connector.connect_volume.assert_called_once_with(
mock.ANY)
fake_connector.disconnect_volume.assert_called_once_with(
mock.ANY, fake_devinfo)
fake_volume.attach.assert_called_once_with(
None, 'glance_store', attach_mode,
host_name=socket.gethostname())
fake_volumes.detach.assert_called_once_with(fake_volume)
def test_open_cinder_volume_rw(self):
self._test_open_cinder_volume('wb', 'rw', None)
@ -228,6 +245,9 @@ class TestCinderStore(base.StoreBaseTest,
multipath_supported=True,
enforce_multipath=True)
def test_open_cinder_volume_nfs_encrypted(self):
self._test_open_cinder_volume('rb', 'ro', None, encrypted_nfs=True)
def test_cinder_configure_add(self):
self.assertRaises(exceptions.BadStoreConfiguration,
self.store._check_context, None)

View File

@ -0,0 +1,6 @@
---
fixes:
- |
`Bug #1884482 <https://bugs.launchpad.net/cinder/+bug/1884482>`_:
Blocked creation of images on encrypted nfs volumes when glance store
is cinder.