From ba9d47a9b585dd619af857b6ea43dfb2ef04029c Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 18 Jun 2020 11:33:33 +0100 Subject: [PATCH] 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 Closes-Bug: #1884052 (cherry picked from commit a87ef7bbabc80bf7f2d078764986aea2cbb90aa5) (cherry picked from commit bf0faeaea4626f7dee37a672da7e3f175b958086) --- os_brick/initiator/connectors/rbd.py | 38 ++++++++++++++++++- .../tests/initiator/connectors/test_rbd.py | 18 ++++++--- .../notes/bug-1884052-798094496dccf23c.yaml | 5 +++ 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/bug-1884052-798094496dccf23c.yaml diff --git a/os_brick/initiator/connectors/rbd.py b/os_brick/initiator/connectors/rbd.py index 9257a260c..d26d56a7f 100644 --- a/os_brick/initiator/connectors/rbd.py +++ b/os_brick/initiator/connectors/rbd.py @@ -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 diff --git a/os_brick/tests/initiator/connectors/test_rbd.py b/os_brick/tests/initiator/connectors/test_rbd.py index 0fd284c23..b8ce8b9a8 100644 --- a/os_brick/tests/initiator/connectors/test_rbd.py +++ b/os_brick/tests/initiator/connectors/test_rbd.py @@ -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', diff --git a/releasenotes/notes/bug-1884052-798094496dccf23c.yaml b/releasenotes/notes/bug-1884052-798094496dccf23c.yaml new file mode 100644 index 000000000..36d747b68 --- /dev/null +++ b/releasenotes/notes/bug-1884052-798094496dccf23c.yaml @@ -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``.