rbd: Support 'rbd showmapped' output from ceph 13.2.0+

Ceph 13.2.0 changed [1] the JSON and XML output format for the 'rbd
showmapped' command, from a object keyed by device ID to a list of
device objects. Handle this change.

Change-Id: I55bc70437d41da3a32b8440d00c139805b8be256
Signed-off-by: Stephen Finucane <sfinucan@redhat.com>
Closes-Bug: #1884052
(cherry picked from commit a87ef7bbab)
(cherry picked from commit bf0faeaea4)
This commit is contained in:
Stephen Finucane 2020-06-18 11:33:33 +01:00
parent c380107de5
commit ba9d47a9b5
3 changed files with 55 additions and 6 deletions

View File

@ -220,7 +220,43 @@ class RBDConnector(base.BaseLinuxConnector):
cmd += self._get_rbd_args(connection_properties)
(out, err) = self._execute(*cmd, root_helper=self._root_helper,
run_as_root=True)
for index, mapping in jsonutils.loads(out).items():
# ceph v13.2.0 (Mimic) changed the output format of 'rbd showmapped'
# from a dict of mappings keyed by ID to a simple list of mappings
# https://docs.ceph.com/docs/master/releases/mimic/
#
# before:
#
# {
# "0": {
# "pool":"volumes",
# "namespace":"",
# "name":"volume-6d54cb90-a5d1-40d8-9cb2-c6adf43a02af",
# "snap":"-",
# "device":"/dev/rbd0"
# }
# }
#
# after:
#
# [
# {
# "id":"0",
# "pool":"volumes",
# "namespace":"",
# "name":"volume-6d54cb90-a5d1-40d8-9cb2-c6adf43a02af",
# "snap":"-",
# "device":"/dev/rbd0"
# }
# ]
#
# TODO(stephenfin): Drop when we drop support for ceph 13.2.0
mappings = jsonutils.loads(out)
if isinstance(mappings, dict):
# yes, we're losing the ID field but we don't need it here
mappings = mappings.values()
for mapping in mappings:
if mapping['name'] == volume:
return mapping['device']
return None

View File

@ -250,17 +250,25 @@ class RBDConnectorTestCase(test_connector.ConnectorTestCase):
self.assertEqual(1, volume_close.call_count)
@ddt.data(
"""
[{"id":"0","pool":"pool","device":"/dev/rbd0","name":"image"},
{"id":"1","pool":"pool","device":"/dev/rdb1","name":"image_2"}]
""", # new-style output (ceph 13.2.0+)
"""
{"0":{"pool":"pool","device":"/dev/rbd0","name":"image"},
"1":{"pool":"pool","device":"/dev/rdb1","name":"image_2"}}
""", # old-style output
)
@mock.patch.object(priv_rootwrap, 'execute', return_value=None)
def test_disconnect_local_volume(self, mock_execute):
def test_disconnect_local_volume(self, rbd_map_out, mock_execute):
"""Test the disconnect volume case with local attach."""
rbd_connector = rbd.RBDConnector(None, do_local_attach=True)
conn = {'name': 'pool/image',
'auth_username': 'fake_user',
'hosts': ['192.168.10.2'],
'ports': ['6789']}
mock_execute.side_effect = [("""
{"0":{"pool":"pool","device":"/dev/rbd0","name":"image"},
"1":{"pool":"pool","device":"/dev/rdb1","name":"image_2"}}""", None),
(None, None)]
mock_execute.side_effect = [(rbd_map_out, None), (None, None)]
show_cmd = ['rbd', 'showmapped', '--format=json', '--id', 'fake_user',
'--mon_host', '192.168.10.2:6789']
unmap_cmd = ['rbd', 'unmap', '/dev/rbd0', '--id', 'fake_user',

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Fix an incompatibility with ceph 13.2.0 (Mimic) or later, caused by a
change in the output of ``rbd map``.