Fix finding local osds

Previously, this function could crash upon encountering
some non-osd files such as `ceph.client.crash.keyring`.

Copy the logic from `find_filestore_osds()` to be more correct
for finding the ceph osd directories.

Closes-Bug: #2072920
Change-Id: I632008b10cfb7f667163c9381ae48432cbd65547
This commit is contained in:
Samuel Allan 2024-07-30 10:07:40 +09:30
parent b4a870af2c
commit 46dbc89d57
No known key found for this signature in database
GPG Key ID: 622F8E99C893BD61
2 changed files with 27 additions and 18 deletions

View File

@ -695,7 +695,7 @@ def get_crimson_osd_ids():
def get_local_osd_ids(): def get_local_osd_ids():
"""This will list the /var/lib/ceph/osd/* directories and try """This will list the /var/lib/ceph/osd/ceph-* directories and try
to split the ID off of the directory name and return it in to split the ID off of the directory name and return it in
a list. Excludes crimson OSD's from the returned list. a list. Excludes crimson OSD's from the returned list.
@ -704,19 +704,18 @@ def get_local_osd_ids():
""" """
osd_ids = [] osd_ids = []
crimson_osds = get_crimson_osd_ids() crimson_osds = get_crimson_osd_ids()
osd_path = os.path.join(os.sep, 'var', 'lib', 'ceph', 'osd') osd_path = '/var/lib/ceph/osd'
if os.path.exists(osd_path): if os.path.exists(osd_path):
try: dirs = [d for d in os.listdir(osd_path)
dirs = os.listdir(osd_path) if d.startswith('ceph-')
for osd_dir in dirs: and os.path.isdir(os.path.join(osd_path, d))]
osd_id = osd_dir.split('-')[1] if '-' in osd_dir else '' for osd_dir in dirs:
if (_is_int(osd_id) and osd_id = osd_dir.split('-', maxsplit=1)[1]
filesystem_mounted(os.path.join( if (_is_int(osd_id) and
os.sep, osd_path, osd_dir)) and filesystem_mounted(os.path.join(
osd_id not in crimson_osds): osd_path, osd_dir)) and
osd_ids.append(osd_id) osd_id not in crimson_osds):
except OSError: osd_ids.append(osd_id)
raise
return osd_ids return osd_ids

View File

@ -120,17 +120,27 @@ class OSDMountTestCase(CharmTestCase):
def setUp(self): def setUp(self):
super(OSDMountTestCase, self).setUp(actions, []) super(OSDMountTestCase, self).setUp(actions, [])
@mock.patch('os.path.isdir')
@mock.patch('os.path.exists') @mock.patch('os.path.exists')
@mock.patch('os.listdir') @mock.patch('os.listdir')
@mock.patch('charms_ceph.utils.filesystem_mounted') @mock.patch('charms_ceph.utils.filesystem_mounted')
def test_mounted_osds(self, fs_mounted, listdir, exists): def test_mounted_osds(self, fs_mounted, listdir, exists, isdir):
# Simulate two osds, only one of which is mounted.
# Also include some unrelated files which should be cleanly ignored.
exists.return_value = True exists.return_value = True
isdir.return_value = True
listdir.return_value = [ listdir.return_value = [
'/var/lib/ceph/osd/ceph-1', '/var/lib/ceph/osd/ceph-2'] 'ceph-1',
fs_mounted.side_effect = lambda x: x == listdir.return_value[0] 'ceph-2',
'ceph.client.crash.keyring',
'ceph.client.osd-removal.keyring',
'ceph.client.osd-upgrade.keyring',
]
fs_mounted.side_effect = lambda x: x == '/var/lib/ceph/osd/ceph-1'
osds = actions.get_local_osd_ids() osds = actions.get_local_osd_ids()
self.assertIn(listdir.return_value[0][-1], osds)
self.assertNotIn(listdir.return_value[1][-1], osds) self.assertEqual(osds, ['1'])
class MainTestCase(CharmTestCase): class MainTestCase(CharmTestCase):