From d8e380c563acc816e4b54cbdb42e1ddb379b5eec Mon Sep 17 00:00:00 2001 From: Aleksei Burlakov Date: Fri, 9 Feb 2024 17:19:35 +0100 Subject: [PATCH] Dev: ui_node: refactor do_clearstate Parse the cibadmin output depending on the pacemaker version. (ref: https://github.com/ClusterLabs/pacemaker/pull/3031, cibadmin has little changed it's format at Version-2.1.7). --- crmsh/ui_node.py | 23 +++++++++++++++++------ crmsh/utils.py | 22 ++++++++++++++++++++-- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/crmsh/ui_node.py b/crmsh/ui_node.py index e9956b373f..f8c5032963 100644 --- a/crmsh/ui_node.py +++ b/crmsh/ui_node.py @@ -501,12 +501,23 @@ def do_clearstate(self, context, node=None): cib_elem = xmlutil.cibdump2elem() if cib_elem is None: return False - if cib_elem.xpath("//node_state[@uname=\"%s\"]/@crmd" % node) == ["online"]: - return utils.ext_cmd(self.node_cleanup_resources % node) == 0 - elif cib_elem.xpath("//node_state[@uname=\"%s\"]/@in_ccm" % node) == ["true"]: - logger.warning("Node is offline according to Pacemaker, but online according to corosync. First shut down node '%s'", node) - return False - else: + if utils.is_pcmk_version_between("1.1.8", "2.1.6"): + if cib_elem.xpath("//node_state[@uname=\"%s\"]/@crmd" % node) == ["online"]: + return utils.ext_cmd(self.node_cleanup_resources % node) == 0 + elif cib_elem.xpath("//node_state[@uname=\"%s\"]/@in_ccm" % node) == ["true"]: + logger.warning("Node is offline according to Pacemaker, but online according to corosync. First shut down node '%s'", node) + return False + else: + return utils.ext_cmd(self.node_clear_state_118 % node) == 0 + # TODO: Add a test with an newer pacemaker version + if utils.is_min_pcmk_ver("2.1.7"): + crmd = cib_elem.xpath("//node_state[@uname=\"%s\"]/@crmd" % node) + if crmd and crmd[0].isdigit() and int(crmd[0]) != 0: + return utils.ext_cmd(self.node_cleanup_resources % node) == 0 + in_ccm = cib_elem.xpath("//node_state[@uname=\"%s\"]/@in_ccm" % node) + if in_ccm and in_ccm[0].isdigit() and int(in_ccm[0]) != 0: + logger.warning("Node is offline according to Pacemaker, but online according to corosync. First shut down node '%s'", node) + return False return utils.ext_cmd(self.node_clear_state_118 % node) == 0 else: return utils.ext_cmd(self.node_clear_state % ("-M -c", node, node)) == 0 and \ diff --git a/crmsh/utils.py b/crmsh/utils.py index c56f5f43af..bff94c49e3 100644 --- a/crmsh/utils.py +++ b/crmsh/utils.py @@ -1828,8 +1828,7 @@ def get_cib_attributes(cib_f, tag, attr_l, dflt_l): def is_larger_than_min_version(version, min_version): return LooseVersion(version) >= LooseVersion(min_version) - -def is_min_pcmk_ver(min_ver, cib_f=None): +def set_pcmk_version(cib_f=None): if not constants.pcmk_version: if cib_f: constants.pcmk_version = get_cib_property(cib_f, "dc-version") @@ -1839,12 +1838,31 @@ def is_min_pcmk_ver(min_ver, cib_f=None): fatal(f"Failed to get 'dc-version' from {cib_f}") else: constants.pcmk_version = get_pcmk_version() + +def is_min_pcmk_ver(min_ver, cib_f=None): + set_pcmk_version(cib_f) return is_larger_than_min_version(constants.pcmk_version, min_ver) def is_larger_than_pcmk_118(cib_f=None): return is_min_pcmk_ver("1.1.8", cib_f=cib_f) +def is_pcmk_version_between(min_version, max_version, exclude_versions=None, cib_f=None): + """ + Check if the pacemaker version is between min_ and max_version, + and not in the exclude_versions list. + """ + set_pcmk_version(cib_f) + if exclude_versions: + for v in exclude_versions: + if LooseVersion(constants.pcmk_version) == LooseVersion(v): + return False + result = True + if min_version: + result = result and ( LooseVersion(constants.pcmk_version) >= LooseVersion(min_version) ) + if max_version: + result = result and ( LooseVersion(constants.pcmk_version) <= LooseVersion(max_version) ) + return result @memoize def cibadmin_features():