diff --git a/manila/share/drivers/cephfs/driver.py b/manila/share/drivers/cephfs/driver.py index 0451b79682..d4504e4c53 100644 --- a/manila/share/drivers/cephfs/driver.py +++ b/manila/share/drivers/cephfs/driver.py @@ -16,6 +16,7 @@ import ipaddress import json +import re import socket import sys @@ -37,6 +38,7 @@ from manila.share.drivers import helpers as driver_helpers rados = None json_command = None +ceph_default_target = None def setup_rados(): @@ -150,7 +152,7 @@ class RadosError(Exception): def rados_command(rados_client, prefix=None, args=None, json_obj=False, - target=('mon-mgr', )): + target=None): """Safer wrapper for ceph_argparse.json_command Raises error exception instead of relying on caller to check return @@ -166,6 +168,9 @@ def rados_command(rados_client, prefix=None, args=None, json_obj=False, If json is False, return a decoded string (the data returned by ceph command) """ + + target = target or ceph_default_target + if args is None: args = {} @@ -216,7 +221,7 @@ class CephFSDriver(driver.ExecuteMixin, driver.GaneshaMixin, self._rados_client = None # name of the filesystem/volume used by the driver self._volname = None - + self._ceph_mon_version = None self.configuration.append_config_values(cephfs_opts) try: @@ -237,6 +242,8 @@ class CephFSDriver(driver.ExecuteMixin, driver.GaneshaMixin, protocol_helper_class = getattr( sys.modules[__name__], 'NFSProtocolHelper') + self.setup_default_ceph_cmd_target() + self.protocol_helper = protocol_helper_class( self._execute, self.configuration, @@ -312,6 +319,44 @@ class CephFSDriver(driver.ExecuteMixin, driver.GaneshaMixin, return self.protocol_helper.get_export_locations(share, subvolume_path) + def setup_default_ceph_cmd_target(self): + global ceph_default_target + if not ceph_default_target: + ceph_default_target = ('mon-mgr', ) + + try: + ceph_major_version = self.ceph_mon_version['major'] + except Exception: + msg = _("Error reading ceph version to set the default " + "target. Please check your Ceph backend is reachable.") + raise exception.ShareBackendException(msg=msg) + + if ceph_major_version == '14': + ceph_default_target = ('mgr', ) + elif ceph_major_version < '14': + msg = _("CephFSDriver does not support Ceph " + "cluster version less than 14.x (Nautilus)") + raise exception.ShareBackendException(msg=msg) + + @property + def ceph_mon_version(self): + if self._ceph_mon_version: + return self._ceph_mon_version + + self._ceph_mon_version = {} + + output = rados_command(self.rados_client, "version", target=('mon', )) + + version_str = json.loads(output)["version"] + + p = re.compile(r"ceph version (\d+)\.(\d+)\.(\d+)") + major, minor, extra = p.match(version_str).groups() + self._ceph_mon_version['major'] = major + self._ceph_mon_version['minor'] = minor + self._ceph_mon_version['extra'] = extra + + return self._ceph_mon_version + @property def rados_client(self): if self._rados_client: diff --git a/manila/tests/share/drivers/cephfs/test_driver.py b/manila/tests/share/drivers/cephfs/test_driver.py index 2a08547229..d0bc855d26 100644 --- a/manila/tests/share/drivers/cephfs/test_driver.py +++ b/manila/tests/share/drivers/cephfs/test_driver.py @@ -89,6 +89,8 @@ class CephFSDriverTestCase(test.TestCase): self.mock_object(driver, 'NativeProtocolHelper') self.mock_object(driver, 'NFSProtocolHelper') + driver.ceph_default_target = ('mon-mgr', ) + self._driver = ( driver.CephFSDriver(execute=self._execute, configuration=self.fake_conf)) @@ -121,6 +123,37 @@ class CephFSDriverTestCase(test.TestCase): self.assertEqual(DEFAULT_VOLUME_MODE, self._driver._cephfs_volume_mode) + @ddt.data( + ('{"version": "ceph version 16.2.4"}', 'pacific'), + ('{"version": "ceph version 15.1.2"}', 'octopus'), + ('{"version": "ceph version 14.3.1"}', 'nautilus'), + ) + @ddt.unpack + def test_version_check(self, ceph_mon_version, codename): + driver.ceph_default_target = None + driver.rados_command.return_value = ceph_mon_version + + self._driver.do_setup(self._context) + + if codename == 'nautilus': + self.assertEqual(('mgr', ), driver.ceph_default_target) + else: + self.assertEqual(('mon-mgr', ), driver.ceph_default_target) + + driver.rados_command.assert_called_once_with( + self._driver.rados_client, "version", target=('mon', )) + + self.assertEqual(1, driver.rados_command.call_count) + + def test_version_check_not_supported(self): + driver.ceph_default_target = None + driver.rados_command.return_value = ( + '{"version": "ceph version 13.0.1"}') + + self.assertRaises(exception.ShareBackendException, + self._driver.do_setup, + self._context) + @ddt.data('cephfs', 'nfs') def test_check_for_setup_error(self, protocol_helper): self._driver.configuration.cephfs_protocol_helper_type = ( @@ -551,6 +584,8 @@ class NativeProtocolHelperTestCase(test.TestCase): self.mock_object(driver, "rados_command") + driver.ceph_default_target = ('mon-mgr', ) + self._native_protocol_helper = driver.NativeProtocolHelper( None, self.fake_conf, @@ -851,6 +886,8 @@ class NFSProtocolHelperTestCase(test.TestCase): self.mock_object(driver.socket, 'gethostname') self.mock_object(driver, "rados_command") + driver.ceph_default_target = ('mon-mgr', ) + self._nfs_helper = driver.NFSProtocolHelper( self._execute, self.fake_conf, @@ -1172,6 +1209,8 @@ class CephFSDriverAltConfigTestCase(test.TestCase): self.mock_object(driver, 'NativeProtocolHelper') self.mock_object(driver, 'NFSProtocolHelper') + driver.ceph_default_target = ('mon-mgr', ) + @ddt.data('cephfs', 'nfs') def test_do_setup_alt_volume_mode(self, protocol_helper): self.fake_conf.set_default('cephfs_volume_mode', ALT_VOLUME_MODE) diff --git a/releasenotes/notes/bug-1930459-add-ceph-version-check-88eee324bc6134ea.yaml b/releasenotes/notes/bug-1930459-add-ceph-version-check-88eee324bc6134ea.yaml new file mode 100644 index 0000000000..68fad305ff --- /dev/null +++ b/releasenotes/notes/bug-1930459-add-ceph-version-check-88eee324bc6134ea.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + A Ceph version check has been added as part of this change to address + the absense of the mon-mgr target in Ceph Nautilus. With this change, + Ceph Nautilus users can leverage their storage backend with the + OpenStack manila Wallaby release. \ No newline at end of file