Add preferred info to ceph nfs export locations
Change the Ceph NFS helpers to update the export locations preferred field based on the configuration. The preferred export location will always relate to the Ceph ADM deployed Ganesha cluster. Partial-Bug: #2035137 Change-Id: I9b05a6444b8ac98f79f297fec9c74a45ef11429d
This commit is contained in:
parent
8fa97dfb7b
commit
3eb34c3ce7
@ -996,19 +996,22 @@ class NFSProtocolHelperMixin():
|
|||||||
# `cephfs_ganesha_server_ip` wasn't possibly set and the used
|
# `cephfs_ganesha_server_ip` wasn't possibly set and the used
|
||||||
# address is the hostname
|
# address is the hostname
|
||||||
try:
|
try:
|
||||||
server_address = driver_helpers.escaped_address(export_ip)
|
server_address = driver_helpers.escaped_address(
|
||||||
|
export_ip['ip'])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
server_address = export_ip
|
server_address = export_ip['ip']
|
||||||
|
|
||||||
export_path = "{server_address}:{mount_path}".format(
|
export_path = "{server_address}:{mount_path}".format(
|
||||||
server_address=server_address, mount_path=subvolume_path)
|
server_address=server_address, mount_path=subvolume_path)
|
||||||
|
|
||||||
LOG.info("Calculated export path for share %(id)s: %(epath)s",
|
LOG.info("Calculated export path for share %(id)s: %(epath)s",
|
||||||
{"id": share['id'], "epath": export_path})
|
{"id": share['id'], "epath": export_path})
|
||||||
|
|
||||||
export_location = {
|
export_location = {
|
||||||
'path': export_path,
|
'path': export_path,
|
||||||
'is_admin_only': False,
|
'is_admin_only': False,
|
||||||
'metadata': {},
|
'metadata': {},
|
||||||
|
'preferred': export_ip['preferred']
|
||||||
}
|
}
|
||||||
export_locations.append(export_location)
|
export_locations.append(export_location)
|
||||||
return export_locations
|
return export_locations
|
||||||
@ -1039,7 +1042,7 @@ class NFSProtocolHelperMixin():
|
|||||||
|
|
||||||
for export_ip in self.export_ips:
|
for export_ip in self.export_ips:
|
||||||
self.configured_ip_versions.add(
|
self.configured_ip_versions.add(
|
||||||
ipaddress.ip_address(str(export_ip)).version)
|
ipaddress.ip_address(str(export_ip['ip'])).version)
|
||||||
except Exception:
|
except Exception:
|
||||||
# export_ips contained a hostname, safest thing is to
|
# export_ips contained a hostname, safest thing is to
|
||||||
# claim support for IPv4 and IPv6 address families
|
# claim support for IPv4 and IPv6 address families
|
||||||
@ -1145,9 +1148,13 @@ class NFSProtocolHelper(NFSProtocolHelperMixin, ganesha.GaneshaNASHelper2):
|
|||||||
rados_command(self.rados_client, "fs subvolume deauthorize", argdict)
|
rados_command(self.rados_client, "fs subvolume deauthorize", argdict)
|
||||||
|
|
||||||
def _get_export_ips(self):
|
def _get_export_ips(self):
|
||||||
export_ips = self.config.cephfs_ganesha_export_ips
|
ganesha_export_ips = self.config.cephfs_ganesha_export_ips
|
||||||
if not export_ips:
|
if not ganesha_export_ips:
|
||||||
export_ips = [self.ganesha_host]
|
ganesha_export_ips = [self.ganesha_host]
|
||||||
|
|
||||||
|
export_ips = []
|
||||||
|
for ip in ganesha_export_ips:
|
||||||
|
export_ips.append({'ip': ip, 'preferred': False})
|
||||||
|
|
||||||
return export_ips
|
return export_ips
|
||||||
|
|
||||||
@ -1186,11 +1193,22 @@ class NFSClusterProtocolHelper(NFSProtocolHelperMixin, ganesha.NASHelperBase):
|
|||||||
|
|
||||||
return self._nfs_clusterid
|
return self._nfs_clusterid
|
||||||
|
|
||||||
|
def _get_configured_export_ips(self):
|
||||||
|
ganesha_server_ips = (
|
||||||
|
self.configuration.safe_get('cephfs_ganesha_export_ips') or [])
|
||||||
|
if not ganesha_server_ips:
|
||||||
|
ganesha_server_ips = (
|
||||||
|
self.configuration.safe_get('cephfs_ganesha_server_ip'))
|
||||||
|
ganesha_server_ips = (
|
||||||
|
[ganesha_server_ips] if ganesha_server_ips else [])
|
||||||
|
|
||||||
|
return ganesha_server_ips
|
||||||
|
|
||||||
def _get_export_ips(self):
|
def _get_export_ips(self):
|
||||||
"""Get NFS cluster export ips."""
|
"""Get NFS cluster export ips."""
|
||||||
nfs_clusterid = self.nfs_clusterid
|
nfs_clusterid = self.nfs_clusterid
|
||||||
export_ips = []
|
ceph_nfs_export_ips = []
|
||||||
|
ganesha_export_ips = self._get_configured_export_ips()
|
||||||
argdict = {
|
argdict = {
|
||||||
"cluster_id": nfs_clusterid,
|
"cluster_id": nfs_clusterid,
|
||||||
}
|
}
|
||||||
@ -1207,17 +1225,28 @@ class NFSClusterProtocolHelper(NFSProtocolHelperMixin, ganesha.NASHelperBase):
|
|||||||
if not vip:
|
if not vip:
|
||||||
hosts = nfs_cluster_info[nfs_clusterid]["backend"]
|
hosts = nfs_cluster_info[nfs_clusterid]["backend"]
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
export_ips.append(host["ip"])
|
ceph_nfs_export_ips.append(host["ip"])
|
||||||
else:
|
else:
|
||||||
export_ips.append(vip)
|
ceph_nfs_export_ips.append(vip)
|
||||||
|
|
||||||
# there are no export IPs, there are no NFS servers we can use
|
# there are no export IPs, there are no NFS servers we can use
|
||||||
if not export_ips:
|
if not ceph_nfs_export_ips:
|
||||||
msg = _("There are no NFS servers available to use. "
|
msg = _("There are no NFS servers available to use. "
|
||||||
"Please check the health of your Ceph cluster "
|
"Please check the health of your Ceph cluster "
|
||||||
"and restart the manila share service.")
|
"and restart the manila share service.")
|
||||||
raise exception.ShareBackendException(msg=msg)
|
raise exception.ShareBackendException(msg=msg)
|
||||||
|
|
||||||
|
export_ips = []
|
||||||
|
for ip in ceph_nfs_export_ips:
|
||||||
|
export_ips.append({'ip': ip, 'preferred': True})
|
||||||
|
|
||||||
|
# It's possible for deployers to state additional
|
||||||
|
# NFS interfaces directly via manila.conf. If they do,
|
||||||
|
# these are represented as non-preferred export paths.
|
||||||
|
# This is mostly to allow NFS-Ganesha server migrations.
|
||||||
|
for ip in ganesha_export_ips:
|
||||||
|
export_ips.append({'ip': ip, 'preferred': False})
|
||||||
|
|
||||||
return export_ips
|
return export_ips
|
||||||
|
|
||||||
def check_for_setup_error(self):
|
def check_for_setup_error(self):
|
||||||
|
@ -1070,7 +1070,8 @@ class NFSProtocolHelperTestCase(test.TestCase):
|
|||||||
[{
|
[{
|
||||||
'path': '1.2.3.4:/foo/bar',
|
'path': '1.2.3.4:/foo/bar',
|
||||||
'is_admin_only': False,
|
'is_admin_only': False,
|
||||||
'metadata': {}
|
'metadata': {},
|
||||||
|
'preferred': False
|
||||||
}], ret)
|
}], ret)
|
||||||
|
|
||||||
def test_get_export_locations_with_export_ips_configured(self):
|
def test_get_export_locations_with_export_ips_configured(self):
|
||||||
@ -1099,16 +1100,19 @@ class NFSProtocolHelperTestCase(test.TestCase):
|
|||||||
'path': '127.0.0.1:/foo/bar',
|
'path': '127.0.0.1:/foo/bar',
|
||||||
'is_admin_only': False,
|
'is_admin_only': False,
|
||||||
'metadata': {},
|
'metadata': {},
|
||||||
|
'preferred': False
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'path': '[fd3f:c057:1192:1::1]:/foo/bar',
|
'path': '[fd3f:c057:1192:1::1]:/foo/bar',
|
||||||
'is_admin_only': False,
|
'is_admin_only': False,
|
||||||
'metadata': {},
|
'metadata': {},
|
||||||
|
'preferred': False
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'path': '[::1]:/foo/bar',
|
'path': '[::1]:/foo/bar',
|
||||||
'is_admin_only': False,
|
'is_admin_only': False,
|
||||||
'metadata': {},
|
'metadata': {},
|
||||||
|
'preferred': False
|
||||||
},
|
},
|
||||||
], ret)
|
], ret)
|
||||||
|
|
||||||
@ -1394,10 +1398,12 @@ class NFSClusterProtocolHelperTestCase(test.TestCase):
|
|||||||
'path': '10.0.0.10:/foo/bar',
|
'path': '10.0.0.10:/foo/bar',
|
||||||
'is_admin_only': False,
|
'is_admin_only': False,
|
||||||
'metadata': {},
|
'metadata': {},
|
||||||
|
'preferred': True
|
||||||
}, {
|
}, {
|
||||||
'path': '10.0.0.11:/foo/bar',
|
'path': '10.0.0.11:/foo/bar',
|
||||||
'is_admin_only': False,
|
'is_admin_only': False,
|
||||||
'metadata': {},
|
'metadata': {},
|
||||||
|
'preferred': True
|
||||||
}]
|
}]
|
||||||
|
|
||||||
export_locations = (
|
export_locations = (
|
||||||
@ -1410,6 +1416,76 @@ class NFSClusterProtocolHelperTestCase(test.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(expected_export_locations, export_locations)
|
self.assertEqual(expected_export_locations, export_locations)
|
||||||
|
|
||||||
|
@ddt.data(
|
||||||
|
('cephfs_ganesha_server_ip', '10.0.0.1'),
|
||||||
|
('cephfs_ganesha_export_ips', ['10.0.0.2, 10.0.0.3'])
|
||||||
|
)
|
||||||
|
@ddt.unpack
|
||||||
|
def test_get_export_locations_ganesha_still_configured(self, opt, val):
|
||||||
|
cluster_info_prefix = "nfs cluster info"
|
||||||
|
nfs_clusterid = self._nfscluster_protocol_helper.nfs_clusterid
|
||||||
|
self.fake_conf.set_default(opt, val)
|
||||||
|
|
||||||
|
cluster_info_dict = {
|
||||||
|
"cluster_id": nfs_clusterid,
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster_info = {"fs-manila": {
|
||||||
|
"virtual_ip": None,
|
||||||
|
"backend": [
|
||||||
|
{"hostname": "fake-ceph-node-1",
|
||||||
|
"ip": "10.0.0.10",
|
||||||
|
"port": "1010"},
|
||||||
|
{"hostname": "fake-ceph-node-2",
|
||||||
|
"ip": "10.0.0.11",
|
||||||
|
"port": "1011"}
|
||||||
|
]
|
||||||
|
}}
|
||||||
|
|
||||||
|
driver.rados_command.return_value = json.dumps(cluster_info)
|
||||||
|
|
||||||
|
fake_cephfs_subvolume_path = "/foo/bar"
|
||||||
|
expected_export_locations = [{
|
||||||
|
'path': '10.0.0.10:/foo/bar',
|
||||||
|
'is_admin_only': False,
|
||||||
|
'metadata': {},
|
||||||
|
'preferred': True
|
||||||
|
}, {
|
||||||
|
'path': '10.0.0.11:/foo/bar',
|
||||||
|
'is_admin_only': False,
|
||||||
|
'metadata': {},
|
||||||
|
'preferred': True
|
||||||
|
}]
|
||||||
|
if isinstance(val, list):
|
||||||
|
for ip in val:
|
||||||
|
expected_export_locations.append(
|
||||||
|
{
|
||||||
|
'path': f'{ip}:/foo/bar',
|
||||||
|
'is_admin_only': False,
|
||||||
|
'metadata': {},
|
||||||
|
'preferred': False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
expected_export_locations.append(
|
||||||
|
{
|
||||||
|
'path': f'{val}:/foo/bar',
|
||||||
|
'is_admin_only': False,
|
||||||
|
'metadata': {},
|
||||||
|
'preferred': False
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export_locations = (
|
||||||
|
self._nfscluster_protocol_helper.get_export_locations(
|
||||||
|
self._share, fake_cephfs_subvolume_path))
|
||||||
|
|
||||||
|
driver.rados_command.assert_called_once_with(
|
||||||
|
self._rados_client,
|
||||||
|
cluster_info_prefix, cluster_info_dict)
|
||||||
|
|
||||||
|
self.assertEqual(expected_export_locations, export_locations)
|
||||||
|
|
||||||
|
|
||||||
@ddt.ddt
|
@ddt.ddt
|
||||||
class CephFSDriverAltConfigTestCase(test.TestCase):
|
class CephFSDriverAltConfigTestCase(test.TestCase):
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
It is now possible to configure `cephfs_ganesha_export_ips` (or
|
||||||
|
alternatively, `cephfs_ganesha_server_ip`) alongside
|
||||||
|
`cephfs_nfs_cluster_id`. Setting these options will allow the CephFS driver
|
||||||
|
to report additional export paths. These additional export paths will have
|
||||||
|
the "preferred" metadata key set to False. The export paths pertaining to
|
||||||
|
the NFS service host discovered by the driver will have the "preferred"
|
||||||
|
metadata key set to True. It is expected that administrators will configure
|
||||||
|
additional IP addresses when preparing to migrate from a standalone
|
||||||
|
NFS-Ganesha service to a NFS service cluster setup facilitated by the Ceph
|
||||||
|
orchestration service. Eventually, when the migration has completed, these
|
||||||
|
configuration options can be removed and the corresponding share export
|
||||||
|
path records will be dropped from Manila. Note that the CephFS driver will
|
||||||
|
not create or manipulate access rules within the NFS service configured via
|
||||||
|
`cephfs_ganesha_export_ips` or `cephfs_ganesha_server_ip`.
|
||||||
|
upgrades:
|
||||||
|
- |
|
||||||
|
In order to assist the user experience when migrating from a standalone
|
||||||
|
CephFS NFS (NFS-Ganesha) service to an NFS service created with the
|
||||||
|
Ceph Orchestrator, the CephFS driver allows configuring
|
||||||
|
`cephfs_ganesha_export_ips` (or alternatively, `cephfs_ganesha_server_ip`)
|
||||||
|
alongside `cephfs_nfs_cluster_id`.
|
Loading…
Reference in New Issue
Block a user