Add Ceph version check
CephFS drivers in OpenStack Manila are directing mgr commands to the mgr by specifying mon-mgr as the target [0]. This target (mon-mgr) was added to Ceph in Octopus [1]. We would need a version check in order to set the correct target while we wait on the backport on Ceph to land [2]. [0]3ea5d50a23
[1]4000d500c0
[2] https://tracker.ceph.com/issues/51039 Closes-Bug: #1930459 Change-Id: I1a1079df8e104c5ddba29cb614eb4e02a304082e
This commit is contained in:
parent
fac7fc52eb
commit
3ed02db00e
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user