From 3814a6c1b711ee21da1646f06a3e7c757a922557 Mon Sep 17 00:00:00 2001 From: Abba Soungui YOUNOUSS Date: Mon, 10 Oct 2022 14:33:46 +0100 Subject: [PATCH] Fix missing informations on geo replication tab of GlusterFS volumes. Since the upgrade to oVirt 4.5 and GlusterFS 10, information about snapshots and geo replication are no more visible on the engine Webui. After digging VDSM logs, I found that it's caused by the change of some XML elements name introduced in a new Gluster release (https://github.com/gluster/glusterfs/pull/1568) and by the addition of the timezone in output of status command. This commit fix the parsing process of the output returned by gluster command, so that data sent to ovirt engine are as expected. Bug-URL: https://bugzilla.redhat.com/show_bug.cgi?id=2104278 --- lib/vdsm/gluster/cli.py | 34 ++++++++++++++++++++++++-------- tests/glusterGeoRepStatus.xml | 20 +++++++++---------- tests/glusterGeoRepStatusOld.xml | 34 ++++++++++++++++++++++++++++++++ tests/glusterTestData.py | 27 +++++++++++++++++++++++++ tests/gluster_cli_test.py | 8 ++++++++ 5 files changed, 105 insertions(+), 18 deletions(-) create mode 100644 tests/glusterGeoRepStatusOld.xml diff --git a/lib/vdsm/gluster/cli.py b/lib/vdsm/gluster/cli.py index b1c0df4e17..8e0926f134 100644 --- a/lib/vdsm/gluster/cli.py +++ b/lib/vdsm/gluster/cli.py @@ -1125,7 +1125,7 @@ def _parseGeoRepStatus(tree): bricks: [{host: 'local node', hostUuid: 'uuid of brick host', brickName: 'brick in the local volume', - remoteHost: 'slave', + remoteHost: 'secondary', status: 'status' remoteUserName: 'root' timeZone: 'nodes time zone' @@ -1142,6 +1142,12 @@ def _parseGeoRepStatus(tree): ].... } """ + if tree.find('geoRep/volume/sessions/session/session_secondary') is None: + # Gluster version < 10 + gluster_format = 9 + else: + # Gluster version >= 10 + gluster_format = 10 status = {} for volume in tree.findall('geoRep/volume'): sessions = [] @@ -1149,17 +1155,29 @@ def _parseGeoRepStatus(tree): for session in volume.findall('sessions/session'): pairs = [] sessionDetail = {} - sessionDetail['sessionKey'] = session.find('session_slave').text + if gluster_format == 9: + # Gluster version < 10 + sessionDetail['sessionKey'] = session.find('session_slave').text + elif gluster_format == 10: + sessionDetail['sessionKey'] = session.find('session_secondary').text sessionDetail['remoteVolumeName'] = sessionDetail[ 'sessionKey'].split("::")[-1].split(":")[0] for pair in session.findall('pair'): pairDetail = {} - pairDetail['host'] = pair.find('master_node').text - pairDetail['hostUuid'] = pair.find( - 'master_node_uuid').text - pairDetail['brickName'] = pair.find('master_brick').text - pairDetail['remoteHost'] = pair.find('slave_node').text - pairDetail['remoteUserName'] = pair.find('slave_user').text + if gluster_format == 9: + pairDetail['host'] = pair.find('master_node').text + pairDetail['hostUuid'] = pair.find('master_node_uuid').text + pairDetail['brickName'] = pair.find('master_brick').text + pairDetail['remoteHost'] = pair.find('slave_node').text + if pairDetail['remoteHost'] is None: + pairDetail['remoteHost'] = pair.find('slave').text.split("::")[0] + pairDetail['remoteUserName'] = pair.find('slave_user').text + elif gluster_format == 10: + pairDetail['host'] = pair.find('primary_node').text + pairDetail['hostUuid'] = pair.find('primary_node_uuid').text + pairDetail['brickName'] = pair.find('primary_brick').text + pairDetail['remoteHost'] = pair.find('secondary').text.split("::")[0] + pairDetail['remoteUserName'] = pair.find('secondary_user').text pairDetail['status'] = pair.find('status').text pairDetail['crawlStatus'] = pair.find('crawl_status').text pairDetail['timeZone'] = _TIME_ZONE diff --git a/tests/glusterGeoRepStatus.xml b/tests/glusterGeoRepStatus.xml index d1dc2ca254..a4805d01ae 100644 --- a/tests/glusterGeoRepStatus.xml +++ b/tests/glusterGeoRepStatus.xml @@ -8,14 +8,14 @@ vol1 - 6a2f7584-05a8-4651-8786-1cd6ae87b896:ssh://192.168.122.145::vol2 + 6a2f7584-05a8-4651-8786-1cd6ae87b896:ssh://192.168.122.145::vol2:3e8382d6-f509-49db-b64f-59a8dfb5ee3b - localhost.localdomain - 6a2f7584-05a8-4651-8786-1cd6ae87b896 - /root/b1_vol1 - root - 192.168.122.145::vol2 - 192.168.122.145 + localhost.localdomain + 6a2f7584-05a8-4651-8786-1cd6ae87b896 + /root/b1_vol1 + root + 192.168.122.145::vol2 + Stopped N/A 2014-12-12 05:18:23 @@ -23,9 +23,9 @@ 0 0 0 - 2014-12-12 05:17:23 - 2014-12-12 05:18:20 - Yes + 2014-12-12 05:17:23 + 2014-12-12 05:18:20 + Yes diff --git a/tests/glusterGeoRepStatusOld.xml b/tests/glusterGeoRepStatusOld.xml new file mode 100644 index 0000000000..d1dc2ca254 --- /dev/null +++ b/tests/glusterGeoRepStatusOld.xml @@ -0,0 +1,34 @@ + + + 0 + 0 + + + + vol1 + + + 6a2f7584-05a8-4651-8786-1cd6ae87b896:ssh://192.168.122.145::vol2 + + localhost.localdomain + 6a2f7584-05a8-4651-8786-1cd6ae87b896 + /root/b1_vol1 + root + 192.168.122.145::vol2 + 192.168.122.145 + Stopped + N/A + 2014-12-12 05:18:23 + 0 + 0 + 0 + 0 + 2014-12-12 05:17:23 + 2014-12-12 05:18:20 + Yes + + + + + + diff --git a/tests/glusterTestData.py b/tests/glusterTestData.py index ca3b015dd6..ee16ca32f4 100644 --- a/tests/glusterTestData.py +++ b/tests/glusterTestData.py @@ -1051,6 +1051,33 @@ class TestStorageDev(object): GLUSTER_GEOREP_STATUS = { + 'vol1': { + 'sessions': [ + {'bricks': [ + {'status': 'Stopped', + 'brickName': '/root/b1_vol1', + 'crawlStatus': 'N/A', + 'hostUuid': '6a2f7584-05a8-4651-8786-1cd6ae87b896', + 'remoteHost': '192.168.122.145', + 'checkpointCompletionTime': 1418361500, + 'meta': '0', + 'checkpointCompleted': 'Yes', + 'host': 'localhost.localdomain', + 'checkpointTime': 1418361443, + 'lastSynced': 1418361503, + 'failures': '0', + 'entry': '0', + 'remoteUserName': 'root', + 'timeZone': 'IST', + 'data': '0'}], + 'remoteVolumeName': 'vol2', + 'sessionKey': '6a2f7584-05a8-4651-8786-1cd6ae87b896:ssh:' + '//192.168.122.145::vol2:3e8382d6-f509-49db-b64f-59a8dfb5ee3b'} + ] + } +} + +GLUSTER_GEOREP_STATUS_OLD = { 'vol1': { 'sessions': [ {'bricks': [ diff --git a/tests/gluster_cli_test.py b/tests/gluster_cli_test.py index b987620f2e..bacb188f7f 100644 --- a/tests/gluster_cli_test.py +++ b/tests/gluster_cli_test.py @@ -1287,6 +1287,14 @@ def test_parseGeoRepStatus(self): status = gcli._parseGeoRepStatus(tree) self.assertEqual(status, glusterTestData.GLUSTER_GEOREP_STATUS) + def test_parseGeoRepStatusOld(self): + with open("glusterGeoRepStatusOld.xml") as f: + out = f.read() + tree = etree.fromstring(out) + gcli._TIME_ZONE = 'IST' + status = gcli._parseGeoRepStatus(tree) + self.assertEqual(status, glusterTestData.GLUSTER_GEOREP_STATUS_OLD) + def test_parseVolumeGeoRepConfig(self): with open("glusterVolumeGeoRepConfigList.xml") as f: out = f.read()