Merge "Add cephfs filesystem to shares metadata"
This commit is contained in:
commit
f4c77bfe71
@ -139,7 +139,7 @@ cephfs_opts = [
|
|||||||
help="The name of the filesystem to use, if there are "
|
help="The name of the filesystem to use, if there are "
|
||||||
"multiple filesystems in the cluster."),
|
"multiple filesystems in the cluster."),
|
||||||
cfg.StrOpt('cephfs_ensure_all_shares_salt',
|
cfg.StrOpt('cephfs_ensure_all_shares_salt',
|
||||||
default="manila_cephfs_reef_bobcat",
|
default="manila_cephfs_reef_caracal",
|
||||||
help="Provide a unique string value to make the driver "
|
help="Provide a unique string value to make the driver "
|
||||||
"ensure all of the shares it has created during "
|
"ensure all of the shares it has created during "
|
||||||
"startup. Ensuring would re-export shares and this "
|
"startup. Ensuring would re-export shares and this "
|
||||||
@ -353,6 +353,14 @@ class CephFSDriver(driver.ExecuteMixin, driver.GaneshaMixin,
|
|||||||
|
|
||||||
return self.protocol_helper.get_export_locations(share, subvolume_path)
|
return self.protocol_helper.get_export_locations(share, subvolume_path)
|
||||||
|
|
||||||
|
def get_optional_share_creation_data(self, share, share_server=None):
|
||||||
|
"""Get the additional properties to be set in a share.
|
||||||
|
|
||||||
|
:return: the metadata to be set in share.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self.protocol_helper.get_optional_share_creation_data(share)
|
||||||
|
|
||||||
def setup_default_ceph_cmd_target(self):
|
def setup_default_ceph_cmd_target(self):
|
||||||
global ceph_default_target
|
global ceph_default_target
|
||||||
if not ceph_default_target:
|
if not ceph_default_target:
|
||||||
@ -558,8 +566,13 @@ class CephFSDriver(driver.ExecuteMixin, driver.GaneshaMixin,
|
|||||||
self.protocol_helper.reapply_rules_while_ensuring_shares,
|
self.protocol_helper.reapply_rules_while_ensuring_shares,
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
|
share_metadata = (
|
||||||
|
self.get_optional_share_creation_data(share).get(
|
||||||
|
"metadata", {})
|
||||||
|
)
|
||||||
share_updates[share['id']].update({
|
share_updates[share['id']].update({
|
||||||
'export_locations': self._get_export_locations(share),
|
'export_locations': self._get_export_locations(share),
|
||||||
|
"metadata": share_metadata
|
||||||
})
|
})
|
||||||
except exception.ShareBackendException as e:
|
except exception.ShareBackendException as e:
|
||||||
if 'does not exist' in str(e).lower():
|
if 'does not exist' in str(e).lower():
|
||||||
@ -842,6 +855,7 @@ class NativeProtocolHelper(ganesha.NASHelperBase):
|
|||||||
return {
|
return {
|
||||||
"cephfs_ensure_all_shares_salt":
|
"cephfs_ensure_all_shares_salt":
|
||||||
self.configuration.cephfs_ensure_all_shares_salt,
|
self.configuration.cephfs_ensure_all_shares_salt,
|
||||||
|
"cephfs_filesystem_name": self.volname,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_export_locations(self, share, subvolume_path):
|
def get_export_locations(self, share, subvolume_path):
|
||||||
@ -861,6 +875,9 @@ class NativeProtocolHelper(ganesha.NASHelperBase):
|
|||||||
'metadata': {},
|
'metadata': {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def get_optional_share_creation_data(self, share, share_server=None):
|
||||||
|
return {"metadata": {"__mount_options": f"fs={self.volname}"}}
|
||||||
|
|
||||||
def _allow_access(self, context, share, access, share_server=None):
|
def _allow_access(self, context, share, access, share_server=None):
|
||||||
if access['access_type'] != CEPHX_ACCESS_TYPE:
|
if access['access_type'] != CEPHX_ACCESS_TYPE:
|
||||||
raise exception.InvalidShareAccessType(type=access['access_type'])
|
raise exception.InvalidShareAccessType(type=access['access_type'])
|
||||||
@ -1057,6 +1074,9 @@ class NFSProtocolHelperMixin():
|
|||||||
export_locations.append(export_location)
|
export_locations.append(export_location)
|
||||||
return export_locations
|
return export_locations
|
||||||
|
|
||||||
|
def get_optional_share_creation_data(self, share, share_server=None):
|
||||||
|
return {}
|
||||||
|
|
||||||
def _get_export_path(self, share):
|
def _get_export_path(self, share):
|
||||||
"""Callback to provide export path."""
|
"""Callback to provide export path."""
|
||||||
argdict = {
|
argdict = {
|
||||||
|
@ -255,32 +255,42 @@ class CephFSDriverTestCase(test.TestCase):
|
|||||||
},
|
},
|
||||||
|
|
||||||
]
|
]
|
||||||
|
share_backend_info = {'metadata': {'__mount_options': 'fs=cephfs'}}
|
||||||
|
metadata = share_backend_info.get('metadata')
|
||||||
expected_updates = {
|
expected_updates = {
|
||||||
shares[0]['id']: {
|
shares[0]['id']: {
|
||||||
'status': constants.STATUS_ERROR,
|
'status': constants.STATUS_ERROR,
|
||||||
'reapply_access_rules': True,
|
'reapply_access_rules': True,
|
||||||
|
'metadata': metadata,
|
||||||
},
|
},
|
||||||
shares[1]['id']: {
|
shares[1]['id']: {
|
||||||
'export_locations': export_locations[0],
|
'export_locations': export_locations[0],
|
||||||
'reapply_access_rules': True,
|
'reapply_access_rules': True,
|
||||||
|
'metadata': metadata,
|
||||||
},
|
},
|
||||||
shares[2]['id']: {
|
shares[2]['id']: {
|
||||||
'export_locations': export_locations[1],
|
'export_locations': export_locations[1],
|
||||||
'reapply_access_rules': True,
|
'reapply_access_rules': True,
|
||||||
|
'metadata': metadata,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err_message = (f"Error ENOENT: subvolume {self._share['id']} does "
|
err_message = (f"Error ENOENT: subvolume {self._share['id']} does "
|
||||||
f"not exist")
|
f"not exist")
|
||||||
expected_exception = exception.ShareBackendException(err_message)
|
expected_exception = exception.ShareBackendException(err_message)
|
||||||
|
|
||||||
self.mock_object(
|
self.mock_object(
|
||||||
self._driver, '_get_export_locations',
|
self._driver, '_get_export_locations',
|
||||||
mock.Mock(side_effect=[expected_exception] + export_locations))
|
mock.Mock(side_effect=[expected_exception] + export_locations))
|
||||||
|
self.mock_object(
|
||||||
|
self._driver, 'get_optional_share_creation_data',
|
||||||
|
mock.Mock(return_value=share_backend_info))
|
||||||
|
|
||||||
actual_updates = self._driver.ensure_shares(self._context, shares)
|
actual_updates = self._driver.ensure_shares(self._context, shares)
|
||||||
|
|
||||||
self.assertEqual(3, self._driver._get_export_locations.call_count)
|
self.assertEqual(3, self._driver._get_export_locations.call_count)
|
||||||
self._driver._get_export_locations.assert_has_calls([
|
self._driver._get_export_locations.assert_has_calls([
|
||||||
mock.call(shares[0]), mock.call(shares[1]), mock.call(shares[2])])
|
mock.call(shares[0]), mock.call(shares[1]), mock.call(shares[2])])
|
||||||
|
self.assertTrue(self._driver.get_optional_share_creation_data.called)
|
||||||
self.assertEqual(expected_updates, actual_updates)
|
self.assertEqual(expected_updates, actual_updates)
|
||||||
|
|
||||||
def test_delete_share(self):
|
def test_delete_share(self):
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
upgrade:
|
||||||
|
- |
|
||||||
|
Shares created using the CEPHFS Native protocol will now have a new
|
||||||
|
`__mount_options` metadata containing the `cephfs_filesystem_name` to
|
||||||
|
enhance usability while mounting shares. Existing shares will be updated
|
||||||
|
through the ensure shares workflow. To preserve backwards compatibility,
|
||||||
|
this metadata is mutable by end users. It is strongly recommended that
|
||||||
|
administrators include "__mount_options" in the
|
||||||
|
`[DEFAULT]/admin_only_metadata_keys` configuration option.
|
Loading…
Reference in New Issue
Block a user